blob: fccfd1ba291382749858a60506fb8bf8a292fe1d [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;
72import org.onosproject.openstacknode.api.OpenstackNode;
Jian Lie6312162018-03-21 21:41:00 +090073import org.onosproject.openstacknode.api.OpenstackPhyInterface;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090074import org.onosproject.ovsdb.controller.OvsdbClientService;
75import org.onosproject.ovsdb.controller.OvsdbController;
76
daniel park04c40cc2018-02-19 17:48:30 +090077import java.util.Collection;
78import java.util.List;
79import java.util.Map;
80import java.util.Objects;
81import java.util.Set;
82import java.util.stream.Collectors;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090083
Ray Milkey0d47a552017-08-22 10:16:31 -070084import static org.easymock.EasyMock.anyObject;
85import static org.easymock.EasyMock.createMock;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090086import static org.easymock.EasyMock.expect;
Ray Milkey0d47a552017-08-22 10:16:31 -070087import static org.easymock.EasyMock.replay;
Hyunsun Moon090d77d2017-07-05 17:48:37 +090088import static org.junit.Assert.assertEquals;
89import static org.onosproject.net.AnnotationKeys.PORT_NAME;
90import static org.onosproject.net.Device.Type.CONTROLLER;
91import static org.onosproject.net.Device.Type.SWITCH;
Ray Milkey0d47a552017-08-22 10:16:31 -070092import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
93import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
94import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
95import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
96import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
97import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
98import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
99import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
100import static org.onosproject.openstacknode.api.Constants.ROUTER_BRIDGE;
101import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
102import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
103import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
104import static org.onosproject.openstacknode.api.NodeState.INIT;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900105import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
106import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
107
108/**
109 * Unit test for DefaultOpenstackNodeHandler.
110 */
111public class DefaultOpenstackNodeHandlerTest {
112
113 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
114 private static final String ERR_STATE_NOT_MATCH = "Node state did not match";
115 private static final NodeId LOCAL_NODE_ID = new NodeId("local");
116 private static final ControllerNode LOCAL_CTRL =
117 new DefaultControllerNode(LOCAL_NODE_ID, IpAddress.valueOf("127.0.0.1"));
118
119 private static final BridgeDescription ROUT_BRIDGE = DefaultBridgeDescription.builder()
120 .name(ROUTER_BRIDGE)
121 .failMode(BridgeDescription.FailMode.SECURE)
122 .disableInBand()
123 .build();
124
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800125 private static final PortDescription PATCH_ROUT = DefaultPortDescription.builder()
126 .withPortNumber(PortNumber.portNumber(1))
127 .isEnabled(true)
128 .annotations(DefaultAnnotations.builder()
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900129 .set(PORT_NAME, PATCH_ROUT_BRIDGE)
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800130 .build())
131 .build();
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900132
133 private static final String COMPUTE_1_HOSTNAME = "compute_1";
134 private static final String COMPUTE_2_HOSTNAME = "compute_2";
135 private static final String COMPUTE_3_HOSTNAME = "compute_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900136 private static final String GATEWAY_1_HOSTNAME = "gateway_1";
137 private static final String GATEWAY_2_HOSTNAME = "gateway_2";
138 private static final String GATEWAY_3_HOSTNAME = "gateway_3";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900139
140 private static final IpAddress COMPUTE_1_IP = IpAddress.valueOf("10.100.0.1");
141 private static final IpAddress COMPUTE_2_IP = IpAddress.valueOf("10.100.0.2");
142 private static final IpAddress COMPUTE_3_IP = IpAddress.valueOf("10.100.0.3");
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900143 private static final IpAddress GATEWAY_1_IP = IpAddress.valueOf("10.100.0.5");
144 private static final IpAddress GATEWAY_2_IP = IpAddress.valueOf("10.100.0.6");
145 private static final IpAddress GATEWAY_3_IP = IpAddress.valueOf("10.100.0.7");
daniel parkb18424c2018-02-05 15:43:43 +0900146
147 private static final String GATEWAY_UPLINK_PORT = "eth0";
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900148
Jian Lie6312162018-03-21 21:41:00 +0900149 private static final Set<OpenstackPhyInterface> COMPUTE_1_PHY_INTFS = createPhyIntfs();
150 private static final Set<OpenstackPhyInterface> COMPUTE_2_PHY_INTFS = createPhyIntfs();
151 private static final Set<OpenstackPhyInterface> COMPUTE_3_PHY_INTFS = createPhyIntfs();
152
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900153 private static final Device COMPUTE_1_INTG_DEVICE = createOpenFlowDevice(1, INTEGRATION_BRIDGE);
154 private static final Device COMPUTE_2_INTG_DEVICE = createOpenFlowDevice(2, INTEGRATION_BRIDGE);
155 private static final Device COMPUTE_3_INTG_DEVICE = createOpenFlowDevice(3, INTEGRATION_BRIDGE);
daniel parkb18424c2018-02-05 15:43:43 +0900156 private static final Device GATEWAY_1_INTG_DEVICE = createOpenFlowDevice(4, INTEGRATION_BRIDGE);
157 private static final Device GATEWAY_2_INTG_DEVICE = createOpenFlowDevice(5, INTEGRATION_BRIDGE);
158 private static final Device GATEWAY_3_INTG_DEVICE = createOpenFlowDevice(6, INTEGRATION_BRIDGE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900159
160 private static final Device COMPUTE_1_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_1_IP);
161 private static final Device COMPUTE_2_OVSDB_DEVICE = createOvsdbDevice(COMPUTE_2_IP);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900162 private static final Device GATEWAY_1_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_1_IP);
163 private static final Device GATEWAY_2_OVSDB_DEVICE = createOvsdbDevice(GATEWAY_2_IP);
164
165 private static final OpenstackNode COMPUTE_1 = createNode(
166 COMPUTE_1_HOSTNAME,
167 COMPUTE,
168 COMPUTE_1_INTG_DEVICE,
169 COMPUTE_1_IP,
Jian Lie6312162018-03-21 21:41:00 +0900170 INIT,
171 COMPUTE_1_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900172 );
173
174 private static final OpenstackNode COMPUTE_2 = createNode(
175 COMPUTE_2_HOSTNAME,
176 COMPUTE,
177 COMPUTE_2_INTG_DEVICE,
178 COMPUTE_2_IP,
Jian Lie6312162018-03-21 21:41:00 +0900179 DEVICE_CREATED,
180 COMPUTE_2_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900181 );
182
183 private static final OpenstackNode COMPUTE_3 = createNode(
184 COMPUTE_3_HOSTNAME,
185 COMPUTE,
186 COMPUTE_3_INTG_DEVICE,
187 COMPUTE_3_IP,
Jian Lie6312162018-03-21 21:41:00 +0900188 COMPLETE,
189 COMPUTE_3_PHY_INTFS
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900190 );
191
Jian Lie6312162018-03-21 21:41:00 +0900192 private static final OpenstackNode GATEWAY_1 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900193 GATEWAY_1_HOSTNAME,
194 GATEWAY,
195 GATEWAY_1_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900196 GATEWAY_1_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900197 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900198 INIT
199 );
200
Jian Lie6312162018-03-21 21:41:00 +0900201 private static final OpenstackNode GATEWAY_2 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900202 GATEWAY_2_HOSTNAME,
203 GATEWAY,
204 GATEWAY_2_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900205 GATEWAY_2_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900206 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900207 DEVICE_CREATED
208 );
209
Jian Lie6312162018-03-21 21:41:00 +0900210 private static final OpenstackNode GATEWAY_3 = createGatewayNode(
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900211 GATEWAY_3_HOSTNAME,
212 GATEWAY,
213 GATEWAY_3_INTG_DEVICE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900214 GATEWAY_3_IP,
daniel parkb18424c2018-02-05 15:43:43 +0900215 GATEWAY_UPLINK_PORT,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900216 COMPLETE
217 );
218
219 private static final TestDeviceService TEST_DEVICE_SERVICE = new TestDeviceService();
220
221 private TestOpenstackNodeManager testNodeManager;
222 private DefaultOpenstackNodeHandler target;
223
224 @Before
225 public void setUp() throws Exception {
226 DeviceAdminService mockDeviceAdminService = createMock(DeviceAdminService.class);
227 mockDeviceAdminService.removeDevice(anyObject());
228 replay(mockDeviceAdminService);
229
230 OvsdbClientService mockOvsdbClient = createMock(OvsdbClientService.class);
231 expect(mockOvsdbClient.isConnected())
232 .andReturn(true)
233 .anyTimes();
234 replay(mockOvsdbClient);
235
236 OvsdbController mockOvsdbController = createMock(OvsdbController.class);
237 expect(mockOvsdbController.getOvsdbClient(anyObject()))
238 .andReturn(mockOvsdbClient)
239 .anyTimes();
240 replay(mockOvsdbController);
241
242 testNodeManager = new TestOpenstackNodeManager();
243 target = new DefaultOpenstackNodeHandler();
244
245 target.coreService = new TestCoreService();
246 target.leadershipService = new TestLeadershipService();
247 target.clusterService = new TestClusterService();
248 target.deviceService = TEST_DEVICE_SERVICE;
249 target.deviceAdminService = mockDeviceAdminService;
250 target.ovsdbController = mockOvsdbController;
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900251 target.osNodeService = testNodeManager;
252 target.osNodeAdminService = testNodeManager;
253 target.componentConfigService = new TestComponentConfigService();
254 TestUtils.setField(target, "eventExecutor", MoreExecutors.newDirectExecutorService());
255 target.activate();
256 }
257
258 @After
259 public void tearDown() {
260 TEST_DEVICE_SERVICE.clear();
261 target.deactivate();
262 target = null;
263 testNodeManager = null;
264 }
265
266 /**
267 * Checks if the compute node state changes from INIT to DEVICE_CREATED
268 * after processing INIT state.
269 */
270 @Test
271 public void testComputeNodeProcessNodeInitState() {
272 testNodeManager.createNode(COMPUTE_1);
273 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_1_OVSDB_DEVICE.id(), COMPUTE_1_OVSDB_DEVICE);
274
275 assertEquals(ERR_STATE_NOT_MATCH, INIT,
276 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
277 target.processInitState(COMPUTE_1);
278 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
279 testNodeManager.node(COMPUTE_1_HOSTNAME).state());
280 }
281
282 /**
283 * Checks if the gateway node state changes from INIT to DEVICE_CREATED
284 * after processing INIT state.
285 */
286 @Test
287 public void testGatewayNodeProcessNodeInitState() {
288 testNodeManager.createNode(GATEWAY_1);
289 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_1_OVSDB_DEVICE.id(), GATEWAY_1_OVSDB_DEVICE);
290
291 assertEquals(ERR_STATE_NOT_MATCH, INIT,
292 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
293 target.processInitState(GATEWAY_1);
294 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
295 testNodeManager.node(GATEWAY_1_HOSTNAME).state());
296 }
297
298 /**
299 * Checks if the compute node state changes from DEVICE_CREATED to
300 * PORT_CREATED after processing DEVICE_CREATED state.
301 */
302 @Test
303 public void testComputeNodeProcessDeviceCreatedState() {
304 testNodeManager.createNode(COMPUTE_2);
305 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_OVSDB_DEVICE.id(), COMPUTE_2_OVSDB_DEVICE);
306 TEST_DEVICE_SERVICE.devMap.put(COMPUTE_2_INTG_DEVICE.id(), COMPUTE_2_INTG_DEVICE);
307
308 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
309 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
310 target.processDeviceCreatedState(COMPUTE_2);
daniel parkb18424c2018-02-05 15:43:43 +0900311 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900312 testNodeManager.node(COMPUTE_2_HOSTNAME).state());
313 }
314
315 /**
316 * Checks if the gateway node state changes from DEVICE_CREATED to
317 * PORT_CREATED after processing DEVICE_CREATED state.
318 */
319 @Test
320 public void testGatewayNodeProcessDeviceCreatedState() {
321 testNodeManager.createNode(GATEWAY_2);
322 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_OVSDB_DEVICE.id(), GATEWAY_2_OVSDB_DEVICE);
323 TEST_DEVICE_SERVICE.devMap.put(GATEWAY_2_INTG_DEVICE.id(), GATEWAY_2_INTG_DEVICE);
daniel parkb18424c2018-02-05 15:43:43 +0900324 TEST_DEVICE_SERVICE.portList.add(createPort(GATEWAY_2_INTG_DEVICE, GATEWAY_UPLINK_PORT));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900325
326 assertEquals(ERR_STATE_NOT_MATCH, DEVICE_CREATED,
327 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
328 target.processDeviceCreatedState(GATEWAY_2);
daniel parkb18424c2018-02-05 15:43:43 +0900329 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900330 testNodeManager.node(GATEWAY_2_HOSTNAME).state());
331 }
332
333 /**
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900334 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
335 * when integration bridge is disconnected.
336 */
337 @Test
338 public void testBackToIncompleteWhenBrIntDisconnected() {
daniel parkb18424c2018-02-05 15:43:43 +0900339 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900340
341 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900342 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
343 TEST_DEVICE_SERVICE.removeDevice(COMPUTE_3_INTG_DEVICE);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900344 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900345 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900346 }
347
348 /**
349 * Checks if the compute node state changes from COMPLETE to INCOMPLETE
350 * when vxlan port is removed from integration bridge.
351 */
352 @Test
353 public void testBackToIncompleteWhenVxlanRemoved() {
daniel parkb18424c2018-02-05 15:43:43 +0900354 testNodeManager.createNode(COMPUTE_3);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900355
356 assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900357 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
358 TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
359 COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900360 assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
daniel parkb18424c2018-02-05 15:43:43 +0900361 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900362
363 }
364
365 private static Device createOvsdbDevice(IpAddress ovsdbIp) {
366 return new TestDevice(new ProviderId("of", "foo"),
367 DeviceId.deviceId("ovsdb:" + ovsdbIp.toString()),
368 CONTROLLER,
369 "manufacturer",
370 "hwVersion",
371 "swVersion",
372 "serialNumber",
373 new ChassisId(1));
374 }
375
376 private static Device createOpenFlowDevice(long devIdNum, String type) {
377 return new TestDevice(new ProviderId("of", "foo"),
378 DeviceId.deviceId(String.format("of:%016d", devIdNum)),
379 SWITCH,
380 type,
381 "hwVersion",
382 "swVersion",
383 "serialNumber",
384 new ChassisId(1));
385 }
386
387 private static Port createPort(Device device, String portName) {
388 return new DefaultPort(device,
389 PortNumber.portNumber(1),
390 true,
391 DefaultAnnotations.builder().set(PORT_NAME, portName).build());
392 }
393
Jian Lie6312162018-03-21 21:41:00 +0900394 private static Set<OpenstackPhyInterface> createPhyIntfs() {
395 return Sets.newConcurrentHashSet();
396 }
397
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900398 private static OpenstackNode createNode(String hostname,
399 OpenstackNode.NodeType type,
400 Device intgBridge,
401 IpAddress ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900402 NodeState state,
403 Set<OpenstackPhyInterface> phyIntfs) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900404 return new TestOpenstackNode(
405 hostname,
406 type,
407 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900408 ipAddr,
409 ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900410 null, null, state, phyIntfs);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900411 }
412
Jian Lie6312162018-03-21 21:41:00 +0900413 private static OpenstackNode createGatewayNode(String hostname,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900414 OpenstackNode.NodeType type,
415 Device intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900416 IpAddress ipAddr,
daniel parkb18424c2018-02-05 15:43:43 +0900417 String uplinkPort,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900418 NodeState state) {
419 return new TestOpenstackNode(
420 hostname,
421 type,
422 intgBridge.id(),
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900423 ipAddr,
424 ipAddr,
Jian Lie6312162018-03-21 21:41:00 +0900425 null, uplinkPort, state, null);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900426 }
427
428 private static final class TestDevice extends DefaultDevice {
429 private TestDevice(ProviderId providerId,
430 DeviceId id,
431 Type type,
432 String manufacturer,
433 String hwVersion,
434 String swVersion,
435 String serialNumber,
436 ChassisId chassisId,
437 Annotations... annotations) {
438 super(providerId,
439 id,
440 type,
441 manufacturer,
442 hwVersion,
443 swVersion,
444 serialNumber,
445 chassisId,
446 annotations);
447 }
448
449 @Override
450 @SuppressWarnings("unchecked")
451 public <B extends Behaviour> B as(Class<B> projectionClass) {
452 if (projectionClass.equals(BridgeConfig.class)) {
453 return (B) new TestBridgeConfig();
454 } else if (projectionClass.equals(InterfaceConfig.class)) {
455 return (B) new TestInterfaceConfig();
456 } else if (projectionClass.equals(ExtensionTreatmentResolver.class)) {
457 ExtensionTreatmentResolver treatmentResolver = createMock(ExtensionTreatmentResolver.class);
458 expect(treatmentResolver.getExtensionInstruction(anyObject()))
459 .andReturn(new TestExtensionTreatment())
460 .anyTimes();
461 replay(treatmentResolver);
462 return (B) treatmentResolver;
463 } else {
464 return null;
465 }
466 }
467
468 @Override
469 public <B extends Behaviour> boolean is(Class<B> projectionClass) {
470 return true;
471 }
472 }
473
474 private static final class TestOpenstackNode extends DefaultOpenstackNode {
475 private TestOpenstackNode(String hostname,
476 NodeType type,
477 DeviceId intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900478 IpAddress managementIp,
479 IpAddress dataIp,
480 String vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900481 String uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900482 NodeState state,
483 Set<OpenstackPhyInterface> phyIntfs) {
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900484 super(hostname,
485 type,
486 intgBridge,
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900487 managementIp,
488 dataIp,
489 vlanIntf,
daniel parkb18424c2018-02-05 15:43:43 +0900490 uplinkPort,
Jian Lie6312162018-03-21 21:41:00 +0900491 state,
492 phyIntfs);
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900493 }
494
495 @Override
496 public PortNumber tunnelPortNum() {
497 return PortNumber.portNumber(1);
498 }
499
500 @Override
501 public PortNumber vlanPortNum() {
502 return PortNumber.portNumber(1);
503 }
504
505 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900506 public MacAddress vlanPortMac() {
507 return MacAddress.NONE;
508 }
509 }
510
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900511 private static class TestDeviceService extends DeviceServiceAdapter {
512 Map<DeviceId, Device> devMap = Maps.newHashMap();
513 List<Port> portList = Lists.newArrayList();
514 List<DeviceListener> listeners = Lists.newArrayList();
515
516 @Override
517 public void addListener(DeviceListener listener) {
518 listeners.add(listener);
519 }
520
521 @Override
522 public void removeListener(DeviceListener listener) {
523 listeners.remove(listener);
524 }
525
526 @Override
527 public Device getDevice(DeviceId deviceId) {
528 return devMap.get(deviceId);
529 }
530
531 @Override
532 public List<Port> getPorts(DeviceId deviceId) {
533 return this.portList.stream()
534 .filter(p -> p.element().id().equals(deviceId))
535 .collect(Collectors.toList());
536 }
537
538 @Override
539 public boolean isAvailable(DeviceId deviceId) {
540 return devMap.containsKey(deviceId);
541 }
542
543 void addDevice(Device device) {
544 devMap.put(device.id(), device);
545 DeviceEvent event = new DeviceEvent(DEVICE_ADDED, device);
546 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
547 }
548
549 void removeDevice(Device device) {
550 devMap.remove(device.id());
551 DeviceEvent event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device);
552 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
553 }
554
555 void addPort(Device device, Port port) {
556 portList.add(port);
557 DeviceEvent event = new DeviceEvent(PORT_ADDED, device, port);
558 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
559 }
560
561 void removePort(Device device, Port port) {
562 portList.remove(port);
563 DeviceEvent event = new DeviceEvent(PORT_REMOVED, device, port);
564 listeners.stream().filter(l -> l.isRelevant(event)).forEach(l -> l.event(event));
565 }
566
567 void clear() {
568 this.listeners.clear();
569 this.devMap.clear();
570 this.portList.clear();
571 }
572 }
573
574 private static class TestBridgeConfig implements BridgeConfig {
575
576 @Override
577 public DriverData data() {
578 return null;
579 }
580
581 @Override
582 public void setData(DriverData data) {
583
584 }
585
586 @Override
587 public DriverHandler handler() {
588 return null;
589 }
590
591 @Override
592 public void setHandler(DriverHandler handler) {
593
594 }
595
596 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900597 public boolean addBridge(BridgeDescription bridge) {
598 TEST_DEVICE_SERVICE.addDevice(new DefaultDevice(new ProviderId("of", "foo"),
599 DeviceId.deviceId("of:" + bridge.datapathId().get()),
600 SWITCH,
601 bridge.name(),
602 "hwVersion",
603 "swVersion",
604 "serialNumber",
605 new ChassisId(1)));
606 return true;
607 }
608
609 @Override
610 public void deleteBridge(BridgeName bridgeName) {
611
612 }
613
614 @Override
615 public Collection<BridgeDescription> getBridges() {
616 return ImmutableSet.of(ROUT_BRIDGE);
617 }
618
619 @Override
620 public void addPort(BridgeName bridgeName, String portName) {
621
622 }
623
624 @Override
625 public void deletePort(BridgeName bridgeName, String portName) {
626
627 }
628
629 @Override
630 public Collection<PortDescription> getPorts() {
631 return ImmutableSet.of(PATCH_ROUT);
632 }
633
634 @Override
635 public Set<PortNumber> getPortNumbers() {
636 return null;
637 }
638
639 @Override
640 public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
641 return null;
642 }
643 }
644
645 private static class TestInterfaceConfig implements InterfaceConfig {
646
647 @Override
648 public DriverData data() {
649 return null;
650 }
651
652 @Override
653 public void setData(DriverData data) {
654
655 }
656
657 @Override
658 public DriverHandler handler() {
659 return null;
660 }
661
662 @Override
663 public void setHandler(DriverHandler handler) {
664
665 }
666
667 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900668 public boolean addAccessMode(String intf, VlanId vlanId) {
669 return false;
670 }
671
672 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900673 public boolean removeAccessMode(String intf) {
674 return false;
675 }
676
677 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900678 public boolean addTrunkMode(String intf, List<VlanId> vlanIds) {
679 return false;
680 }
681
682 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900683 public boolean removeTrunkMode(String intf) {
684 return false;
685 }
686
687 @Override
688 public boolean addRateLimit(String intf, short limit) {
689 return false;
690 }
691
692 @Override
693 public boolean removeRateLimit(String intf) {
694 return false;
695 }
696
697 @Override
698 public boolean addTunnelMode(String intf, TunnelDescription tunnelDesc) {
699 TEST_DEVICE_SERVICE.devMap.values().stream()
700 .filter(device -> device.type() == SWITCH &&
701 device.manufacturer().equals(INTEGRATION_BRIDGE))
702 .forEach(device -> {
703 TEST_DEVICE_SERVICE.addPort(device, createPort(device, intf));
704 });
705 return true;
706 }
707
708 @Override
709 public boolean removeTunnelMode(String intf) {
710 return false;
711 }
712
713 @Override
714 public boolean addPatchMode(String ifaceName, PatchDescription patchInterface) {
715 if (ifaceName.equals(PATCH_INTG_BRIDGE)) {
716 TEST_DEVICE_SERVICE.devMap.values().stream()
717 .filter(device -> device.type() == SWITCH &&
718 device.manufacturer().equals(INTEGRATION_BRIDGE))
719 .forEach(device -> {
720 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
721 });
722 } else if (ifaceName.equals(PATCH_ROUT_BRIDGE)) {
723 TEST_DEVICE_SERVICE.devMap.values().stream()
724 .filter(device -> device.type() == SWITCH &&
725 device.manufacturer().equals(ROUTER_BRIDGE))
726 .forEach(device -> {
727 TEST_DEVICE_SERVICE.addPort(device, createPort(device, ifaceName));
728 });
729 }
730 return true;
731 }
732
733 @Override
734 public boolean removePatchMode(String ifaceName) {
735 return false;
736 }
737
738 @Override
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900739 public List<DeviceInterfaceDescription> getInterfaces() {
740 return null;
741 }
742 }
743
Hyunsun Moon090d77d2017-07-05 17:48:37 +0900744 private static class TestExtensionTreatment implements ExtensionTreatment {
745 Ip4Address tunnelDst;
746
747 @Override
748 public ExtensionTreatmentType type() {
749 return null;
750 }
751
752 @Override
753 public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
754 tunnelDst = (Ip4Address) value;
755 }
756
757 @Override
758 public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
759 return null;
760 }
761
762 @Override
763 public List<String> getProperties() {
764 return null;
765 }
766
767 @Override
768 public byte[] serialize() {
769 return new byte[0];
770 }
771
772 @Override
773 public void deserialize(byte[] data) {
774
775 }
776
777 @Override
778 public boolean equals(Object obj) {
779 TestExtensionTreatment that = (TestExtensionTreatment) obj;
780 return Objects.equals(tunnelDst, that.tunnelDst);
781 }
782
783 @Override
784 public int hashCode() {
785 return Objects.hash(tunnelDst);
786 }
787 }
788
789 private static class TestCoreService extends CoreServiceAdapter {
790
791 @Override
792 public ApplicationId getAppId(String name) {
793 return TEST_APP_ID;
794 }
795 }
796
797 private static class TestLeadershipService extends LeadershipServiceAdapter {
798
799 @Override
800 public NodeId getLeader(String path) {
801 return LOCAL_NODE_ID;
802 }
803 }
804
805 private static class TestClusterService extends ClusterServiceAdapter {
806
807 @Override
808 public ControllerNode getLocalNode() {
809 return LOCAL_CTRL;
810 }
811 }
812
813 private class TestComponentConfigService extends ComponentConfigAdapter {
814
815 }
816}