blob: 3f191a48a86fe99949c428567b32cb73dc2debcf [file] [log] [blame]
Jian Lifae7b382018-07-12 22:27:47 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
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.openstacknetworking.impl;
17
18import com.google.common.collect.ImmutableSet;
19import com.google.common.collect.Lists;
20import com.google.common.util.concurrent.MoreExecutors;
21import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.junit.TestUtils;
25import org.onlab.packet.IpAddress;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
Jian Li078cd202018-07-23 18:58:20 +090028import org.onosproject.cluster.ClusterServiceAdapter;
29import org.onosproject.cluster.LeadershipServiceAdapter;
Jian Lifae7b382018-07-12 22:27:47 +090030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreServiceAdapter;
32import org.onosproject.core.DefaultApplicationId;
33import org.onosproject.event.Event;
34import org.onosproject.net.DefaultAnnotations;
35import org.onosproject.net.DefaultHost;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.Host;
38import org.onosproject.net.HostId;
39import org.onosproject.net.HostLocation;
40import org.onosproject.net.PortNumber;
41import org.onosproject.net.host.HostServiceAdapter;
42import org.onosproject.net.provider.ProviderId;
43import org.onosproject.openstacknetworking.api.InstancePort;
44import org.onosproject.openstacknetworking.api.InstancePortEvent;
45import org.onosproject.openstacknetworking.api.InstancePortListener;
46import org.onosproject.store.service.TestStorageService;
47
48import java.util.List;
49import java.util.Set;
50
51import static org.junit.Assert.assertEquals;
52import static org.junit.Assert.assertNotNull;
53import static org.junit.Assert.assertNull;
Jian Liec5c32b2018-07-13 14:28:58 +090054import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_CREATE_TIME;
Jian Lifae7b382018-07-12 22:27:47 +090055import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
56import static org.onosproject.openstacknetworking.api.InstancePort.State.INACTIVE;
Jian Liec5c32b2018-07-13 14:28:58 +090057import static org.onosproject.openstacknetworking.api.InstancePort.State.MIGRATED;
Jian Lifae7b382018-07-12 22:27:47 +090058import static org.onosproject.openstacknetworking.api.InstancePort.State.MIGRATING;
59import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_ENDED;
60import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
61import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_DETECTED;
62import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_UPDATED;
63import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_VANISHED;
64import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_RESTARTED;
65import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_TERMINATED;
Jian Lifae7b382018-07-12 22:27:47 +090066
67/**
68 * Unit tests for instance port manager.
69 */
70public class InstancePortManagerTest {
71
72 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
73
74 private static final String ANNOTATION_NETWORK_ID = "networkId";
75 private static final String ANNOTATION_PORT_ID = "portId";
76
77 private static final IpAddress IP_ADDRESS_1 = IpAddress.valueOf("1.2.3.4");
78 private static final IpAddress IP_ADDRESS_2 = IpAddress.valueOf("5.6.7.8");
79
80 private static final MacAddress MAC_ADDRESS_1 = MacAddress.valueOf("11:22:33:44:55:66");
81 private static final MacAddress MAC_ADDRESS_2 = MacAddress.valueOf("77:88:99:AA:BB:CC");
82
83 private static final DeviceId DEV_ID_1 = DeviceId.deviceId("of:0000000000000001");
84 private static final DeviceId DEV_ID_2 = DeviceId.deviceId("of:0000000000000002");
85 private static final PortNumber PORT_NUM_1 = PortNumber.portNumber(1L);
86 private static final PortNumber PORT_NUM_2 = PortNumber.portNumber(2L);
87
88 private static final VlanId VLAN_ID = VlanId.vlanId();
89 private static final ProviderId PROVIDER_ID = ProviderId.NONE;
90 private static final HostId HOST_ID_1 = HostId.hostId("00:00:11:00:00:01/1");
91 private static final HostId HOST_ID_2 = HostId.hostId("00:00:11:00:00:02/1");
92
93 private static final String NETWORK_ID_1 = "net-id-1";
94 private static final String NETWORK_ID_2 = "net-id-2";
95 private static final String PORT_ID_1 = "port-id-1";
96 private static final String PORT_ID_2 = "port-id-2";
97 private static final String UNKNOWN_ID = "port-id-x";
98
99 private static final long TIME_1 = 1L;
100 private static final long TIME_2 = 2L;
101
102 private InstancePort instancePort1;
103 private InstancePort instancePort2;
104
105 private InstancePortManager target;
106 private DistributedInstancePortStore store;
107
108 private final TestInstancePortListener testInstancePortListener = new TestInstancePortListener();
109
110 /**
111 * Initial setup for this unit test.
112 */
113 @Before
114 public void setUp() {
115
116 store = new DistributedInstancePortStore();
117 TestUtils.setField(store, "coreService", new TestCoreService());
118 TestUtils.setField(store, "storageService", new TestStorageService());
119 TestUtils.setField(store, "eventExecutor", MoreExecutors.newDirectExecutorService());
120 store.activate();
121
122 target = new InstancePortManager();
123 TestUtils.setField(target, "coreService", new TestCoreService());
124 TestUtils.setField(target, "hostService", new TestHostService());
Jian Li078cd202018-07-23 18:58:20 +0900125 TestUtils.setField(target, "leadershipService", new TestLeadershipService());
126 TestUtils.setField(target, "clusterService", new TestClusterService());
Jian Lifae7b382018-07-12 22:27:47 +0900127 target.instancePortStore = store;
128 target.addListener(testInstancePortListener);
129 target.activate();
130
131 HostLocation location1 = new HostLocation(DEV_ID_1, PORT_NUM_1, TIME_1);
132 HostLocation location2 = new HostLocation(DEV_ID_2, PORT_NUM_2, TIME_2);
133
134 DefaultAnnotations.Builder annotations1 = DefaultAnnotations.builder()
135 .set(ANNOTATION_NETWORK_ID, NETWORK_ID_1)
136 .set(ANNOTATION_PORT_ID, PORT_ID_1)
137 .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_1));
138
139 DefaultAnnotations.Builder annotations2 = DefaultAnnotations.builder()
140 .set(ANNOTATION_NETWORK_ID, NETWORK_ID_2)
141 .set(ANNOTATION_PORT_ID, PORT_ID_2)
142 .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_2));
143
144 Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_1, MAC_ADDRESS_1,
145 VLAN_ID, location1, ImmutableSet.of(IP_ADDRESS_1),
146 annotations1.build());
147 Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_2, MAC_ADDRESS_2,
148 VLAN_ID, location2, ImmutableSet.of(IP_ADDRESS_2),
149 annotations2.build());
150
151 instancePort1 = DefaultInstancePort.from(host1, ACTIVE);
152 instancePort2 = DefaultInstancePort.from(host2, INACTIVE);
153 }
154
155 /**
156 * Tears down all of this unit test.
157 */
158 @After
159 public void tearDown() {
160 target.removeListener(testInstancePortListener);
161 store.deactivate();
162 target.deactivate();
163 store = null;
164 target = null;
165 }
166
167 /**
168 * Tests if getting all instance ports returns the correct set of ports.
169 */
170 @Test
171 public void testGetInstancePorts() {
172 createBasicInstancePorts();
173 assertEquals("Number of instance port did not match",
174 2, target.instancePorts().size());
175 }
176
177 /**
178 * Tests if getting an instance port with port ID returns the correct port.
179 */
180 @Test
181 public void testGetInstancePortById() {
182 createBasicInstancePorts();
183 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
184 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_2));
185 assertNull("Instance port did not match", target.instancePort(UNKNOWN_ID));
186 }
187
188
189 /**
190 * Tests if getting an instance port with IP and network ID returns correct port.
191 */
192 @Test
193 public void testGetInstancePortByIpAndNetId() {
194 createBasicInstancePorts();
195 InstancePort port = target.instancePort(IP_ADDRESS_1, NETWORK_ID_1);
196 assertEquals("Instance port did not match", port, instancePort1);
197 }
198
199 /**
200 * Tests if getting an instance port with MAC returns correct port.
201 */
202 @Test
203 public void testGetInstancePortByMac() {
204 createBasicInstancePorts();
205 InstancePort port = target.instancePort(MAC_ADDRESS_1);
206 assertEquals("Instance port did not match", port, instancePort1);
207 }
208
209 /**
210 * Tests if getting instance ports with network ID returns correct ports.
211 */
212 @Test
213 public void testGetInstancePortsByNetId() {
214 createBasicInstancePorts();
215 Set<InstancePort> ports = target.instancePorts(NETWORK_ID_1);
216 assertEquals("Number of instance port did not match",
217 1, ports.size());
218 }
219
220 /**
221 * Tests creating and removing an instance port, and checks if it triggers proper events.
222 */
223 @Test
224 public void testCreateAndRemoveInstancePort() {
225 target.createInstancePort(instancePort1);
226 assertEquals("Number of instance port did not match",
227 1, target.instancePorts().size());
228 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
229
230 target.removeInstancePort(PORT_ID_1);
231 assertEquals("Number of instance port did not match",
232 0, target.instancePorts().size());
233 assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
234
235 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_PORT_VANISHED);
236 }
237
238 /**
239 * Tests updating an instance port, and checks if it triggers proper events.
240 */
241 @Test
242 public void testCreateAndUpdateInstancePort() {
243 target.createInstancePort(instancePort1);
244 assertEquals("Number of instance port did not match",
245 1, target.instancePorts().size());
246 assertEquals("Instance port did not match", PORT_NUM_1,
247 target.instancePort(PORT_ID_1).portNumber());
248
249 HostLocation location = new HostLocation(DEV_ID_2, PORT_NUM_2, TIME_2);
250
251 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
252 .set(ANNOTATION_NETWORK_ID, NETWORK_ID_2)
253 .set(ANNOTATION_PORT_ID, PORT_ID_1)
254 .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_2));
255
256 Host host = new DefaultHost(PROVIDER_ID, HOST_ID_2, MAC_ADDRESS_2,
257 VLAN_ID, location, ImmutableSet.of(IP_ADDRESS_2),
258 annotations.build());
259
260 final InstancePort updated = DefaultInstancePort.from(host, ACTIVE);
261 target.updateInstancePort(updated);
262
263 assertEquals("Number of instance port did not match",
264 1, target.instancePorts().size());
265 assertEquals("Instance port did not match", PORT_NUM_2,
266 target.instancePort(PORT_ID_1).portNumber());
267
268 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_PORT_UPDATED);
269 }
270
271 /**
272 * Tests if creating a null instance port fails with an exception.
273 */
274 @Test(expected = NullPointerException.class)
275 public void testCreateNullInstancePort() {
276 target.createInstancePort(null);
277 }
278
279 /**
280 * Tests if creating a duplicated instance port fails with an exception.
281 */
282 @Test(expected = IllegalArgumentException.class)
283 public void testCreateDuplicateInstancePort() {
284 target.createInstancePort(instancePort1);
285 target.createInstancePort(instancePort1);
286 }
287
288 /**
289 * Tests if removing instance port with null ID fails with an exception.
290 */
291 @Test(expected = IllegalArgumentException.class)
292 public void testRemoveInstancePortWithNull() {
293 target.removeInstancePort(null);
294 }
295
296 /**
297 * Tests if updating an unregistered instance port fails with an exception.
298 */
Jian Lida03ce92018-07-24 21:41:53 +0900299 @Test
Jian Lifae7b382018-07-12 22:27:47 +0900300 public void testUpdateUnregisteredInstancePort() {
301 target.updateInstancePort(instancePort1);
302 }
303
304 /**
305 * Tests if it triggers the instance termination event.
306 */
307 @Test
308 public void testTerminateInstance() {
309 InstancePort instancePort = instancePort1;
310 target.createInstancePort(instancePort);
311
312 InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
313 target.updateInstancePort(inactiveInstancePort);
314
315 assertEquals("Number of instance port did not match",
316 1, target.instancePorts().size());
317 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
318
Jian Liec5c32b2018-07-13 14:28:58 +0900319 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_TERMINATED);
Jian Lifae7b382018-07-12 22:27:47 +0900320 }
321
322 /**
323 * Tests if it triggers the instance restart event.
324 */
325 @Test
326 public void testRestartInstance() {
327 InstancePort instancePort = instancePort1;
328 InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
329
330 target.createInstancePort(inactiveInstancePort);
331 target.updateInstancePort(instancePort);
332
333 assertEquals("Number of instance port did not match",
334 1, target.instancePorts().size());
335 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
336
Jian Liec5c32b2018-07-13 14:28:58 +0900337 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_RESTARTED);
Jian Lifae7b382018-07-12 22:27:47 +0900338 }
339
340 /**
341 * Tests if it triggers the instance migration start event.
342 */
343 @Test
344 public void testMigrateInstanceStart() {
345 InstancePort instancePort = instancePort1;
346 target.createInstancePort(instancePort);
347
Jian Liec5c32b2018-07-13 14:28:58 +0900348 InstancePort migratingPort = instancePort.updateState(MIGRATING);
349 target.updateInstancePort(migratingPort);
Jian Lifae7b382018-07-12 22:27:47 +0900350
351 assertEquals("Number of instance port did not match",
352 1, target.instancePorts().size());
353 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
354
Jian Liec5c32b2018-07-13 14:28:58 +0900355 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_MIGRATION_STARTED);
Jian Lifae7b382018-07-12 22:27:47 +0900356 }
357
358 /**
359 * Tests if it triggers the instance migration end event.
360 */
361 @Test
362 public void testMigrateInstanceEnd() {
363 InstancePort instancePort = instancePort1;
Jian Liec5c32b2018-07-13 14:28:58 +0900364 InstancePort migratingPort = instancePort.updateState(MIGRATING);
365 target.createInstancePort(migratingPort);
Jian Lifae7b382018-07-12 22:27:47 +0900366
Jian Liec5c32b2018-07-13 14:28:58 +0900367 InstancePort migratedPort = instancePort.updateState(MIGRATED);
368 target.updateInstancePort(migratedPort);
Jian Lifae7b382018-07-12 22:27:47 +0900369
370 assertEquals("Number of instance port did not match",
371 1, target.instancePorts().size());
372 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
373
Jian Liec5c32b2018-07-13 14:28:58 +0900374 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_MIGRATION_ENDED);
Jian Lifae7b382018-07-12 22:27:47 +0900375 }
376
377 /**
378 * Tests if it triggers the instance removal event from termination status.
379 */
380 @Test
381 public void testRemoveInstanceFromTermination() {
382 InstancePort instancePort = instancePort1;
383 target.createInstancePort(instancePort);
384
385 InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
386 target.updateInstancePort(inactiveInstancePort);
387
388 assertEquals("Number of instance port did not match",
389 1, target.instancePorts().size());
390 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
391
392 target.removeInstancePort(PORT_ID_1);
393
394 assertEquals("Number of instance port did not match",
395 0, target.instancePorts().size());
396 assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
397
Jian Liec5c32b2018-07-13 14:28:58 +0900398 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_TERMINATED,
Jian Lifae7b382018-07-12 22:27:47 +0900399 OPENSTACK_INSTANCE_PORT_VANISHED);
400 }
401
402 /**
403 * Tests if it triggers the instance removal event from migration status.
404 */
405 @Test
406 public void testRemoveInstanceFromMigration() {
407 InstancePort instancePort = instancePort1;
408 target.createInstancePort(instancePort);
409
410 InstancePort inactiveInstancePort = instancePort.updateState(MIGRATING);
411 target.updateInstancePort(inactiveInstancePort);
412
413 assertEquals("Number of instance port did not match",
414 1, target.instancePorts().size());
415 assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
416
417 target.removeInstancePort(PORT_ID_1);
418
419 assertEquals("Number of instance port did not match",
420 0, target.instancePorts().size());
421 assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
422
Jian Liec5c32b2018-07-13 14:28:58 +0900423 validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_MIGRATION_STARTED,
Jian Lifae7b382018-07-12 22:27:47 +0900424 OPENSTACK_INSTANCE_PORT_VANISHED);
425 }
426
427 private void createBasicInstancePorts() {
428 target.createInstancePort(instancePort1);
429 target.createInstancePort(instancePort2);
430 }
431
432 private static class TestCoreService extends CoreServiceAdapter {
433
434 @Override
435 public ApplicationId registerApplication(String name) {
436 return TEST_APP_ID;
437 }
438 }
439
Jian Li078cd202018-07-23 18:58:20 +0900440 private static class TestLeadershipService extends LeadershipServiceAdapter {
441 }
442
443 private static class TestClusterService extends ClusterServiceAdapter {
444 }
445
Jian Lifae7b382018-07-12 22:27:47 +0900446 private static class TestHostService extends HostServiceAdapter {
447 }
448
449 private static class TestInstancePortListener implements InstancePortListener {
450 private List<InstancePortEvent> events = Lists.newArrayList();
451
452 @Override
453 public void event(InstancePortEvent event) {
454 events.add(event);
455 }
456 }
457
458 private void validateEvents(Enum... types) {
459 int i = 0;
460 assertEquals("Number of events did not match", types.length,
461 testInstancePortListener.events.size());
462 for (Event event : testInstancePortListener.events) {
463 assertEquals("Incorrect event received", types[i], event.type());
464 i++;
465 }
466 testInstancePortListener.events.clear();
467 }
468}