blob: b7362b903dbf33a0d91b5512770915b9a7d82e89 [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;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -07004import com.google.common.collect.Sets;
tom0872a172014-09-23 11:24:26 -07005import com.hazelcast.config.Config;
6import com.hazelcast.core.Hazelcast;
tom85ff08b2014-09-22 17:14:18 -07007import com.hazelcast.core.HazelcastInstance;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07008import org.junit.After;
9import org.junit.Before;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070010import org.junit.Test;
tomb41d1ac2014-09-24 01:51:24 -070011import org.onlab.onos.cluster.MastershipServiceAdapter;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070012import org.onlab.onos.cluster.NodeId;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070013import org.onlab.onos.event.Event;
tom0872a172014-09-23 11:24:26 -070014import org.onlab.onos.event.impl.TestEventDispatcher;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070015import org.onlab.onos.net.Device;
16import org.onlab.onos.net.DeviceId;
17import org.onlab.onos.net.MastershipRole;
18import org.onlab.onos.net.Port;
19import org.onlab.onos.net.PortNumber;
20import org.onlab.onos.net.device.DefaultDeviceDescription;
21import org.onlab.onos.net.device.DefaultPortDescription;
22import org.onlab.onos.net.device.DeviceAdminService;
23import org.onlab.onos.net.device.DeviceDescription;
24import org.onlab.onos.net.device.DeviceEvent;
25import org.onlab.onos.net.device.DeviceListener;
26import org.onlab.onos.net.device.DeviceProvider;
27import org.onlab.onos.net.device.DeviceProviderRegistry;
28import org.onlab.onos.net.device.DeviceProviderService;
29import org.onlab.onos.net.device.DeviceService;
30import org.onlab.onos.net.device.PortDescription;
31import org.onlab.onos.net.provider.AbstractProvider;
32import org.onlab.onos.net.provider.ProviderId;
tom0755a362014-09-24 11:54:43 -070033import org.onlab.onos.store.common.StoreService;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070034import org.onlab.onos.store.device.impl.DistributedDeviceStore;
tom0872a172014-09-23 11:24:26 -070035import org.onlab.onos.store.impl.StoreManager;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070036
37import java.util.ArrayList;
38import java.util.Iterator;
39import java.util.List;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070040import java.util.Set;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070041import java.util.UUID;
42
43import static org.junit.Assert.*;
44import static org.onlab.onos.net.Device.Type.SWITCH;
45import static org.onlab.onos.net.DeviceId.deviceId;
46import static org.onlab.onos.net.device.DeviceEvent.Type.*;
47
48// FIXME This test is painfully slow starting up Hazelcast on each test cases,
49// turning it off in repository for now.
50// FIXME DistributedDeviceStore should have it's own test cases.
tomb41d1ac2014-09-24 01:51:24 -070051
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070052/**
53 * Test codifying the device service & device provider service contracts.
54 */
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070055public class DistributedDeviceManagerTest {
56
57 private static final ProviderId PID = new ProviderId("of", "foo");
58 private static final DeviceId DID1 = deviceId("of:foo");
59 private static final DeviceId DID2 = deviceId("of:bar");
60 private static final String MFR = "whitebox";
61 private static final String HW = "1.1.x";
62 private static final String SW1 = "3.8.1";
63 private static final String SW2 = "3.9.5";
64 private static final String SN = "43311-12345";
65
66 private static final PortNumber P1 = PortNumber.portNumber(1);
67 private static final PortNumber P2 = PortNumber.portNumber(2);
68 private static final PortNumber P3 = PortNumber.portNumber(3);
69
70 private DeviceManager mgr;
71
tom0872a172014-09-23 11:24:26 -070072 protected StoreManager storeManager;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070073 protected DeviceService service;
74 protected DeviceAdminService admin;
75 protected DeviceProviderRegistry registry;
76 protected DeviceProviderService providerService;
77 protected TestProvider provider;
78 protected TestListener listener = new TestListener();
79 private DistributedDeviceStore dstore;
80
81 @Before
82 public void setUp() {
83 mgr = new DeviceManager();
84 service = mgr;
85 admin = mgr;
86 registry = mgr;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070087 // FIXME should be reading the hazelcast.xml
88 Config config = new Config();
89 // avoid accidentally joining other cluster
90 config.getGroupConfig().setName(UUID.randomUUID().toString());
91 // quickly form single node cluster
Yuta HIGUCHI1b9f4dc2014-09-22 10:25:06 -070092 config.getNetworkConfig().getJoin()
tomb41d1ac2014-09-24 01:51:24 -070093 .getTcpIpConfig()
94 .setEnabled(true).setConnectionTimeoutSeconds(0);
Yuta HIGUCHI1b9f4dc2014-09-22 10:25:06 -070095 config.getNetworkConfig().getJoin()
tomb41d1ac2014-09-24 01:51:24 -070096 .getMulticastConfig()
97 .setEnabled(false);
tom0872a172014-09-23 11:24:26 -070098
99 storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
100 storeManager.activate();
101
102 dstore = new TestDistributedDeviceStore(storeManager);
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700103 dstore.activate();
104 mgr.store = dstore;
105 mgr.eventDispatcher = new TestEventDispatcher();
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700106 mgr.mastershipService = new TestMastershipService();
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700107 mgr.activate();
108
109 service.addListener(listener);
110
111 provider = new TestProvider();
112 providerService = registry.register(provider);
113 assertTrue("provider should be registered",
114 registry.getProviders().contains(provider.id()));
115 }
116
117 @After
118 public void tearDown() {
119 registry.unregister(provider);
120 assertFalse("provider should not be registered",
121 registry.getProviders().contains(provider.id()));
122 service.removeListener(listener);
123 mgr.deactivate();
124
125 dstore.deactivate();
tom0872a172014-09-23 11:24:26 -0700126 storeManager.deactivate();
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700127 }
128
129 private void connectDevice(DeviceId deviceId, String swVersion) {
130 DeviceDescription description =
131 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
132 HW, swVersion, SN);
133 providerService.deviceConnected(deviceId, description);
134 assertNotNull("device should be found", service.getDevice(DID1));
135 }
136
137 @Test
138 public void deviceConnected() {
139 assertNull("device should not be found", service.getDevice(DID1));
140 connectDevice(DID1, SW1);
141 validateEvents(DEVICE_ADDED);
142
143 assertEquals("only one device expected", 1, Iterables.size(service.getDevices()));
144 Iterator<Device> it = service.getDevices().iterator();
145 assertNotNull("one device expected", it.next());
146 assertFalse("only one device expected", it.hasNext());
147
148 assertEquals("incorrect device count", 1, service.getDeviceCount());
149 assertTrue("device should be available", service.isAvailable(DID1));
150 }
151
152 @Test
153 public void deviceDisconnected() {
154 connectDevice(DID1, SW1);
155 connectDevice(DID2, SW1);
156 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
157 assertTrue("device should be available", service.isAvailable(DID1));
158
159 // Disconnect
160 providerService.deviceDisconnected(DID1);
161 assertNotNull("device should not be found", service.getDevice(DID1));
162 assertFalse("device should not be available", service.isAvailable(DID1));
163 validateEvents(DEVICE_AVAILABILITY_CHANGED);
164
165 // Reconnect
166 connectDevice(DID1, SW1);
167 validateEvents(DEVICE_AVAILABILITY_CHANGED);
168
169 assertEquals("incorrect device count", 2, service.getDeviceCount());
170 }
171
172 @Test
173 public void deviceUpdated() {
174 connectDevice(DID1, SW1);
175 validateEvents(DEVICE_ADDED);
176
177 connectDevice(DID1, SW2);
178 validateEvents(DEVICE_UPDATED);
179 }
180
181 @Test
182 public void getRole() {
183 connectDevice(DID1, SW1);
184 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
185 }
186
187 @Test
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700188 public void updatePorts() {
189 connectDevice(DID1, SW1);
190 List<PortDescription> pds = new ArrayList<>();
191 pds.add(new DefaultPortDescription(P1, true));
192 pds.add(new DefaultPortDescription(P2, true));
193 pds.add(new DefaultPortDescription(P3, true));
194 providerService.updatePorts(DID1, pds);
195 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
196 pds.clear();
197
198 pds.add(new DefaultPortDescription(P1, false));
199 pds.add(new DefaultPortDescription(P3, true));
200 providerService.updatePorts(DID1, pds);
201 validateEvents(PORT_UPDATED, PORT_REMOVED);
202 }
203
204 @Test
205 public void updatePortStatus() {
206 connectDevice(DID1, SW1);
207 List<PortDescription> pds = new ArrayList<>();
208 pds.add(new DefaultPortDescription(P1, true));
209 pds.add(new DefaultPortDescription(P2, true));
210 providerService.updatePorts(DID1, pds);
211 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
212
213 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
214 validateEvents(PORT_UPDATED);
215 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
216 assertTrue("no events expected", listener.events.isEmpty());
217 }
218
219 @Test
220 public void getPorts() {
221 connectDevice(DID1, SW1);
222 List<PortDescription> pds = new ArrayList<>();
223 pds.add(new DefaultPortDescription(P1, true));
224 pds.add(new DefaultPortDescription(P2, true));
225 providerService.updatePorts(DID1, pds);
226 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
227 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
228
229 Port port = service.getPort(DID1, P1);
230 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
231 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
232 }
233
234 @Test
235 public void removeDevice() {
236 connectDevice(DID1, SW1);
237 connectDevice(DID2, SW2);
238 assertEquals("incorrect device count", 2, service.getDeviceCount());
239 admin.removeDevice(DID1);
240 assertNull("device should not be found", service.getDevice(DID1));
241 assertNotNull("device should be found", service.getDevice(DID2));
242 assertEquals("incorrect device count", 1, service.getDeviceCount());
243
244 }
245
246 protected void validateEvents(Enum... types) {
247 int i = 0;
248 assertEquals("wrong events received", types.length, listener.events.size());
249 for (Event event : listener.events) {
250 assertEquals("incorrect event type", types[i], event.type());
251 i++;
252 }
253 listener.events.clear();
254 }
255
256
257 private class TestProvider extends AbstractProvider implements DeviceProvider {
258 private Device deviceReceived;
259 private MastershipRole roleReceived;
260
261 public TestProvider() {
262 super(PID);
263 }
264
265 @Override
266 public void triggerProbe(Device device) {
267 }
268
269 @Override
270 public void roleChanged(Device device, MastershipRole newRole) {
271 deviceReceived = device;
272 roleReceived = newRole;
273 }
274 }
275
276 private static class TestListener implements DeviceListener {
277 final List<DeviceEvent> events = new ArrayList<>();
278
279 @Override
280 public void event(DeviceEvent event) {
281 events.add(event);
282 }
283 }
284
tom85ff08b2014-09-22 17:14:18 -0700285 private class TestDistributedDeviceStore extends DistributedDeviceStore {
tom0872a172014-09-23 11:24:26 -0700286 public TestDistributedDeviceStore(StoreService storeService) {
287 this.storeService = storeService;
288 }
289 }
290
291 private class TestStoreManager extends StoreManager {
292 TestStoreManager(HazelcastInstance instance) {
293 this.instance = instance;
tom85ff08b2014-09-22 17:14:18 -0700294 }
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700295
tom0872a172014-09-23 11:24:26 -0700296 @Override
297 public void activate() {
298 setupKryoPool();
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700299 }
tom85ff08b2014-09-22 17:14:18 -0700300 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700301
tomb41d1ac2014-09-24 01:51:24 -0700302 private static class TestMastershipService extends MastershipServiceAdapter {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700303 @Override
tomb41d1ac2014-09-24 01:51:24 -0700304 public MastershipRole getLocalRole(DeviceId deviceId) {
305 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700306 }
307
308 @Override
309 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
310 return Sets.newHashSet(DID1, DID2);
311 }
312
313 @Override
314 public MastershipRole requestRoleFor(DeviceId deviceId) {
315 return MastershipRole.MASTER;
316 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700317 }
318
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700319}