Simple{Device,Link}Store test
Change-Id: I2463248be1ba9d4640e5e9d5110825c747e9094c
Showing
6 changed files
with
729 additions
and
11 deletions
... | @@ -41,6 +41,9 @@ import com.google.common.collect.Sets; | ... | @@ -41,6 +41,9 @@ import com.google.common.collect.Sets; |
41 | import com.hazelcast.config.Config; | 41 | import com.hazelcast.config.Config; |
42 | import com.hazelcast.core.Hazelcast; | 42 | import com.hazelcast.core.Hazelcast; |
43 | 43 | ||
44 | +/** | ||
45 | + * Test of the Hazelcast based distributed DeviceStore implementation. | ||
46 | + */ | ||
44 | public class DistributedDeviceStoreTest { | 47 | public class DistributedDeviceStoreTest { |
45 | 48 | ||
46 | private static final ProviderId PID = new ProviderId("of", "foo"); | 49 | private static final ProviderId PID = new ProviderId("of", "foo"); | ... | ... |
... | @@ -34,16 +34,14 @@ import com.google.common.collect.Iterables; | ... | @@ -34,16 +34,14 @@ import com.google.common.collect.Iterables; |
34 | import com.hazelcast.config.Config; | 34 | import com.hazelcast.config.Config; |
35 | import com.hazelcast.core.Hazelcast; | 35 | import com.hazelcast.core.Hazelcast; |
36 | 36 | ||
37 | +/** | ||
38 | + * Test of the Hazelcast based distributed LinkStore implementation. | ||
39 | + */ | ||
37 | public class DistributedLinkStoreTest { | 40 | public class DistributedLinkStoreTest { |
38 | 41 | ||
39 | private static final ProviderId PID = new ProviderId("of", "foo"); | 42 | private static final ProviderId PID = new ProviderId("of", "foo"); |
40 | private static final DeviceId DID1 = deviceId("of:foo"); | 43 | private static final DeviceId DID1 = deviceId("of:foo"); |
41 | private static final DeviceId DID2 = deviceId("of:bar"); | 44 | private static final DeviceId DID2 = deviceId("of:bar"); |
42 | -// private static final String MFR = "whitebox"; | ||
43 | -// private static final String HW = "1.1.x"; | ||
44 | -// private static final String SW1 = "3.8.1"; | ||
45 | -// private static final String SW2 = "3.9.5"; | ||
46 | -// private static final String SN = "43311-12345"; | ||
47 | 45 | ||
48 | private static final PortNumber P1 = PortNumber.portNumber(1); | 46 | private static final PortNumber P1 = PortNumber.portNumber(1); |
49 | private static final PortNumber P2 = PortNumber.portNumber(2); | 47 | private static final PortNumber P2 = PortNumber.portNumber(2); | ... | ... |
... | @@ -101,9 +101,6 @@ public class SimpleDeviceStore | ... | @@ -101,9 +101,6 @@ public class SimpleDeviceStore |
101 | synchronized (this) { | 101 | synchronized (this) { |
102 | devices.put(deviceId, device); | 102 | devices.put(deviceId, device); |
103 | availableDevices.add(deviceId); | 103 | availableDevices.add(deviceId); |
104 | - | ||
105 | - // For now claim the device as a master automatically. | ||
106 | - // roles.put(deviceId, MastershipRole.MASTER); | ||
107 | } | 104 | } |
108 | return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); | 105 | return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null); |
109 | } | 106 | } |
... | @@ -189,7 +186,7 @@ public class SimpleDeviceStore | ... | @@ -189,7 +186,7 @@ public class SimpleDeviceStore |
189 | new DefaultPort(device, portDescription.portNumber(), | 186 | new DefaultPort(device, portDescription.portNumber(), |
190 | portDescription.isEnabled()); | 187 | portDescription.isEnabled()); |
191 | ports.put(port.number(), updatedPort); | 188 | ports.put(port.number(), updatedPort); |
192 | - return new DeviceEvent(PORT_UPDATED, device, port); | 189 | + return new DeviceEvent(PORT_UPDATED, device, updatedPort); |
193 | } | 190 | } |
194 | return null; | 191 | return null; |
195 | } | 192 | } | ... | ... |
... | @@ -51,8 +51,6 @@ public class SimpleLinkStore | ... | @@ -51,8 +51,6 @@ public class SimpleLinkStore |
51 | private final Multimap<DeviceId, Link> srcLinks = HashMultimap.create(); | 51 | private final Multimap<DeviceId, Link> srcLinks = HashMultimap.create(); |
52 | private final Multimap<DeviceId, Link> dstLinks = HashMultimap.create(); | 52 | private final Multimap<DeviceId, Link> dstLinks = HashMultimap.create(); |
53 | 53 | ||
54 | - private static final Set<Link> EMPTY = ImmutableSet.of(); | ||
55 | - | ||
56 | @Activate | 54 | @Activate |
57 | public void activate() { | 55 | public void activate() { |
58 | log.info("Started"); | 56 | log.info("Started"); | ... | ... |
core/store/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStoreTest.java
0 → 100644
1 | +/** | ||
2 | + * | ||
3 | + */ | ||
4 | +package org.onlab.onos.net.trivial.impl; | ||
5 | + | ||
6 | +import static org.junit.Assert.*; | ||
7 | +import static org.onlab.onos.net.Device.Type.SWITCH; | ||
8 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
9 | +import static org.onlab.onos.net.device.DeviceEvent.Type.*; | ||
10 | + | ||
11 | +import java.util.Arrays; | ||
12 | +import java.util.HashMap; | ||
13 | +import java.util.List; | ||
14 | +import java.util.Map; | ||
15 | +import java.util.Set; | ||
16 | +import java.util.concurrent.CountDownLatch; | ||
17 | +import java.util.concurrent.TimeUnit; | ||
18 | + | ||
19 | +import org.junit.After; | ||
20 | +import org.junit.AfterClass; | ||
21 | +import org.junit.Before; | ||
22 | +import org.junit.BeforeClass; | ||
23 | +import org.junit.Ignore; | ||
24 | +import org.junit.Test; | ||
25 | +import org.onlab.onos.net.Device; | ||
26 | +import org.onlab.onos.net.DeviceId; | ||
27 | +import org.onlab.onos.net.Port; | ||
28 | +import org.onlab.onos.net.PortNumber; | ||
29 | +import org.onlab.onos.net.device.DefaultDeviceDescription; | ||
30 | +import org.onlab.onos.net.device.DefaultPortDescription; | ||
31 | +import org.onlab.onos.net.device.DeviceDescription; | ||
32 | +import org.onlab.onos.net.device.DeviceEvent; | ||
33 | +import org.onlab.onos.net.device.DeviceStore; | ||
34 | +import org.onlab.onos.net.device.DeviceStoreDelegate; | ||
35 | +import org.onlab.onos.net.device.PortDescription; | ||
36 | +import org.onlab.onos.net.provider.ProviderId; | ||
37 | + | ||
38 | +import com.google.common.collect.Iterables; | ||
39 | +import com.google.common.collect.Sets; | ||
40 | + | ||
41 | +/** | ||
42 | + * Test of the simple DeviceStore implementation. | ||
43 | + */ | ||
44 | +public class SimpleDeviceStoreTest { | ||
45 | + | ||
46 | + private static final ProviderId PID = new ProviderId("of", "foo"); | ||
47 | + private static final DeviceId DID1 = deviceId("of:foo"); | ||
48 | + private static final DeviceId DID2 = deviceId("of:bar"); | ||
49 | + private static final String MFR = "whitebox"; | ||
50 | + private static final String HW = "1.1.x"; | ||
51 | + private static final String SW1 = "3.8.1"; | ||
52 | + private static final String SW2 = "3.9.5"; | ||
53 | + private static final String SN = "43311-12345"; | ||
54 | + | ||
55 | + private static final PortNumber P1 = PortNumber.portNumber(1); | ||
56 | + private static final PortNumber P2 = PortNumber.portNumber(2); | ||
57 | + private static final PortNumber P3 = PortNumber.portNumber(3); | ||
58 | + | ||
59 | + private SimpleDeviceStore simpleDeviceStore; | ||
60 | + private DeviceStore deviceStore; | ||
61 | + | ||
62 | + | ||
63 | + | ||
64 | + @BeforeClass | ||
65 | + public static void setUpBeforeClass() throws Exception { | ||
66 | + } | ||
67 | + | ||
68 | + @AfterClass | ||
69 | + public static void tearDownAfterClass() throws Exception { | ||
70 | + } | ||
71 | + | ||
72 | + | ||
73 | + @Before | ||
74 | + public void setUp() throws Exception { | ||
75 | + simpleDeviceStore = new SimpleDeviceStore(); | ||
76 | + simpleDeviceStore.activate(); | ||
77 | + deviceStore = simpleDeviceStore; | ||
78 | + } | ||
79 | + | ||
80 | + @After | ||
81 | + public void tearDown() throws Exception { | ||
82 | + simpleDeviceStore.deactivate(); | ||
83 | + } | ||
84 | + | ||
85 | + private void putDevice(DeviceId deviceId, String swVersion) { | ||
86 | + DeviceDescription description = | ||
87 | + new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR, | ||
88 | + HW, swVersion, SN); | ||
89 | + deviceStore.createOrUpdateDevice(PID, deviceId, description); | ||
90 | + } | ||
91 | + | ||
92 | + private static void assertDevice(DeviceId id, String swVersion, Device device) { | ||
93 | + assertNotNull(device); | ||
94 | + assertEquals(id, device.id()); | ||
95 | + assertEquals(MFR, device.manufacturer()); | ||
96 | + assertEquals(HW, device.hwVersion()); | ||
97 | + assertEquals(swVersion, device.swVersion()); | ||
98 | + assertEquals(SN, device.serialNumber()); | ||
99 | + } | ||
100 | + | ||
101 | + @Test | ||
102 | + public final void testGetDeviceCount() { | ||
103 | + assertEquals("initialy empty", 0, deviceStore.getDeviceCount()); | ||
104 | + | ||
105 | + putDevice(DID1, SW1); | ||
106 | + putDevice(DID2, SW2); | ||
107 | + putDevice(DID1, SW1); | ||
108 | + | ||
109 | + assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount()); | ||
110 | + } | ||
111 | + | ||
112 | + @Test | ||
113 | + public final void testGetDevices() { | ||
114 | + assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices())); | ||
115 | + | ||
116 | + putDevice(DID1, SW1); | ||
117 | + putDevice(DID2, SW2); | ||
118 | + putDevice(DID1, SW1); | ||
119 | + | ||
120 | + assertEquals("expect 2 uniq devices", | ||
121 | + 2, Iterables.size(deviceStore.getDevices())); | ||
122 | + | ||
123 | + Map<DeviceId, Device> devices = new HashMap<>(); | ||
124 | + for (Device device : deviceStore.getDevices()) { | ||
125 | + devices.put(device.id(), device); | ||
126 | + } | ||
127 | + | ||
128 | + assertDevice(DID1, SW1, devices.get(DID1)); | ||
129 | + assertDevice(DID2, SW2, devices.get(DID2)); | ||
130 | + | ||
131 | + // add case for new node? | ||
132 | + } | ||
133 | + | ||
134 | + @Test | ||
135 | + public final void testGetDevice() { | ||
136 | + | ||
137 | + putDevice(DID1, SW1); | ||
138 | + | ||
139 | + assertDevice(DID1, SW1, deviceStore.getDevice(DID1)); | ||
140 | + assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2)); | ||
141 | + } | ||
142 | + | ||
143 | + @Test | ||
144 | + public final void testCreateOrUpdateDevice() { | ||
145 | + DeviceDescription description = | ||
146 | + new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, | ||
147 | + HW, SW1, SN); | ||
148 | + DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description); | ||
149 | + assertEquals(DEVICE_ADDED, event.type()); | ||
150 | + assertDevice(DID1, SW1, event.subject()); | ||
151 | + | ||
152 | + DeviceDescription description2 = | ||
153 | + new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, | ||
154 | + HW, SW2, SN); | ||
155 | + DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2); | ||
156 | + assertEquals(DEVICE_UPDATED, event2.type()); | ||
157 | + assertDevice(DID1, SW2, event2.subject()); | ||
158 | + | ||
159 | + assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2)); | ||
160 | + } | ||
161 | + | ||
162 | + @Test | ||
163 | + public final void testMarkOffline() { | ||
164 | + | ||
165 | + putDevice(DID1, SW1); | ||
166 | + assertTrue(deviceStore.isAvailable(DID1)); | ||
167 | + | ||
168 | + DeviceEvent event = deviceStore.markOffline(DID1); | ||
169 | + assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type()); | ||
170 | + assertDevice(DID1, SW1, event.subject()); | ||
171 | + assertFalse(deviceStore.isAvailable(DID1)); | ||
172 | + | ||
173 | + DeviceEvent event2 = deviceStore.markOffline(DID1); | ||
174 | + assertNull("No change, no event", event2); | ||
175 | +} | ||
176 | + | ||
177 | + @Test | ||
178 | + public final void testUpdatePorts() { | ||
179 | + putDevice(DID1, SW1); | ||
180 | + List<PortDescription> pds = Arrays.<PortDescription>asList( | ||
181 | + new DefaultPortDescription(P1, true), | ||
182 | + new DefaultPortDescription(P2, true) | ||
183 | + ); | ||
184 | + | ||
185 | + List<DeviceEvent> events = deviceStore.updatePorts(DID1, pds); | ||
186 | + | ||
187 | + Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2); | ||
188 | + for (DeviceEvent event : events) { | ||
189 | + assertEquals(PORT_ADDED, event.type()); | ||
190 | + assertDevice(DID1, SW1, event.subject()); | ||
191 | + assertTrue("PortNumber is one of expected", | ||
192 | + expectedPorts.remove(event.port().number())); | ||
193 | + assertTrue("Port is enabled", event.port().isEnabled()); | ||
194 | + } | ||
195 | + assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty()); | ||
196 | + | ||
197 | + | ||
198 | + List<PortDescription> pds2 = Arrays.<PortDescription>asList( | ||
199 | + new DefaultPortDescription(P1, false), | ||
200 | + new DefaultPortDescription(P2, true), | ||
201 | + new DefaultPortDescription(P3, true) | ||
202 | + ); | ||
203 | + | ||
204 | + events = deviceStore.updatePorts(DID1, pds2); | ||
205 | + assertFalse("event should be triggered", events.isEmpty()); | ||
206 | + for (DeviceEvent event : events) { | ||
207 | + PortNumber num = event.port().number(); | ||
208 | + if (P1.equals(num)) { | ||
209 | + assertEquals(PORT_UPDATED, event.type()); | ||
210 | + assertDevice(DID1, SW1, event.subject()); | ||
211 | + assertFalse("Port is disabled", event.port().isEnabled()); | ||
212 | + } else if (P2.equals(num)) { | ||
213 | + fail("P2 event not expected."); | ||
214 | + } else if (P3.equals(num)) { | ||
215 | + assertEquals(PORT_ADDED, event.type()); | ||
216 | + assertDevice(DID1, SW1, event.subject()); | ||
217 | + assertTrue("Port is enabled", event.port().isEnabled()); | ||
218 | + } else { | ||
219 | + fail("Unknown port number encountered: " + num); | ||
220 | + } | ||
221 | + } | ||
222 | + | ||
223 | + List<PortDescription> pds3 = Arrays.<PortDescription>asList( | ||
224 | + new DefaultPortDescription(P1, false), | ||
225 | + new DefaultPortDescription(P2, true) | ||
226 | + ); | ||
227 | + events = deviceStore.updatePorts(DID1, pds3); | ||
228 | + assertFalse("event should be triggered", events.isEmpty()); | ||
229 | + for (DeviceEvent event : events) { | ||
230 | + PortNumber num = event.port().number(); | ||
231 | + if (P1.equals(num)) { | ||
232 | + fail("P1 event not expected."); | ||
233 | + } else if (P2.equals(num)) { | ||
234 | + fail("P2 event not expected."); | ||
235 | + } else if (P3.equals(num)) { | ||
236 | + assertEquals(PORT_REMOVED, event.type()); | ||
237 | + assertDevice(DID1, SW1, event.subject()); | ||
238 | + assertTrue("Port was enabled", event.port().isEnabled()); | ||
239 | + } else { | ||
240 | + fail("Unknown port number encountered: " + num); | ||
241 | + } | ||
242 | + } | ||
243 | + | ||
244 | + } | ||
245 | + | ||
246 | + @Test | ||
247 | + public final void testUpdatePortStatus() { | ||
248 | + putDevice(DID1, SW1); | ||
249 | + List<PortDescription> pds = Arrays.<PortDescription>asList( | ||
250 | + new DefaultPortDescription(P1, true) | ||
251 | + ); | ||
252 | + deviceStore.updatePorts(DID1, pds); | ||
253 | + | ||
254 | + DeviceEvent event = deviceStore.updatePortStatus(DID1, | ||
255 | + new DefaultPortDescription(P1, false)); | ||
256 | + assertEquals(PORT_UPDATED, event.type()); | ||
257 | + assertDevice(DID1, SW1, event.subject()); | ||
258 | + assertEquals(P1, event.port().number()); | ||
259 | + assertFalse("Port is disabled", event.port().isEnabled()); | ||
260 | + } | ||
261 | + | ||
262 | + @Test | ||
263 | + public final void testGetPorts() { | ||
264 | + putDevice(DID1, SW1); | ||
265 | + putDevice(DID2, SW1); | ||
266 | + List<PortDescription> pds = Arrays.<PortDescription>asList( | ||
267 | + new DefaultPortDescription(P1, true), | ||
268 | + new DefaultPortDescription(P2, true) | ||
269 | + ); | ||
270 | + deviceStore.updatePorts(DID1, pds); | ||
271 | + | ||
272 | + Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2); | ||
273 | + List<Port> ports = deviceStore.getPorts(DID1); | ||
274 | + for (Port port : ports) { | ||
275 | + assertTrue("Port is enabled", port.isEnabled()); | ||
276 | + assertTrue("PortNumber is one of expected", | ||
277 | + expectedPorts.remove(port.number())); | ||
278 | + } | ||
279 | + assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty()); | ||
280 | + | ||
281 | + | ||
282 | + assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty()); | ||
283 | + } | ||
284 | + | ||
285 | + @Test | ||
286 | + public final void testGetPort() { | ||
287 | + putDevice(DID1, SW1); | ||
288 | + putDevice(DID2, SW1); | ||
289 | + List<PortDescription> pds = Arrays.<PortDescription>asList( | ||
290 | + new DefaultPortDescription(P1, true), | ||
291 | + new DefaultPortDescription(P2, false) | ||
292 | + ); | ||
293 | + deviceStore.updatePorts(DID1, pds); | ||
294 | + | ||
295 | + Port port1 = deviceStore.getPort(DID1, P1); | ||
296 | + assertEquals(P1, port1.number()); | ||
297 | + assertTrue("Port is enabled", port1.isEnabled()); | ||
298 | + | ||
299 | + Port port2 = deviceStore.getPort(DID1, P2); | ||
300 | + assertEquals(P2, port2.number()); | ||
301 | + assertFalse("Port is disabled", port2.isEnabled()); | ||
302 | + | ||
303 | + Port port3 = deviceStore.getPort(DID1, P3); | ||
304 | + assertNull("P3 not expected", port3); | ||
305 | + } | ||
306 | + | ||
307 | + @Test | ||
308 | + public final void testRemoveDevice() { | ||
309 | + putDevice(DID1, SW1); | ||
310 | + putDevice(DID2, SW1); | ||
311 | + | ||
312 | + assertEquals(2, deviceStore.getDeviceCount()); | ||
313 | + | ||
314 | + DeviceEvent event = deviceStore.removeDevice(DID1); | ||
315 | + assertEquals(DEVICE_REMOVED, event.type()); | ||
316 | + assertDevice(DID1, SW1, event.subject()); | ||
317 | + | ||
318 | + assertEquals(1, deviceStore.getDeviceCount()); | ||
319 | + } | ||
320 | + | ||
321 | + // If Delegates should be called only on remote events, | ||
322 | + // then Simple* should never call them, thus not test required. | ||
323 | + // TODO add test for Port events when we have them | ||
324 | + @Ignore("Ignore until Delegate spec. is clear.") | ||
325 | + @Test | ||
326 | + public final void testEvents() throws InterruptedException { | ||
327 | + final CountDownLatch addLatch = new CountDownLatch(1); | ||
328 | + DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() { | ||
329 | + @Override | ||
330 | + public void notify(DeviceEvent event) { | ||
331 | + assertEquals(DEVICE_ADDED, event.type()); | ||
332 | + assertDevice(DID1, SW1, event.subject()); | ||
333 | + addLatch.countDown(); | ||
334 | + } | ||
335 | + }; | ||
336 | + final CountDownLatch updateLatch = new CountDownLatch(1); | ||
337 | + DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() { | ||
338 | + @Override | ||
339 | + public void notify(DeviceEvent event) { | ||
340 | + assertEquals(DEVICE_UPDATED, event.type()); | ||
341 | + assertDevice(DID1, SW2, event.subject()); | ||
342 | + updateLatch.countDown(); | ||
343 | + } | ||
344 | + }; | ||
345 | + final CountDownLatch removeLatch = new CountDownLatch(1); | ||
346 | + DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() { | ||
347 | + @Override | ||
348 | + public void notify(DeviceEvent event) { | ||
349 | + assertEquals(DEVICE_REMOVED, event.type()); | ||
350 | + assertDevice(DID1, SW2, event.subject()); | ||
351 | + removeLatch.countDown(); | ||
352 | + } | ||
353 | + }; | ||
354 | + | ||
355 | + DeviceDescription description = | ||
356 | + new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, | ||
357 | + HW, SW1, SN); | ||
358 | + deviceStore.setDelegate(checkAdd); | ||
359 | + deviceStore.createOrUpdateDevice(PID, DID1, description); | ||
360 | + assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS)); | ||
361 | + | ||
362 | + | ||
363 | + DeviceDescription description2 = | ||
364 | + new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR, | ||
365 | + HW, SW2, SN); | ||
366 | + deviceStore.unsetDelegate(checkAdd); | ||
367 | + deviceStore.setDelegate(checkUpdate); | ||
368 | + deviceStore.createOrUpdateDevice(PID, DID1, description2); | ||
369 | + assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS)); | ||
370 | + | ||
371 | + deviceStore.unsetDelegate(checkUpdate); | ||
372 | + deviceStore.setDelegate(checkRemove); | ||
373 | + deviceStore.removeDevice(DID1); | ||
374 | + assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS)); | ||
375 | + } | ||
376 | +} |
core/store/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkStoreTest.java
0 → 100644
1 | +package org.onlab.onos.net.trivial.impl; | ||
2 | + | ||
3 | +import static org.junit.Assert.*; | ||
4 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
5 | +import static org.onlab.onos.net.Link.Type.*; | ||
6 | +import static org.onlab.onos.net.link.LinkEvent.Type.*; | ||
7 | + | ||
8 | +import java.util.HashMap; | ||
9 | +import java.util.Map; | ||
10 | +import java.util.Set; | ||
11 | +import java.util.concurrent.CountDownLatch; | ||
12 | +import java.util.concurrent.TimeUnit; | ||
13 | + | ||
14 | +import org.junit.After; | ||
15 | +import org.junit.AfterClass; | ||
16 | +import org.junit.Before; | ||
17 | +import org.junit.BeforeClass; | ||
18 | +import org.junit.Ignore; | ||
19 | +import org.junit.Test; | ||
20 | +import org.onlab.onos.net.ConnectPoint; | ||
21 | +import org.onlab.onos.net.DeviceId; | ||
22 | +import org.onlab.onos.net.Link; | ||
23 | +import org.onlab.onos.net.LinkKey; | ||
24 | +import org.onlab.onos.net.PortNumber; | ||
25 | +import org.onlab.onos.net.Link.Type; | ||
26 | +import org.onlab.onos.net.link.DefaultLinkDescription; | ||
27 | +import org.onlab.onos.net.link.LinkEvent; | ||
28 | +import org.onlab.onos.net.link.LinkStore; | ||
29 | +import org.onlab.onos.net.link.LinkStoreDelegate; | ||
30 | +import org.onlab.onos.net.provider.ProviderId; | ||
31 | + | ||
32 | +import com.google.common.collect.Iterables; | ||
33 | + | ||
34 | +/** | ||
35 | + * Test of the simple LinkStore implementation. | ||
36 | + */ | ||
37 | +public class SimpleLinkStoreTest { | ||
38 | + | ||
39 | + private static final ProviderId PID = new ProviderId("of", "foo"); | ||
40 | + private static final DeviceId DID1 = deviceId("of:foo"); | ||
41 | + private static final DeviceId DID2 = deviceId("of:bar"); | ||
42 | + | ||
43 | + private static final PortNumber P1 = PortNumber.portNumber(1); | ||
44 | + private static final PortNumber P2 = PortNumber.portNumber(2); | ||
45 | + private static final PortNumber P3 = PortNumber.portNumber(3); | ||
46 | + | ||
47 | + | ||
48 | + private SimpleLinkStore simpleLinkStore; | ||
49 | + private LinkStore linkStore; | ||
50 | + | ||
51 | + @BeforeClass | ||
52 | + public static void setUpBeforeClass() throws Exception { | ||
53 | + } | ||
54 | + | ||
55 | + @AfterClass | ||
56 | + public static void tearDownAfterClass() throws Exception { | ||
57 | + } | ||
58 | + | ||
59 | + @Before | ||
60 | + public void setUp() throws Exception { | ||
61 | + simpleLinkStore = new SimpleLinkStore(); | ||
62 | + simpleLinkStore.activate(); | ||
63 | + linkStore = simpleLinkStore; | ||
64 | + } | ||
65 | + | ||
66 | + @After | ||
67 | + public void tearDown() throws Exception { | ||
68 | + simpleLinkStore.deactivate(); | ||
69 | + } | ||
70 | + | ||
71 | + private void putLink(DeviceId srcId, PortNumber srcNum, | ||
72 | + DeviceId dstId, PortNumber dstNum, Type type) { | ||
73 | + ConnectPoint src = new ConnectPoint(srcId, srcNum); | ||
74 | + ConnectPoint dst = new ConnectPoint(dstId, dstNum); | ||
75 | + linkStore.createOrUpdateLink(PID, new DefaultLinkDescription(src, dst, type)); | ||
76 | + } | ||
77 | + | ||
78 | + private void putLink(LinkKey key, Type type) { | ||
79 | + putLink(key.src().deviceId(), key.src().port(), | ||
80 | + key.dst().deviceId(), key.dst().port(), | ||
81 | + type); | ||
82 | + } | ||
83 | + | ||
84 | + private static void assertLink(DeviceId srcId, PortNumber srcNum, | ||
85 | + DeviceId dstId, PortNumber dstNum, Type type, | ||
86 | + Link link) { | ||
87 | + assertEquals(srcId, link.src().deviceId()); | ||
88 | + assertEquals(srcNum, link.src().port()); | ||
89 | + assertEquals(dstId, link.dst().deviceId()); | ||
90 | + assertEquals(dstNum, link.dst().port()); | ||
91 | + assertEquals(type, link.type()); | ||
92 | + } | ||
93 | + | ||
94 | + private static void assertLink(LinkKey key, Type type, Link link) { | ||
95 | + assertLink(key.src().deviceId(), key.src().port(), | ||
96 | + key.dst().deviceId(), key.dst().port(), | ||
97 | + type, link); | ||
98 | + } | ||
99 | + | ||
100 | + @Test | ||
101 | + public final void testGetLinkCount() { | ||
102 | + assertEquals("initialy empty", 0, linkStore.getLinkCount()); | ||
103 | + | ||
104 | + putLink(DID1, P1, DID2, P2, DIRECT); | ||
105 | + putLink(DID2, P2, DID1, P1, DIRECT); | ||
106 | + putLink(DID1, P1, DID2, P2, DIRECT); | ||
107 | + | ||
108 | + assertEquals("expecting 2 unique link", 2, linkStore.getLinkCount()); | ||
109 | + } | ||
110 | + | ||
111 | + @Test | ||
112 | + public final void testGetLinks() { | ||
113 | + assertEquals("initialy empty", 0, | ||
114 | + Iterables.size(linkStore.getLinks())); | ||
115 | + | ||
116 | + LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2)); | ||
117 | + LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1)); | ||
118 | + | ||
119 | + putLink(linkId1, DIRECT); | ||
120 | + putLink(linkId2, DIRECT); | ||
121 | + putLink(linkId1, DIRECT); | ||
122 | + | ||
123 | + assertEquals("expecting 2 unique link", 2, | ||
124 | + Iterables.size(linkStore.getLinks())); | ||
125 | + | ||
126 | + Map<LinkKey, Link> links = new HashMap<>(); | ||
127 | + for (Link link : linkStore.getLinks()) { | ||
128 | + links.put(new LinkKey(link.src(), link.dst()), link); | ||
129 | + } | ||
130 | + | ||
131 | + assertLink(linkId1, DIRECT, links.get(linkId1)); | ||
132 | + assertLink(linkId2, DIRECT, links.get(linkId2)); | ||
133 | + } | ||
134 | + | ||
135 | + @Test | ||
136 | + public final void testGetDeviceEgressLinks() { | ||
137 | + LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2)); | ||
138 | + LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1)); | ||
139 | + LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3)); | ||
140 | + | ||
141 | + putLink(linkId1, DIRECT); | ||
142 | + putLink(linkId2, DIRECT); | ||
143 | + putLink(linkId3, DIRECT); | ||
144 | + | ||
145 | + // DID1,P1 => DID2,P2 | ||
146 | + // DID2,P2 => DID1,P1 | ||
147 | + // DID1,P2 => DID2,P3 | ||
148 | + | ||
149 | + Set<Link> links1 = linkStore.getDeviceEgressLinks(DID1); | ||
150 | + assertEquals(2, links1.size()); | ||
151 | + // check | ||
152 | + | ||
153 | + Set<Link> links2 = linkStore.getDeviceEgressLinks(DID2); | ||
154 | + assertEquals(1, links2.size()); | ||
155 | + assertLink(linkId2, DIRECT, links2.iterator().next()); | ||
156 | + } | ||
157 | + | ||
158 | + @Test | ||
159 | + public final void testGetDeviceIngressLinks() { | ||
160 | + LinkKey linkId1 = new LinkKey(new ConnectPoint(DID1, P1), new ConnectPoint(DID2, P2)); | ||
161 | + LinkKey linkId2 = new LinkKey(new ConnectPoint(DID2, P2), new ConnectPoint(DID1, P1)); | ||
162 | + LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3)); | ||
163 | + | ||
164 | + putLink(linkId1, DIRECT); | ||
165 | + putLink(linkId2, DIRECT); | ||
166 | + putLink(linkId3, DIRECT); | ||
167 | + | ||
168 | + // DID1,P1 => DID2,P2 | ||
169 | + // DID2,P2 => DID1,P1 | ||
170 | + // DID1,P2 => DID2,P3 | ||
171 | + | ||
172 | + Set<Link> links1 = linkStore.getDeviceIngressLinks(DID2); | ||
173 | + assertEquals(2, links1.size()); | ||
174 | + // check | ||
175 | + | ||
176 | + Set<Link> links2 = linkStore.getDeviceIngressLinks(DID1); | ||
177 | + assertEquals(1, links2.size()); | ||
178 | + assertLink(linkId2, DIRECT, links2.iterator().next()); | ||
179 | + } | ||
180 | + | ||
181 | + @Test | ||
182 | + public final void testGetLink() { | ||
183 | + ConnectPoint src = new ConnectPoint(DID1, P1); | ||
184 | + ConnectPoint dst = new ConnectPoint(DID2, P2); | ||
185 | + LinkKey linkId1 = new LinkKey(src, dst); | ||
186 | + | ||
187 | + putLink(linkId1, DIRECT); | ||
188 | + | ||
189 | + Link link = linkStore.getLink(src, dst); | ||
190 | + assertLink(linkId1, DIRECT, link); | ||
191 | + | ||
192 | + assertNull("There shouldn't be reverese link", | ||
193 | + linkStore.getLink(dst, src)); | ||
194 | + } | ||
195 | + | ||
196 | + @Test | ||
197 | + public final void testGetEgressLinks() { | ||
198 | + final ConnectPoint d1P1 = new ConnectPoint(DID1, P1); | ||
199 | + final ConnectPoint d2P2 = new ConnectPoint(DID2, P2); | ||
200 | + LinkKey linkId1 = new LinkKey(d1P1, d2P2); | ||
201 | + LinkKey linkId2 = new LinkKey(d2P2, d1P1); | ||
202 | + LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3)); | ||
203 | + | ||
204 | + putLink(linkId1, DIRECT); | ||
205 | + putLink(linkId2, DIRECT); | ||
206 | + putLink(linkId3, DIRECT); | ||
207 | + | ||
208 | + // DID1,P1 => DID2,P2 | ||
209 | + // DID2,P2 => DID1,P1 | ||
210 | + // DID1,P2 => DID2,P3 | ||
211 | + | ||
212 | + Set<Link> links1 = linkStore.getEgressLinks(d1P1); | ||
213 | + assertEquals(1, links1.size()); | ||
214 | + assertLink(linkId1, DIRECT, links1.iterator().next()); | ||
215 | + | ||
216 | + Set<Link> links2 = linkStore.getEgressLinks(d2P2); | ||
217 | + assertEquals(1, links2.size()); | ||
218 | + assertLink(linkId2, DIRECT, links2.iterator().next()); | ||
219 | + } | ||
220 | + | ||
221 | + @Test | ||
222 | + public final void testGetIngressLinks() { | ||
223 | + final ConnectPoint d1P1 = new ConnectPoint(DID1, P1); | ||
224 | + final ConnectPoint d2P2 = new ConnectPoint(DID2, P2); | ||
225 | + LinkKey linkId1 = new LinkKey(d1P1, d2P2); | ||
226 | + LinkKey linkId2 = new LinkKey(d2P2, d1P1); | ||
227 | + LinkKey linkId3 = new LinkKey(new ConnectPoint(DID1, P2), new ConnectPoint(DID2, P3)); | ||
228 | + | ||
229 | + putLink(linkId1, DIRECT); | ||
230 | + putLink(linkId2, DIRECT); | ||
231 | + putLink(linkId3, DIRECT); | ||
232 | + | ||
233 | + // DID1,P1 => DID2,P2 | ||
234 | + // DID2,P2 => DID1,P1 | ||
235 | + // DID1,P2 => DID2,P3 | ||
236 | + | ||
237 | + Set<Link> links1 = linkStore.getIngressLinks(d2P2); | ||
238 | + assertEquals(1, links1.size()); | ||
239 | + assertLink(linkId1, DIRECT, links1.iterator().next()); | ||
240 | + | ||
241 | + Set<Link> links2 = linkStore.getIngressLinks(d1P1); | ||
242 | + assertEquals(1, links2.size()); | ||
243 | + assertLink(linkId2, DIRECT, links2.iterator().next()); | ||
244 | + } | ||
245 | + | ||
246 | + @Test | ||
247 | + public final void testCreateOrUpdateLink() { | ||
248 | + ConnectPoint src = new ConnectPoint(DID1, P1); | ||
249 | + ConnectPoint dst = new ConnectPoint(DID2, P2); | ||
250 | + | ||
251 | + // add link | ||
252 | + LinkEvent event = linkStore.createOrUpdateLink(PID, | ||
253 | + new DefaultLinkDescription(src, dst, INDIRECT)); | ||
254 | + | ||
255 | + assertLink(DID1, P1, DID2, P2, INDIRECT, event.subject()); | ||
256 | + assertEquals(LINK_ADDED, event.type()); | ||
257 | + | ||
258 | + // update link type | ||
259 | + LinkEvent event2 = linkStore.createOrUpdateLink(PID, | ||
260 | + new DefaultLinkDescription(src, dst, DIRECT)); | ||
261 | + | ||
262 | + assertLink(DID1, P1, DID2, P2, DIRECT, event2.subject()); | ||
263 | + assertEquals(LINK_UPDATED, event2.type()); | ||
264 | + | ||
265 | + // no change | ||
266 | + LinkEvent event3 = linkStore.createOrUpdateLink(PID, | ||
267 | + new DefaultLinkDescription(src, dst, DIRECT)); | ||
268 | + | ||
269 | + assertNull("No change event expected", event3); | ||
270 | + } | ||
271 | + | ||
272 | + @Test | ||
273 | + public final void testRemoveLink() { | ||
274 | + final ConnectPoint d1P1 = new ConnectPoint(DID1, P1); | ||
275 | + final ConnectPoint d2P2 = new ConnectPoint(DID2, P2); | ||
276 | + LinkKey linkId1 = new LinkKey(d1P1, d2P2); | ||
277 | + LinkKey linkId2 = new LinkKey(d2P2, d1P1); | ||
278 | + | ||
279 | + putLink(linkId1, DIRECT); | ||
280 | + putLink(linkId2, DIRECT); | ||
281 | + | ||
282 | + // DID1,P1 => DID2,P2 | ||
283 | + // DID2,P2 => DID1,P1 | ||
284 | + // DID1,P2 => DID2,P3 | ||
285 | + | ||
286 | + LinkEvent event = linkStore.removeLink(d1P1, d2P2); | ||
287 | + assertEquals(LINK_REMOVED, event.type()); | ||
288 | + LinkEvent event2 = linkStore.removeLink(d1P1, d2P2); | ||
289 | + assertNull(event2); | ||
290 | + | ||
291 | + assertLink(linkId2, DIRECT, linkStore.getLink(d2P2, d1P1)); | ||
292 | + } | ||
293 | + | ||
294 | + // If Delegates should be called only on remote events, | ||
295 | + // then Simple* should never call them, thus not test required. | ||
296 | + @Ignore("Ignore until Delegate spec. is clear.") | ||
297 | + @Test | ||
298 | + public final void testEvents() throws InterruptedException { | ||
299 | + | ||
300 | + final ConnectPoint d1P1 = new ConnectPoint(DID1, P1); | ||
301 | + final ConnectPoint d2P2 = new ConnectPoint(DID2, P2); | ||
302 | + final LinkKey linkId1 = new LinkKey(d1P1, d2P2); | ||
303 | + | ||
304 | + final CountDownLatch addLatch = new CountDownLatch(1); | ||
305 | + LinkStoreDelegate checkAdd = new LinkStoreDelegate() { | ||
306 | + @Override | ||
307 | + public void notify(LinkEvent event) { | ||
308 | + assertEquals(LINK_ADDED, event.type()); | ||
309 | + assertLink(linkId1, INDIRECT, event.subject()); | ||
310 | + addLatch.countDown(); | ||
311 | + } | ||
312 | + }; | ||
313 | + final CountDownLatch updateLatch = new CountDownLatch(1); | ||
314 | + LinkStoreDelegate checkUpdate = new LinkStoreDelegate() { | ||
315 | + @Override | ||
316 | + public void notify(LinkEvent event) { | ||
317 | + assertEquals(LINK_UPDATED, event.type()); | ||
318 | + assertLink(linkId1, DIRECT, event.subject()); | ||
319 | + updateLatch.countDown(); | ||
320 | + } | ||
321 | + }; | ||
322 | + final CountDownLatch removeLatch = new CountDownLatch(1); | ||
323 | + LinkStoreDelegate checkRemove = new LinkStoreDelegate() { | ||
324 | + @Override | ||
325 | + public void notify(LinkEvent event) { | ||
326 | + assertEquals(LINK_REMOVED, event.type()); | ||
327 | + assertLink(linkId1, DIRECT, event.subject()); | ||
328 | + removeLatch.countDown(); | ||
329 | + } | ||
330 | + }; | ||
331 | + | ||
332 | + linkStore.setDelegate(checkAdd); | ||
333 | + putLink(linkId1, INDIRECT); | ||
334 | + assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS)); | ||
335 | + | ||
336 | + linkStore.unsetDelegate(checkAdd); | ||
337 | + linkStore.setDelegate(checkUpdate); | ||
338 | + putLink(linkId1, DIRECT); | ||
339 | + assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS)); | ||
340 | + | ||
341 | + linkStore.unsetDelegate(checkUpdate); | ||
342 | + linkStore.setDelegate(checkRemove); | ||
343 | + linkStore.removeLink(d1P1, d2P2); | ||
344 | + assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS)); | ||
345 | + } | ||
346 | +} |
-
Please register or login to post a comment