blob: 4305cc32ee84aa6b886b9e40c713633acf8684c5 [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;
Jian Li5a38ab62018-07-02 22:34:11 +090071import org.onosproject.openstacknode.api.DefaultOpenstackNode;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090072import org.onosproject.openstacknode.api.NodeState;
Jian Li27841662018-04-14 01:59:47 +090073import org.onosproject.openstacknode.api.OpenstackAuth;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090074import org.onosproject.openstacknode.api.OpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090075import org.onosproject.openstacknode.api.OpenstackPhyInterface;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090076import org.onosproject.ovsdb.controller.OvsdbClientService;
77import org.onosproject.ovsdb.controller.OvsdbController;
78
daniel park04c40cc2018-02-19 17:48:30 +090079import java.util.Collection;
80import java.util.List;
81import java.util.Map;
82import java.util.Objects;
83import java.util.Set;
84import java.util.stream.Collectors;
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
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800127 private static final PortDescription PATCH_ROUT = DefaultPortDescription.builder()
128 .withPortNumber(PortNumber.portNumber(1))
129 .isEnabled(true)
130 .annotations(DefaultAnnotations.builder()
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900131 .set(PORT_NAME, PATCH_ROUT_BRIDGE)
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800132 .build())
133 .build();
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900134
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
Jian Lie6312162018-03-21 21:41:00 +0900151 private static final Set<OpenstackPhyInterface> COMPUTE_1_PHY_INTFS = createPhyIntfs();
152 private static final Set<OpenstackPhyInterface> COMPUTE_2_PHY_INTFS = createPhyIntfs();
153 private static final Set<OpenstackPhyInterface> COMPUTE_3_PHY_INTFS = createPhyIntfs();
154
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900155 private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
156 private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
157 private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
daniel parkb18424c2018-02-05 15:43:43 +0900158 private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
159 private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
160 private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(6, INTEGRATION_BRIDGE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900161
162 private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
163 private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900164 private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
165 private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
166
167 private static final OpenstackNode COMPUTE_1 = createNode(
168 COMPUTE_1_HOSTNAME,
169 COMPUTE,
170 COMPUTE_1_INTG_DEVICE,
171 COMPUTE_1_IP,
Jian Lie6312162018-03-21 21:41:00 +0900172 INIT,
173 COMPUTE_1_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900174 );
175
176 private static final OpenstackNode COMPUTE_2 = createNode(
177 COMPUTE_2_HOSTNAME,
178 COMPUTE,
179 COMPUTE_2_INTG_DEVICE,
180 COMPUTE_2_IP,
Jian Lie6312162018-03-21 21:41:00 +0900181 DEVICE_CREATED,
182 COMPUTE_2_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900183 );
184
185 private static final OpenstackNode COMPUTE_3 = createNode(
186 COMPUTE_3_HOSTNAME,
187 COMPUTE,
188 COMPUTE_3_INTG_DEVICE,
189 COMPUTE_3_IP,
Jian Lie6312162018-03-21 21:41:00 +0900190 COMPLETE,
191 COMPUTE_3_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900192 );
193
Jian Lie6312162018-03-21 21:41:00 +0900194 private static final OpenstackNode GATEWAY_1 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900195 GATEWAY_1_HOSTNAME,
196 GATEWAY,
197 GATEWAY_1_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900198 GATEWAY_1_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900199 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900200 INIT
201 );
202
Jian Lie6312162018-03-21 21:41:00 +0900203 private static final OpenstackNode GATEWAY_2 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900204 GATEWAY_2_HOSTNAME,
205 GATEWAY,
206 GATEWAY_2_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900207 GATEWAY_2_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900208 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900209 DEVICE_CREATED
210 );
211
Jian Lie6312162018-03-21 21:41:00 +0900212 private static final OpenstackNode GATEWAY_3 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900213 GATEWAY_3_HOSTNAME,
214 GATEWAY,
215 GATEWAY_3_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900216 GATEWAY_3_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900217 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900218 COMPLETE
219 );
220
221 private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
222
223 private TestOpenstackNodeManager testNodeManager;
224 private DefaultOpenstackNodeHandler target;
225
226 @Before
227 public void setUp() throws Exception {
228 DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
229 mockDeviceAdminService.removeDevice(anyObject());
230 replay(mockDeviceAdminService);
231
232 OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
233 expect(mockOvsdbClient.isConnected())
234 .andReturn(true)
235 .anyTimes();
236 replay(mockOvsdbClient);
237
238 OvsdbController mockOvsdbController = createMock(OvsdbController.class);
239 expect(mockOvsdbController.getOvsdbClient(anyObject()))
240 .andReturn(mockOvsdbClient)
241 .anyTimes();
242 replay(mockOvsdbController);
243
244 testNodeManager = new TestOpenstackNodeManager();
245 target = new DefaultOpenstackNodeHandler();
246
247 target.coreService = new TestCoreService();
248 target.leadershipService = new TestLeadershipService();
249 target.clusterService = new TestClusterService();
250 target.deviceService = TEST_DEVICE_SERVICE;
251 target.deviceAdminService = mockDeviceAdminService;
252 target.ovsdbController = mockOvsdbController;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900253 target.osNodeService = testNodeManager;
254 target.osNodeAdminService = testNodeManager;
255 target.componentConfigService = new TestComponentConfigService();
256 TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
257 target.activate();
258 }
259
260 @After
261 public void tearDown() {
262 TEST_DEVICE_SERVICE.clear();
263 target.deactivate();
264 target = null;
265 testNodeManager = null;
266 }
267
268 /**
269 * Checks if the compute node state changes from INIT to DEVICE_CREATED
270 * after processing INIT state.
271 */
272 @Test
273 public void testComputeNodeProcessNodeInitState() {
274 testNodeManager.createNode(COMPUTE_1);
275 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
276
277 assertEquals(ERR_STATE_NOT_MATCH, INIT,
278 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
279 target.processInitState(COMPUTE_1);
280 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
281 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
282 }
283
284 /**
285 * Checks if the gateway node state changes from INIT to DEVICE_CREATED
286 * after processing INIT state.
287 */
288 @Test
289 public void testGatewayNodeProcessNodeInitState() {
290 testNodeManager.createNode(GATEWAY_1);
291 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
292
293 assertEquals(ERR_STATE_NOT_MATCH, INIT,
294 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
295 target.processInitState(GATEWAY_1);
296 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
297 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
298 }
299
300 /**
301 * Checks if the compute node state changes from DEVICE_CREATED to
302 * PORT_CREATED after processing DEVICE_CREATED state.
303 */
304 @Test
305 public void testComputeNodeProcessDeviceCreatedState() {
306 testNodeManager.createNode(COMPUTE_2);
307 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
308 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
309
310 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
311 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
312 target.processDeviceCreatedState(COMPUTE_2);
daniel parkb18424c2018-02-05 15:43:43 +0900313 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900314 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
315 }
316
317 /**
318 * Checks if the gateway node state changes from DEVICE_CREATED to
319 * PORT_CREATED after processing DEVICE_CREATED state.
320 */
321 @Test
322 public void testGatewayNodeProcessDeviceCreatedState() {
323 testNodeManager.createNode(GATEWAY_2);
324 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
325 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
daniel parkb18424c2018-02-05 15:43:43 +0900326 TEST_DEVICE_SERVICE.portList.add(createPort(GATEWAY_2_INTG_DEVICE, GATEWAY_UPLINK_PORT));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900327
328 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
329 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
330 target.processDeviceCreatedState(GATEWAY_2);
daniel parkb18424c2018-02-05 15:43:43 +0900331 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900332 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
333 }
334
335 /**
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900336 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
337 * when integration bridge is disconnected.
338 */
339 @Test
340 public void testBackToIncompleteWhenBrIntDisconnected() {
daniel parkb18424c2018-02-05 15:43:43 +0900341 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900342
343 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900344 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
345 TEST_DEVICE_SERVICE.removeDevice(COMPUTE_3_INTG_DEVICE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900346 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900347 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900348 }
349
350 /**
351 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
352 * when vxlan port is removed from integration bridge.
353 */
354 @Test
355 public void testBackToIncompleteWhenVxlanRemoved() {
daniel parkb18424c2018-02-05 15:43:43 +0900356 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900357
358 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900359 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
360 TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
361 COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900362 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900363 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900364
365 }
366
367 private static Device createOvsdbDevice(IpAddress ovsdbIp) {
368 return new TestDevice(new ProviderId("of", "foo"),
369 DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
370 CONTROLLER,
371 "manufacturer",
372 "hwVersion",
373 "swVersion",
374 "serialNumber",
375 new ChassisId(1));
376 }
377
378 private static Device createOpenFlowDevice(long devIdNum, String type) {
379 return new TestDevice(new ProviderId("of", "foo"),
380 DeviceId.deviceId(String.format("of:%016d", devIdNum)),
381 SWITCH,
382 type,
383 "hwVersion",
384 "swVersion",
385 "serialNumber",
386 new ChassisId(1));
387 }
388
389 private static Port createPort(Device device, String portName) {
390 return new DefaultPort(device,
391 PortNumber.portNumber(1),
392 true,
393 DefaultAnnotations.builder().set(PORT_NAME, portName).build());
394 }
395
Jian Lie6312162018-03-21 21:41:00 +0900396 private static Set<OpenstackPhyInterface> createPhyIntfs() {
397 return Sets.newConcurrentHashSet();
398 }
399
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900400 private static OpenstackNode createNode(String hostname,
401 OpenstackNode.NodeType type,
402 Device intgBridge,
403 IpAddress ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900404 NodeState state,
405 Set<OpenstackPhyInterface> phyIntfs) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900406 return new TestOpenstackNode(
407 hostname,
408 type,
409 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900410 ipAddr,
411 ipAddr,
Jian Li92d42fc2018-05-25 16:23:49 +0900412 null, null, state, phyIntfs, null, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900413 }
414
Jian Lie6312162018-03-21 21:41:00 +0900415 private static OpenstackNode createGatewayNode(String hostname,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900416 OpenstackNode.NodeType type,
417 Device intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900418 IpAddress ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900419 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900420 NodeState state) {
421 return new TestOpenstackNode(
422 hostname,
423 type,
424 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900425 ipAddr,
426 ipAddr,
Jian Li92d42fc2018-05-25 16:23:49 +0900427 null, uplinkPort, state, null, null, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900428 }
429
430 private static final class TestDevice extends DefaultDevice {
431 private TestDevice(ProviderId providerId,
432 DeviceId id,
433 Type type,
434 String manufacturer,
435 String hwVersion,
436 String swVersion,
437 String serialNumber,
438 ChassisId chassisId,
439 Annotations... annotations) {
440 super(providerId,
441 id,
442 type,
443 manufacturer,
444 hwVersion,
445 swVersion,
446 serialNumber,
447 chassisId,
448 annotations);
449 }
450
451 @Override
452 @SuppressWarnings("unchecked")
453 public <B extends Behaviour> B as(Class<B> projectionClass) {
454 if (projectionClass.equals(BridgeConfig.class)) {
455 return (B) new TestBridgeConfig();
456 } else if (projectionClass.equals(InterfaceConfig.class)) {
457 return (B) new TestInterfaceConfig();
458 } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
459 ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
460 expect(treatmentResolver.getExtensionInstruction(anyObject()))
461 .andReturn(new TestExtensionTreatment())
462 .anyTimes();
463 replay(treatmentResolver);
464 return (B) treatmentResolver;
465 } else {
466 return null;
467 }
468 }
469
470 @Override
471 public <B extends Behaviour> boolean is(Class<B> projectionClass) {
472 return true;
473 }
474 }
475
476 private static final class TestOpenstackNode extends DefaultOpenstackNode {
477 private TestOpenstackNode(String hostname,
478 NodeType type,
479 DeviceId intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900480 IpAddress managementIp,
481 IpAddress dataIp,
482 String vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900483 String uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900484 NodeState state,
Jian Li27841662018-04-14 01:59:47 +0900485 Set<OpenstackPhyInterface> phyIntfs,
Jian Li92d42fc2018-05-25 16:23:49 +0900486 OpenstackAuth auth,
487 String endPoint) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900488 super(hostname,
489 type,
490 intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900491 managementIp,
492 dataIp,
493 vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900494 uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900495 state,
Jian Li27841662018-04-14 01:59:47 +0900496 phyIntfs,
Jian Li92d42fc2018-05-25 16:23:49 +0900497 auth,
498 endPoint);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900499 }
500
501 @Override
502 public PortNumber tunnelPortNum() {
503 return PortNumber.portNumber(1);
504 }
505
506 @Override
507 public PortNumber vlanPortNum() {
508 return PortNumber.portNumber(1);
509 }
510
511 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900512 public MacAddress vlanPortMac() {
513 return MacAddress.NONE;
514 }
515 }
516
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900517 private static class TestDeviceService extends DeviceServiceAdapter {
518 Map<DeviceId, Device> devMap = Maps.newHashMap();
519 List<Port> portList = Lists.newArrayList();
520 List<DeviceListener> listeners = Lists.newArrayList();
521
522 @Override
523 public void addListener(DeviceListener listener) {
524 listeners.add(listener);
525 }
526
527 @Override
528 public void removeListener(DeviceListener listener) {
529 listeners.remove(listener);
530 }
531
532 @Override
533 public Device getDevice(DeviceId deviceId) {
534 return devMap.get(deviceId);
535 }
536
537 @Override
538 public List<Port> getPorts(DeviceId deviceId) {
539 return this.portList.stream()
540 .filter(p -> p.element().id().equals(deviceId))
541 .collect(Collectors.toList());
542 }
543
544 @Override
545 public boolean isAvailable(DeviceId deviceId) {
546 return devMap.containsKey(deviceId);
547 }
548
549 void addDevice(Device device) {
550 devMap.put(device.id(), device);
551 DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
552 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
553 }
554
555 void removeDevice(Device device) {
556 devMap.remove(device.id());
557 DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
558 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
559 }
560
561 void addPort(Device device, Port port) {
562 portList.add(port);
563 DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
564 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
565 }
566
567 void removePort(Device device, Port port) {
568 portList.remove(port);
569 DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
570 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
571 }
572
573 void clear() {
574 this.listeners.clear();
575 this.devMap.clear();
576 this.portList.clear();
577 }
578 }
579
580 private static class TestBridgeConfig implements BridgeConfig {
581
582 @Override
583 public DriverData data() {
584 return null;
585 }
586
587 @Override
588 public void setData(DriverData data) {
589
590 }
591
592 @Override
593 public DriverHandler handler() {
594 return null;
595 }
596
597 @Override
598 public void setHandler(DriverHandler handler) {
599
600 }
601
602 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900603 public boolean addBridge(BridgeDescription bridge) {
604 TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
605 DeviceId.deviceId("of:" + bridge.datapathId().get()),
606 SWITCH,
607 bridge.name(),
608 "hwVersion",
609 "swVersion",
610 "serialNumber",
611 new ChassisId(1)));
612 return true;
613 }
614
615 @Override
616 public void deleteBridge(BridgeName bridgeName) {
617
618 }
619
620 @Override
621 public Collection<BridgeDescription> getBridges() {
622 return ImmutableSet.of(ROUT_BRIDGE);
623 }
624
625 @Override
626 public void addPort(BridgeName bridgeName, String portName) {
627
628 }
629
630 @Override
631 public void deletePort(BridgeName bridgeName, String portName) {
632
633 }
634
635 @Override
636 public Collection<PortDescription> getPorts() {
637 return ImmutableSet.of(PATCH_ROUT);
638 }
639
640 @Override
641 public Set<PortNumber> getPortNumbers() {
642 return null;
643 }
644
645 @Override
646 public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
647 return null;
648 }
649 }
650
651 private static class TestInterfaceConfig implements InterfaceConfig {
652
653 @Override
654 public DriverData data() {
655 return null;
656 }
657
658 @Override
659 public void setData(DriverData data) {
660
661 }
662
663 @Override
664 public DriverHandler handler() {
665 return null;
666 }
667
668 @Override
669 public void setHandler(DriverHandler handler) {
670
671 }
672
673 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900674 public boolean addAccessMode(String intf, VlanId vlanId) {
675 return false;
676 }
677
678 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900679 public boolean removeAccessMode(String intf) {
680 return false;
681 }
682
683 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900684 public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
685 return false;
686 }
687
688 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900689 public boolean removeTrunkMode(String intf) {
690 return false;
691 }
692
693 @Override
694 public boolean addRateLimit(String intf, short limit) {
695 return false;
696 }
697
698 @Override
699 public boolean removeRateLimit(String intf) {
700 return false;
701 }
702
703 @Override
704 public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
705 TEST_DEVICE_SERVICE.devMap.values().stream()
706 .filter(device -> device.type() == SWITCH &&
707 device.manufacturer().equals(INTEGRATION_BRIDGE))
708 .forEach(device -> {
709 TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
710 });
711 return true;
712 }
713
714 @Override
715 public boolean removeTunnelMode(String intf) {
716 return false;
717 }
718
719 @Override
720 public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
721 if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
722 TEST_DEVICE_SERVICE.devMap.values().stream()
723 .filter(device -> device.type() == SWITCH &&
724 device.manufacturer().equals(INTEGRATION_BRIDGE))
725 .forEach(device -> {
726 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
727 });
728 } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
729 TEST_DEVICE_SERVICE.devMap.values().stream()
730 .filter(device -> device.type() == SWITCH &&
731 device.manufacturer().equals(ROUTER_BRIDGE))
732 .forEach(device -> {
733 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
734 });
735 }
736 return true;
737 }
738
739 @Override
740 public boolean removePatchMode(String ifaceName) {
741 return false;
742 }
743
744 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900745 public List<DeviceInterfaceDescription> getInterfaces() {
746 return null;
747 }
748 }
749
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900750 private static class TestExtensionTreatment implements ExtensionTreatment {
751 Ip4Address tunnelDst;
752
753 @Override
754 public ExtensionTreatmentType type() {
755 return null;
756 }
757
758 @Override
759 public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
760 tunnelDst = (Ip4Address) value;
761 }
762
763 @Override
764 public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
765 return null;
766 }
767
768 @Override
769 public List<String> getProperties() {
770 return null;
771 }
772
773 @Override
774 public byte[] serialize() {
775 return new byte[0];
776 }
777
778 @Override
779 public void deserialize(byte[] data) {
780
781 }
782
783 @Override
784 public boolean equals(Object obj) {
785 TestExtensionTreatment that = (TestExtensionTreatment) obj;
786 return Objects.equals(tunnelDst, that.tunnelDst);
787 }
788
789 @Override
790 public int hashCode() {
791 return Objects.hash(tunnelDst);
792 }
793 }
794
795 private static class TestCoreService extends CoreServiceAdapter {
796
797 @Override
798 public ApplicationId getAppId(String name) {
799 return TEST_APP_ID;
800 }
801 }
802
803 private static class TestLeadershipService extends LeadershipServiceAdapter {
804
805 @Override
806 public NodeId getLeader(String path) {
807 return LOCAL_NODE_ID;
808 }
809 }
810
811 private static class TestClusterService extends ClusterServiceAdapter {
812
813 @Override
814 public ControllerNode getLocalNode() {
815 return LOCAL_CTRL;
816 }
817 }
818
819 private class TestComponentConfigService extends ComponentConfigAdapter {
820
821 }
822}