blob: 5641e4c881cf37fdf5529e37f3428545b863f8a9 [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
daniel park04c40cc2018-02-19 17:48:30 +090018import com.google.common.collect.ImmutableSet;
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
Jian Lie6312162018-03-21 21:41:00 +090021import com.google.common.collect.Sets;
daniel park04c40cc2018-02-19 17:48:30 +090022import com.google.common.util.concurrent.MoreExecutors;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
26import org.onlab.junit.TestUtils;
27import org.onlab.packet.ChassisId;
28import org.onlab.packet.Ip4Address;
29import org.onlab.packet.IpAddress;
30import org.onlab.packet.MacAddress;
31import org.onlab.packet.VlanId;
32import org.onosproject.cfg.ComponentConfigAdapter;
33import org.onosproject.cluster.ClusterServiceAdapter;
34import org.onosproject.cluster.ControllerNode;
35import org.onosproject.cluster.DefaultControllerNode;
36import org.onosproject.cluster.LeadershipServiceAdapter;
37import org.onosproject.cluster.NodeId;
38import org.onosproject.core.ApplicationId;
39import org.onosproject.core.CoreServiceAdapter;
40import org.onosproject.core.DefaultApplicationId;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090041import org.onosproject.net.Annotations;
42import org.onosproject.net.DefaultAnnotations;
43import org.onosproject.net.DefaultDevice;
44import org.onosproject.net.DefaultPort;
45import org.onosproject.net.Device;
46import org.onosproject.net.DeviceId;
47import org.onosproject.net.Port;
48import org.onosproject.net.PortNumber;
49import org.onosproject.net.behaviour.BridgeConfig;
50import org.onosproject.net.behaviour.BridgeDescription;
51import org.onosproject.net.behaviour.BridgeName;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090052import org.onosproject.net.behaviour.DefaultBridgeDescription;
53import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
54import org.onosproject.net.behaviour.InterfaceConfig;
55import org.onosproject.net.behaviour.PatchDescription;
56import org.onosproject.net.behaviour.TunnelDescription;
57import org.onosproject.net.device.DefaultPortDescription;
58import org.onosproject.net.device.DeviceAdminService;
59import org.onosproject.net.device.DeviceEvent;
60import org.onosproject.net.device.DeviceInterfaceDescription;
61import org.onosproject.net.device.DeviceListener;
62import org.onosproject.net.device.DeviceServiceAdapter;
63import org.onosproject.net.device.PortDescription;
64import org.onosproject.net.driver.Behaviour;
65import org.onosproject.net.driver.DriverData;
66import org.onosproject.net.driver.DriverHandler;
67import org.onosproject.net.flow.instructions.ExtensionPropertyException;
68import org.onosproject.net.flow.instructions.ExtensionTreatment;
69import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090070import org.onosproject.net.provider.ProviderId;
71import org.onosproject.openstacknode.api.NodeState;
Jian Li27841662018-04-14 01:59:47 +090072import org.onosproject.openstacknode.api.OpenstackAuth;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090073import org.onosproject.openstacknode.api.OpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090074import org.onosproject.openstacknode.api.OpenstackPhyInterface;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090075import org.onosproject.ovsdb.controller.OvsdbClientService;
76import org.onosproject.ovsdb.controller.OvsdbController;
77
daniel park04c40cc2018-02-19 17:48:30 +090078import java.util.Collection;
79import java.util.List;
80import java.util.Map;
81import java.util.Objects;
82import java.util.Set;
83import java.util.stream.Collectors;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090084
Jian Li7d691f32018-05-03 16:56:50 +090085import static org.easymock.EasyMock.anyBoolean;
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;
Jian Li7d691f32018-05-03 16:56:50 +090089import static org.easymock.EasyMock.expectLastCall;
Ray Milkey0d47a552017-08-22 10:16:31 -070090import static org.easymock.EasyMock.replay;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090091import static org.junit.Assert.assertEquals;
92import static org.onosproject.net.AnnotationKeys.PORT_NAME;
93import static org.onosproject.net.Device.Type.CONTROLLER;
94import static org.onosproject.net.Device.Type.SWITCH;
Ray Milkey0d47a552017-08-22 10:16:31 -070095import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
96import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
97import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
98import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
99import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
100import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
101import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
102import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
103import static org.onosproject.openstacknode.api.Constants.ROUTER_BRIDGE;
104import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
105import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
106import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
107import static org.onosproject.openstacknode.api.NodeState.INIT;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900108import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
109import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
110
111/**
112 * Unit test for DefaultOpenstackNodeHandler.
113 */
114public class DefaultOpenstackNodeHandlerTest {
115
116 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
117 private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
118 private static final NodeId LOCAL_NODE_ID = new NodeId("local");
119 private static final ControllerNode LOCAL_CTRL =
120 new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));
121
122 private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
123 .name(ROUTER_BRIDGE)
124 .failMode(BridgeDescription.FailMode.SECURE)
125 .disableInBand()
126 .build();
127
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800128 private static final PortDescription PATCH_ROUT = DefaultPortDescription.builder()
129 .withPortNumber(PortNumber.portNumber(1))
130 .isEnabled(true)
131 .annotations(DefaultAnnotations.builder()
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900132 .set(PORT_NAME, PATCH_ROUT_BRIDGE)
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800133 .build())
134 .build();
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900135
136 private static final String COMPUTE_1_HOSTNAME = "compute_1";
137 private static final String COMPUTE_2_HOSTNAME = "compute_2";
138 private static final String COMPUTE_3_HOSTNAME = "compute_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900139 private static final String GATEWAY_1_HOSTNAME = "gateway_1";
140 private static final String GATEWAY_2_HOSTNAME = "gateway_2";
141 private static final String GATEWAY_3_HOSTNAME = "gateway_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900142
143 private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
144 private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
145 private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900146 private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
147 private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
148 private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
daniel parkb18424c2018-02-05 15:43:43 +0900149
150 private static final String GATEWAY_UPLINK_PORT = "eth0";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900151
Jian Lie6312162018-03-21 21:41:00 +0900152 private static final Set<OpenstackPhyInterface> COMPUTE_1_PHY_INTFS = createPhyIntfs();
153 private static final Set<OpenstackPhyInterface> COMPUTE_2_PHY_INTFS = createPhyIntfs();
154 private static final Set<OpenstackPhyInterface> COMPUTE_3_PHY_INTFS = createPhyIntfs();
155
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900156 private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
157 private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
158 private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
daniel parkb18424c2018-02-05 15:43:43 +0900159 private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
160 private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
161 private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(6, INTEGRATION_BRIDGE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900162
163 private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
164 private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900165 private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
166 private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
167
168 private static final OpenstackNode COMPUTE_1 = createNode(
169 COMPUTE_1_HOSTNAME,
170 COMPUTE,
171 COMPUTE_1_INTG_DEVICE,
172 COMPUTE_1_IP,
Jian Lie6312162018-03-21 21:41:00 +0900173 INIT,
174 COMPUTE_1_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900175 );
176
177 private static final OpenstackNode COMPUTE_2 = createNode(
178 COMPUTE_2_HOSTNAME,
179 COMPUTE,
180 COMPUTE_2_INTG_DEVICE,
181 COMPUTE_2_IP,
Jian Lie6312162018-03-21 21:41:00 +0900182 DEVICE_CREATED,
183 COMPUTE_2_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900184 );
185
186 private static final OpenstackNode COMPUTE_3 = createNode(
187 COMPUTE_3_HOSTNAME,
188 COMPUTE,
189 COMPUTE_3_INTG_DEVICE,
190 COMPUTE_3_IP,
Jian Lie6312162018-03-21 21:41:00 +0900191 COMPLETE,
192 COMPUTE_3_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900193 );
194
Jian Lie6312162018-03-21 21:41:00 +0900195 private static final OpenstackNode GATEWAY_1 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900196 GATEWAY_1_HOSTNAME,
197 GATEWAY,
198 GATEWAY_1_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900199 GATEWAY_1_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900200 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900201 INIT
202 );
203
Jian Lie6312162018-03-21 21:41:00 +0900204 private static final OpenstackNode GATEWAY_2 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900205 GATEWAY_2_HOSTNAME,
206 GATEWAY,
207 GATEWAY_2_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900208 GATEWAY_2_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900209 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900210 DEVICE_CREATED
211 );
212
Jian Lie6312162018-03-21 21:41:00 +0900213 private static final OpenstackNode GATEWAY_3 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900214 GATEWAY_3_HOSTNAME,
215 GATEWAY,
216 GATEWAY_3_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900217 GATEWAY_3_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900218 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900219 COMPLETE
220 );
221
222 private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
223
224 private TestOpenstackNodeManager testNodeManager;
225 private DefaultOpenstackNodeHandler target;
226
227 @Before
228 public void setUp() throws Exception {
229 DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
230 mockDeviceAdminService.removeDevice(anyObject());
231 replay(mockDeviceAdminService);
232
233 OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
234 expect(mockOvsdbClient.isConnected())
235 .andReturn(true)
236 .anyTimes();
237 replay(mockOvsdbClient);
238
239 OvsdbController mockOvsdbController = createMock(OvsdbController.class);
240 expect(mockOvsdbController.getOvsdbClient(anyObject()))
241 .andReturn(mockOvsdbClient)
242 .anyTimes();
Jian Li7d691f32018-05-03 16:56:50 +0900243 mockOvsdbController.setServerMode(anyBoolean());
244 expectLastCall();
245
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900246 replay(mockOvsdbController);
247
248 testNodeManager = new TestOpenstackNodeManager();
249 target = new DefaultOpenstackNodeHandler();
250
251 target.coreService = new TestCoreService();
252 target.leadershipService = new TestLeadershipService();
253 target.clusterService = new TestClusterService();
254 target.deviceService = TEST_DEVICE_SERVICE;
255 target.deviceAdminService = mockDeviceAdminService;
256 target.ovsdbController = mockOvsdbController;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900257 target.osNodeService = testNodeManager;
258 target.osNodeAdminService = testNodeManager;
259 target.componentConfigService = new TestComponentConfigService();
260 TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
261 target.activate();
262 }
263
264 @After
265 public void tearDown() {
266 TEST_DEVICE_SERVICE.clear();
267 target.deactivate();
268 target = null;
269 testNodeManager = null;
270 }
271
272 /**
273 * Checks if the compute node state changes from INIT to DEVICE_CREATED
274 * after processing INIT state.
275 */
276 @Test
277 public void testComputeNodeProcessNodeInitState() {
278 testNodeManager.createNode(COMPUTE_1);
279 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
280
281 assertEquals(ERR_STATE_NOT_MATCH, INIT,
282 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
283 target.processInitState(COMPUTE_1);
284 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
285 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
286 }
287
288 /**
289 * Checks if the gateway node state changes from INIT to DEVICE_CREATED
290 * after processing INIT state.
291 */
292 @Test
293 public void testGatewayNodeProcessNodeInitState() {
294 testNodeManager.createNode(GATEWAY_1);
295 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
296
297 assertEquals(ERR_STATE_NOT_MATCH, INIT,
298 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
299 target.processInitState(GATEWAY_1);
300 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
301 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
302 }
303
304 /**
305 * Checks if the compute node state changes from DEVICE_CREATED to
306 * PORT_CREATED after processing DEVICE_CREATED state.
307 */
308 @Test
309 public void testComputeNodeProcessDeviceCreatedState() {
310 testNodeManager.createNode(COMPUTE_2);
311 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
312 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
313
314 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
315 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
316 target.processDeviceCreatedState(COMPUTE_2);
daniel parkb18424c2018-02-05 15:43:43 +0900317 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900318 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
319 }
320
321 /**
322 * Checks if the gateway node state changes from DEVICE_CREATED to
323 * PORT_CREATED after processing DEVICE_CREATED state.
324 */
325 @Test
326 public void testGatewayNodeProcessDeviceCreatedState() {
327 testNodeManager.createNode(GATEWAY_2);
328 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
329 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
daniel parkb18424c2018-02-05 15:43:43 +0900330 TEST_DEVICE_SERVICE.portList.add(createPort(GATEWAY_2_INTG_DEVICE, GATEWAY_UPLINK_PORT));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900331
332 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
333 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
334 target.processDeviceCreatedState(GATEWAY_2);
daniel parkb18424c2018-02-05 15:43:43 +0900335 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900336 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
337 }
338
339 /**
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900340 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
341 * when integration bridge is disconnected.
342 */
343 @Test
344 public void testBackToIncompleteWhenBrIntDisconnected() {
daniel parkb18424c2018-02-05 15:43:43 +0900345 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900346
347 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900348 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
349 TEST_DEVICE_SERVICE.removeDevice(COMPUTE_3_INTG_DEVICE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900350 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900351 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900352 }
353
354 /**
355 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
356 * when vxlan port is removed from integration bridge.
357 */
358 @Test
359 public void testBackToIncompleteWhenVxlanRemoved() {
daniel parkb18424c2018-02-05 15:43:43 +0900360 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900361
362 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900363 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
364 TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
365 COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900366 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900367 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900368
369 }
370
371 private static Device createOvsdbDevice(IpAddress ovsdbIp) {
372 return new TestDevice(new ProviderId("of", "foo"),
373 DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
374 CONTROLLER,
375 "manufacturer",
376 "hwVersion",
377 "swVersion",
378 "serialNumber",
379 new ChassisId(1));
380 }
381
382 private static Device createOpenFlowDevice(long devIdNum, String type) {
383 return new TestDevice(new ProviderId("of", "foo"),
384 DeviceId.deviceId(String.format("of:%016d", devIdNum)),
385 SWITCH,
386 type,
387 "hwVersion",
388 "swVersion",
389 "serialNumber",
390 new ChassisId(1));
391 }
392
393 private static Port createPort(Device device, String portName) {
394 return new DefaultPort(device,
395 PortNumber.portNumber(1),
396 true,
397 DefaultAnnotations.builder().set(PORT_NAME, portName).build());
398 }
399
Jian Lie6312162018-03-21 21:41:00 +0900400 private static Set<OpenstackPhyInterface> createPhyIntfs() {
401 return Sets.newConcurrentHashSet();
402 }
403
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900404 private static OpenstackNode createNode(String hostname,
405 OpenstackNode.NodeType type,
406 Device intgBridge,
407 IpAddress ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900408 NodeState state,
409 Set<OpenstackPhyInterface> phyIntfs) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900410 return new TestOpenstackNode(
411 hostname,
412 type,
413 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900414 ipAddr,
415 ipAddr,
Jian Li27841662018-04-14 01:59:47 +0900416 null, null, state, phyIntfs, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900417 }
418
Jian Lie6312162018-03-21 21:41:00 +0900419 private static OpenstackNode createGatewayNode(String hostname,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900420 OpenstackNode.NodeType type,
421 Device intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900422 IpAddress ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900423 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900424 NodeState state) {
425 return new TestOpenstackNode(
426 hostname,
427 type,
428 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900429 ipAddr,
430 ipAddr,
Jian Li27841662018-04-14 01:59:47 +0900431 null, uplinkPort, state, null, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900432 }
433
434 private static final class TestDevice extends DefaultDevice {
435 private TestDevice(ProviderId providerId,
436 DeviceId id,
437 Type type,
438 String manufacturer,
439 String hwVersion,
440 String swVersion,
441 String serialNumber,
442 ChassisId chassisId,
443 Annotations... annotations) {
444 super(providerId,
445 id,
446 type,
447 manufacturer,
448 hwVersion,
449 swVersion,
450 serialNumber,
451 chassisId,
452 annotations);
453 }
454
455 @Override
456 @SuppressWarnings("unchecked")
457 public <B extends Behaviour> B as(Class<B> projectionClass) {
458 if (projectionClass.equals(BridgeConfig.class)) {
459 return (B) new TestBridgeConfig();
460 } else if (projectionClass.equals(InterfaceConfig.class)) {
461 return (B) new TestInterfaceConfig();
462 } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
463 ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
464 expect(treatmentResolver.getExtensionInstruction(anyObject()))
465 .andReturn(new TestExtensionTreatment())
466 .anyTimes();
467 replay(treatmentResolver);
468 return (B) treatmentResolver;
469 } else {
470 return null;
471 }
472 }
473
474 @Override
475 public <B extends Behaviour> boolean is(Class<B> projectionClass) {
476 return true;
477 }
478 }
479
480 private static final class TestOpenstackNode extends DefaultOpenstackNode {
481 private TestOpenstackNode(String hostname,
482 NodeType type,
483 DeviceId intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900484 IpAddress managementIp,
485 IpAddress dataIp,
486 String vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900487 String uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900488 NodeState state,
Jian Li27841662018-04-14 01:59:47 +0900489 Set<OpenstackPhyInterface> phyIntfs,
490 OpenstackAuth auth) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900491 super(hostname,
492 type,
493 intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900494 managementIp,
495 dataIp,
496 vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900497 uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900498 state,
Jian Li27841662018-04-14 01:59:47 +0900499 phyIntfs,
500 auth);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900501 }
502
503 @Override
504 public PortNumber tunnelPortNum() {
505 return PortNumber.portNumber(1);
506 }
507
508 @Override
509 public PortNumber vlanPortNum() {
510 return PortNumber.portNumber(1);
511 }
512
513 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900514 public MacAddress vlanPortMac() {
515 return MacAddress.NONE;
516 }
517 }
518
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900519 private static class TestDeviceService extends DeviceServiceAdapter {
520 Map<DeviceId, Device> devMap = Maps.newHashMap();
521 List<Port> portList = Lists.newArrayList();
522 List<DeviceListener> listeners = Lists.newArrayList();
523
524 @Override
525 public void addListener(DeviceListener listener) {
526 listeners.add(listener);
527 }
528
529 @Override
530 public void removeListener(DeviceListener listener) {
531 listeners.remove(listener);
532 }
533
534 @Override
535 public Device getDevice(DeviceId deviceId) {
536 return devMap.get(deviceId);
537 }
538
539 @Override
540 public List<Port> getPorts(DeviceId deviceId) {
541 return this.portList.stream()
542 .filter(p -> p.element().id().equals(deviceId))
543 .collect(Collectors.toList());
544 }
545
546 @Override
547 public boolean isAvailable(DeviceId deviceId) {
548 return devMap.containsKey(deviceId);
549 }
550
551 void addDevice(Device device) {
552 devMap.put(device.id(), device);
553 DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
554 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
555 }
556
557 void removeDevice(Device device) {
558 devMap.remove(device.id());
559 DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
560 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
561 }
562
563 void addPort(Device device, Port port) {
564 portList.add(port);
565 DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
566 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
567 }
568
569 void removePort(Device device, Port port) {
570 portList.remove(port);
571 DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
572 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
573 }
574
575 void clear() {
576 this.listeners.clear();
577 this.devMap.clear();
578 this.portList.clear();
579 }
580 }
581
582 private static class TestBridgeConfig implements BridgeConfig {
583
584 @Override
585 public DriverData data() {
586 return null;
587 }
588
589 @Override
590 public void setData(DriverData data) {
591
592 }
593
594 @Override
595 public DriverHandler handler() {
596 return null;
597 }
598
599 @Override
600 public void setHandler(DriverHandler handler) {
601
602 }
603
604 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900605 public boolean addBridge(BridgeDescription bridge) {
606 TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
607 DeviceId.deviceId("of:" + bridge.datapathId().get()),
608 SWITCH,
609 bridge.name(),
610 "hwVersion",
611 "swVersion",
612 "serialNumber",
613 new ChassisId(1)));
614 return true;
615 }
616
617 @Override
618 public void deleteBridge(BridgeName bridgeName) {
619
620 }
621
622 @Override
623 public Collection<BridgeDescription> getBridges() {
624 return ImmutableSet.of(ROUT_BRIDGE);
625 }
626
627 @Override
628 public void addPort(BridgeName bridgeName, String portName) {
629
630 }
631
632 @Override
633 public void deletePort(BridgeName bridgeName, String portName) {
634
635 }
636
637 @Override
638 public Collection<PortDescription> getPorts() {
639 return ImmutableSet.of(PATCH_ROUT);
640 }
641
642 @Override
643 public Set<PortNumber> getPortNumbers() {
644 return null;
645 }
646
647 @Override
648 public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
649 return null;
650 }
651 }
652
653 private static class TestInterfaceConfig implements InterfaceConfig {
654
655 @Override
656 public DriverData data() {
657 return null;
658 }
659
660 @Override
661 public void setData(DriverData data) {
662
663 }
664
665 @Override
666 public DriverHandler handler() {
667 return null;
668 }
669
670 @Override
671 public void setHandler(DriverHandler handler) {
672
673 }
674
675 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900676 public boolean addAccessMode(String intf, VlanId vlanId) {
677 return false;
678 }
679
680 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900681 public boolean removeAccessMode(String intf) {
682 return false;
683 }
684
685 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900686 public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
687 return false;
688 }
689
690 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900691 public boolean removeTrunkMode(String intf) {
692 return false;
693 }
694
695 @Override
696 public boolean addRateLimit(String intf, short limit) {
697 return false;
698 }
699
700 @Override
701 public boolean removeRateLimit(String intf) {
702 return false;
703 }
704
705 @Override
706 public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
707 TEST_DEVICE_SERVICE.devMap.values().stream()
708 .filter(device -> device.type() == SWITCH &&
709 device.manufacturer().equals(INTEGRATION_BRIDGE))
710 .forEach(device -> {
711 TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
712 });
713 return true;
714 }
715
716 @Override
717 public boolean removeTunnelMode(String intf) {
718 return false;
719 }
720
721 @Override
722 public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
723 if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
724 TEST_DEVICE_SERVICE.devMap.values().stream()
725 .filter(device -> device.type() == SWITCH &&
726 device.manufacturer().equals(INTEGRATION_BRIDGE))
727 .forEach(device -> {
728 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
729 });
730 } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
731 TEST_DEVICE_SERVICE.devMap.values().stream()
732 .filter(device -> device.type() == SWITCH &&
733 device.manufacturer().equals(ROUTER_BRIDGE))
734 .forEach(device -> {
735 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
736 });
737 }
738 return true;
739 }
740
741 @Override
742 public boolean removePatchMode(String ifaceName) {
743 return false;
744 }
745
746 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900747 public List<DeviceInterfaceDescription> getInterfaces() {
748 return null;
749 }
750 }
751
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900752 private static class TestExtensionTreatment implements ExtensionTreatment {
753 Ip4Address tunnelDst;
754
755 @Override
756 public ExtensionTreatmentType type() {
757 return null;
758 }
759
760 @Override
761 public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
762 tunnelDst = (Ip4Address) value;
763 }
764
765 @Override
766 public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
767 return null;
768 }
769
770 @Override
771 public List<String> getProperties() {
772 return null;
773 }
774
775 @Override
776 public byte[] serialize() {
777 return new byte[0];
778 }
779
780 @Override
781 public void deserialize(byte[] data) {
782
783 }
784
785 @Override
786 public boolean equals(Object obj) {
787 TestExtensionTreatment that = (TestExtensionTreatment) obj;
788 return Objects.equals(tunnelDst, that.tunnelDst);
789 }
790
791 @Override
792 public int hashCode() {
793 return Objects.hash(tunnelDst);
794 }
795 }
796
797 private static class TestCoreService extends CoreServiceAdapter {
798
799 @Override
800 public ApplicationId getAppId(String name) {
801 return TEST_APP_ID;
802 }
803 }
804
805 private static class TestLeadershipService extends LeadershipServiceAdapter {
806
807 @Override
808 public NodeId getLeader(String path) {
809 return LOCAL_NODE_ID;
810 }
811 }
812
813 private static class TestClusterService extends ClusterServiceAdapter {
814
815 @Override
816 public ControllerNode getLocalNode() {
817 return LOCAL_CTRL;
818 }
819 }
820
821 private class TestComponentConfigService extends ComponentConfigAdapter {
822
823 }
824}