blob: 94b31618b1749c7f34761ac12eed4a7f5410d502 [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
Jian Lida7ec152021-03-05 12:21:50 +090041import java.util.HashSet;
Jian Li810f58c2021-02-27 01:10:50 +090042import java.util.List;
Jian Lida7ec152021-03-05 12:21:50 +090043import java.util.Set;
Jian Li810f58c2021-02-27 01:10:50 +090044
45import static org.junit.Assert.assertEquals;
46import static org.junit.Assert.assertNotNull;
47import static org.junit.Assert.assertNull;
Jian Li073f1ba2021-02-28 03:50:15 +090048import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_ASSOCIATED;
49import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_CREATED;
50import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_DISASSOCIATED;
51import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_REMOVED;
52import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_UPDATED;
Jian Li810f58c2021-02-27 01:10:50 +090053import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_CREATED;
Jian Lib636f702021-03-03 14:46:50 +090054import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED;
55import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED;
56import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED;
57import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED;
Jian Li810f58c2021-02-27 01:10:50 +090058import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_REMOVED;
59import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_UPDATED;
60
61/**
62 * Unit tests for kubernetes router manager.
63 */
64public class KubevirtRouterManagerTest {
65
66 private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
67
68 private static final String ROUTER_NAME = "router-1";
Jian Li073f1ba2021-02-28 03:50:15 +090069 private static final String POD_NAME = "pod-1";
Jian Lib636f702021-03-03 14:46:50 +090070 private static final String NETWORK_NAME = "flat-1";
Jian Li810f58c2021-02-27 01:10:50 +090071 private static final String UPDATED_DESCRIPTION = "router-updated";
Jian Li810f58c2021-02-27 01:10:50 +090072 private static final MacAddress UPDATED_MAC = MacAddress.valueOf("FF:FF:FF:FF:FF:FF");
73
Jian Li073f1ba2021-02-28 03:50:15 +090074 private static final String FLOATING_IP_ID = "fip-1";
75 private static final String UNKNOWN_ID = "unknown";
76
Jian Li810f58c2021-02-27 01:10:50 +090077 private static final KubevirtRouter ROUTER = DefaultKubevirtRouter.builder()
78 .name(ROUTER_NAME)
79 .description(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +090080 .internal(ImmutableSet.of())
81 .external(ImmutableMap.of())
Jian Li810f58c2021-02-27 01:10:50 +090082 .enableSnat(true)
Jian Li810f58c2021-02-27 01:10:50 +090083 .build();
84
85 private static final KubevirtRouter ROUTER_UPDATED = DefaultKubevirtRouter.builder()
86 .name(ROUTER_NAME)
87 .description(UPDATED_DESCRIPTION)
Jian Lib636f702021-03-03 14:46:50 +090088 .internal(ImmutableSet.of())
89 .external(ImmutableMap.of())
90 .enableSnat(true)
91 .build();
92
93 private static final KubevirtRouter ROUTER_WITH_INTERNAL = DefaultKubevirtRouter.builder()
94 .name(ROUTER_NAME)
95 .description(ROUTER_NAME)
Jian Li810f58c2021-02-27 01:10:50 +090096 .internal(ImmutableSet.of("vxlan-1", "vxlan-2"))
Jian Lib636f702021-03-03 14:46:50 +090097 .external(ImmutableMap.of())
98 .enableSnat(true)
99 .build();
100
Jian Lida7ec152021-03-05 12:21:50 +0900101 private static final KubevirtRouter ROUTER_WITH_SINGLE_INTERNAL = DefaultKubevirtRouter.builder()
102 .name(ROUTER_NAME)
103 .description(ROUTER_NAME)
104 .internal(ImmutableSet.of("vxlan-1"))
105 .external(ImmutableMap.of())
106 .enableSnat(true)
107 .build();
108
Jian Lib636f702021-03-03 14:46:50 +0900109 private static final KubevirtRouter ROUTER_WITH_EXTERNAL = DefaultKubevirtRouter.builder()
110 .name(ROUTER_NAME)
111 .description(ROUTER_NAME)
112 .internal(ImmutableSet.of())
Jian Li810f58c2021-02-27 01:10:50 +0900113 .external(ImmutableMap.of("10.10.10.10", "flat"))
114 .enableSnat(true)
115 .peerRouter(new KubevirtPeerRouter(IpAddress.valueOf("20.20.20.20"),
116 MacAddress.valueOf("11:22:33:44:55:66")))
117 .build();
118
Jian Li073f1ba2021-02-28 03:50:15 +0900119 private static final KubevirtFloatingIp FLOATING_IP_DISASSOCIATED = DefaultKubevirtFloatingIp.builder()
120 .id(FLOATING_IP_ID)
121 .routerName(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +0900122 .networkName(NETWORK_NAME)
Jian Li073f1ba2021-02-28 03:50:15 +0900123 .floatingIp(IpAddress.valueOf("10.10.10.10"))
124 .build();
125
126 private static final KubevirtFloatingIp FLOATING_IP_ASSOCIATED = DefaultKubevirtFloatingIp.builder()
127 .id(FLOATING_IP_ID)
128 .routerName(ROUTER_NAME)
Jian Lib636f702021-03-03 14:46:50 +0900129 .networkName(NETWORK_NAME)
Jian Li073f1ba2021-02-28 03:50:15 +0900130 .floatingIp(IpAddress.valueOf("10.10.10.10"))
131 .fixedIp(IpAddress.valueOf("20.20.20.20"))
132 .podName(POD_NAME)
133 .build();
134
Jian Li810f58c2021-02-27 01:10:50 +0900135 private final TestKubevirtRouterListener testListener = new TestKubevirtRouterListener();
136
137 private KubevirtRouterManager target;
138 private DistributedKubevirtRouterStore kubevirtRouterStore;
139
140 @Before
141 public void setUp() throws Exception {
142 kubevirtRouterStore = new DistributedKubevirtRouterStore();
143 TestUtils.setField(kubevirtRouterStore, "coreService", new TestCoreService());
144 TestUtils.setField(kubevirtRouterStore, "storageService", new TestStorageService());
145 TestUtils.setField(kubevirtRouterStore, "eventExecutor", MoreExecutors.newDirectExecutorService());
146 kubevirtRouterStore.activate();
147
148 target = new KubevirtRouterManager();
149 TestUtils.setField(target, "coreService", new TestCoreService());
150 target.kubevirtRouterStore = kubevirtRouterStore;
151 target.addListener(testListener);
152 target.activate();
153 }
154
155 @After
156 public void tearDown() {
157 target.removeListener(testListener);
158 kubevirtRouterStore.deactivate();
159 target.deactivate();
160 kubevirtRouterStore = null;
161 target = null;
162 }
163
164 /**
165 * Tests if getting all routers returns correct set of values.
166 */
167 @Test
168 public void testGetRouters() {
169 createBasicRouters();
170 assertEquals("Number of router did not match", 1, target.routers().size());
171 }
172
173 /**
174 * Tests if getting a router with name returns correct value.
175 */
176 @Test
177 public void testGetRouterByName() {
178 createBasicRouters();
179 assertNotNull("Router did not match", target.router(ROUTER_NAME));
180 }
181
182 /**
183 * Tests creating and removing a router, and checks if proper event is triggered.
184 */
185 @Test
186 public void testCreateAndRemoveRouter() {
187 target.createRouter(ROUTER);
188 assertEquals("Number of router did not match", 1, target.routers().size());
189 assertNotNull("Router was not created", target.router(ROUTER_NAME));
190
191 target.removeRouter(ROUTER_NAME);
192 assertEquals("Number of router did not match", 0, target.routers().size());
193 assertNull("Router was not created", target.router(ROUTER_NAME));
194
195 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_REMOVED);
196 }
197
198 /**
199 * Tests creating and updating a port, and checks if proper event is triggered.
200 */
201 @Test
202 public void testCreateAndUpdateRouter() {
203 target.createRouter(ROUTER);
204 assertEquals("Number of router did not match", 1, target.routers().size());
205
206 target.updateRouter(ROUTER_UPDATED);
207 assertEquals("Number of router did not match", 1, target.routers().size());
208 assertEquals("Router did not match", UPDATED_DESCRIPTION, target.router(ROUTER_NAME).description());
209
210 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED);
211 }
212
213 /**
214 * Tests updating peer router MAC address.
215 */
216 @Test
217 public void testPeerRouterMacUpdate() {
Jian Lib636f702021-03-03 14:46:50 +0900218 target.createRouter(ROUTER_WITH_EXTERNAL);
Jian Li810f58c2021-02-27 01:10:50 +0900219
220 target.updatePeerRouterMac(ROUTER_NAME, UPDATED_MAC);
221 assertEquals("MAC address was not updated", UPDATED_MAC,
222 target.router(ROUTER_NAME).peerRouter().macAddress());
223
224 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED);
225 }
226
227 /**
Jian Lib636f702021-03-03 14:46:50 +0900228 * Tests router's internal networks attached and detached.
229 */
230 @Test
231 public void testRouterInternalAttachedAndDetached() {
232 target.createRouter(ROUTER);
233 assertEquals("Number of router did not match", 1, target.routers().size());
234 assertEquals("Router internal did not match", 0, target.router(ROUTER_NAME).internal().size());
235
236 target.updateRouter(ROUTER_WITH_INTERNAL);
237 assertEquals("Number of router did not match", 1, target.routers().size());
238 assertEquals("Router internal did not match", 2, target.router(ROUTER_NAME).internal().size());
239
240 target.updateRouter(ROUTER);
241 assertEquals("Number of router did not match", 1, target.routers().size());
242 assertEquals("Router internal did not match", 0, target.router(ROUTER_NAME).internal().size());
243
244 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED,
245 KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED, KUBEVIRT_ROUTER_UPDATED,
246 KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED);
247 }
248
Jian Lida7ec152021-03-05 12:21:50 +0900249 @Test
250 public void testRouterInternalShrink() {
251 target.createRouter(ROUTER_WITH_INTERNAL);
252 assertEquals("Number of router did not match", 1, target.routers().size());
253 assertEquals("Router internal did not match", 2, target.router(ROUTER_NAME).internal().size());
254
255 target.updateRouter(ROUTER_WITH_SINGLE_INTERNAL);
256 assertEquals("Number of router did not match", 1, target.routers().size());
257 assertEquals("Router internal did not match", 1, target.router(ROUTER_NAME).internal().size());
258
259 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED,
260 KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED);
261
262 validateInternalRemoval(ImmutableSet.of("vxlan-2"));
263 }
264
Jian Lib636f702021-03-03 14:46:50 +0900265 /**
266 * Tests router's external networks attached and detached.
267 */
268 @Test
269 public void testRouterExternalAttachedAndDetached() {
270 target.createRouter(ROUTER);
271 assertEquals("Number of router did not match", 1, target.routers().size());
272 assertNull(target.router(ROUTER_NAME).peerRouter());
273 assertEquals(0, target.router(ROUTER_NAME).external().size());
274
275 target.updateRouter(ROUTER_WITH_EXTERNAL);
276 assertEquals("Number of router did not match", 1, target.routers().size());
277 assertNotNull(target.router(ROUTER_NAME).peerRouter());
278 assertEquals(1, target.router(ROUTER_NAME).external().size());
279
280 target.updateRouter(ROUTER);
281 assertEquals("Number of router did not match", 1, target.routers().size());
282 assertNull(target.router(ROUTER_NAME).peerRouter());
283 assertEquals(0, target.router(ROUTER_NAME).external().size());
284
285 validateEvents(KUBEVIRT_ROUTER_CREATED, KUBEVIRT_ROUTER_UPDATED,
286 KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED, KUBEVIRT_ROUTER_UPDATED,
287 KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED);
288 }
289
290 /**
Jian Li810f58c2021-02-27 01:10:50 +0900291 * Tests if creating a null router fails with an exception.
292 */
293 @Test(expected = NullPointerException.class)
294 public void testCreateNullRouter() {
295 target.createRouter(null);
296 }
297
298 /**
299 * Tests if creating a duplicate router fails with an exception.
300 */
301 @Test(expected = IllegalArgumentException.class)
302 public void createDuplicateRouter() {
303 target.createRouter(ROUTER);
304 target.createRouter(ROUTER);
305 }
306
307 /**
308 * Tests if updating an unregistered router fails with an exception.
309 */
310 @Test(expected = IllegalArgumentException.class)
311 public void testUpdateUnregisteredRouter() {
312 target.updateRouter(ROUTER);
313 }
314
315 /**
316 * Tests if updating a null router fails with an exception.
317 */
318 @Test(expected = NullPointerException.class)
319 public void testUpdateNullRouter() {
320 target.updateRouter(null);
321 }
322
Jian Li073f1ba2021-02-28 03:50:15 +0900323 /**
324 * Tests if getting all floating IPs returns the correct set of floating IPs.
325 */
326 @Test
327 public void testGetFloatingIps() {
328 createBasicFloatingIpDisassociated();
329 assertEquals("Number of floating IPs did not match", 1, target.floatingIps().size());
330 }
331
332 /**
333 * Tests if getting a floating IP with ID returns the correct floating IP.
334 */
335 @Test
336 public void testGetFloatingIpById() {
337 createBasicFloatingIpDisassociated();
338 assertNotNull("Floating IP did not match", target.floatingIp(FLOATING_IP_ID));
339 assertNull("Floating IP did not match", target.floatingIp(UNKNOWN_ID));
340 }
341
342 /**
343 * Tests if getting a floating IP with POD name returns the correct floating IP.
344 */
345 @Test
346 public void testGetFloatingIpByPodName() {
347 createBasicFloatingIpAssociated();
348 assertNotNull("Floating IP did not match", target.floatingIpByPodName(POD_NAME));
349 assertNull("Floating IP did not match", target.floatingIpByPodName(UNKNOWN_ID));
350 }
351
352 /**
353 * Tests if getting floating IPs with router name returns the correct floating IPs.
354 */
355 @Test
356 public void testGetFloatingIpsByRouterName() {
357 createBasicFloatingIpDisassociated();
358 assertEquals("Number of floating IPs did not match", 1,
359 target.floatingIpsByRouter(ROUTER_NAME).size());
360 }
361
362 /**
363 * Tests creating and removing a floating IP, and checks if it triggers proper events.
364 */
365 @Test
366 public void testCreateAndRemoveFloatingIp() {
367 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
368 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
369 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
370
371 target.removeFloatingIp(FLOATING_IP_ID);
372 assertEquals("Number of floating IP did not match", 0, target.floatingIps().size());
373 assertNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
374
375 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_REMOVED);
376 }
377
378 /**
379 * Tests associating a floating IP, and checks if it triggers proper events.
380 */
381 @Test
382 public void testAssociateFloatingIp() {
383 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
384 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
385 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
386
387 target.updateFloatingIp(FLOATING_IP_ASSOCIATED);
388 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
389 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
390
391 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_UPDATED,
392 KUBEVIRT_FLOATING_IP_ASSOCIATED);
393 }
394
395 /**
396 * Tests disassociating a floating IP, and checks if it triggers proper events.
397 */
398 @Test
399 public void testDisassociateFloatingIp() {
400 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
401 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
402 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
403
404 target.updateFloatingIp(FLOATING_IP_DISASSOCIATED);
405 assertEquals("Number of floating IP did not match", 1, target.floatingIps().size());
406 assertNotNull("Floating IP was not created", target.floatingIp(FLOATING_IP_ID));
407
408 validateEvents(KUBEVIRT_FLOATING_IP_CREATED, KUBEVIRT_FLOATING_IP_UPDATED,
409 KUBEVIRT_FLOATING_IP_DISASSOCIATED);
410 }
411
412 /**
413 * Tests if creating a null floating IP fails with an exception.
414 */
415 @Test(expected = NullPointerException.class)
416 public void testCreateNullFloatingIp() {
417 target.createFloatingIp(null);
418 }
419
420 /**
421 * Tests if creating a duplicate floating IP fails with an exception.
422 */
423 @Test(expected = IllegalArgumentException.class)
424 public void testCreateDuplicateFloatingIp() {
425 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
426 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
427 }
428
429 /**
430 * Tests if removing floating IP with null ID fails with an exception.
431 */
432 @Test(expected = IllegalArgumentException.class)
433 public void testRemoveFloatingIpWithNull() {
434 target.removeFloatingIp(null);
435 }
436
437 /**
438 * Tests if updating an unregistered floating IP fails with an exception.
439 */
440 @Test(expected = IllegalArgumentException.class)
441 public void testUpdateUnregisteredFloatingIp() {
442 target.updateFloatingIp(FLOATING_IP_ASSOCIATED);
443 }
444
Jian Li810f58c2021-02-27 01:10:50 +0900445 private void createBasicRouters() {
446 target.createRouter(ROUTER);
447 }
448
Jian Li073f1ba2021-02-28 03:50:15 +0900449 private void createBasicFloatingIpDisassociated() {
450 target.createFloatingIp(FLOATING_IP_DISASSOCIATED);
451 }
452
453 private void createBasicFloatingIpAssociated() {
454 target.createFloatingIp(FLOATING_IP_ASSOCIATED);
455 }
456
Jian Li810f58c2021-02-27 01:10:50 +0900457 private static class TestCoreService extends CoreServiceAdapter {
458
459 @Override
460 public ApplicationId registerApplication(String name) {
461 return TEST_APP_ID;
462 }
463 }
464
465 private static class TestKubevirtRouterListener implements KubevirtRouterListener {
466
467 private List<KubevirtRouterEvent> events = Lists.newArrayList();
Jian Lida7ec152021-03-05 12:21:50 +0900468 private Set<String> internalAdded = new HashSet<>();
469 private Set<String> internalRemoved = new HashSet<>();
Jian Li810f58c2021-02-27 01:10:50 +0900470
471 @Override
472 public void event(KubevirtRouterEvent event) {
473 events.add(event);
Jian Lida7ec152021-03-05 12:21:50 +0900474 if (event.type() == KUBEVIRT_ROUTER_INTERNAL_NETWORKS_ATTACHED) {
475 internalAdded = event.internal();
476 }
477 if (event.type() == KUBEVIRT_ROUTER_INTERNAL_NETWORKS_DETACHED) {
478 internalRemoved = event.internal();
479 }
Jian Li810f58c2021-02-27 01:10:50 +0900480 }
481 }
482
483 private void validateEvents(Enum... types) {
484 int i = 0;
485 assertEquals("Number of events did not match", types.length, testListener.events.size());
486 for (Event event : testListener.events) {
487 assertEquals("Incorrect event received", types[i], event.type());
488 i++;
489 }
490 testListener.events.clear();
491 }
Jian Lida7ec152021-03-05 12:21:50 +0900492
493 private void validateInternalAddition(Set<String> internal) {
494 assertEquals("internal addition entries", internal, testListener.internalAdded);
495 testListener.internalAdded.clear();
496 }
497
498 private void validateInternalRemoval(Set<String> internal) {
499 assertEquals("internal addition entries", internal, testListener.internalRemoved);
500 testListener.internalRemoved.clear();
501 }
Jian Li810f58c2021-02-27 01:10:50 +0900502}