blob: a55cb25c70e81587e9e8753007ed5b401387fdfc [file] [log] [blame]
Hyunsun Moon090d77d2017-07-05 17:48:37 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Hyunsun Moon090d77d2017-07-05 17:48:37 +09003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.openstacknode.impl;
17
Ray Milkey0d47a552017-08-22 10:16:31 -070018import java.util.Collection;
19import java.util.List;
20import java.util.Map;
21import java.util.Objects;
22import java.util.Set;
23import java.util.stream.Collectors;
24
Hyunsun Moon090d77d2017-07-05 17:48:37 +090025import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.junit.TestUtils;
29import org.onlab.packet.ChassisId;
30import org.onlab.packet.Ip4Address;
31import org.onlab.packet.IpAddress;
32import org.onlab.packet.MacAddress;
33import org.onlab.packet.VlanId;
34import org.onosproject.cfg.ComponentConfigAdapter;
35import org.onosproject.cluster.ClusterServiceAdapter;
36import org.onosproject.cluster.ControllerNode;
37import org.onosproject.cluster.DefaultControllerNode;
38import org.onosproject.cluster.LeadershipServiceAdapter;
39import org.onosproject.cluster.NodeId;
40import org.onosproject.core.ApplicationId;
41import org.onosproject.core.CoreServiceAdapter;
42import org.onosproject.core.DefaultApplicationId;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090043import org.onosproject.net.Annotations;
44import org.onosproject.net.DefaultAnnotations;
45import org.onosproject.net.DefaultDevice;
46import org.onosproject.net.DefaultPort;
47import org.onosproject.net.Device;
48import org.onosproject.net.DeviceId;
49import org.onosproject.net.Port;
50import org.onosproject.net.PortNumber;
51import org.onosproject.net.behaviour.BridgeConfig;
52import org.onosproject.net.behaviour.BridgeDescription;
53import org.onosproject.net.behaviour.BridgeName;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090054import org.onosproject.net.behaviour.DefaultBridgeDescription;
55import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
56import org.onosproject.net.behaviour.InterfaceConfig;
57import org.onosproject.net.behaviour.PatchDescription;
58import org.onosproject.net.behaviour.TunnelDescription;
59import org.onosproject.net.device.DefaultPortDescription;
60import org.onosproject.net.device.DeviceAdminService;
61import org.onosproject.net.device.DeviceEvent;
62import org.onosproject.net.device.DeviceInterfaceDescription;
63import org.onosproject.net.device.DeviceListener;
64import org.onosproject.net.device.DeviceServiceAdapter;
65import org.onosproject.net.device.PortDescription;
66import org.onosproject.net.driver.Behaviour;
67import org.onosproject.net.driver.DriverData;
68import org.onosproject.net.driver.DriverHandler;
69import org.onosproject.net.flow.instructions.ExtensionPropertyException;
70import org.onosproject.net.flow.instructions.ExtensionTreatment;
71import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090072import org.onosproject.net.provider.ProviderId;
73import org.onosproject.openstacknode.api.NodeState;
74import org.onosproject.openstacknode.api.OpenstackNode;
75import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
76import org.onosproject.openstacknode.api.OpenstackNodeListener;
77import org.onosproject.openstacknode.api.OpenstackNodeService;
78import org.onosproject.ovsdb.controller.OvsdbClientService;
79import org.onosproject.ovsdb.controller.OvsdbController;
80
Ray Milkey0d47a552017-08-22 10:16:31 -070081import com.google.common.collect.ImmutableSet;
82import com.google.common.collect.Lists;
83import com.google.common.collect.Maps;
84import com.google.common.util.concurrent.MoreExecutors;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090085
Ray Milkey0d47a552017-08-22 10:16:31 -070086import static org.easymock.EasyMock.anyObject;
87import static org.easymock.EasyMock.createMock;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090088import static org.easymock.EasyMock.expect;
Ray Milkey0d47a552017-08-22 10:16:31 -070089import static org.easymock.EasyMock.replay;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090090import static org.junit.Assert.assertEquals;
91import static org.onosproject.net.AnnotationKeys.PORT_NAME;
92import static org.onosproject.net.Device.Type.CONTROLLER;
93import static org.onosproject.net.Device.Type.SWITCH;
Ray Milkey0d47a552017-08-22 10:16:31 -070094import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
95import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
96import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
97import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
98import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
99import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
100import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
101import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
102import static org.onosproject.openstacknode.api.Constants.ROUTER_BRIDGE;
103import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
104import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
105import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
106import static org.onosproject.openstacknode.api.NodeState.INIT;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900107import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
108import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
109
110/**
111 * Unit test for DefaultOpenstackNodeHandler.
112 */
113public class DefaultOpenstackNodeHandlerTest {
114
115 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
116 private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
117 private static final NodeId LOCAL_NODE_ID = new NodeId("local");
118 private static final ControllerNode LOCAL_CTRL =
119 new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));
120
121 private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
122 .name(ROUTER_BRIDGE)
123 .failMode(BridgeDescription.FailMode.SECURE)
124 .disableInBand()
125 .build();
126
127 private static final PortDescription PATCH_ROUT = new DefaultPortDescription(
128 PortNumber.portNumber(1),
129 true,
130 DefaultAnnotations.builder()
131 .set(PORT_NAME, PATCH_ROUT_BRIDGE)
132 .build()
133 );
134
135 private static final String COMPUTE_1_HOSTNAME = "compute_1";
136 private static final String COMPUTE_2_HOSTNAME = "compute_2";
137 private static final String COMPUTE_3_HOSTNAME = "compute_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900138 private static final String GATEWAY_1_HOSTNAME = "gateway_1";
139 private static final String GATEWAY_2_HOSTNAME = "gateway_2";
140 private static final String GATEWAY_3_HOSTNAME = "gateway_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900141
142 private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
143 private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
144 private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900145 private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
146 private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
147 private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
daniel parkb18424c2018-02-05 15:43:43 +0900148
149 private static final String GATEWAY_UPLINK_PORT = "eth0";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900150
151 private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
152 private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
153 private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
daniel parkb18424c2018-02-05 15:43:43 +0900154 private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
155 private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
156 private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(6, INTEGRATION_BRIDGE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900157
158 private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
159 private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900160 private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
161 private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
162
163 private static final OpenstackNode COMPUTE_1 = createNode(
164 COMPUTE_1_HOSTNAME,
165 COMPUTE,
166 COMPUTE_1_INTG_DEVICE,
167 COMPUTE_1_IP,
168 INIT
169 );
170
171 private static final OpenstackNode COMPUTE_2 = createNode(
172 COMPUTE_2_HOSTNAME,
173 COMPUTE,
174 COMPUTE_2_INTG_DEVICE,
175 COMPUTE_2_IP,
176 DEVICE_CREATED
177 );
178
179 private static final OpenstackNode COMPUTE_3 = createNode(
180 COMPUTE_3_HOSTNAME,
181 COMPUTE,
182 COMPUTE_3_INTG_DEVICE,
183 COMPUTE_3_IP,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900184 COMPLETE
185 );
186
187 private static final OpenstackNode GATEWAY_1 = createNode(
188 GATEWAY_1_HOSTNAME,
189 GATEWAY,
190 GATEWAY_1_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900191 GATEWAY_1_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900192 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900193 INIT
194 );
195
196 private static final OpenstackNode GATEWAY_2 = createNode(
197 GATEWAY_2_HOSTNAME,
198 GATEWAY,
199 GATEWAY_2_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900200 GATEWAY_2_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900201 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900202 DEVICE_CREATED
203 );
204
205 private static final OpenstackNode GATEWAY_3 = createNode(
206 GATEWAY_3_HOSTNAME,
207 GATEWAY,
208 GATEWAY_3_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900209 GATEWAY_3_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900210 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900211 COMPLETE
212 );
213
214 private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
215
216 private TestOpenstackNodeManager testNodeManager;
217 private DefaultOpenstackNodeHandler target;
218
219 @Before
220 public void setUp() throws Exception {
221 DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
222 mockDeviceAdminService.removeDevice(anyObject());
223 replay(mockDeviceAdminService);
224
225 OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
226 expect(mockOvsdbClient.isConnected())
227 .andReturn(true)
228 .anyTimes();
229 replay(mockOvsdbClient);
230
231 OvsdbController mockOvsdbController = createMock(OvsdbController.class);
232 expect(mockOvsdbController.getOvsdbClient(anyObject()))
233 .andReturn(mockOvsdbClient)
234 .anyTimes();
235 replay(mockOvsdbController);
236
237 testNodeManager = new TestOpenstackNodeManager();
238 target = new DefaultOpenstackNodeHandler();
239
240 target.coreService = new TestCoreService();
241 target.leadershipService = new TestLeadershipService();
242 target.clusterService = new TestClusterService();
243 target.deviceService = TEST_DEVICE_SERVICE;
244 target.deviceAdminService = mockDeviceAdminService;
245 target.ovsdbController = mockOvsdbController;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900246 target.osNodeService = testNodeManager;
247 target.osNodeAdminService = testNodeManager;
248 target.componentConfigService = new TestComponentConfigService();
249 TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
250 target.activate();
251 }
252
253 @After
254 public void tearDown() {
255 TEST_DEVICE_SERVICE.clear();
256 target.deactivate();
257 target = null;
258 testNodeManager = null;
259 }
260
261 /**
262 * Checks if the compute node state changes from INIT to DEVICE_CREATED
263 * after processing INIT state.
264 */
265 @Test
266 public void testComputeNodeProcessNodeInitState() {
267 testNodeManager.createNode(COMPUTE_1);
268 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
269
270 assertEquals(ERR_STATE_NOT_MATCH, INIT,
271 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
272 target.processInitState(COMPUTE_1);
273 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
274 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
275 }
276
277 /**
278 * Checks if the gateway node state changes from INIT to DEVICE_CREATED
279 * after processing INIT state.
280 */
281 @Test
282 public void testGatewayNodeProcessNodeInitState() {
283 testNodeManager.createNode(GATEWAY_1);
284 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
285
286 assertEquals(ERR_STATE_NOT_MATCH, INIT,
287 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
288 target.processInitState(GATEWAY_1);
289 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
290 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
291 }
292
293 /**
294 * Checks if the compute node state changes from DEVICE_CREATED to
295 * PORT_CREATED after processing DEVICE_CREATED state.
296 */
297 @Test
298 public void testComputeNodeProcessDeviceCreatedState() {
299 testNodeManager.createNode(COMPUTE_2);
300 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
301 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
302
303 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
304 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
305 target.processDeviceCreatedState(COMPUTE_2);
daniel parkb18424c2018-02-05 15:43:43 +0900306 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900307 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
308 }
309
310 /**
311 * Checks if the gateway node state changes from DEVICE_CREATED to
312 * PORT_CREATED after processing DEVICE_CREATED state.
313 */
314 @Test
315 public void testGatewayNodeProcessDeviceCreatedState() {
316 testNodeManager.createNode(GATEWAY_2);
317 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
318 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
daniel parkb18424c2018-02-05 15:43:43 +0900319 TEST_DEVICE_SERVICE.portList.add(createPort(GATEWAY_2_INTG_DEVICE, GATEWAY_UPLINK_PORT));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900320
321 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
322 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
323 target.processDeviceCreatedState(GATEWAY_2);
daniel parkb18424c2018-02-05 15:43:43 +0900324 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900325 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
326 }
327
328 /**
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900329 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
330 * when integration bridge is disconnected.
331 */
332 @Test
333 public void testBackToIncompleteWhenBrIntDisconnected() {
daniel parkb18424c2018-02-05 15:43:43 +0900334 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900335
336 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900337 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
338 TEST_DEVICE_SERVICE.removeDevice(COMPUTE_3_INTG_DEVICE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900339 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900340 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900341 }
342
343 /**
344 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
345 * when vxlan port is removed from integration bridge.
346 */
347 @Test
348 public void testBackToIncompleteWhenVxlanRemoved() {
daniel parkb18424c2018-02-05 15:43:43 +0900349 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900350
351 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900352 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
353 TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
354 COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900355 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900356 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900357
358 }
359
360 private static Device createOvsdbDevice(IpAddress ovsdbIp) {
361 return new TestDevice(new ProviderId("of", "foo"),
362 DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
363 CONTROLLER,
364 "manufacturer",
365 "hwVersion",
366 "swVersion",
367 "serialNumber",
368 new ChassisId(1));
369 }
370
371 private static Device createOpenFlowDevice(long devIdNum, String type) {
372 return new TestDevice(new ProviderId("of", "foo"),
373 DeviceId.deviceId(String.format("of:%016d", devIdNum)),
374 SWITCH,
375 type,
376 "hwVersion",
377 "swVersion",
378 "serialNumber",
379 new ChassisId(1));
380 }
381
382 private static Port createPort(Device device, String portName) {
383 return new DefaultPort(device,
384 PortNumber.portNumber(1),
385 true,
386 DefaultAnnotations.builder().set(PORT_NAME, portName).build());
387 }
388
389 private static OpenstackNode createNode(String hostname,
390 OpenstackNode.NodeType type,
391 Device intgBridge,
392 IpAddress ipAddr,
393 NodeState state) {
394 return new TestOpenstackNode(
395 hostname,
396 type,
397 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900398 ipAddr,
399 ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900400 null, null, state);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900401 }
402
403 private static OpenstackNode createNode(String hostname,
404 OpenstackNode.NodeType type,
405 Device intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900406 IpAddress ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900407 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900408 NodeState state) {
409 return new TestOpenstackNode(
410 hostname,
411 type,
412 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900413 ipAddr,
414 ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900415 null, uplinkPort, state);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900416 }
417
418 private static final class TestDevice extends DefaultDevice {
419 private TestDevice(ProviderId providerId,
420 DeviceId id,
421 Type type,
422 String manufacturer,
423 String hwVersion,
424 String swVersion,
425 String serialNumber,
426 ChassisId chassisId,
427 Annotations... annotations) {
428 super(providerId,
429 id,
430 type,
431 manufacturer,
432 hwVersion,
433 swVersion,
434 serialNumber,
435 chassisId,
436 annotations);
437 }
438
439 @Override
440 @SuppressWarnings("unchecked")
441 public <B extends Behaviour> B as(Class<B> projectionClass) {
442 if (projectionClass.equals(BridgeConfig.class)) {
443 return (B) new TestBridgeConfig();
444 } else if (projectionClass.equals(InterfaceConfig.class)) {
445 return (B) new TestInterfaceConfig();
446 } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
447 ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
448 expect(treatmentResolver.getExtensionInstruction(anyObject()))
449 .andReturn(new TestExtensionTreatment())
450 .anyTimes();
451 replay(treatmentResolver);
452 return (B) treatmentResolver;
453 } else {
454 return null;
455 }
456 }
457
458 @Override
459 public <B extends Behaviour> boolean is(Class<B> projectionClass) {
460 return true;
461 }
462 }
463
464 private static final class TestOpenstackNode extends DefaultOpenstackNode {
465 private TestOpenstackNode(String hostname,
466 NodeType type,
467 DeviceId intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900468 IpAddress managementIp,
469 IpAddress dataIp,
470 String vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900471 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900472 NodeState state) {
473 super(hostname,
474 type,
475 intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900476 managementIp,
477 dataIp,
478 vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900479 uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900480 state);
481 }
482
483 @Override
484 public PortNumber tunnelPortNum() {
485 return PortNumber.portNumber(1);
486 }
487
488 @Override
489 public PortNumber vlanPortNum() {
490 return PortNumber.portNumber(1);
491 }
492
493 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900494 public MacAddress vlanPortMac() {
495 return MacAddress.NONE;
496 }
497 }
498
499 private static class TestOpenstackNodeManager implements OpenstackNodeService, OpenstackNodeAdminService {
500 Map<String, OpenstackNode> osNodeMap = Maps.newHashMap();
501 List<OpenstackNodeListener> listeners = Lists.newArrayList();
502
503 @Override
504 public Set<OpenstackNode> nodes() {
505 return ImmutableSet.copyOf(osNodeMap.values());
506 }
507
508 @Override
509 public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) {
510 return osNodeMap.values().stream()
511 .filter(osNode -> osNode.type() == type)
512 .collect(Collectors.toSet());
513 }
514
515 @Override
516 public Set<OpenstackNode> completeNodes() {
517 return osNodeMap.values().stream()
518 .filter(osNode -> osNode.state() == COMPLETE)
519 .collect(Collectors.toSet());
520 }
521
522 @Override
523 public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) {
524 return osNodeMap.values().stream()
525 .filter(osNode -> osNode.type() == type && osNode.state() == COMPLETE)
526 .collect(Collectors.toSet());
527 }
528
529 @Override
530 public OpenstackNode node(String hostname) {
531 return osNodeMap.get(hostname);
532 }
533
534 @Override
535 public OpenstackNode node(DeviceId deviceId) {
536 return osNodeMap.values().stream()
537 .filter(osNode -> Objects.equals(osNode.intgBridge(), deviceId) ||
daniel parkb18424c2018-02-05 15:43:43 +0900538 Objects.equals(osNode.ovsdb(), deviceId))
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900539 .findFirst().orElse(null);
540 }
541
542 @Override
543 public void addListener(OpenstackNodeListener listener) {
544 listeners.add(listener);
545 }
546
547 @Override
548 public void removeListener(OpenstackNodeListener listener) {
549 listeners.remove(listener);
550 }
551
552 @Override
553 public void createNode(OpenstackNode osNode) {
554 osNodeMap.put(osNode.hostname(), osNode);
555 }
556
557 @Override
558 public void updateNode(OpenstackNode osNode) {
559 osNodeMap.put(osNode.hostname(), osNode);
560 }
561
562 @Override
563 public OpenstackNode removeNode(String hostname) {
564 return null;
565 }
566 }
567
568 private static class TestDeviceService extends DeviceServiceAdapter {
569 Map<DeviceId, Device> devMap = Maps.newHashMap();
570 List<Port> portList = Lists.newArrayList();
571 List<DeviceListener> listeners = Lists.newArrayList();
572
573 @Override
574 public void addListener(DeviceListener listener) {
575 listeners.add(listener);
576 }
577
578 @Override
579 public void removeListener(DeviceListener listener) {
580 listeners.remove(listener);
581 }
582
583 @Override
584 public Device getDevice(DeviceId deviceId) {
585 return devMap.get(deviceId);
586 }
587
588 @Override
589 public List<Port> getPorts(DeviceId deviceId) {
590 return this.portList.stream()
591 .filter(p -> p.element().id().equals(deviceId))
592 .collect(Collectors.toList());
593 }
594
595 @Override
596 public boolean isAvailable(DeviceId deviceId) {
597 return devMap.containsKey(deviceId);
598 }
599
600 void addDevice(Device device) {
601 devMap.put(device.id(), device);
602 DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
603 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
604 }
605
606 void removeDevice(Device device) {
607 devMap.remove(device.id());
608 DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
609 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
610 }
611
612 void addPort(Device device, Port port) {
613 portList.add(port);
614 DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
615 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
616 }
617
618 void removePort(Device device, Port port) {
619 portList.remove(port);
620 DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
621 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
622 }
623
624 void clear() {
625 this.listeners.clear();
626 this.devMap.clear();
627 this.portList.clear();
628 }
629 }
630
631 private static class TestBridgeConfig implements BridgeConfig {
632
633 @Override
634 public DriverData data() {
635 return null;
636 }
637
638 @Override
639 public void setData(DriverData data) {
640
641 }
642
643 @Override
644 public DriverHandler handler() {
645 return null;
646 }
647
648 @Override
649 public void setHandler(DriverHandler handler) {
650
651 }
652
653 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900654 public boolean addBridge(BridgeDescription bridge) {
655 TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
656 DeviceId.deviceId("of:" + bridge.datapathId().get()),
657 SWITCH,
658 bridge.name(),
659 "hwVersion",
660 "swVersion",
661 "serialNumber",
662 new ChassisId(1)));
663 return true;
664 }
665
666 @Override
667 public void deleteBridge(BridgeName bridgeName) {
668
669 }
670
671 @Override
672 public Collection<BridgeDescription> getBridges() {
673 return ImmutableSet.of(ROUT_BRIDGE);
674 }
675
676 @Override
677 public void addPort(BridgeName bridgeName, String portName) {
678
679 }
680
681 @Override
682 public void deletePort(BridgeName bridgeName, String portName) {
683
684 }
685
686 @Override
687 public Collection<PortDescription> getPorts() {
688 return ImmutableSet.of(PATCH_ROUT);
689 }
690
691 @Override
692 public Set<PortNumber> getPortNumbers() {
693 return null;
694 }
695
696 @Override
697 public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
698 return null;
699 }
700 }
701
702 private static class TestInterfaceConfig implements InterfaceConfig {
703
704 @Override
705 public DriverData data() {
706 return null;
707 }
708
709 @Override
710 public void setData(DriverData data) {
711
712 }
713
714 @Override
715 public DriverHandler handler() {
716 return null;
717 }
718
719 @Override
720 public void setHandler(DriverHandler handler) {
721
722 }
723
724 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900725 public boolean addAccessMode(String intf, VlanId vlanId) {
726 return false;
727 }
728
729 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900730 public boolean removeAccessMode(String intf) {
731 return false;
732 }
733
734 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900735 public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
736 return false;
737 }
738
739 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900740 public boolean removeTrunkMode(String intf) {
741 return false;
742 }
743
744 @Override
745 public boolean addRateLimit(String intf, short limit) {
746 return false;
747 }
748
749 @Override
750 public boolean removeRateLimit(String intf) {
751 return false;
752 }
753
754 @Override
755 public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
756 TEST_DEVICE_SERVICE.devMap.values().stream()
757 .filter(device -> device.type() == SWITCH &&
758 device.manufacturer().equals(INTEGRATION_BRIDGE))
759 .forEach(device -> {
760 TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
761 });
762 return true;
763 }
764
765 @Override
766 public boolean removeTunnelMode(String intf) {
767 return false;
768 }
769
770 @Override
771 public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
772 if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
773 TEST_DEVICE_SERVICE.devMap.values().stream()
774 .filter(device -> device.type() == SWITCH &&
775 device.manufacturer().equals(INTEGRATION_BRIDGE))
776 .forEach(device -> {
777 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
778 });
779 } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
780 TEST_DEVICE_SERVICE.devMap.values().stream()
781 .filter(device -> device.type() == SWITCH &&
782 device.manufacturer().equals(ROUTER_BRIDGE))
783 .forEach(device -> {
784 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
785 });
786 }
787 return true;
788 }
789
790 @Override
791 public boolean removePatchMode(String ifaceName) {
792 return false;
793 }
794
795 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900796 public List<DeviceInterfaceDescription> getInterfaces() {
797 return null;
798 }
799 }
800
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900801 private static class TestExtensionTreatment implements ExtensionTreatment {
802 Ip4Address tunnelDst;
803
804 @Override
805 public ExtensionTreatmentType type() {
806 return null;
807 }
808
809 @Override
810 public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
811 tunnelDst = (Ip4Address) value;
812 }
813
814 @Override
815 public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
816 return null;
817 }
818
819 @Override
820 public List<String> getProperties() {
821 return null;
822 }
823
824 @Override
825 public byte[] serialize() {
826 return new byte[0];
827 }
828
829 @Override
830 public void deserialize(byte[] data) {
831
832 }
833
834 @Override
835 public boolean equals(Object obj) {
836 TestExtensionTreatment that = (TestExtensionTreatment) obj;
837 return Objects.equals(tunnelDst, that.tunnelDst);
838 }
839
840 @Override
841 public int hashCode() {
842 return Objects.hash(tunnelDst);
843 }
844 }
845
846 private static class TestCoreService extends CoreServiceAdapter {
847
848 @Override
849 public ApplicationId getAppId(String name) {
850 return TEST_APP_ID;
851 }
852 }
853
854 private static class TestLeadershipService extends LeadershipServiceAdapter {
855
856 @Override
857 public NodeId getLeader(String path) {
858 return LOCAL_NODE_ID;
859 }
860 }
861
862 private static class TestClusterService extends ClusterServiceAdapter {
863
864 @Override
865 public ControllerNode getLocalNode() {
866 return LOCAL_CTRL;
867 }
868 }
869
870 private class TestComponentConfigService extends ComponentConfigAdapter {
871
872 }
873}