blob: 2b9071200e27c5282a04acf88364e1aca099fc83 [file] [log] [blame]
Jian Li810f58c2021-02-27 01:10:50 +09001/*
2 * Copyright 2021-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.kubevirtnetworking.impl;
17
18import com.google.common.collect.ImmutableMap;
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.Lists;
21import com.google.common.util.concurrent.MoreExecutors;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25import org.onlab.junit.TestUtils;
26import org.onlab.packet.IpAddress;
27import org.onlab.packet.MacAddress;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreServiceAdapter;
30import org.onosproject.core.DefaultApplicationId;
31import org.onosproject.event.Event;
Jian Li073f1ba2021-02-28 03:50:15 +090032import org.onosproject.kubevirtnetworking.api.DefaultKubevirtFloatingIp;
Jian Li810f58c2021-02-27 01:10:50 +090033import org.onosproject.kubevirtnetworking.api.DefaultKubevirtRouter;
Jian Li073f1ba2021-02-28 03:50:15 +090034import org.onosproject.kubevirtnetworking.api.KubevirtFloatingIp;
Jian Li810f58c2021-02-27 01:10:50 +090035import org.onosproject.kubevirtnetworking.api.KubevirtPeerRouter;
36import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
37import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
38import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
39import org.onosproject.store.service.TestStorageService;
40
41import java.util.List;
42
43import static org.junit.Assert.assertEquals;
44import static org.junit.Assert.assertNotNull;
45import static org.junit.Assert.assertNull;
Jian Li073f1ba2021-02-28 03:50:15 +090046import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_ASSOCIATED;
47import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_CREATED;
48import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_DISASSOCIATED;
49import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_REMOVED;
50import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_UPDATED;
Jian Li810f58c2021-02-27 01:10:50 +090051import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_CREATED;
Jian Lib636f702021-03-03 14:46:50 +090052import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED;
53import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED;
54import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED;
55import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED;
Jian Li810f58c2021-02-27 01:10:50 +090056import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_REMOVED;
57import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_UPDATED;
58
59/**
60 * Unit tests for kubernetes router manager.
61 */
62public class KubevirtRouterManagerTest {
63
64 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
65
66 private static final String ROUTER_NAME = "router-1";
Jian Li073f1ba2021-02-28 03:50:15 +090067 private static final String POD_NAME = "pod-1";
Jian Lib636f702021-03-03 14:46:50 +090068 private static final String NETWORK_NAME = "flat-1";
Jian Li810f58c2021-02-27 01:10:50 +090069 private static final String UPDATED_DESCRIPTION = "router-updated";
Jian Li810f58c2021-02-27 01:10:50 +090070 private static final MacAddress UPDATED_MAC = MacAddress.valueOf("FF:FF:FF:FF:FF:FF");
71
Jian Li073f1ba2021-02-28 03:50:15 +090072 private static final String FLOATING_IP_ID = "fip-1";
73 private static final String UNKNOWN_ID = "unknown";
74
Jian Li810f58c2021-02-27 01:10:50 +090075 private static final KubevirtRouter ROUTER = DefaultKubevirtRouter.builder()
76 .name(ROUTER_NAME)
77 .description(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +090078 .internal(ImmutableSet.of())
79 .external(ImmutableMap.of())
Jian Li810f58c2021-02-27 01:10:50 +090080 .enableSnat(true)
Jian Li810f58c2021-02-27 01:10:50 +090081 .build();
82
83 private static final KubevirtRouter ROUTER_UPDATED = DefaultKubevirtRouter.builder()
84 .name(ROUTER_NAME)
85 .description(UPDATED_DESCRIPTION)
Jian Lib636f702021-03-03 14:46:50 +090086 .internal(ImmutableSet.of())
87 .external(ImmutableMap.of())
88 .enableSnat(true)
89 .build();
90
91 private static final KubevirtRouter ROUTER_WITH_INTERNAL = DefaultKubevirtRouter.builder()
92 .name(ROUTER_NAME)
93 .description(ROUTER_NAME)
Jian Li810f58c2021-02-27 01:10:50 +090094 .internal(ImmutableSet.of("vxlan-1", "vxlan-2"))
Jian Lib636f702021-03-03 14:46:50 +090095 .external(ImmutableMap.of())
96 .enableSnat(true)
97 .build();
98
99 private static final KubevirtRouter ROUTER_WITH_EXTERNAL = DefaultKubevirtRouter.builder()
100 .name(ROUTER_NAME)
101 .description(ROUTER_NAME)
102 .internal(ImmutableSet.of())
Jian Li810f58c2021-02-27 01:10:50 +0900103 .external(ImmutableMap.of("10.10.10.10", "flat"))
104 .enableSnat(true)
105 .peerRouter(new KubevirtPeerRouter(IpAddress.valueOf("20.20.20.20"),
106 MacAddress.valueOf("11:22:33:44:55:66")))
107 .build();
108
Jian Li073f1ba2021-02-28 03:50:15 +0900109 private static final KubevirtFloatingIp FLOATING_IP_DISASSOCIATED = DefaultKubevirtFloatingIp.builder()
110 .id(FLOATING_IP_ID)
111 .routerName(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +0900112 .networkName(NETWORK_NAME)
Jian Li073f1ba2021-02-28 03:50:15 +0900113 .floatingIp(IpAddress.valueOf("10.10.10.10"))
114 .build();
115
116 private static final KubevirtFloatingIp FLOATING_IP_ASSOCIATED = DefaultKubevirtFloatingIp.builder()
117 .id(FLOATING_IP_ID)
118 .routerName(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +0900119 .networkName(NETWORK_NAME)
Jian Li073f1ba2021-02-28 03:50:15 +0900120 .floatingIp(IpAddress.valueOf("10.10.10.10"))
121 .fixedIp(IpAddress.valueOf("20.20.20.20"))
122 .podName(POD_NAME)
123 .build();
124
Jian Li810f58c2021-02-27 01:10:50 +0900125 private final TestKubevirtRouterListener testListener = new TestKubevirtRouterListener();
126
127 private KubevirtRouterManager target;
128 private DistributedKubevirtRouterStore kubevirtRouterStore;
129
130 @Before
131 public void setUp() throws Exception {
132 kubevirtRouterStore = new DistributedKubevirtRouterStore();
133 TestUtils.setField(kubevirtRouterStore, "coreService", new TestCoreService());
134 TestUtils.setField(kubevirtRouterStore, "storageService", new TestStorageService());
135 TestUtils.setField(kubevirtRouterStore, "eventExecutor", MoreExecutors.newDirectExecutorService());
136 kubevirtRouterStore.activate();
137
138 target = new KubevirtRouterManager();
139 TestUtils.setField(target, "coreService", new TestCoreService());
140 target.kubevirtRouterStore = kubevirtRouterStore;
141 target.addListener(testListener);
142 target.activate();
143 }
144
145 @After
146 public void tearDown() {
147 target.removeListener(testListener);
148 kubevirtRouterStore.deactivate();
149 target.deactivate();
150 kubevirtRouterStore = null;
151 target = null;
152 }
153
154 /**
155 * Tests if getting all routers returns correct set of values.
156 */
157 @Test
158 public void testGetRouters() {
159 createBasicRouters();
160 assertEquals("Number of router did not match", 1, target.routers().size());
161 }
162
163 /**
164 * Tests if getting a router with name returns correct value.
165 */
166 @Test
167 public void testGetRouterByName() {
168 createBasicRouters();
169 assertNotNull("Router did not match", target.router(ROUTER_NAME));
170 }
171
172 /**
173 * Tests creating and removing a router, and checks if proper event is triggered.
174 */
175 @Test
176 public void testCreateAndRemoveRouter() {
177 target.createRouter(ROUTER);
178 assertEquals("Number of router did not match", 1, target.routers().size());
179 assertNotNull("Router was not created", target.router(ROUTER_NAME));
180
181 target.removeRouter(ROUTER_NAME);
182 assertEquals("Number of router did not match", 0, target.routers().size());
183 assertNull("Router was not created", target.router(ROUTER_NAME));
184
185 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_REMOVED);
186 }
187
188 /**
189 * Tests creating and updating a port, and checks if proper event is triggered.
190 */
191 @Test
192 public void testCreateAndUpdateRouter() {
193 target.createRouter(ROUTER);
194 assertEquals("Number of router did not match", 1, target.routers().size());
195
196 target.updateRouter(ROUTER_UPDATED);
197 assertEquals("Number of router did not match", 1, target.routers().size());
198 assertEquals("Router did not match", UPDATED_DESCRIPTION, target.router(ROUTER_NAME).description());
199
200 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED);
201 }
202
203 /**
204 * Tests updating peer router MAC address.
205 */
206 @Test
207 public void testPeerRouterMacUpdate() {
Jian Lib636f702021-03-03 14:46:50 +0900208 target.createRouter(ROUTER_WITH_EXTERNAL);
Jian Li810f58c2021-02-27 01:10:50 +0900209
210 target.updatePeerRouterMac(ROUTER_NAME, UPDATED_MAC);
211 assertEquals("MAC address was not updated", UPDATED_MAC,
212 target.router(ROUTER_NAME).peerRouter().macAddress());
213
214 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED);
215 }
216
217 /**
Jian Lib636f702021-03-03 14:46:50 +0900218 * Tests router's internal networks attached and detached.
219 */
220 @Test
221 public void testRouterInternalAttachedAndDetached() {
222 target.createRouter(ROUTER);
223 assertEquals("Number of router did not match", 1, target.routers().size());
224 assertEquals("Router internal did not match", 0, target.router(ROUTER_NAME).internal().size());
225
226 target.updateRouter(ROUTER_WITH_INTERNAL);
227 assertEquals("Number of router did not match", 1, target.routers().size());
228 assertEquals("Router internal did not match", 2, target.router(ROUTER_NAME).internal().size());
229
230 target.updateRouter(ROUTER);
231 assertEquals("Number of router did not match", 1, target.routers().size());
232 assertEquals("Router internal did not match", 0, target.router(ROUTER_NAME).internal().size());
233
234 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED,
235 KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED, KUBEVIRT_ROUTER_UPDATED,
236 KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED);
237 }
238
239 /**
240 * Tests router's external networks attached and detached.
241 */
242 @Test
243 public void testRouterExternalAttachedAndDetached() {
244 target.createRouter(ROUTER);
245 assertEquals("Number of router did not match", 1, target.routers().size());
246 assertNull(target.router(ROUTER_NAME).peerRouter());
247 assertEquals(0, target.router(ROUTER_NAME).external().size());
248
249 target.updateRouter(ROUTER_WITH_EXTERNAL);
250 assertEquals("Number of router did not match", 1, target.routers().size());
251 assertNotNull(target.router(ROUTER_NAME).peerRouter());
252 assertEquals(1, target.router(ROUTER_NAME).external().size());
253
254 target.updateRouter(ROUTER);
255 assertEquals("Number of router did not match", 1, target.routers().size());
256 assertNull(target.router(ROUTER_NAME).peerRouter());
257 assertEquals(0, target.router(ROUTER_NAME).external().size());
258
259 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED,
260 KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED, KUBEVIRT_ROUTER_UPDATED,
261 KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED);
262 }
263
264 /**
Jian Li810f58c2021-02-27 01:10:50 +0900265 * Tests if creating a null router fails with an exception.
266 */
267 @Test(expected = NullPointerException.class)
268 public void testCreateNullRouter() {
269 target.createRouter(null);
270 }
271
272 /**
273 * Tests if creating a duplicate router fails with an exception.
274 */
275 @Test(expected = IllegalArgumentException.class)
276 public void createDuplicateRouter() {
277 target.createRouter(ROUTER);
278 target.createRouter(ROUTER);
279 }
280
281 /**
282 * Tests if updating an unregistered router fails with an exception.
283 */
284 @Test(expected = IllegalArgumentException.class)
285 public void testUpdateUnregisteredRouter() {
286 target.updateRouter(ROUTER);
287 }
288
289 /**
290 * Tests if updating a null router fails with an exception.
291 */
292 @Test(expected = NullPointerException.class)
293 public void testUpdateNullRouter() {
294 target.updateRouter(null);
295 }
296
Jian Li073f1ba2021-02-28 03:50:15 +0900297 /**
298 * Tests if getting all floating IPs returns the correct set of floating IPs.
299 */
300 @Test
301 public void testGetFloatingIps() {
302 createBasicFloatingIpDisassociated();
303 assertEquals("Number of floating IPs did not match", 1, target.floatingIps().size());
304 }
305
306 /**
307 * Tests if getting a floating IP with ID returns the correct floating IP.
308 */
309 @Test
310 public void testGetFloatingIpById() {
311 createBasicFloatingIpDisassociated();
312 assertNotNull("Floating IP did not match", target.floatingIp(FLOATING_IP_ID));
313 assertNull("Floating IP did not match", target.floatingIp(UNKNOWN_ID));
314 }
315
316 /**
317 * Tests if getting a floating IP with POD name returns the correct floating IP.
318 */
319 @Test
320 public void testGetFloatingIpByPodName() {
321 createBasicFloatingIpAssociated();
322 assertNotNull("Floating IP did not match", target.floatingIpByPodName(POD_NAME));
323 assertNull("Floating IP did not match", target.floatingIpByPodName(UNKNOWN_ID));
324 }
325
326 /**
327 * Tests if getting floating IPs with router name returns the correct floating IPs.
328 */
329 @Test
330 public void testGetFloatingIpsByRouterName() {
331 createBasicFloatingIpDisassociated();
332 assertEquals("Number of floating IPs did not match", 1,
333 target.floatingIpsByRouter(ROUTER_NAME).size());
334 }
335
336 /**
337 * Tests creating and removing a floating IP, and checks if it triggers proper events.
338 */
339 @Test
340 public void testCreateAndRemoveFloatingIp() {
341 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
342 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
343 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
344
345 target.removeFloatingIp(FLOATING_IP_ID);
346 assertEquals("Number of floating IP did not match", 0, target.floatingIps().size());
347 assertNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
348
349 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_REMOVED);
350 }
351
352 /**
353 * Tests associating a floating IP, and checks if it triggers proper events.
354 */
355 @Test
356 public void testAssociateFloatingIp() {
357 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
358 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
359 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
360
361 target.updateFloatingIp(FLOATING_IP_ASSOCIATED);
362 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
363 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
364
365 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_UPDATED,
366 KUBEVIRT_FLOATING_IP_ASSOCIATED);
367 }
368
369 /**
370 * Tests disassociating a floating IP, and checks if it triggers proper events.
371 */
372 @Test
373 public void testDisassociateFloatingIp() {
374 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
375 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
376 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
377
378 target.updateFloatingIp(FLOATING_IP_DISASSOCIATED);
379 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
380 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
381
382 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_UPDATED,
383 KUBEVIRT_FLOATING_IP_DISASSOCIATED);
384 }
385
386 /**
387 * Tests if creating a null floating IP fails with an exception.
388 */
389 @Test(expected = NullPointerException.class)
390 public void testCreateNullFloatingIp() {
391 target.createFloatingIp(null);
392 }
393
394 /**
395 * Tests if creating a duplicate floating IP fails with an exception.
396 */
397 @Test(expected = IllegalArgumentException.class)
398 public void testCreateDuplicateFloatingIp() {
399 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
400 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
401 }
402
403 /**
404 * Tests if removing floating IP with null ID fails with an exception.
405 */
406 @Test(expected = IllegalArgumentException.class)
407 public void testRemoveFloatingIpWithNull() {
408 target.removeFloatingIp(null);
409 }
410
411 /**
412 * Tests if updating an unregistered floating IP fails with an exception.
413 */
414 @Test(expected = IllegalArgumentException.class)
415 public void testUpdateUnregisteredFloatingIp() {
416 target.updateFloatingIp(FLOATING_IP_ASSOCIATED);
417 }
418
Jian Li810f58c2021-02-27 01:10:50 +0900419 private void createBasicRouters() {
420 target.createRouter(ROUTER);
421 }
422
Jian Li073f1ba2021-02-28 03:50:15 +0900423 private void createBasicFloatingIpDisassociated() {
424 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
425 }
426
427 private void createBasicFloatingIpAssociated() {
428 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
429 }
430
Jian Li810f58c2021-02-27 01:10:50 +0900431 private static class TestCoreService extends CoreServiceAdapter {
432
433 @Override
434 public ApplicationId registerApplication(String name) {
435 return TEST_APP_ID;
436 }
437 }
438
439 private static class TestKubevirtRouterListener implements KubevirtRouterListener {
440
441 private List<KubevirtRouterEvent> events = Lists.newArrayList();
442
443 @Override
444 public void event(KubevirtRouterEvent event) {
445 events.add(event);
446 }
447 }
448
449 private void validateEvents(Enum... types) {
450 int i = 0;
451 assertEquals("Number of events did not match", types.length, testListener.events.size());
452 for (Event event : testListener.events) {
453 assertEquals("Incorrect event received", types[i], event.type());
454 i++;
455 }
456 testListener.events.clear();
457 }
458}