blob: 222216cde966312cd6f5fe9c17e851fac64aa9bb [file] [log] [blame]
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07001package org.onlab.onos.net.device.impl;
2
tom85ff08b2014-09-22 17:14:18 -07003import com.hazelcast.core.HazelcastInstance;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07004import org.junit.After;
5import org.junit.Before;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -07006import org.junit.Test;
7import org.onlab.onos.event.Event;
8import org.onlab.onos.net.Device;
9import org.onlab.onos.net.DeviceId;
10import org.onlab.onos.net.MastershipRole;
11import org.onlab.onos.net.Port;
12import org.onlab.onos.net.PortNumber;
13import org.onlab.onos.net.device.DefaultDeviceDescription;
14import org.onlab.onos.net.device.DefaultPortDescription;
15import org.onlab.onos.net.device.DeviceAdminService;
16import org.onlab.onos.net.device.DeviceDescription;
17import org.onlab.onos.net.device.DeviceEvent;
18import org.onlab.onos.net.device.DeviceListener;
19import org.onlab.onos.net.device.DeviceProvider;
20import org.onlab.onos.net.device.DeviceProviderRegistry;
21import org.onlab.onos.net.device.DeviceProviderService;
22import org.onlab.onos.net.device.DeviceService;
23import org.onlab.onos.net.device.PortDescription;
24import org.onlab.onos.net.provider.AbstractProvider;
25import org.onlab.onos.net.provider.ProviderId;
26import org.onlab.onos.event.impl.TestEventDispatcher;
tom85ff08b2014-09-22 17:14:18 -070027import org.onlab.onos.store.StoreService;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070028import org.onlab.onos.store.device.impl.DistributedDeviceStore;
29
30import com.google.common.collect.Iterables;
31import com.hazelcast.config.Config;
32import com.hazelcast.core.Hazelcast;
33
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
67 protected DeviceService service;
68 protected DeviceAdminService admin;
69 protected DeviceProviderRegistry registry;
70 protected DeviceProviderService providerService;
71 protected TestProvider provider;
72 protected TestListener listener = new TestListener();
73 private DistributedDeviceStore dstore;
74
75 @Before
76 public void setUp() {
77 mgr = new DeviceManager();
78 service = mgr;
79 admin = mgr;
80 registry = mgr;
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070081 // FIXME should be reading the hazelcast.xml
82 Config config = new Config();
83 // avoid accidentally joining other cluster
84 config.getGroupConfig().setName(UUID.randomUUID().toString());
85 // quickly form single node cluster
Yuta HIGUCHI1b9f4dc2014-09-22 10:25:06 -070086 config.getNetworkConfig().getJoin()
87 .getTcpIpConfig()
88 .setEnabled(true).setConnectionTimeoutSeconds(0);
89 config.getNetworkConfig().getJoin()
90 .getMulticastConfig()
91 .setEnabled(false);
tom85ff08b2014-09-22 17:14:18 -070092 dstore = new TestDistributedDeviceStore(Hazelcast.newHazelcastInstance(config));
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -070093 dstore.activate();
94 mgr.store = dstore;
95 mgr.eventDispatcher = new TestEventDispatcher();
96 mgr.activate();
97
98 service.addListener(listener);
99
100 provider = new TestProvider();
101 providerService = registry.register(provider);
102 assertTrue("provider should be registered",
103 registry.getProviders().contains(provider.id()));
104 }
105
106 @After
107 public void tearDown() {
108 registry.unregister(provider);
109 assertFalse("provider should not be registered",
110 registry.getProviders().contains(provider.id()));
111 service.removeListener(listener);
112 mgr.deactivate();
113
114 dstore.deactivate();
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700115 ((TestDistributedDeviceStore) dstore).shutdownHz();
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700116 }
117
118 private void connectDevice(DeviceId deviceId, String swVersion) {
119 DeviceDescription description =
120 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
121 HW, swVersion, SN);
122 providerService.deviceConnected(deviceId, description);
123 assertNotNull("device should be found", service.getDevice(DID1));
124 }
125
126 @Test
127 public void deviceConnected() {
128 assertNull("device should not be found", service.getDevice(DID1));
129 connectDevice(DID1, SW1);
130 validateEvents(DEVICE_ADDED);
131
132 assertEquals("only one device expected", 1, Iterables.size(service.getDevices()));
133 Iterator<Device> it = service.getDevices().iterator();
134 assertNotNull("one device expected", it.next());
135 assertFalse("only one device expected", it.hasNext());
136
137 assertEquals("incorrect device count", 1, service.getDeviceCount());
138 assertTrue("device should be available", service.isAvailable(DID1));
139 }
140
141 @Test
142 public void deviceDisconnected() {
143 connectDevice(DID1, SW1);
144 connectDevice(DID2, SW1);
145 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
146 assertTrue("device should be available", service.isAvailable(DID1));
147
148 // Disconnect
149 providerService.deviceDisconnected(DID1);
150 assertNotNull("device should not be found", service.getDevice(DID1));
151 assertFalse("device should not be available", service.isAvailable(DID1));
152 validateEvents(DEVICE_AVAILABILITY_CHANGED);
153
154 // Reconnect
155 connectDevice(DID1, SW1);
156 validateEvents(DEVICE_AVAILABILITY_CHANGED);
157
158 assertEquals("incorrect device count", 2, service.getDeviceCount());
159 }
160
161 @Test
162 public void deviceUpdated() {
163 connectDevice(DID1, SW1);
164 validateEvents(DEVICE_ADDED);
165
166 connectDevice(DID1, SW2);
167 validateEvents(DEVICE_UPDATED);
168 }
169
170 @Test
171 public void getRole() {
172 connectDevice(DID1, SW1);
173 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
174 }
175
176 @Test
177 public void setRole() throws InterruptedException {
178 connectDevice(DID1, SW1);
179 admin.setRole(DID1, MastershipRole.STANDBY);
180 validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
181 assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
182 assertEquals("incorrect device", DID1, provider.deviceReceived.id());
183 assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
184 }
185
186 @Test
187 public void updatePorts() {
188 connectDevice(DID1, SW1);
189 List<PortDescription> pds = new ArrayList<>();
190 pds.add(new DefaultPortDescription(P1, true));
191 pds.add(new DefaultPortDescription(P2, true));
192 pds.add(new DefaultPortDescription(P3, true));
193 providerService.updatePorts(DID1, pds);
194 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
195 pds.clear();
196
197 pds.add(new DefaultPortDescription(P1, false));
198 pds.add(new DefaultPortDescription(P3, true));
199 providerService.updatePorts(DID1, pds);
200 validateEvents(PORT_UPDATED, PORT_REMOVED);
201 }
202
203 @Test
204 public void updatePortStatus() {
205 connectDevice(DID1, SW1);
206 List<PortDescription> pds = new ArrayList<>();
207 pds.add(new DefaultPortDescription(P1, true));
208 pds.add(new DefaultPortDescription(P2, true));
209 providerService.updatePorts(DID1, pds);
210 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
211
212 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
213 validateEvents(PORT_UPDATED);
214 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
215 assertTrue("no events expected", listener.events.isEmpty());
216 }
217
218 @Test
219 public void getPorts() {
220 connectDevice(DID1, SW1);
221 List<PortDescription> pds = new ArrayList<>();
222 pds.add(new DefaultPortDescription(P1, true));
223 pds.add(new DefaultPortDescription(P2, true));
224 providerService.updatePorts(DID1, pds);
225 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
226 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
227
228 Port port = service.getPort(DID1, P1);
229 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
230 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
231 }
232
233 @Test
234 public void removeDevice() {
235 connectDevice(DID1, SW1);
236 connectDevice(DID2, SW2);
237 assertEquals("incorrect device count", 2, service.getDeviceCount());
238 admin.removeDevice(DID1);
239 assertNull("device should not be found", service.getDevice(DID1));
240 assertNotNull("device should be found", service.getDevice(DID2));
241 assertEquals("incorrect device count", 1, service.getDeviceCount());
242
243 }
244
245 protected void validateEvents(Enum... types) {
246 int i = 0;
247 assertEquals("wrong events received", types.length, listener.events.size());
248 for (Event event : listener.events) {
249 assertEquals("incorrect event type", types[i], event.type());
250 i++;
251 }
252 listener.events.clear();
253 }
254
255
256 private class TestProvider extends AbstractProvider implements DeviceProvider {
257 private Device deviceReceived;
258 private MastershipRole roleReceived;
259
260 public TestProvider() {
261 super(PID);
262 }
263
264 @Override
265 public void triggerProbe(Device device) {
266 }
267
268 @Override
269 public void roleChanged(Device device, MastershipRole newRole) {
270 deviceReceived = device;
271 roleReceived = newRole;
272 }
273 }
274
275 private static class TestListener implements DeviceListener {
276 final List<DeviceEvent> events = new ArrayList<>();
277
278 @Override
279 public void event(DeviceEvent event) {
280 events.add(event);
281 }
282 }
283
tom85ff08b2014-09-22 17:14:18 -0700284 private class TestDistributedDeviceStore extends DistributedDeviceStore {
285 public TestDistributedDeviceStore(final HazelcastInstance hazelcastInstance) {
286 storeService = new StoreService() {
287 @Override
288 public HazelcastInstance getHazelcastInstance() {
289 return hazelcastInstance;
290 }
291 };
292 }
Yuta HIGUCHIc7052012014-09-22 19:11:00 -0700293
294 /**
295 * Shutdowns the hazelcast instance.
296 */
297 public void shutdownHz() {
298 theInstance.shutdown();
299 }
tom85ff08b2014-09-22 17:14:18 -0700300 }
Yuta HIGUCHIb3b2ac42014-09-21 23:37:11 -0700301}