blob: 43e3bcfc90043ff1205fbfc32432afb1e50d9fe4 [file] [log] [blame]
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -07001/**
2 *
3 */
4package org.onlab.onos.store.device.impl;
5
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;
Yuta HIGUCHIfec9e192014-09-28 14:58:02 -070023import org.junit.Ignore;
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070024import org.junit.Test;
25import org.onlab.onos.net.Device;
26import org.onlab.onos.net.DeviceId;
27import org.onlab.onos.net.Port;
28import org.onlab.onos.net.PortNumber;
29import org.onlab.onos.net.device.DefaultDeviceDescription;
30import org.onlab.onos.net.device.DefaultPortDescription;
31import org.onlab.onos.net.device.DeviceDescription;
32import org.onlab.onos.net.device.DeviceEvent;
33import org.onlab.onos.net.device.DeviceStoreDelegate;
34import org.onlab.onos.net.device.PortDescription;
35import org.onlab.onos.net.provider.ProviderId;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070036import org.onlab.onos.store.common.StoreManager;
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070037import org.onlab.onos.store.common.StoreService;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070038import org.onlab.onos.store.common.TestStoreManager;
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070039import com.google.common.collect.Iterables;
40import com.google.common.collect.Sets;
41import com.hazelcast.config.Config;
42import com.hazelcast.core.Hazelcast;
alshabib7911a052014-10-16 17:49:37 -070043import org.onlab.packet.ChassisId;
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070044
Yuta HIGUCHIf5712ff2014-09-27 23:52:37 -070045/**
46 * Test of the Hazelcast based distributed DeviceStore implementation.
47 */
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070048public class DistributedDeviceStoreTest {
49
50 private static final ProviderId PID = new ProviderId("of", "foo");
51 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";
alshabib7911a052014-10-16 17:49:37 -070058 private static final ChassisId CID = new ChassisId();
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070059
60 private static final PortNumber P1 = PortNumber.portNumber(1);
61 private static final PortNumber P2 = PortNumber.portNumber(2);
62 private static final PortNumber P3 = PortNumber.portNumber(3);
63
64 private DistributedDeviceStore deviceStore;
65
66 private StoreManager storeManager;
67
68
69 @BeforeClass
70 public static void setUpBeforeClass() throws Exception {
71 }
72
73 @AfterClass
74 public static void tearDownAfterClass() throws Exception {
75 }
76
77
78 @Before
79 public void setUp() throws Exception {
80 // TODO should find a way to clean Hazelcast instance without shutdown.
81 Config config = TestStoreManager.getTestConfig();
82
83 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
84 storeManager.activate();
85
Yuta HIGUCHI672488d2014-10-07 09:23:43 -070086 deviceStore = new TestDistributedDeviceStore(storeManager);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -070087 deviceStore.activate();
88 }
89
90 @After
91 public void tearDown() throws Exception {
92 deviceStore.deactivate();
93
94 storeManager.deactivate();
95 }
96
97 private void putDevice(DeviceId deviceId, String swVersion) {
98 DeviceDescription description =
99 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700100 HW, swVersion, SN, CID);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700101 deviceStore.createOrUpdateDevice(PID, deviceId, description);
102 }
103
104 private static void assertDevice(DeviceId id, String swVersion, Device device) {
105 assertNotNull(device);
106 assertEquals(id, device.id());
107 assertEquals(MFR, device.manufacturer());
108 assertEquals(HW, device.hwVersion());
109 assertEquals(swVersion, device.swVersion());
110 assertEquals(SN, device.serialNumber());
111 }
112
113 @Test
114 public final void testGetDeviceCount() {
115 assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
116
117 putDevice(DID1, SW1);
118 putDevice(DID2, SW2);
119 putDevice(DID1, SW1);
120
121 assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
122 }
123
124 @Test
125 public final void testGetDevices() {
126 assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
127
128 putDevice(DID1, SW1);
129 putDevice(DID2, SW2);
130 putDevice(DID1, SW1);
131
132 assertEquals("expect 2 uniq devices",
133 2, Iterables.size(deviceStore.getDevices()));
134
135 Map<DeviceId, Device> devices = new HashMap<>();
136 for (Device device : deviceStore.getDevices()) {
137 devices.put(device.id(), device);
138 }
139
140 assertDevice(DID1, SW1, devices.get(DID1));
141 assertDevice(DID2, SW2, devices.get(DID2));
142
143 // add case for new node?
144 }
145
146 @Test
147 public final void testGetDevice() {
148
149 putDevice(DID1, SW1);
150
151 assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
152 assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
153 }
154
155 @Test
156 public final void testCreateOrUpdateDevice() {
157 DeviceDescription description =
158 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700159 HW, SW1, SN, CID);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700160 DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
161 assertEquals(DEVICE_ADDED, event.type());
162 assertDevice(DID1, SW1, event.subject());
163
164 DeviceDescription description2 =
165 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700166 HW, SW2, SN, CID);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700167 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
168 assertEquals(DEVICE_UPDATED, event2.type());
169 assertDevice(DID1, SW2, event2.subject());
170
171 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
172 }
173
174 @Test
175 public final void testMarkOffline() {
176
177 putDevice(DID1, SW1);
178 assertTrue(deviceStore.isAvailable(DID1));
179
180 DeviceEvent event = deviceStore.markOffline(DID1);
181 assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
182 assertDevice(DID1, SW1, event.subject());
183 assertFalse(deviceStore.isAvailable(DID1));
184
185 DeviceEvent event2 = deviceStore.markOffline(DID1);
186 assertNull("No change, no event", event2);
187}
188
189 @Test
190 public final void testUpdatePorts() {
191 putDevice(DID1, SW1);
192 List<PortDescription> pds = Arrays.<PortDescription>asList(
193 new DefaultPortDescription(P1, true),
194 new DefaultPortDescription(P2, true)
195 );
196
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700197 List<DeviceEvent> events = deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700198
199 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
200 for (DeviceEvent event : events) {
201 assertEquals(PORT_ADDED, event.type());
202 assertDevice(DID1, SW1, event.subject());
203 assertTrue("PortNumber is one of expected",
204 expectedPorts.remove(event.port().number()));
205 assertTrue("Port is enabled", event.port().isEnabled());
206 }
207 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
208
209
210 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
211 new DefaultPortDescription(P1, false),
212 new DefaultPortDescription(P2, true),
213 new DefaultPortDescription(P3, true)
214 );
215
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700216 events = deviceStore.updatePorts(PID, DID1, pds2);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700217 assertFalse("event should be triggered", events.isEmpty());
218 for (DeviceEvent event : events) {
219 PortNumber num = event.port().number();
220 if (P1.equals(num)) {
221 assertEquals(PORT_UPDATED, event.type());
222 assertDevice(DID1, SW1, event.subject());
223 assertFalse("Port is disabled", event.port().isEnabled());
224 } else if (P2.equals(num)) {
225 fail("P2 event not expected.");
226 } else if (P3.equals(num)) {
227 assertEquals(PORT_ADDED, event.type());
228 assertDevice(DID1, SW1, event.subject());
229 assertTrue("Port is enabled", event.port().isEnabled());
230 } else {
231 fail("Unknown port number encountered: " + num);
232 }
233 }
234
235 List<PortDescription> pds3 = Arrays.<PortDescription>asList(
236 new DefaultPortDescription(P1, false),
237 new DefaultPortDescription(P2, true)
238 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700239 events = deviceStore.updatePorts(PID, DID1, pds3);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700240 assertFalse("event should be triggered", events.isEmpty());
241 for (DeviceEvent event : events) {
242 PortNumber num = event.port().number();
243 if (P1.equals(num)) {
244 fail("P1 event not expected.");
245 } else if (P2.equals(num)) {
246 fail("P2 event not expected.");
247 } else if (P3.equals(num)) {
248 assertEquals(PORT_REMOVED, event.type());
249 assertDevice(DID1, SW1, event.subject());
250 assertTrue("Port was enabled", event.port().isEnabled());
251 } else {
252 fail("Unknown port number encountered: " + num);
253 }
254 }
255
256 }
257
258 @Test
259 public final void testUpdatePortStatus() {
260 putDevice(DID1, SW1);
261 List<PortDescription> pds = Arrays.<PortDescription>asList(
262 new DefaultPortDescription(P1, true)
263 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700264 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700265
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700266 DeviceEvent event = deviceStore.updatePortStatus(PID, DID1,
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700267 new DefaultPortDescription(P1, false));
268 assertEquals(PORT_UPDATED, event.type());
269 assertDevice(DID1, SW1, event.subject());
270 assertEquals(P1, event.port().number());
271 assertFalse("Port is disabled", event.port().isEnabled());
272 }
273
274 @Test
275 public final void testGetPorts() {
276 putDevice(DID1, SW1);
277 putDevice(DID2, SW1);
278 List<PortDescription> pds = Arrays.<PortDescription>asList(
279 new DefaultPortDescription(P1, true),
280 new DefaultPortDescription(P2, true)
281 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700282 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700283
284 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
285 List<Port> ports = deviceStore.getPorts(DID1);
286 for (Port port : ports) {
287 assertTrue("Port is enabled", port.isEnabled());
288 assertTrue("PortNumber is one of expected",
289 expectedPorts.remove(port.number()));
290 }
291 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
292
293
294 assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
295 }
296
297 @Test
298 public final void testGetPort() {
299 putDevice(DID1, SW1);
300 putDevice(DID2, SW1);
301 List<PortDescription> pds = Arrays.<PortDescription>asList(
302 new DefaultPortDescription(P1, true),
303 new DefaultPortDescription(P2, false)
304 );
Yuta HIGUCHI5f6739c2014-10-01 14:04:01 -0700305 deviceStore.updatePorts(PID, DID1, pds);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700306
307 Port port1 = deviceStore.getPort(DID1, P1);
308 assertEquals(P1, port1.number());
309 assertTrue("Port is enabled", port1.isEnabled());
310
311 Port port2 = deviceStore.getPort(DID1, P2);
312 assertEquals(P2, port2.number());
313 assertFalse("Port is disabled", port2.isEnabled());
314
315 Port port3 = deviceStore.getPort(DID1, P3);
316 assertNull("P3 not expected", port3);
317 }
318
319 @Test
320 public final void testRemoveDevice() {
321 putDevice(DID1, SW1);
322 putDevice(DID2, SW1);
323
324 assertEquals(2, deviceStore.getDeviceCount());
325
326 DeviceEvent event = deviceStore.removeDevice(DID1);
327 assertEquals(DEVICE_REMOVED, event.type());
328 assertDevice(DID1, SW1, event.subject());
329
330 assertEquals(1, deviceStore.getDeviceCount());
331 }
332
333 // TODO add test for Port events when we have them
Yuta HIGUCHIfec9e192014-09-28 14:58:02 -0700334 @Ignore("Ignore until Delegate spec. is clear.")
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700335 @Test
336 public final void testEvents() throws InterruptedException {
337 final CountDownLatch addLatch = new CountDownLatch(1);
338 DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
339 @Override
340 public void notify(DeviceEvent event) {
341 assertEquals(DEVICE_ADDED, event.type());
342 assertDevice(DID1, SW1, event.subject());
343 addLatch.countDown();
344 }
345 };
346 final CountDownLatch updateLatch = new CountDownLatch(1);
347 DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
348 @Override
349 public void notify(DeviceEvent event) {
350 assertEquals(DEVICE_UPDATED, event.type());
351 assertDevice(DID1, SW2, event.subject());
352 updateLatch.countDown();
353 }
354 };
355 final CountDownLatch removeLatch = new CountDownLatch(1);
356 DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
357 @Override
358 public void notify(DeviceEvent event) {
359 assertEquals(DEVICE_REMOVED, event.type());
360 assertDevice(DID1, SW2, event.subject());
361 removeLatch.countDown();
362 }
363 };
364
365 DeviceDescription description =
366 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700367 HW, SW1, SN, CID);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700368 deviceStore.setDelegate(checkAdd);
369 deviceStore.createOrUpdateDevice(PID, DID1, description);
370 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
371
372
373 DeviceDescription description2 =
374 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700375 HW, SW2, SN, CID);
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700376 deviceStore.unsetDelegate(checkAdd);
377 deviceStore.setDelegate(checkUpdate);
378 deviceStore.createOrUpdateDevice(PID, DID1, description2);
379 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
380
381 deviceStore.unsetDelegate(checkUpdate);
382 deviceStore.setDelegate(checkRemove);
383 deviceStore.removeDevice(DID1);
384 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
385 }
386
387 private class TestDistributedDeviceStore extends DistributedDeviceStore {
Yuta HIGUCHI672488d2014-10-07 09:23:43 -0700388 public TestDistributedDeviceStore(StoreService storeService) {
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700389 this.storeService = storeService;
Yuta HIGUCHI4ee707a2014-09-25 00:10:09 -0700390 }
391 }
392}