blob: 85246e9a91616276a67f8690434a8a29985ae6a1 [file] [log] [blame]
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07001package org.onlab.onos.net.device.impl;
2
tom0872a172014-09-23 11:24:26 -07003import com.google.common.collect.Iterables;
4import com.hazelcast.config.Config;
5import com.hazelcast.core.Hazelcast;
tom85ff08b2014-09-22 17:14:18 -07006import com.hazelcast.core.HazelcastInstance;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07007import org.junit.After;
8import org.junit.Before;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07009import org.junit.Test;
10import org.onlab.onos.event.Event;
tom0872a172014-09-23 11:24:26 -070011import org.onlab.onos.event.impl.TestEventDispatcher;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070012import org.onlab.onos.net.Device;
13import org.onlab.onos.net.DeviceId;
14import org.onlab.onos.net.MastershipRole;
15import org.onlab.onos.net.Port;
16import org.onlab.onos.net.PortNumber;
17import org.onlab.onos.net.device.DefaultDeviceDescription;
18import org.onlab.onos.net.device.DefaultPortDescription;
19import org.onlab.onos.net.device.DeviceAdminService;
20import org.onlab.onos.net.device.DeviceDescription;
21import org.onlab.onos.net.device.DeviceEvent;
22import org.onlab.onos.net.device.DeviceListener;
23import org.onlab.onos.net.device.DeviceProvider;
24import org.onlab.onos.net.device.DeviceProviderRegistry;
25import org.onlab.onos.net.device.DeviceProviderService;
26import org.onlab.onos.net.device.DeviceService;
27import org.onlab.onos.net.device.PortDescription;
28import org.onlab.onos.net.provider.AbstractProvider;
29import org.onlab.onos.net.provider.ProviderId;
tom85ff08b2014-09-22 17:14:18 -070030import org.onlab.onos.store.StoreService;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070031import org.onlab.onos.store.device.impl.DistributedDeviceStore;
tom0872a172014-09-23 11:24:26 -070032import org.onlab.onos.store.impl.StoreManager;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070033
34import java.util.ArrayList;
35import java.util.Iterator;
36import java.util.List;
37import java.util.UUID;
38
39import static org.junit.Assert.*;
40import static org.onlab.onos.net.Device.Type.SWITCH;
41import static org.onlab.onos.net.DeviceId.deviceId;
42import static org.onlab.onos.net.device.DeviceEvent.Type.*;
43
44// FIXME This test is painfully slow starting up Hazelcast on each test cases,
45// turning it off in repository for now.
46// FIXME DistributedDeviceStore should have it's own test cases.
47/**
48 * Test codifying the device service & device provider service contracts.
49 */
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070050public class DistributedDeviceManagerTest {
51
52 private static final ProviderId PID = new ProviderId("of", "foo");
53 private static final DeviceId DID1 = deviceId("of:foo");
54 private static final DeviceId DID2 = deviceId("of:bar");
55 private static final String MFR = "whitebox";
56 private static final String HW = "1.1.x";
57 private static final String SW1 = "3.8.1";
58 private static final String SW2 = "3.9.5";
59 private static final String SN = "43311-12345";
60
61 private static final PortNumber P1 = PortNumber.portNumber(1);
62 private static final PortNumber P2 = PortNumber.portNumber(2);
63 private static final PortNumber P3 = PortNumber.portNumber(3);
64
65 private DeviceManager mgr;
66
tom0872a172014-09-23 11:24:26 -070067 protected StoreManager storeManager;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070068 protected DeviceService service;
69 protected DeviceAdminService admin;
70 protected DeviceProviderRegistry registry;
71 protected DeviceProviderService providerService;
72 protected TestProvider provider;
73 protected TestListener listener = new TestListener();
74 private DistributedDeviceStore dstore;
75
76 @Before
77 public void setUp() {
78 mgr = new DeviceManager();
79 service = mgr;
80 admin = mgr;
81 registry = mgr;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070082 // FIXME should be reading the hazelcast.xml
83 Config config = new Config();
84 // avoid accidentally joining other cluster
85 config.getGroupConfig().setName(UUID.randomUUID().toString());
86 // quickly form single node cluster
Yuta HIGUCHI1b9f4dc2014-09-22 10:25:06 -070087 config.getNetworkConfig().getJoin()
88 .getTcpIpConfig()
89 .setEnabled(true).setConnectionTimeoutSeconds(0);
90 config.getNetworkConfig().getJoin()
91 .getMulticastConfig()
92 .setEnabled(false);
tom0872a172014-09-23 11:24:26 -070093
94 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
95 storeManager.activate();
96
97 dstore = new TestDistributedDeviceStore(storeManager);
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070098 dstore.activate();
99 mgr.store = dstore;
100 mgr.eventDispatcher = new TestEventDispatcher();
101 mgr.activate();
102
103 service.addListener(listener);
104
105 provider = new TestProvider();
106 providerService = registry.register(provider);
107 assertTrue("provider should be registered",
108 registry.getProviders().contains(provider.id()));
109 }
110
111 @After
112 public void tearDown() {
113 registry.unregister(provider);
114 assertFalse("provider should not be registered",
115 registry.getProviders().contains(provider.id()));
116 service.removeListener(listener);
117 mgr.deactivate();
118
119 dstore.deactivate();
tom0872a172014-09-23 11:24:26 -0700120 storeManager.deactivate();
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700121 }
122
123 private void connectDevice(DeviceId deviceId, String swVersion) {
124 DeviceDescription description =
125 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
126 HW, swVersion, SN);
127 providerService.deviceConnected(deviceId, description);
128 assertNotNull("device should be found", service.getDevice(DID1));
129 }
130
131 @Test
132 public void deviceConnected() {
133 assertNull("device should not be found", service.getDevice(DID1));
134 connectDevice(DID1, SW1);
135 validateEvents(DEVICE_ADDED);
136
137 assertEquals("only one device expected", 1, Iterables.size(service.getDevices()));
138 Iterator<Device> it = service.getDevices().iterator();
139 assertNotNull("one device expected", it.next());
140 assertFalse("only one device expected", it.hasNext());
141
142 assertEquals("incorrect device count", 1, service.getDeviceCount());
143 assertTrue("device should be available", service.isAvailable(DID1));
144 }
145
146 @Test
147 public void deviceDisconnected() {
148 connectDevice(DID1, SW1);
149 connectDevice(DID2, SW1);
150 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
151 assertTrue("device should be available", service.isAvailable(DID1));
152
153 // Disconnect
154 providerService.deviceDisconnected(DID1);
155 assertNotNull("device should not be found", service.getDevice(DID1));
156 assertFalse("device should not be available", service.isAvailable(DID1));
157 validateEvents(DEVICE_AVAILABILITY_CHANGED);
158
159 // Reconnect
160 connectDevice(DID1, SW1);
161 validateEvents(DEVICE_AVAILABILITY_CHANGED);
162
163 assertEquals("incorrect device count", 2, service.getDeviceCount());
164 }
165
166 @Test
167 public void deviceUpdated() {
168 connectDevice(DID1, SW1);
169 validateEvents(DEVICE_ADDED);
170
171 connectDevice(DID1, SW2);
172 validateEvents(DEVICE_UPDATED);
173 }
174
175 @Test
176 public void getRole() {
177 connectDevice(DID1, SW1);
178 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
179 }
180
181 @Test
182 public void setRole() throws InterruptedException {
183 connectDevice(DID1, SW1);
184 admin.setRole(DID1, MastershipRole.STANDBY);
185 validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
186 assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
187 assertEquals("incorrect device", DID1, provider.deviceReceived.id());
188 assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
189 }
190
191 @Test
192 public void updatePorts() {
193 connectDevice(DID1, SW1);
194 List<PortDescription> pds = new ArrayList<>();
195 pds.add(new DefaultPortDescription(P1, true));
196 pds.add(new DefaultPortDescription(P2, true));
197 pds.add(new DefaultPortDescription(P3, true));
198 providerService.updatePorts(DID1, pds);
199 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
200 pds.clear();
201
202 pds.add(new DefaultPortDescription(P1, false));
203 pds.add(new DefaultPortDescription(P3, true));
204 providerService.updatePorts(DID1, pds);
205 validateEvents(PORT_UPDATED, PORT_REMOVED);
206 }
207
208 @Test
209 public void updatePortStatus() {
210 connectDevice(DID1, SW1);
211 List<PortDescription> pds = new ArrayList<>();
212 pds.add(new DefaultPortDescription(P1, true));
213 pds.add(new DefaultPortDescription(P2, true));
214 providerService.updatePorts(DID1, pds);
215 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
216
217 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
218 validateEvents(PORT_UPDATED);
219 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
220 assertTrue("no events expected", listener.events.isEmpty());
221 }
222
223 @Test
224 public void getPorts() {
225 connectDevice(DID1, SW1);
226 List<PortDescription> pds = new ArrayList<>();
227 pds.add(new DefaultPortDescription(P1, true));
228 pds.add(new DefaultPortDescription(P2, true));
229 providerService.updatePorts(DID1, pds);
230 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
231 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
232
233 Port port = service.getPort(DID1, P1);
234 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
235 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
236 }
237
238 @Test
239 public void removeDevice() {
240 connectDevice(DID1, SW1);
241 connectDevice(DID2, SW2);
242 assertEquals("incorrect device count", 2, service.getDeviceCount());
243 admin.removeDevice(DID1);
244 assertNull("device should not be found", service.getDevice(DID1));
245 assertNotNull("device should be found", service.getDevice(DID2));
246 assertEquals("incorrect device count", 1, service.getDeviceCount());
247
248 }
249
250 protected void validateEvents(Enum... types) {
251 int i = 0;
252 assertEquals("wrong events received", types.length, listener.events.size());
253 for (Event event : listener.events) {
254 assertEquals("incorrect event type", types[i], event.type());
255 i++;
256 }
257 listener.events.clear();
258 }
259
260
261 private class TestProvider extends AbstractProvider implements DeviceProvider {
262 private Device deviceReceived;
263 private MastershipRole roleReceived;
264
265 public TestProvider() {
266 super(PID);
267 }
268
269 @Override
270 public void triggerProbe(Device device) {
271 }
272
273 @Override
274 public void roleChanged(Device device, MastershipRole newRole) {
275 deviceReceived = device;
276 roleReceived = newRole;
277 }
278 }
279
280 private static class TestListener implements DeviceListener {
281 final List<DeviceEvent> events = new ArrayList<>();
282
283 @Override
284 public void event(DeviceEvent event) {
285 events.add(event);
286 }
287 }
288
tom85ff08b2014-09-22 17:14:18 -0700289 private class TestDistributedDeviceStore extends DistributedDeviceStore {
tom0872a172014-09-23 11:24:26 -0700290 public TestDistributedDeviceStore(StoreService storeService) {
291 this.storeService = storeService;
292 }
293 }
294
295 private class TestStoreManager extends StoreManager {
296 TestStoreManager(HazelcastInstance instance) {
297 this.instance = instance;
tom85ff08b2014-09-22 17:14:18 -0700298 }
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700299
tom0872a172014-09-23 11:24:26 -0700300 @Override
301 public void activate() {
302 setupKryoPool();
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700303 }
tom85ff08b2014-09-22 17:14:18 -0700304 }
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700305}