blob: b07044f23231f0f48a68528979b7675d8a782dbf [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
Ray Milkey0d47a552017-08-22 10:16:31 -070085import static org.easymock.EasyMock.anyObject;
86import static org.easymock.EasyMock.createMock;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090087import static org.easymock.EasyMock.expect;
Ray Milkey0d47a552017-08-22 10:16:31 -070088import static org.easymock.EasyMock.replay;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090089import static org.junit.Assert.assertEquals;
90import static org.onosproject.net.AnnotationKeys.PORT_NAME;
91import static org.onosproject.net.Device.Type.CONTROLLER;
92import static org.onosproject.net.Device.Type.SWITCH;
Ray Milkey0d47a552017-08-22 10:16:31 -070093import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
94import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
95import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
96import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
97import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
98import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
99import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
100import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
101import static org.onosproject.openstacknode.api.Constants.ROUTER_BRIDGE;
102import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
103import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
104import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
105import static org.onosproject.openstacknode.api.NodeState.INIT;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900106import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
107import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
108
109/**
110 * Unit test for DefaultOpenstackNodeHandler.
111 */
112public class DefaultOpenstackNodeHandlerTest {
113
114 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
115 private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
116 private static final NodeId LOCAL_NODE_ID = new NodeId("local");
117 private static final ControllerNode LOCAL_CTRL =
118 new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));
119
120 private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
121 .name(ROUTER_BRIDGE)
122 .failMode(BridgeDescription.FailMode.SECURE)
123 .disableInBand()
124 .build();
125
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800126 private static final PortDescription PATCH_ROUT = DefaultPortDescription.builder()
127 .withPortNumber(PortNumber.portNumber(1))
128 .isEnabled(true)
129 .annotations(DefaultAnnotations.builder()
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900130 .set(PORT_NAME, PATCH_ROUT_BRIDGE)
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800131 .build())
132 .build();
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900133
134 private static final String COMPUTE_1_HOSTNAME = "compute_1";
135 private static final String COMPUTE_2_HOSTNAME = "compute_2";
136 private static final String COMPUTE_3_HOSTNAME = "compute_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900137 private static final String GATEWAY_1_HOSTNAME = "gateway_1";
138 private static final String GATEWAY_2_HOSTNAME = "gateway_2";
139 private static final String GATEWAY_3_HOSTNAME = "gateway_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900140
141 private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
142 private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
143 private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900144 private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
145 private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
146 private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
daniel parkb18424c2018-02-05 15:43:43 +0900147
148 private static final String GATEWAY_UPLINK_PORT = "eth0";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900149
Jian Lie6312162018-03-21 21:41:00 +0900150 private static final Set<OpenstackPhyInterface> COMPUTE_1_PHY_INTFS = createPhyIntfs();
151 private static final Set<OpenstackPhyInterface> COMPUTE_2_PHY_INTFS = createPhyIntfs();
152 private static final Set<OpenstackPhyInterface> COMPUTE_3_PHY_INTFS = createPhyIntfs();
153
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900154 private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
155 private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
156 private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
daniel parkb18424c2018-02-05 15:43:43 +0900157 private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
158 private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
159 private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(6, INTEGRATION_BRIDGE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900160
161 private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
162 private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900163 private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
164 private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
165
166 private static final OpenstackNode COMPUTE_1 = createNode(
167 COMPUTE_1_HOSTNAME,
168 COMPUTE,
169 COMPUTE_1_INTG_DEVICE,
170 COMPUTE_1_IP,
Jian Lie6312162018-03-21 21:41:00 +0900171 INIT,
172 COMPUTE_1_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900173 );
174
175 private static final OpenstackNode COMPUTE_2 = createNode(
176 COMPUTE_2_HOSTNAME,
177 COMPUTE,
178 COMPUTE_2_INTG_DEVICE,
179 COMPUTE_2_IP,
Jian Lie6312162018-03-21 21:41:00 +0900180 DEVICE_CREATED,
181 COMPUTE_2_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900182 );
183
184 private static final OpenstackNode COMPUTE_3 = createNode(
185 COMPUTE_3_HOSTNAME,
186 COMPUTE,
187 COMPUTE_3_INTG_DEVICE,
188 COMPUTE_3_IP,
Jian Lie6312162018-03-21 21:41:00 +0900189 COMPLETE,
190 COMPUTE_3_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900191 );
192
Jian Lie6312162018-03-21 21:41:00 +0900193 private static final OpenstackNode GATEWAY_1 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900194 GATEWAY_1_HOSTNAME,
195 GATEWAY,
196 GATEWAY_1_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900197 GATEWAY_1_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900198 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900199 INIT
200 );
201
Jian Lie6312162018-03-21 21:41:00 +0900202 private static final OpenstackNode GATEWAY_2 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900203 GATEWAY_2_HOSTNAME,
204 GATEWAY,
205 GATEWAY_2_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900206 GATEWAY_2_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900207 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900208 DEVICE_CREATED
209 );
210
Jian Lie6312162018-03-21 21:41:00 +0900211 private static final OpenstackNode GATEWAY_3 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900212 GATEWAY_3_HOSTNAME,
213 GATEWAY,
214 GATEWAY_3_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900215 GATEWAY_3_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900216 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900217 COMPLETE
218 );
219
220 private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
221
222 private TestOpenstackNodeManager testNodeManager;
223 private DefaultOpenstackNodeHandler target;
224
225 @Before
226 public void setUp() throws Exception {
227 DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
228 mockDeviceAdminService.removeDevice(anyObject());
229 replay(mockDeviceAdminService);
230
231 OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
232 expect(mockOvsdbClient.isConnected())
233 .andReturn(true)
234 .anyTimes();
235 replay(mockOvsdbClient);
236
237 OvsdbController mockOvsdbController = createMock(OvsdbController.class);
238 expect(mockOvsdbController.getOvsdbClient(anyObject()))
239 .andReturn(mockOvsdbClient)
240 .anyTimes();
241 replay(mockOvsdbController);
242
243 testNodeManager = new TestOpenstackNodeManager();
244 target = new DefaultOpenstackNodeHandler();
245
246 target.coreService = new TestCoreService();
247 target.leadershipService = new TestLeadershipService();
248 target.clusterService = new TestClusterService();
249 target.deviceService = TEST_DEVICE_SERVICE;
250 target.deviceAdminService = mockDeviceAdminService;
251 target.ovsdbController = mockOvsdbController;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900252 target.osNodeService = testNodeManager;
253 target.osNodeAdminService = testNodeManager;
254 target.componentConfigService = new TestComponentConfigService();
255 TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
256 target.activate();
257 }
258
259 @After
260 public void tearDown() {
261 TEST_DEVICE_SERVICE.clear();
262 target.deactivate();
263 target = null;
264 testNodeManager = null;
265 }
266
267 /**
268 * Checks if the compute node state changes from INIT to DEVICE_CREATED
269 * after processing INIT state.
270 */
271 @Test
272 public void testComputeNodeProcessNodeInitState() {
273 testNodeManager.createNode(COMPUTE_1);
274 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
275
276 assertEquals(ERR_STATE_NOT_MATCH, INIT,
277 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
278 target.processInitState(COMPUTE_1);
279 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
280 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
281 }
282
283 /**
284 * Checks if the gateway node state changes from INIT to DEVICE_CREATED
285 * after processing INIT state.
286 */
287 @Test
288 public void testGatewayNodeProcessNodeInitState() {
289 testNodeManager.createNode(GATEWAY_1);
290 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
291
292 assertEquals(ERR_STATE_NOT_MATCH, INIT,
293 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
294 target.processInitState(GATEWAY_1);
295 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
296 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
297 }
298
299 /**
300 * Checks if the compute node state changes from DEVICE_CREATED to
301 * PORT_CREATED after processing DEVICE_CREATED state.
302 */
303 @Test
304 public void testComputeNodeProcessDeviceCreatedState() {
305 testNodeManager.createNode(COMPUTE_2);
306 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
307 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
308
309 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
310 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
311 target.processDeviceCreatedState(COMPUTE_2);
daniel parkb18424c2018-02-05 15:43:43 +0900312 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900313 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
314 }
315
316 /**
317 * Checks if the gateway node state changes from DEVICE_CREATED to
318 * PORT_CREATED after processing DEVICE_CREATED state.
319 */
320 @Test
321 public void testGatewayNodeProcessDeviceCreatedState() {
322 testNodeManager.createNode(GATEWAY_2);
323 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
324 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
daniel parkb18424c2018-02-05 15:43:43 +0900325 TEST_DEVICE_SERVICE.portList.add(createPort(GATEWAY_2_INTG_DEVICE, GATEWAY_UPLINK_PORT));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900326
327 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
328 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
329 target.processDeviceCreatedState(GATEWAY_2);
daniel parkb18424c2018-02-05 15:43:43 +0900330 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900331 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
332 }
333
334 /**
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900335 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
336 * when integration bridge is disconnected.
337 */
338 @Test
339 public void testBackToIncompleteWhenBrIntDisconnected() {
daniel parkb18424c2018-02-05 15:43:43 +0900340 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900341
342 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900343 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
344 TEST_DEVICE_SERVICE.removeDevice(COMPUTE_3_INTG_DEVICE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900345 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900346 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900347 }
348
349 /**
350 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
351 * when vxlan port is removed from integration bridge.
352 */
353 @Test
354 public void testBackToIncompleteWhenVxlanRemoved() {
daniel parkb18424c2018-02-05 15:43:43 +0900355 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900356
357 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900358 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
359 TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
360 COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900361 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900362 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900363
364 }
365
366 private static Device createOvsdbDevice(IpAddress ovsdbIp) {
367 return new TestDevice(new ProviderId("of", "foo"),
368 DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
369 CONTROLLER,
370 "manufacturer",
371 "hwVersion",
372 "swVersion",
373 "serialNumber",
374 new ChassisId(1));
375 }
376
377 private static Device createOpenFlowDevice(long devIdNum, String type) {
378 return new TestDevice(new ProviderId("of", "foo"),
379 DeviceId.deviceId(String.format("of:%016d", devIdNum)),
380 SWITCH,
381 type,
382 "hwVersion",
383 "swVersion",
384 "serialNumber",
385 new ChassisId(1));
386 }
387
388 private static Port createPort(Device device, String portName) {
389 return new DefaultPort(device,
390 PortNumber.portNumber(1),
391 true,
392 DefaultAnnotations.builder().set(PORT_NAME, portName).build());
393 }
394
Jian Lie6312162018-03-21 21:41:00 +0900395 private static Set<OpenstackPhyInterface> createPhyIntfs() {
396 return Sets.newConcurrentHashSet();
397 }
398
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900399 private static OpenstackNode createNode(String hostname,
400 OpenstackNode.NodeType type,
401 Device intgBridge,
402 IpAddress ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900403 NodeState state,
404 Set<OpenstackPhyInterface> phyIntfs) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900405 return new TestOpenstackNode(
406 hostname,
407 type,
408 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900409 ipAddr,
410 ipAddr,
Jian Li92d42fc2018-05-25 16:23:49 +0900411 null, null, state, phyIntfs, null, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900412 }
413
Jian Lie6312162018-03-21 21:41:00 +0900414 private static OpenstackNode createGatewayNode(String hostname,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900415 OpenstackNode.NodeType type,
416 Device intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900417 IpAddress ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900418 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900419 NodeState state) {
420 return new TestOpenstackNode(
421 hostname,
422 type,
423 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900424 ipAddr,
425 ipAddr,
Jian Li92d42fc2018-05-25 16:23:49 +0900426 null, uplinkPort, state, null, null, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900427 }
428
429 private static final class TestDevice extends DefaultDevice {
430 private TestDevice(ProviderId providerId,
431 DeviceId id,
432 Type type,
433 String manufacturer,
434 String hwVersion,
435 String swVersion,
436 String serialNumber,
437 ChassisId chassisId,
438 Annotations... annotations) {
439 super(providerId,
440 id,
441 type,
442 manufacturer,
443 hwVersion,
444 swVersion,
445 serialNumber,
446 chassisId,
447 annotations);
448 }
449
450 @Override
451 @SuppressWarnings("unchecked")
452 public <B extends Behaviour> B as(Class<B> projectionClass) {
453 if (projectionClass.equals(BridgeConfig.class)) {
454 return (B) new TestBridgeConfig();
455 } else if (projectionClass.equals(InterfaceConfig.class)) {
456 return (B) new TestInterfaceConfig();
457 } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
458 ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
459 expect(treatmentResolver.getExtensionInstruction(anyObject()))
460 .andReturn(new TestExtensionTreatment())
461 .anyTimes();
462 replay(treatmentResolver);
463 return (B) treatmentResolver;
464 } else {
465 return null;
466 }
467 }
468
469 @Override
470 public <B extends Behaviour> boolean is(Class<B> projectionClass) {
471 return true;
472 }
473 }
474
475 private static final class TestOpenstackNode extends DefaultOpenstackNode {
476 private TestOpenstackNode(String hostname,
477 NodeType type,
478 DeviceId intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900479 IpAddress managementIp,
480 IpAddress dataIp,
481 String vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900482 String uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900483 NodeState state,
Jian Li27841662018-04-14 01:59:47 +0900484 Set<OpenstackPhyInterface> phyIntfs,
Jian Li92d42fc2018-05-25 16:23:49 +0900485 OpenstackAuth auth,
486 String endPoint) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900487 super(hostname,
488 type,
489 intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900490 managementIp,
491 dataIp,
492 vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900493 uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900494 state,
Jian Li27841662018-04-14 01:59:47 +0900495 phyIntfs,
Jian Li92d42fc2018-05-25 16:23:49 +0900496 auth,
497 endPoint);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900498 }
499
500 @Override
501 public PortNumber tunnelPortNum() {
502 return PortNumber.portNumber(1);
503 }
504
505 @Override
506 public PortNumber vlanPortNum() {
507 return PortNumber.portNumber(1);
508 }
509
510 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900511 public MacAddress vlanPortMac() {
512 return MacAddress.NONE;
513 }
514 }
515
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900516 private static class TestDeviceService extends DeviceServiceAdapter {
517 Map<DeviceId, Device> devMap = Maps.newHashMap();
518 List<Port> portList = Lists.newArrayList();
519 List<DeviceListener> listeners = Lists.newArrayList();
520
521 @Override
522 public void addListener(DeviceListener listener) {
523 listeners.add(listener);
524 }
525
526 @Override
527 public void removeListener(DeviceListener listener) {
528 listeners.remove(listener);
529 }
530
531 @Override
532 public Device getDevice(DeviceId deviceId) {
533 return devMap.get(deviceId);
534 }
535
536 @Override
537 public List<Port> getPorts(DeviceId deviceId) {
538 return this.portList.stream()
539 .filter(p -> p.element().id().equals(deviceId))
540 .collect(Collectors.toList());
541 }
542
543 @Override
544 public boolean isAvailable(DeviceId deviceId) {
545 return devMap.containsKey(deviceId);
546 }
547
548 void addDevice(Device device) {
549 devMap.put(device.id(), device);
550 DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
551 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
552 }
553
554 void removeDevice(Device device) {
555 devMap.remove(device.id());
556 DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
557 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
558 }
559
560 void addPort(Device device, Port port) {
561 portList.add(port);
562 DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
563 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
564 }
565
566 void removePort(Device device, Port port) {
567 portList.remove(port);
568 DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
569 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
570 }
571
572 void clear() {
573 this.listeners.clear();
574 this.devMap.clear();
575 this.portList.clear();
576 }
577 }
578
579 private static class TestBridgeConfig implements BridgeConfig {
580
581 @Override
582 public DriverData data() {
583 return null;
584 }
585
586 @Override
587 public void setData(DriverData data) {
588
589 }
590
591 @Override
592 public DriverHandler handler() {
593 return null;
594 }
595
596 @Override
597 public void setHandler(DriverHandler handler) {
598
599 }
600
601 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900602 public boolean addBridge(BridgeDescription bridge) {
603 TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
604 DeviceId.deviceId("of:" + bridge.datapathId().get()),
605 SWITCH,
606 bridge.name(),
607 "hwVersion",
608 "swVersion",
609 "serialNumber",
610 new ChassisId(1)));
611 return true;
612 }
613
614 @Override
615 public void deleteBridge(BridgeName bridgeName) {
616
617 }
618
619 @Override
620 public Collection<BridgeDescription> getBridges() {
621 return ImmutableSet.of(ROUT_BRIDGE);
622 }
623
624 @Override
625 public void addPort(BridgeName bridgeName, String portName) {
626
627 }
628
629 @Override
630 public void deletePort(BridgeName bridgeName, String portName) {
631
632 }
633
634 @Override
635 public Collection<PortDescription> getPorts() {
636 return ImmutableSet.of(PATCH_ROUT);
637 }
638
639 @Override
640 public Set<PortNumber> getPortNumbers() {
641 return null;
642 }
643
644 @Override
645 public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
646 return null;
647 }
648 }
649
650 private static class TestInterfaceConfig implements InterfaceConfig {
651
652 @Override
653 public DriverData data() {
654 return null;
655 }
656
657 @Override
658 public void setData(DriverData data) {
659
660 }
661
662 @Override
663 public DriverHandler handler() {
664 return null;
665 }
666
667 @Override
668 public void setHandler(DriverHandler handler) {
669
670 }
671
672 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900673 public boolean addAccessMode(String intf, VlanId vlanId) {
674 return false;
675 }
676
677 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900678 public boolean removeAccessMode(String intf) {
679 return false;
680 }
681
682 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900683 public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
684 return false;
685 }
686
687 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900688 public boolean removeTrunkMode(String intf) {
689 return false;
690 }
691
692 @Override
693 public boolean addRateLimit(String intf, short limit) {
694 return false;
695 }
696
697 @Override
698 public boolean removeRateLimit(String intf) {
699 return false;
700 }
701
702 @Override
703 public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
704 TEST_DEVICE_SERVICE.devMap.values().stream()
705 .filter(device -> device.type() == SWITCH &&
706 device.manufacturer().equals(INTEGRATION_BRIDGE))
707 .forEach(device -> {
708 TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
709 });
710 return true;
711 }
712
713 @Override
714 public boolean removeTunnelMode(String intf) {
715 return false;
716 }
717
718 @Override
719 public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
720 if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
721 TEST_DEVICE_SERVICE.devMap.values().stream()
722 .filter(device -> device.type() == SWITCH &&
723 device.manufacturer().equals(INTEGRATION_BRIDGE))
724 .forEach(device -> {
725 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
726 });
727 } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
728 TEST_DEVICE_SERVICE.devMap.values().stream()
729 .filter(device -> device.type() == SWITCH &&
730 device.manufacturer().equals(ROUTER_BRIDGE))
731 .forEach(device -> {
732 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
733 });
734 }
735 return true;
736 }
737
738 @Override
739 public boolean removePatchMode(String ifaceName) {
740 return false;
741 }
742
743 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900744 public List<DeviceInterfaceDescription> getInterfaces() {
745 return null;
746 }
747 }
748
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900749 private static class TestExtensionTreatment implements ExtensionTreatment {
750 Ip4Address tunnelDst;
751
752 @Override
753 public ExtensionTreatmentType type() {
754 return null;
755 }
756
757 @Override
758 public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
759 tunnelDst = (Ip4Address) value;
760 }
761
762 @Override
763 public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
764 return null;
765 }
766
767 @Override
768 public List<String> getProperties() {
769 return null;
770 }
771
772 @Override
773 public byte[] serialize() {
774 return new byte[0];
775 }
776
777 @Override
778 public void deserialize(byte[] data) {
779
780 }
781
782 @Override
783 public boolean equals(Object obj) {
784 TestExtensionTreatment that = (TestExtensionTreatment) obj;
785 return Objects.equals(tunnelDst, that.tunnelDst);
786 }
787
788 @Override
789 public int hashCode() {
790 return Objects.hash(tunnelDst);
791 }
792 }
793
794 private static class TestCoreService extends CoreServiceAdapter {
795
796 @Override
797 public ApplicationId getAppId(String name) {
798 return TEST_APP_ID;
799 }
800 }
801
802 private static class TestLeadershipService extends LeadershipServiceAdapter {
803
804 @Override
805 public NodeId getLeader(String path) {
806 return LOCAL_NODE_ID;
807 }
808 }
809
810 private static class TestClusterService extends ClusterServiceAdapter {
811
812 @Override
813 public ControllerNode getLocalNode() {
814 return LOCAL_CTRL;
815 }
816 }
817
818 private class TestComponentConfigService extends ComponentConfigAdapter {
819
820 }
821}