blob: 146086a6a5f0c578fe986dc9cbbf9c580d9cda80 [file] [log] [blame]
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -07001/**
2 *
3 */
tomea961ff2014-10-01 12:45:15 -07004package org.onlab.onos.store.trivial.impl;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -07005
6import static org.junit.Assert.*;
7import static org.onlab.onos.net.Device.Type.SWITCH;
8import static org.onlab.onos.net.DeviceId.deviceId;
9import static org.onlab.onos.net.device.DeviceEvent.Type.*;
10
11import java.util.Arrays;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Set;
16import java.util.concurrent.CountDownLatch;
17import java.util.concurrent.TimeUnit;
18
19import org.junit.After;
20import org.junit.AfterClass;
21import org.junit.Before;
22import org.junit.BeforeClass;
23import org.junit.Ignore;
24import org.junit.Test;
Yuta HIGUCHI55710e72014-10-02 14:58:32 -070025import org.onlab.onos.net.Annotations;
26import org.onlab.onos.net.DefaultAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070027import org.onlab.onos.net.Device;
28import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.Port;
30import org.onlab.onos.net.PortNumber;
Yuta HIGUCHI55710e72014-10-02 14:58:32 -070031import org.onlab.onos.net.SparseAnnotations;
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070032import org.onlab.onos.net.device.DefaultDeviceDescription;
33import org.onlab.onos.net.device.DefaultPortDescription;
34import org.onlab.onos.net.device.DeviceDescription;
35import org.onlab.onos.net.device.DeviceEvent;
36import org.onlab.onos.net.device.DeviceStore;
37import org.onlab.onos.net.device.DeviceStoreDelegate;
38import org.onlab.onos.net.device.PortDescription;
39import org.onlab.onos.net.provider.ProviderId;
40
41import com.google.common.collect.Iterables;
42import com.google.common.collect.Sets;
43
44/**
45 * Test of the simple DeviceStore implementation.
46 */
47public class SimpleDeviceStoreTest {
48
49 private static final ProviderId PID = new ProviderId("of", "foo");
Yuta HIGUCHI8e493792014-10-01 19:36:32 -070050 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070051 private static final DeviceId DID1 = deviceId("of:foo");
52 private static final DeviceId DID2 = deviceId("of:bar");
53 private static final String MFR = "whitebox";
54 private static final String HW = "1.1.x";
55 private static final String SW1 = "3.8.1";
56 private static final String SW2 = "3.9.5";
57 private static final String SN = "43311-12345";
58
59 private static final PortNumber P1 = PortNumber.portNumber(1);
60 private static final PortNumber P2 = PortNumber.portNumber(2);
61 private static final PortNumber P3 = PortNumber.portNumber(3);
62
Yuta HIGUCHI55710e72014-10-02 14:58:32 -070063 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
64 .set("A1", "a1")
65 .set("B1", "b1")
66 .build();
67 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
68 .remove("A1")
69 .set("B3", "b3")
70 .build();
71 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
72 .set("A2", "a2")
73 .set("B2", "b2")
74 .build();
75 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
76 .remove("A2")
77 .set("B4", "b4")
78 .build();
79
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070080 private SimpleDeviceStore simpleDeviceStore;
81 private DeviceStore deviceStore;
82
83
84
85 @BeforeClass
86 public static void setUpBeforeClass() throws Exception {
87 }
88
89 @AfterClass
90 public static void tearDownAfterClass() throws Exception {
91 }
92
93
94 @Before
95 public void setUp() throws Exception {
96 simpleDeviceStore = new SimpleDeviceStore();
97 simpleDeviceStore.activate();
98 deviceStore = simpleDeviceStore;
99 }
100
101 @After
102 public void tearDown() throws Exception {
103 simpleDeviceStore.deactivate();
104 }
105
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700106 private void putDevice(DeviceId deviceId, String swVersion,
107 SparseAnnotations... annotations) {
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700108 DeviceDescription description =
109 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700110 HW, swVersion, SN, annotations);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700111 deviceStore.createOrUpdateDevice(PID, deviceId, description);
112 }
113
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700114 private void putDeviceAncillary(DeviceId deviceId, String swVersion,
115 SparseAnnotations... annotations) {
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700116 DeviceDescription description =
117 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700118 HW, swVersion, SN, annotations);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700119 deviceStore.createOrUpdateDevice(PIDA, deviceId, description);
120 }
121
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700122 private static void assertDevice(DeviceId id, String swVersion, Device device) {
123 assertNotNull(device);
124 assertEquals(id, device.id());
125 assertEquals(MFR, device.manufacturer());
126 assertEquals(HW, device.hwVersion());
127 assertEquals(swVersion, device.swVersion());
128 assertEquals(SN, device.serialNumber());
129 }
130
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700131 // TODO slice this out somewhere
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700132 /**
133 * Verifies that Annotations created by merging {@code annotations} is
134 * equal to actual Annotations.
135 *
136 * @param actual Annotations to check
137 * @param annotations
138 */
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700139 public static void assertAnnotationsEquals(Annotations actual, SparseAnnotations... annotations) {
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700140 DefaultAnnotations expected = DefaultAnnotations.builder().build();
141 for (SparseAnnotations a : annotations) {
142 expected = DefaultAnnotations.merge(expected, a);
143 }
144 assertEquals(expected.keys(), actual.keys());
145 for (String key : expected.keys()) {
146 assertEquals(expected.value(key), actual.value(key));
147 }
148 }
149
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700150 @Test
151 public final void testGetDeviceCount() {
152 assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
153
154 putDevice(DID1, SW1);
155 putDevice(DID2, SW2);
156 putDevice(DID1, SW1);
157
158 assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
159 }
160
161 @Test
162 public final void testGetDevices() {
163 assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
164
165 putDevice(DID1, SW1);
166 putDevice(DID2, SW2);
167 putDevice(DID1, SW1);
168
169 assertEquals("expect 2 uniq devices",
170 2, Iterables.size(deviceStore.getDevices()));
171
172 Map<DeviceId, Device> devices = new HashMap<>();
173 for (Device device : deviceStore.getDevices()) {
174 devices.put(device.id(), device);
175 }
176
177 assertDevice(DID1, SW1, devices.get(DID1));
178 assertDevice(DID2, SW2, devices.get(DID2));
179
180 // add case for new node?
181 }
182
183 @Test
184 public final void testGetDevice() {
185
186 putDevice(DID1, SW1);
187
188 assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
189 assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
190 }
191
192 @Test
193 public final void testCreateOrUpdateDevice() {
194 DeviceDescription description =
195 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
196 HW, SW1, SN);
197 DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
198 assertEquals(DEVICE_ADDED, event.type());
199 assertDevice(DID1, SW1, event.subject());
200
201 DeviceDescription description2 =
202 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
203 HW, SW2, SN);
204 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
205 assertEquals(DEVICE_UPDATED, event2.type());
206 assertDevice(DID1, SW2, event2.subject());
207
208 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
209 }
210
211 @Test
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700212 public final void testCreateOrUpdateDeviceAncillary() {
213 DeviceDescription description =
214 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700215 HW, SW1, SN, A2);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700216 DeviceEvent event = deviceStore.createOrUpdateDevice(PIDA, DID1, description);
217 assertEquals(DEVICE_ADDED, event.type());
218 assertDevice(DID1, SW1, event.subject());
219 assertEquals(PIDA, event.subject().providerId());
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700220 assertAnnotationsEquals(event.subject().annotations(), A2);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700221 assertFalse("Ancillary will not bring device up", deviceStore.isAvailable(DID1));
222
223 DeviceDescription description2 =
224 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700225 HW, SW2, SN, A1);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700226 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
227 assertEquals(DEVICE_UPDATED, event2.type());
228 assertDevice(DID1, SW2, event2.subject());
229 assertEquals(PID, event2.subject().providerId());
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700230 assertAnnotationsEquals(event2.subject().annotations(), A1, A2);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700231 assertTrue(deviceStore.isAvailable(DID1));
232
233 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
234
235 // For now, Ancillary is ignored once primary appears
236 assertNull("No change expected", deviceStore.createOrUpdateDevice(PIDA, DID1, description));
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700237
238 // But, Ancillary annotations will be in effect
239 DeviceDescription description3 =
240 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
241 HW, SW1, SN, A2_2);
242 DeviceEvent event3 = deviceStore.createOrUpdateDevice(PIDA, DID1, description3);
243 assertEquals(DEVICE_UPDATED, event3.type());
244 // basic information will be the one from Primary
245 assertDevice(DID1, SW2, event3.subject());
246 assertEquals(PID, event3.subject().providerId());
247 // but annotation from Ancillary will be merged
248 assertAnnotationsEquals(event3.subject().annotations(), A1, A2, A2_2);
249 assertTrue(deviceStore.isAvailable(DID1));
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700250 }
251
252
253 @Test
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700254 public final void testMarkOffline() {
255
256 putDevice(DID1, SW1);
257 assertTrue(deviceStore.isAvailable(DID1));
258
259 DeviceEvent event = deviceStore.markOffline(DID1);
260 assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
261 assertDevice(DID1, SW1, event.subject());
262 assertFalse(deviceStore.isAvailable(DID1));
263
264 DeviceEvent event2 = deviceStore.markOffline(DID1);
265 assertNull("No change, no event", event2);
266}
267
268 @Test
269 public final void testUpdatePorts() {
270 putDevice(DID1, SW1);
271 List<PortDescription> pds = Arrays.<PortDescription>asList(
272 new DefaultPortDescription(P1, true),
273 new DefaultPortDescription(P2, true)
274 );
275
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700276 List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700277
278 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
279 for (DeviceEvent event : events) {
280 assertEquals(PORT_ADDED, event.type());
281 assertDevice(DID1, SW1, event.subject());
282 assertTrue("PortNumber is one of expected",
283 expectedPorts.remove(event.port().number()));
284 assertTrue("Port is enabled", event.port().isEnabled());
285 }
286 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
287
288
289 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
290 new DefaultPortDescription(P1, false),
291 new DefaultPortDescription(P2, true),
292 new DefaultPortDescription(P3, true)
293 );
294
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700295 events = deviceStore.updatePorts(PID, DID1, pds2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700296 assertFalse("event should be triggered", events.isEmpty());
297 for (DeviceEvent event : events) {
298 PortNumber num = event.port().number();
299 if (P1.equals(num)) {
300 assertEquals(PORT_UPDATED, event.type());
301 assertDevice(DID1, SW1, event.subject());
302 assertFalse("Port is disabled", event.port().isEnabled());
303 } else if (P2.equals(num)) {
304 fail("P2 event not expected.");
305 } else if (P3.equals(num)) {
306 assertEquals(PORT_ADDED, event.type());
307 assertDevice(DID1, SW1, event.subject());
308 assertTrue("Port is enabled", event.port().isEnabled());
309 } else {
310 fail("Unknown port number encountered: " + num);
311 }
312 }
313
314 List<PortDescription> pds3 = Arrays.<PortDescription>asList(
315 new DefaultPortDescription(P1, false),
316 new DefaultPortDescription(P2, true)
317 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700318 events = deviceStore.updatePorts(PID, DID1, pds3);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700319 assertFalse("event should be triggered", events.isEmpty());
320 for (DeviceEvent event : events) {
321 PortNumber num = event.port().number();
322 if (P1.equals(num)) {
323 fail("P1 event not expected.");
324 } else if (P2.equals(num)) {
325 fail("P2 event not expected.");
326 } else if (P3.equals(num)) {
327 assertEquals(PORT_REMOVED, event.type());
328 assertDevice(DID1, SW1, event.subject());
329 assertTrue("Port was enabled", event.port().isEnabled());
330 } else {
331 fail("Unknown port number encountered: " + num);
332 }
333 }
334
335 }
336
337 @Test
338 public final void testUpdatePortStatus() {
339 putDevice(DID1, SW1);
340 List<PortDescription> pds = Arrays.<PortDescription>asList(
341 new DefaultPortDescription(P1, true)
342 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700343 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700344
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700345 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700346 new DefaultPortDescription(P1, false));
347 assertEquals(PORT_UPDATED, event.type());
348 assertDevice(DID1, SW1, event.subject());
349 assertEquals(P1, event.port().number());
350 assertFalse("Port is disabled", event.port().isEnabled());
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700351
352 }
Yuta HIGUCHI39ede6a2014-10-03 15:23:33 -0700353
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700354 @Test
355 public final void testUpdatePortStatusAncillary() {
356 putDeviceAncillary(DID1, SW1);
357 putDevice(DID1, SW1);
358 List<PortDescription> pds = Arrays.<PortDescription>asList(
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700359 new DefaultPortDescription(P1, true, A1)
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700360 );
361 deviceStore.updatePorts(PID, DID1, pds);
362
363 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700364 new DefaultPortDescription(P1, false, A1_2));
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700365 assertEquals(PORT_UPDATED, event.type());
366 assertDevice(DID1, SW1, event.subject());
367 assertEquals(P1, event.port().number());
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700368 assertAnnotationsEquals(event.port().annotations(), A1, A1_2);
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700369 assertFalse("Port is disabled", event.port().isEnabled());
370
371 DeviceEvent event2 = deviceStore.updatePortStatus(PIDA, DID1,
372 new DefaultPortDescription(P1, true));
373 assertNull("Ancillary is ignored if primary exists", event2);
374
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700375 // but, Ancillary annotation update will be notified
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700376 DeviceEvent event3 = deviceStore.updatePortStatus(PIDA, DID1,
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700377 new DefaultPortDescription(P1, true, A2));
378 assertEquals(PORT_UPDATED, event3.type());
Yuta HIGUCHI8e493792014-10-01 19:36:32 -0700379 assertDevice(DID1, SW1, event3.subject());
Yuta HIGUCHI55710e72014-10-02 14:58:32 -0700380 assertEquals(P1, event3.port().number());
381 assertAnnotationsEquals(event3.port().annotations(), A1, A1_2, A2);
382 assertFalse("Port is disabled", event3.port().isEnabled());
383
384 // port only reported from Ancillary will be notified as down
385 DeviceEvent event4 = deviceStore.updatePortStatus(PIDA, DID1,
386 new DefaultPortDescription(P2, true));
387 assertEquals(PORT_ADDED, event4.type());
388 assertDevice(DID1, SW1, event4.subject());
389 assertEquals(P2, event4.port().number());
390 assertAnnotationsEquals(event4.port().annotations());
391 assertFalse("Port is disabled if not given from primary provider",
392 event4.port().isEnabled());
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700393 }
394
395 @Test
396 public final void testGetPorts() {
397 putDevice(DID1, SW1);
398 putDevice(DID2, SW1);
399 List<PortDescription> pds = Arrays.<PortDescription>asList(
400 new DefaultPortDescription(P1, true),
401 new DefaultPortDescription(P2, true)
402 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700403 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700404
405 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
406 List<Port> ports = deviceStore.getPorts(DID1);
407 for (Port port : ports) {
408 assertTrue("Port is enabled", port.isEnabled());
409 assertTrue("PortNumber is one of expected",
410 expectedPorts.remove(port.number()));
411 }
412 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
413
414
415 assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
416 }
417
418 @Test
419 public final void testGetPort() {
420 putDevice(DID1, SW1);
421 putDevice(DID2, SW1);
422 List<PortDescription> pds = Arrays.<PortDescription>asList(
423 new DefaultPortDescription(P1, true),
424 new DefaultPortDescription(P2, false)
425 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700426 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700427
428 Port port1 = deviceStore.getPort(DID1, P1);
429 assertEquals(P1, port1.number());
430 assertTrue("Port is enabled", port1.isEnabled());
431
432 Port port2 = deviceStore.getPort(DID1, P2);
433 assertEquals(P2, port2.number());
434 assertFalse("Port is disabled", port2.isEnabled());
435
436 Port port3 = deviceStore.getPort(DID1, P3);
437 assertNull("P3 not expected", port3);
438 }
439
440 @Test
441 public final void testRemoveDevice() {
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700442 putDevice(DID1, SW1, A1);
443 List<PortDescription> pds = Arrays.<PortDescription>asList(
444 new DefaultPortDescription(P1, true, A2)
445 );
446 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700447 putDevice(DID2, SW1);
448
449 assertEquals(2, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700450 assertEquals(1, deviceStore.getPorts(DID1).size());
451 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations(), A1);
452 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations(), A2);
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700453
454 DeviceEvent event = deviceStore.removeDevice(DID1);
455 assertEquals(DEVICE_REMOVED, event.type());
456 assertDevice(DID1, SW1, event.subject());
457
458 assertEquals(1, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700459 assertEquals(0, deviceStore.getPorts(DID1).size());
460
461 // putBack Device, Port w/o annotation
462 putDevice(DID1, SW1);
463 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
464 new DefaultPortDescription(P1, true)
465 );
466 deviceStore.updatePorts(PID, DID1, pds2);
467
468 // annotations should not survive
469 assertEquals(2, deviceStore.getDeviceCount());
470 assertEquals(1, deviceStore.getPorts(DID1).size());
471 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations());
472 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations());
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -0700473 }
474
475 // If Delegates should be called only on remote events,
476 // then Simple* should never call them, thus not test required.
477 // TODO add test for Port events when we have them
478 @Ignore("Ignore until Delegate spec. is clear.")
479 @Test
480 public final void testEvents() throws InterruptedException {
481 final CountDownLatch addLatch = new CountDownLatch(1);
482 DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
483 @Override
484 public void notify(DeviceEvent event) {
485 assertEquals(DEVICE_ADDED, event.type());
486 assertDevice(DID1, SW1, event.subject());
487 addLatch.countDown();
488 }
489 };
490 final CountDownLatch updateLatch = new CountDownLatch(1);
491 DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
492 @Override
493 public void notify(DeviceEvent event) {
494 assertEquals(DEVICE_UPDATED, event.type());
495 assertDevice(DID1, SW2, event.subject());
496 updateLatch.countDown();
497 }
498 };
499 final CountDownLatch removeLatch = new CountDownLatch(1);
500 DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
501 @Override
502 public void notify(DeviceEvent event) {
503 assertEquals(DEVICE_REMOVED, event.type());
504 assertDevice(DID1, SW2, event.subject());
505 removeLatch.countDown();
506 }
507 };
508
509 DeviceDescription description =
510 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
511 HW, SW1, SN);
512 deviceStore.setDelegate(checkAdd);
513 deviceStore.createOrUpdateDevice(PID, DID1, description);
514 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
515
516
517 DeviceDescription description2 =
518 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
519 HW, SW2, SN);
520 deviceStore.unsetDelegate(checkAdd);
521 deviceStore.setDelegate(checkUpdate);
522 deviceStore.createOrUpdateDevice(PID, DID1, description2);
523 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
524
525 deviceStore.unsetDelegate(checkUpdate);
526 deviceStore.setDelegate(checkRemove);
527 deviceStore.removeDevice(DID1);
528 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
529 }
530}