package net.floodlightcontroller.debugevent; import static org.junit.Assert.*; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import net.floodlightcontroller.debugevent.IDebugEventService.EventColumn; import net.floodlightcontroller.debugevent.IDebugEventService.EventFieldType; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EventTest { protected static Logger log = LoggerFactory.getLogger(EventTest.class); @Test public void testFormat() { River r = new River("ganges", 42); Event e = new Event(1L, 32, "test", new RiverEvent(1L, (short)10, true, "big river", 5, 4L, r)); Map<String, String> expected = new HashMap<String, String>(); expected.put("dpid", "00:00:00:00:00:00:00:01"); expected.put("portId", "10"); expected.put("valid", "true"); expected.put("desc", "big river"); expected.put("ip", "0.0.0.5"); expected.put("mac", "00:00:00:00:00:04"); expected.put("obj", "ganges/42"); //log.info("{} \n expected {}", e.getFormattedEvent(RiverEvent.class, "test"), expected); for (Entry<String, String> elem : expected.entrySet()) assertEquals(elem.getValue(), e.getFormattedEvent(RiverEvent.class, "test").get(elem.getKey())); // ensure timestamp comes in ISO8601 time assertEquals("1969-12-31T16:00:00.001-0800", e.getFormattedEvent(RiverEvent.class, "test2").get("Timestamp")); //1L // change the timestamp - the call should return cached value e.setTimestamp(2L); assertEquals("1969-12-31T16:00:00.001-0800", e.getFormattedEvent(RiverEvent.class, "test2").get("Timestamp")); //1L // ensure that cached value is not returned for incorrect class for (Entry<String, String> elem : expected.entrySet()) assertFalse(elem.getValue().equals( e.getFormattedEvent(River.class, "test").get(elem.getKey()))); assertEquals("null event data or event-class does not match event-data", e.getFormattedEvent(River.class, "test").get("Error")); assertEquals("null event data or event-class does not match event-data", e.getFormattedEvent(null, "test").get("Error")); } @Test public void testIncorrectAnnotation() { Event e = new Event(1L, 32, "test", new LakeEvent(199)); // dpid cannot be int assertEquals("java.lang.Integer cannot be cast to java.lang.Long", e.getFormattedEvent(LakeEvent.class, "test").get("Error")); Event e2 = new Event(1L, 32, "test", new LakeEvent2(199)); // mac cannot be int assertEquals("java.lang.Integer cannot be cast to java.lang.Long", e2.getFormattedEvent(LakeEvent2.class, "test").get("Error")); } class RiverEvent { @EventColumn(name = "dpid", description = EventFieldType.DPID) long dpid; @EventColumn(name = "portId", description = EventFieldType.PRIMITIVE) short srcPort; @EventColumn(name = "valid", description = EventFieldType.PRIMITIVE) boolean isValid; @EventColumn(name = "desc", description = EventFieldType.STRING) String desc; @EventColumn(name = "ip", description = EventFieldType.IPv4) int ipAddr; @EventColumn(name = "mac", description = EventFieldType.MAC) long macAddr; @EventColumn(name = "obj", description = EventFieldType.OBJECT) River amazon; // Instances of RiverEvent ensure that that any internal object // (eg. River instances) has been copied before it is given to DebugEvents. public RiverEvent(long dpid, short srcPort, boolean isValid, String desc, int ip, long mac, River passedin) { this.dpid = dpid; this.srcPort = srcPort; this.isValid = isValid; this.desc = desc; this.ipAddr = ip; this.macAddr = mac; this.amazon = new River(passedin); // invoke copy constructor } } // Object of the River class will be passed in as part of the EventExample instance // The user needs to ensure that the River class has a copy constructor // and it overrides the toString method. class River { String r1; long r2; public River(String r1, long r2) { this.r1 = r1; this.r2 = r2; } // should have copy constructor public River(River passedin) { this.r1 = passedin.r1; this.r2 = passedin.r2; } // needs to override toString method @Override public String toString() { return (r1 + "/" + r2); } } class LakeEvent { @EventColumn(name = "dpid", description = EventFieldType.DPID) int dpid; public LakeEvent(int dpid) { this.dpid = dpid; } } class LakeEvent2 { @EventColumn(name = "mac", description = EventFieldType.MAC) int mac; public LakeEvent2(int mac) { this.mac = mac; } } }