blob: d7494beb184e3b0fc9a5430d37b1a316ee74fbe1 [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;
23import org.junit.Test;
24import org.onlab.onos.net.Device;
25import org.onlab.onos.net.DeviceId;
26import org.onlab.onos.net.Port;
27import org.onlab.onos.net.PortNumber;
28import org.onlab.onos.net.device.DefaultDeviceDescription;
29import org.onlab.onos.net.device.DefaultPortDescription;
30import org.onlab.onos.net.device.DeviceDescription;
31import org.onlab.onos.net.device.DeviceEvent;
32import org.onlab.onos.net.device.DeviceStoreDelegate;
33import org.onlab.onos.net.device.PortDescription;
34import org.onlab.onos.net.provider.ProviderId;
35import org.onlab.onos.store.common.StoreService;
36import org.onlab.onos.store.impl.StoreManager;
37import org.onlab.onos.store.impl.TestStoreManager;
38
39import com.google.common.collect.Iterables;
40import com.google.common.collect.Sets;
41import com.hazelcast.config.Config;
42import com.hazelcast.core.Hazelcast;
43
44public class DistributedDeviceStoreTest {
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 DistributedDeviceStore deviceStore;
60
61 private StoreManager storeManager;
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 // TODO should find a way to clean Hazelcast instance without shutdown.
76 Config config = TestStoreManager.getTestConfig();
77
78 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
79 storeManager.activate();
80
81 deviceStore = new TestDistributedDeviceStore(storeManager);
82 deviceStore.activate();
83 }
84
85 @After
86 public void tearDown() throws Exception {
87 deviceStore.deactivate();
88
89 storeManager.deactivate();
90 }
91
92 private void putDevice(DeviceId deviceId, String swVersion) {
93 DeviceDescription description =
94 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
95 HW, swVersion, SN);
96 deviceStore.createOrUpdateDevice(PID, deviceId, description);
97 }
98
99 private static void assertDevice(DeviceId id, String swVersion, Device device) {
100 assertNotNull(device);
101 assertEquals(id, device.id());
102 assertEquals(MFR, device.manufacturer());
103 assertEquals(HW, device.hwVersion());
104 assertEquals(swVersion, device.swVersion());
105 assertEquals(SN, device.serialNumber());
106 }
107
108 @Test
109 public final void testGetDeviceCount() {
110 assertEquals("initialy empty", 0, deviceStore.getDeviceCount());
111
112 putDevice(DID1, SW1);
113 putDevice(DID2, SW2);
114 putDevice(DID1, SW1);
115
116 assertEquals("expect 2 uniq devices", 2, deviceStore.getDeviceCount());
117 }
118
119 @Test
120 public final void testGetDevices() {
121 assertEquals("initialy empty", 0, Iterables.size(deviceStore.getDevices()));
122
123 putDevice(DID1, SW1);
124 putDevice(DID2, SW2);
125 putDevice(DID1, SW1);
126
127 assertEquals("expect 2 uniq devices",
128 2, Iterables.size(deviceStore.getDevices()));
129
130 Map<DeviceId, Device> devices = new HashMap<>();
131 for (Device device : deviceStore.getDevices()) {
132 devices.put(device.id(), device);
133 }
134
135 assertDevice(DID1, SW1, devices.get(DID1));
136 assertDevice(DID2, SW2, devices.get(DID2));
137
138 // add case for new node?
139 }
140
141 @Test
142 public final void testGetDevice() {
143
144 putDevice(DID1, SW1);
145
146 assertDevice(DID1, SW1, deviceStore.getDevice(DID1));
147 assertNull("DID2 shouldn't be there", deviceStore.getDevice(DID2));
148 }
149
150 @Test
151 public final void testCreateOrUpdateDevice() {
152 DeviceDescription description =
153 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
154 HW, SW1, SN);
155 DeviceEvent event = deviceStore.createOrUpdateDevice(PID, DID1, description);
156 assertEquals(DEVICE_ADDED, event.type());
157 assertDevice(DID1, SW1, event.subject());
158
159 DeviceDescription description2 =
160 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
161 HW, SW2, SN);
162 DeviceEvent event2 = deviceStore.createOrUpdateDevice(PID, DID1, description2);
163 assertEquals(DEVICE_UPDATED, event2.type());
164 assertDevice(DID1, SW2, event2.subject());
165
166 assertNull("No change expected", deviceStore.createOrUpdateDevice(PID, DID1, description2));
167 }
168
169 @Test
170 public final void testMarkOffline() {
171
172 putDevice(DID1, SW1);
173 assertTrue(deviceStore.isAvailable(DID1));
174
175 DeviceEvent event = deviceStore.markOffline(DID1);
176 assertEquals(DEVICE_AVAILABILITY_CHANGED, event.type());
177 assertDevice(DID1, SW1, event.subject());
178 assertFalse(deviceStore.isAvailable(DID1));
179
180 DeviceEvent event2 = deviceStore.markOffline(DID1);
181 assertNull("No change, no event", event2);
182}
183
184 @Test
185 public final void testUpdatePorts() {
186 putDevice(DID1, SW1);
187 List<PortDescription> pds = Arrays.<PortDescription>asList(
188 new DefaultPortDescription(P1, true),
189 new DefaultPortDescription(P2, true)
190 );
191
192 List<DeviceEvent> events = deviceStore.updatePorts(DID1, pds);
193
194 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
195 for (DeviceEvent event : events) {
196 assertEquals(PORT_ADDED, event.type());
197 assertDevice(DID1, SW1, event.subject());
198 assertTrue("PortNumber is one of expected",
199 expectedPorts.remove(event.port().number()));
200 assertTrue("Port is enabled", event.port().isEnabled());
201 }
202 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
203
204
205 List<PortDescription> pds2 = Arrays.<PortDescription>asList(
206 new DefaultPortDescription(P1, false),
207 new DefaultPortDescription(P2, true),
208 new DefaultPortDescription(P3, true)
209 );
210
211 events = deviceStore.updatePorts(DID1, pds2);
212 assertFalse("event should be triggered", events.isEmpty());
213 for (DeviceEvent event : events) {
214 PortNumber num = event.port().number();
215 if (P1.equals(num)) {
216 assertEquals(PORT_UPDATED, event.type());
217 assertDevice(DID1, SW1, event.subject());
218 assertFalse("Port is disabled", event.port().isEnabled());
219 } else if (P2.equals(num)) {
220 fail("P2 event not expected.");
221 } else if (P3.equals(num)) {
222 assertEquals(PORT_ADDED, event.type());
223 assertDevice(DID1, SW1, event.subject());
224 assertTrue("Port is enabled", event.port().isEnabled());
225 } else {
226 fail("Unknown port number encountered: " + num);
227 }
228 }
229
230 List<PortDescription> pds3 = Arrays.<PortDescription>asList(
231 new DefaultPortDescription(P1, false),
232 new DefaultPortDescription(P2, true)
233 );
234 events = deviceStore.updatePorts(DID1, pds3);
235 assertFalse("event should be triggered", events.isEmpty());
236 for (DeviceEvent event : events) {
237 PortNumber num = event.port().number();
238 if (P1.equals(num)) {
239 fail("P1 event not expected.");
240 } else if (P2.equals(num)) {
241 fail("P2 event not expected.");
242 } else if (P3.equals(num)) {
243 assertEquals(PORT_REMOVED, event.type());
244 assertDevice(DID1, SW1, event.subject());
245 assertTrue("Port was enabled", event.port().isEnabled());
246 } else {
247 fail("Unknown port number encountered: " + num);
248 }
249 }
250
251 }
252
253 @Test
254 public final void testUpdatePortStatus() {
255 putDevice(DID1, SW1);
256 List<PortDescription> pds = Arrays.<PortDescription>asList(
257 new DefaultPortDescription(P1, true)
258 );
259 deviceStore.updatePorts(DID1, pds);
260
261 DeviceEvent event = deviceStore.updatePortStatus(DID1,
262 new DefaultPortDescription(P1, false));
263 assertEquals(PORT_UPDATED, event.type());
264 assertDevice(DID1, SW1, event.subject());
265 assertEquals(P1, event.port().number());
266 assertFalse("Port is disabled", event.port().isEnabled());
267 }
268
269 @Test
270 public final void testGetPorts() {
271 putDevice(DID1, SW1);
272 putDevice(DID2, SW1);
273 List<PortDescription> pds = Arrays.<PortDescription>asList(
274 new DefaultPortDescription(P1, true),
275 new DefaultPortDescription(P2, true)
276 );
277 deviceStore.updatePorts(DID1, pds);
278
279 Set<PortNumber> expectedPorts = Sets.newHashSet(P1, P2);
280 List<Port> ports = deviceStore.getPorts(DID1);
281 for (Port port : ports) {
282 assertTrue("Port is enabled", port.isEnabled());
283 assertTrue("PortNumber is one of expected",
284 expectedPorts.remove(port.number()));
285 }
286 assertTrue("Event for all expectedport appeared", expectedPorts.isEmpty());
287
288
289 assertTrue("DID2 has no ports", deviceStore.getPorts(DID2).isEmpty());
290 }
291
292 @Test
293 public final void testGetPort() {
294 putDevice(DID1, SW1);
295 putDevice(DID2, SW1);
296 List<PortDescription> pds = Arrays.<PortDescription>asList(
297 new DefaultPortDescription(P1, true),
298 new DefaultPortDescription(P2, false)
299 );
300 deviceStore.updatePorts(DID1, pds);
301
302 Port port1 = deviceStore.getPort(DID1, P1);
303 assertEquals(P1, port1.number());
304 assertTrue("Port is enabled", port1.isEnabled());
305
306 Port port2 = deviceStore.getPort(DID1, P2);
307 assertEquals(P2, port2.number());
308 assertFalse("Port is disabled", port2.isEnabled());
309
310 Port port3 = deviceStore.getPort(DID1, P3);
311 assertNull("P3 not expected", port3);
312 }
313
314 @Test
315 public final void testRemoveDevice() {
316 putDevice(DID1, SW1);
317 putDevice(DID2, SW1);
318
319 assertEquals(2, deviceStore.getDeviceCount());
320
321 DeviceEvent event = deviceStore.removeDevice(DID1);
322 assertEquals(DEVICE_REMOVED, event.type());
323 assertDevice(DID1, SW1, event.subject());
324
325 assertEquals(1, deviceStore.getDeviceCount());
326 }
327
328 // TODO add test for Port events when we have them
329 @Test
330 public final void testEvents() throws InterruptedException {
331 final CountDownLatch addLatch = new CountDownLatch(1);
332 DeviceStoreDelegate checkAdd = new DeviceStoreDelegate() {
333 @Override
334 public void notify(DeviceEvent event) {
335 assertEquals(DEVICE_ADDED, event.type());
336 assertDevice(DID1, SW1, event.subject());
337 addLatch.countDown();
338 }
339 };
340 final CountDownLatch updateLatch = new CountDownLatch(1);
341 DeviceStoreDelegate checkUpdate = new DeviceStoreDelegate() {
342 @Override
343 public void notify(DeviceEvent event) {
344 assertEquals(DEVICE_UPDATED, event.type());
345 assertDevice(DID1, SW2, event.subject());
346 updateLatch.countDown();
347 }
348 };
349 final CountDownLatch removeLatch = new CountDownLatch(1);
350 DeviceStoreDelegate checkRemove = new DeviceStoreDelegate() {
351 @Override
352 public void notify(DeviceEvent event) {
353 assertEquals(DEVICE_REMOVED, event.type());
354 assertDevice(DID1, SW2, event.subject());
355 removeLatch.countDown();
356 }
357 };
358
359 DeviceDescription description =
360 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
361 HW, SW1, SN);
362 deviceStore.setDelegate(checkAdd);
363 deviceStore.createOrUpdateDevice(PID, DID1, description);
364 assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
365
366
367 DeviceDescription description2 =
368 new DefaultDeviceDescription(DID1.uri(), SWITCH, MFR,
369 HW, SW2, SN);
370 deviceStore.unsetDelegate(checkAdd);
371 deviceStore.setDelegate(checkUpdate);
372 deviceStore.createOrUpdateDevice(PID, DID1, description2);
373 assertTrue("Update event fired", updateLatch.await(1, TimeUnit.SECONDS));
374
375 deviceStore.unsetDelegate(checkUpdate);
376 deviceStore.setDelegate(checkRemove);
377 deviceStore.removeDevice(DID1);
378 assertTrue("Remove event fired", removeLatch.await(1, TimeUnit.SECONDS));
379 }
380
381 private class TestDistributedDeviceStore extends DistributedDeviceStore {
382 public TestDistributedDeviceStore(StoreService storeService) {
383 this.storeService = storeService;
384 }
385 }
386}