blob: fa42a6b9d7979ec9253ebc40f008cb6a6bca1c85 [file] [log] [blame]
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -07001package org.onlab.onos.store.device.impl;
2
3import static org.junit.Assert.*;
4import static org.onlab.onos.net.Device.Type.SWITCH;
5import static org.onlab.onos.net.DeviceId.deviceId;
6import static org.onlab.onos.net.device.DeviceEvent.Type.*;
7
Madan Jampani47c93732014-10-06 20:46:08 -07008import java.io.IOException;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -07009import java.util.Arrays;
10import java.util.HashMap;
11import java.util.List;
12import java.util.Map;
13import java.util.Set;
14import java.util.concurrent.CountDownLatch;
15import java.util.concurrent.TimeUnit;
16
17import org.junit.After;
18import org.junit.AfterClass;
19import org.junit.Before;
20import org.junit.BeforeClass;
21import org.junit.Ignore;
22import org.junit.Test;
Madan Jampani53e44e62014-10-07 12:39:51 -070023import org.onlab.onos.cluster.ClusterEventListener;
24import org.onlab.onos.cluster.ClusterService;
25import org.onlab.onos.cluster.ControllerNode;
26import org.onlab.onos.cluster.ControllerNode.State;
27import org.onlab.onos.cluster.DefaultControllerNode;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -070028import org.onlab.onos.cluster.MastershipTerm;
29import org.onlab.onos.cluster.NodeId;
30import org.onlab.onos.net.Annotations;
31import org.onlab.onos.net.DefaultAnnotations;
32import org.onlab.onos.net.Device;
33import org.onlab.onos.net.DeviceId;
34import org.onlab.onos.net.Port;
35import org.onlab.onos.net.PortNumber;
36import org.onlab.onos.net.SparseAnnotations;
37import org.onlab.onos.net.device.DefaultDeviceDescription;
38import org.onlab.onos.net.device.DefaultPortDescription;
39import org.onlab.onos.net.device.DeviceDescription;
40import org.onlab.onos.net.device.DeviceEvent;
41import org.onlab.onos.net.device.DeviceStore;
42import org.onlab.onos.net.device.DeviceStoreDelegate;
43import org.onlab.onos.net.device.PortDescription;
44import org.onlab.onos.net.provider.ProviderId;
45import org.onlab.onos.store.ClockService;
Madan Jampani47c93732014-10-06 20:46:08 -070046import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
47import org.onlab.onos.store.cluster.messaging.ClusterMessage;
48import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
49import org.onlab.onos.store.cluster.messaging.MessageSubject;
Madan Jampani53e44e62014-10-07 12:39:51 -070050import org.onlab.packet.IpPrefix;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -070051
52import com.google.common.collect.Iterables;
53import com.google.common.collect.Sets;
54
55
56// TODO add tests for remote replication
57/**
58 * Test of the gossip based distributed DeviceStore implementation.
59 */
60public class GossipDeviceStoreTest {
61
62 private static final ProviderId PID = new ProviderId("of", "foo");
63 private static final ProviderId PIDA = new ProviderId("of", "bar", true);
64 private static final DeviceId DID1 = deviceId("of:foo");
65 private static final DeviceId DID2 = deviceId("of:bar");
66 private static final String MFR = "whitebox";
67 private static final String HW = "1.1.x";
68 private static final String SW1 = "3.8.1";
69 private static final String SW2 = "3.9.5";
70 private static final String SN = "43311-12345";
71
72 private static final PortNumber P1 = PortNumber.portNumber(1);
73 private static final PortNumber P2 = PortNumber.portNumber(2);
74 private static final PortNumber P3 = PortNumber.portNumber(3);
75
76 private static final SparseAnnotations A1 = DefaultAnnotations.builder()
77 .set("A1", "a1")
78 .set("B1", "b1")
79 .build();
80 private static final SparseAnnotations A1_2 = DefaultAnnotations.builder()
81 .remove("A1")
82 .set("B3", "b3")
83 .build();
84 private static final SparseAnnotations A2 = DefaultAnnotations.builder()
85 .set("A2", "a2")
86 .set("B2", "b2")
87 .build();
88 private static final SparseAnnotations A2_2 = DefaultAnnotations.builder()
89 .remove("A2")
90 .set("B4", "b4")
91 .build();
92
93 private static final NodeId MYSELF = new NodeId("myself");
94
95 private GossipDeviceStore gossipDeviceStore;
96 private DeviceStore deviceStore;
97
98 private DeviceClockManager deviceClockManager;
99 private ClockService clockService;
100
101 @BeforeClass
102 public static void setUpBeforeClass() throws Exception {
103 }
104
105 @AfterClass
106 public static void tearDownAfterClass() throws Exception {
107 }
108
109
110 @Before
111 public void setUp() throws Exception {
112 deviceClockManager = new DeviceClockManager();
113 deviceClockManager.activate();
114 clockService = deviceClockManager;
115
116 deviceClockManager.setMastershipTerm(DID1, MastershipTerm.of(MYSELF, 1));
117 deviceClockManager.setMastershipTerm(DID2, MastershipTerm.of(MYSELF, 2));
118
Madan Jampani47c93732014-10-06 20:46:08 -0700119 ClusterCommunicationService clusterCommunicator = new TestClusterCommunicationService();
Madan Jampani53e44e62014-10-07 12:39:51 -0700120 ClusterService clusterService = new TestClusterService();
Madan Jampani47c93732014-10-06 20:46:08 -0700121
Madan Jampani53e44e62014-10-07 12:39:51 -0700122 gossipDeviceStore = new TestGossipDeviceStore(clockService, clusterService, clusterCommunicator);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700123 gossipDeviceStore.activate();
124 deviceStore = gossipDeviceStore;
125 }
126
127 @After
128 public void tearDown() throws Exception {
129 gossipDeviceStore.deactivate();
130 deviceClockManager.deactivate();
131 }
132
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700133 private void putDevice(DeviceId deviceId, String swVersion,
134 SparseAnnotations... annotations) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700135 DeviceDescription description =
136 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700137 HW, swVersion, SN, annotations);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700138 deviceStore.createOrUpdateDevice(PID, deviceId, description);
139 }
140
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700141 private void putDeviceAncillary(DeviceId deviceId, String swVersion,
142 SparseAnnotations... annotations) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700143 DeviceDescription description =
144 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700145 HW, swVersion, SN, annotations);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700146 deviceStore.createOrUpdateDevice(PIDA, deviceId, description);
147 }
148
149 private static void assertDevice(DeviceId id, String swVersion, Device device) {
150 assertNotNull(device);
151 assertEquals(id, device.id());
152 assertEquals(MFR, device.manufacturer());
153 assertEquals(HW, device.hwVersion());
154 assertEquals(swVersion, device.swVersion());
155 assertEquals(SN, device.serialNumber());
156 }
157
158 /**
159 * Verifies that Annotations created by merging {@code annotations} is
160 * equal to actual Annotations.
161 *
162 * @param actual Annotations to check
163 * @param annotations
164 */
165 private static void assertAnnotationsEquals(Annotations actual, SparseAnnotations... annotations) {
166 DefaultAnnotations expected = DefaultAnnotations.builder().build();
167 for (SparseAnnotations a : annotations) {
168 expected = DefaultAnnotations.merge(expected, a);
169 }
170 assertEquals(expected.keys(), actual.keys());
171 for (String key : expected.keys()) {
172 assertEquals(expected.value(key), actual.value(key));
173 }
174 }
175
176 @Test
177 public final void testGetDeviceCount() {
178 assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
179
180 putDevice(DID1, SW1);
181 putDevice(DID2, SW2);
182 putDevice(DID1, SW1);
183
184 assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
185 }
186
187 @Test
188 public final void testGetDevices() {
189 assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
190
191 putDevice(DID1, SW1);
192 putDevice(DID2, SW2);
193 putDevice(DID1, SW1);
194
195 assertEquals("expect 2 uniq devices",
196 2, Iterables.size(deviceStore.getDevices()));
197
198 Map<DeviceId, Device> devices = new HashMap<>();
199 for (Device device : deviceStore.getDevices()) {
200 devices.put(device.id(), device);
201 }
202
203 assertDevice(DID1, SW1, devices.get(DID1));
204 assertDevice(DID2, SW2, devices.get(DID2));
205
206 // add case for new node?
207 }
208
209 @Test
210 public final void testGetDevice() {
211
212 putDevice(DID1, SW1);
213
214 assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
215 assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
216 }
217
218 @Test
219 public final void testCreateOrUpdateDevice() {
220 DeviceDescription description =
221 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
222 HW, SW1, SN);
223 DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
224 assertEquals(DEVICE_ADDED, event.type());
225 assertDevice(DID1, SW1, event.subject());
226
227 DeviceDescription description2 =
228 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
229 HW, SW2, SN);
230 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
231 assertEquals(DEVICE_UPDATED, event2.type());
232 assertDevice(DID1, SW2, event2.subject());
233
234 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
235 }
236
237 @Test
238 public final void testCreateOrUpdateDeviceAncillary() {
239 DeviceDescription description =
240 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
241 HW, SW1, SN, A2);
242 DeviceEvent event = deviceStore.createOrUpdateDevice(PIDA, DID1, description);
243 assertEquals(DEVICE_ADDED, event.type());
244 assertDevice(DID1, SW1, event.subject());
245 assertEquals(PIDA, event.subject().providerId());
246 assertAnnotationsEquals(event.subject().annotations(), A2);
247 assertFalse("Ancillary will not bring device up", deviceStore.isAvailable(DID1));
248
249 DeviceDescription description2 =
250 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
251 HW, SW2, SN, A1);
252 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
253 assertEquals(DEVICE_UPDATED, event2.type());
254 assertDevice(DID1, SW2, event2.subject());
255 assertEquals(PID, event2.subject().providerId());
256 assertAnnotationsEquals(event2.subject().annotations(), A1, A2);
257 assertTrue(deviceStore.isAvailable(DID1));
258
259 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
260
261 // For now, Ancillary is ignored once primary appears
262 assertNull("No change expected", deviceStore.createOrUpdateDevice(PIDA, DID1, description));
263
264 // But, Ancillary annotations will be in effect
265 DeviceDescription description3 =
266 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
267 HW, SW1, SN, A2_2);
268 DeviceEvent event3 = deviceStore.createOrUpdateDevice(PIDA, DID1, description3);
269 assertEquals(DEVICE_UPDATED, event3.type());
270 // basic information will be the one from Primary
271 assertDevice(DID1, SW2, event3.subject());
272 assertEquals(PID, event3.subject().providerId());
273 // but annotation from Ancillary will be merged
274 assertAnnotationsEquals(event3.subject().annotations(), A1, A2, A2_2);
275 assertTrue(deviceStore.isAvailable(DID1));
276 }
277
278
279 @Test
280 public final void testMarkOffline() {
281
282 putDevice(DID1, SW1);
283 assertTrue(deviceStore.isAvailable(DID1));
284
285 DeviceEvent event = deviceStore.markOffline(DID1);
286 assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
287 assertDevice(DID1, SW1, event.subject());
288 assertFalse(deviceStore.isAvailable(DID1));
289
290 DeviceEvent event2 = deviceStore.markOffline(DID1);
291 assertNull("No change, no event", event2);
292}
293
294 @Test
295 public final void testUpdatePorts() {
296 putDevice(DID1, SW1);
297 List<PortDescription> pds = Arrays.<PortDescription>asList(
298 new DefaultPortDescription(P1, true),
299 new DefaultPortDescription(P2, true)
300 );
301
302 List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds);
303
304 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
305 for (DeviceEvent event : events) {
306 assertEquals(PORT_ADDED, event.type());
307 assertDevice(DID1, SW1, event.subject());
308 assertTrue("PortNumber is one of expected",
309 expectedPorts.remove(event.port().number()));
310 assertTrue("Port is enabled", event.port().isEnabled());
311 }
312 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
313
314
315 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
316 new DefaultPortDescription(P1, false),
317 new DefaultPortDescription(P2, true),
318 new DefaultPortDescription(P3, true)
319 );
320
321 events = deviceStore.updatePorts(PID, DID1, pds2);
322 assertFalse("event should be triggered", events.isEmpty());
323 for (DeviceEvent event : events) {
324 PortNumber num = event.port().number();
325 if (P1.equals(num)) {
326 assertEquals(PORT_UPDATED, event.type());
327 assertDevice(DID1, SW1, event.subject());
328 assertFalse("Port is disabled", event.port().isEnabled());
329 } else if (P2.equals(num)) {
330 fail("P2 event not expected.");
331 } else if (P3.equals(num)) {
332 assertEquals(PORT_ADDED, event.type());
333 assertDevice(DID1, SW1, event.subject());
334 assertTrue("Port is enabled", event.port().isEnabled());
335 } else {
336 fail("Unknown port number encountered: " + num);
337 }
338 }
339
340 List<PortDescription> pds3 = Arrays.<PortDescription>asList(
341 new DefaultPortDescription(P1, false),
342 new DefaultPortDescription(P2, true)
343 );
344 events = deviceStore.updatePorts(PID, DID1, pds3);
345 assertFalse("event should be triggered", events.isEmpty());
346 for (DeviceEvent event : events) {
347 PortNumber num = event.port().number();
348 if (P1.equals(num)) {
349 fail("P1 event not expected.");
350 } else if (P2.equals(num)) {
351 fail("P2 event not expected.");
352 } else if (P3.equals(num)) {
353 assertEquals(PORT_REMOVED, event.type());
354 assertDevice(DID1, SW1, event.subject());
355 assertTrue("Port was enabled", event.port().isEnabled());
356 } else {
357 fail("Unknown port number encountered: " + num);
358 }
359 }
360
361 }
362
363 @Test
364 public final void testUpdatePortStatus() {
365 putDevice(DID1, SW1);
366 List<PortDescription> pds = Arrays.<PortDescription>asList(
367 new DefaultPortDescription(P1, true)
368 );
369 deviceStore.updatePorts(PID, DID1, pds);
370
371 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
372 new DefaultPortDescription(P1, false));
373 assertEquals(PORT_UPDATED, event.type());
374 assertDevice(DID1, SW1, event.subject());
375 assertEquals(P1, event.port().number());
376 assertFalse("Port is disabled", event.port().isEnabled());
377
378 }
379 @Test
380 public final void testUpdatePortStatusAncillary() {
381 putDeviceAncillary(DID1, SW1);
382 putDevice(DID1, SW1);
383 List<PortDescription> pds = Arrays.<PortDescription>asList(
384 new DefaultPortDescription(P1, true, A1)
385 );
386 deviceStore.updatePorts(PID, DID1, pds);
387
388 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
389 new DefaultPortDescription(P1, false, A1_2));
390 assertEquals(PORT_UPDATED, event.type());
391 assertDevice(DID1, SW1, event.subject());
392 assertEquals(P1, event.port().number());
393 assertAnnotationsEquals(event.port().annotations(), A1, A1_2);
394 assertFalse("Port is disabled", event.port().isEnabled());
395
396 DeviceEvent event2 = deviceStore.updatePortStatus(PIDA, DID1,
397 new DefaultPortDescription(P1, true));
398 assertNull("Ancillary is ignored if primary exists", event2);
399
400 // but, Ancillary annotation update will be notified
401 DeviceEvent event3 = deviceStore.updatePortStatus(PIDA, DID1,
402 new DefaultPortDescription(P1, true, A2));
403 assertEquals(PORT_UPDATED, event3.type());
404 assertDevice(DID1, SW1, event3.subject());
405 assertEquals(P1, event3.port().number());
406 assertAnnotationsEquals(event3.port().annotations(), A1, A1_2, A2);
407 assertFalse("Port is disabled", event3.port().isEnabled());
408
409 // port only reported from Ancillary will be notified as down
410 DeviceEvent event4 = deviceStore.updatePortStatus(PIDA, DID1,
411 new DefaultPortDescription(P2, true));
412 assertEquals(PORT_ADDED, event4.type());
413 assertDevice(DID1, SW1, event4.subject());
414 assertEquals(P2, event4.port().number());
415 assertAnnotationsEquals(event4.port().annotations());
416 assertFalse("Port is disabled if not given from primary provider",
417 event4.port().isEnabled());
418 }
419
420 @Test
421 public final void testGetPorts() {
422 putDevice(DID1, SW1);
423 putDevice(DID2, SW1);
424 List<PortDescription> pds = Arrays.<PortDescription>asList(
425 new DefaultPortDescription(P1, true),
426 new DefaultPortDescription(P2, true)
427 );
428 deviceStore.updatePorts(PID, DID1, pds);
429
430 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
431 List<Port> ports = deviceStore.getPorts(DID1);
432 for (Port port : ports) {
433 assertTrue("Port is enabled", port.isEnabled());
434 assertTrue("PortNumber is one of expected",
435 expectedPorts.remove(port.number()));
436 }
437 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
438
439
440 assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
441 }
442
443 @Test
444 public final void testGetPort() {
445 putDevice(DID1, SW1);
446 putDevice(DID2, SW1);
447 List<PortDescription> pds = Arrays.<PortDescription>asList(
448 new DefaultPortDescription(P1, true),
449 new DefaultPortDescription(P2, false)
450 );
451 deviceStore.updatePorts(PID, DID1, pds);
452
453 Port port1 = deviceStore.getPort(DID1, P1);
454 assertEquals(P1, port1.number());
455 assertTrue("Port is enabled", port1.isEnabled());
456
457 Port port2 = deviceStore.getPort(DID1, P2);
458 assertEquals(P2, port2.number());
459 assertFalse("Port is disabled", port2.isEnabled());
460
461 Port port3 = deviceStore.getPort(DID1, P3);
462 assertNull("P3 not expected", port3);
463 }
464
465 @Test
466 public final void testRemoveDevice() {
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700467 putDevice(DID1, SW1, A1);
468 List<PortDescription> pds = Arrays.<PortDescription>asList(
469 new DefaultPortDescription(P1, true, A2)
470 );
471 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700472 putDevice(DID2, SW1);
473
474 assertEquals(2, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700475 assertEquals(1, deviceStore.getPorts(DID1).size());
476 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations(), A1);
477 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations(), A2);
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700478
479 DeviceEvent event = deviceStore.removeDevice(DID1);
480 assertEquals(DEVICE_REMOVED, event.type());
481 assertDevice(DID1, SW1, event.subject());
482
483 assertEquals(1, deviceStore.getDeviceCount());
Yuta HIGUCHI0d6a5e62014-10-03 15:54:09 -0700484 assertEquals(0, deviceStore.getPorts(DID1).size());
485
486 // putBack Device, Port w/o annotation
487 putDevice(DID1, SW1);
488 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
489 new DefaultPortDescription(P1, true)
490 );
491 deviceStore.updatePorts(PID, DID1, pds2);
492
493 // annotations should not survive
494 assertEquals(2, deviceStore.getDeviceCount());
495 assertEquals(1, deviceStore.getPorts(DID1).size());
496 assertAnnotationsEquals(deviceStore.getDevice(DID1).annotations());
497 assertAnnotationsEquals(deviceStore.getPort(DID1, P1).annotations());
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700498 }
499
500 // If Delegates should be called only on remote events,
501 // then Simple* should never call them, thus not test required.
502 // TODO add test for Port events when we have them
503 @Ignore("Ignore until Delegate spec. is clear.")
504 @Test
505 public final void testEvents() throws InterruptedException {
506 final CountDownLatch addLatch = new CountDownLatch(1);
507 DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
508 @Override
509 public void notify(DeviceEvent event) {
510 assertEquals(DEVICE_ADDED, event.type());
511 assertDevice(DID1, SW1, event.subject());
512 addLatch.countDown();
513 }
514 };
515 final CountDownLatch updateLatch = new CountDownLatch(1);
516 DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
517 @Override
518 public void notify(DeviceEvent event) {
519 assertEquals(DEVICE_UPDATED, event.type());
520 assertDevice(DID1, SW2, event.subject());
521 updateLatch.countDown();
522 }
523 };
524 final CountDownLatch removeLatch = new CountDownLatch(1);
525 DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
526 @Override
527 public void notify(DeviceEvent event) {
528 assertEquals(DEVICE_REMOVED, event.type());
529 assertDevice(DID1, SW2, event.subject());
530 removeLatch.countDown();
531 }
532 };
533
534 DeviceDescription description =
535 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
536 HW, SW1, SN);
537 deviceStore.setDelegate(checkAdd);
538 deviceStore.createOrUpdateDevice(PID, DID1, description);
539 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
540
541
542 DeviceDescription description2 =
543 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
544 HW, SW2, SN);
545 deviceStore.unsetDelegate(checkAdd);
546 deviceStore.setDelegate(checkUpdate);
547 deviceStore.createOrUpdateDevice(PID, DID1, description2);
548 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
549
550 deviceStore.unsetDelegate(checkUpdate);
551 deviceStore.setDelegate(checkRemove);
552 deviceStore.removeDevice(DID1);
553 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
554 }
555
556 private static final class TestGossipDeviceStore extends GossipDeviceStore {
557
Madan Jampani53e44e62014-10-07 12:39:51 -0700558 public TestGossipDeviceStore(
559 ClockService clockService,
560 ClusterService clusterService,
561 ClusterCommunicationService clusterCommunicator) {
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700562 this.clockService = clockService;
Madan Jampani53e44e62014-10-07 12:39:51 -0700563 this.clusterService = clusterService;
Madan Jampani47c93732014-10-06 20:46:08 -0700564 this.clusterCommunicator = clusterCommunicator;
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700565 }
566 }
Madan Jampani47c93732014-10-06 20:46:08 -0700567
568 private static final class TestClusterCommunicationService implements ClusterCommunicationService {
569 @Override
570 public boolean broadcast(ClusterMessage message) throws IOException { return true; }
571 @Override
572 public boolean unicast(ClusterMessage message, NodeId nodeId) throws IOException { return true; }
573 @Override
574 public boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException { return true; }
575 @Override
576 public void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber) {}
577 }
Madan Jampani53e44e62014-10-07 12:39:51 -0700578
579 private static final class TestClusterService implements ClusterService {
580
581 private static final ControllerNode ONOS1 =
582 new DefaultControllerNode(new NodeId("N1"), IpPrefix.valueOf("127.0.0.1"));
583 private final Map<NodeId, ControllerNode> nodes = new HashMap<>();
584 private final Map<NodeId, ControllerNode.State> nodeStates = new HashMap<>();
585
586 public TestClusterService() {
587 nodes.put(new NodeId("N1"), ONOS1);
588 nodeStates.put(new NodeId("N1"), ControllerNode.State.ACTIVE);
589 }
590
591 @Override
592 public ControllerNode getLocalNode() {
593 return ONOS1;
594 }
595
596 @Override
597 public Set<ControllerNode> getNodes() {
598 return Sets.newHashSet(nodes.values());
599 }
600
601 @Override
602 public ControllerNode getNode(NodeId nodeId) {
603 return nodes.get(nodeId);
604 }
605
606 @Override
607 public State getState(NodeId nodeId) {
608 return nodeStates.get(nodeId);
609 }
610
611 @Override
612 public void addListener(ClusterEventListener listener) {
613 }
614
615 @Override
616 public void removeListener(ClusterEventListener listener) {
617 }
618 }
Yuta HIGUCHI67a527f2014-10-02 22:23:54 -0700619}