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