blob: ee037833c5713d412efa0dc7471f506d864a782f [file] [log] [blame]
Brian Stankefb61df42016-07-25 11:47:51 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Brian Stankefb61df42016-07-25 11:47:51 -04003 *
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 */
16
yoonseon214963b2016-11-21 15:41:07 -080017package org.onosproject.incubator.net.virtual.impl.provider;
Brian Stankefb61df42016-07-25 11:47:51 -040018
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.junit.TestUtils;
yoonseonc6a69272017-01-12 18:22:20 -080023import org.onlab.osgi.TestServiceDirectory;
Brian Stankefb61df42016-07-25 11:47:51 -040024import org.onosproject.common.event.impl.TestEventDispatcher;
25import org.onosproject.core.CoreService;
26import org.onosproject.core.CoreServiceAdapter;
27import org.onosproject.core.IdGenerator;
28import org.onosproject.event.Event;
29import org.onosproject.incubator.net.tunnel.TunnelId;
30import org.onosproject.incubator.net.virtual.NetworkId;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080031import org.onosproject.net.TenantId;
Brian Stankefb61df42016-07-25 11:47:51 -040032import org.onosproject.incubator.net.virtual.VirtualDevice;
33import org.onosproject.incubator.net.virtual.VirtualLink;
34import org.onosproject.incubator.net.virtual.VirtualNetwork;
yoonseon6b972c32016-12-06 16:45:03 -080035import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProvider;
36import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderRegistry;
37import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
yoonseon214963b2016-11-21 15:41:07 -080038import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080039import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
Brian Stankefb61df42016-07-25 11:47:51 -040040import org.onosproject.net.ConnectPoint;
Brian Stankefb61df42016-07-25 11:47:51 -040041import org.onosproject.net.Link;
42import org.onosproject.net.NetTestTools;
43import org.onosproject.net.PortNumber;
44import org.onosproject.net.TestDeviceParams;
45import org.onosproject.net.intent.FakeIntentManager;
46import org.onosproject.net.intent.TestableIntentService;
47import org.onosproject.net.link.LinkEvent;
48import org.onosproject.net.provider.AbstractProviderService;
49import org.onosproject.net.provider.ProviderId;
50import org.onosproject.net.topology.TopologyEvent;
51import org.onosproject.net.topology.TopologyService;
52import org.onosproject.store.service.TestStorageService;
53
54import java.util.ArrayList;
55import java.util.List;
56import java.util.Set;
57import java.util.concurrent.Semaphore;
58import java.util.concurrent.TimeUnit;
59import java.util.concurrent.atomic.AtomicLong;
60
61import static org.junit.Assert.*;
62
63/**
64 * Junit tests for VirtualNetworkTopologyProvider.
65 */
66public class VirtualNetworkTopologyProviderTest extends TestDeviceParams {
67
68 private final String tenantIdValue1 = "TENANT_ID1";
69
70 private VirtualNetwork virtualNetwork;
71 private VirtualDevice virtualDevice1;
72 private VirtualDevice virtualDevice2;
73 private VirtualDevice virtualDevice3;
74 private VirtualDevice virtualDevice4;
75 private VirtualDevice virtualDevice5;
76 private ConnectPoint cp1;
77 private ConnectPoint cp2;
78 private ConnectPoint cp3;
79 private ConnectPoint cp4;
80 private ConnectPoint cp5;
81 private ConnectPoint cp6;
82 private ConnectPoint cp7;
83 private ConnectPoint cp8;
84 private ConnectPoint cp9;
85
86 private VirtualNetworkManager manager;
87 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
88 private CoreService coreService;
yoonseon214963b2016-11-21 15:41:07 -080089 private DefaultVirtualNetworkProvider topologyProvider;
Brian Stankefb61df42016-07-25 11:47:51 -040090 private TopologyService topologyService;
91 private TestableIntentService intentService = new FakeIntentManager();
yoonseonc6a69272017-01-12 18:22:20 -080092 private TestServiceDirectory testDirectory;
Brian Stankefb61df42016-07-25 11:47:51 -040093 private final VirtualNetworkRegistryAdapter virtualNetworkRegistry = new VirtualNetworkRegistryAdapter();
94
95 private static final int MAX_WAIT_TIME = 5;
96 private static final int MAX_PERMITS = 1;
97 private static Semaphore changed;
98
99 private Set<Set<ConnectPoint>> clusters;
100
101 @Before
102 public void setUp() throws Exception {
103
104 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
105
106 coreService = new VirtualNetworkTopologyProviderTest.TestCoreService();
107
yoonseon214963b2016-11-21 15:41:07 -0800108 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
109 TestUtils.setField(virtualNetworkManagerStore, "storageService",
110 new TestStorageService());
Brian Stankefb61df42016-07-25 11:47:51 -0400111 virtualNetworkManagerStore.activate();
112
113 manager = new VirtualNetworkManager();
yoonseon322c9c32016-12-07 16:47:02 -0800114 TestUtils.setField(manager, "coreService", coreService);
yoonseon214963b2016-11-21 15:41:07 -0800115 TestUtils.setField(manager, "store", virtualNetworkManagerStore);
116 TestUtils.setField(manager, "intentService", intentService);
Brian Stankefb61df42016-07-25 11:47:51 -0400117 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
yoonseonc6a69272017-01-12 18:22:20 -0800118
119 testDirectory = new TestServiceDirectory();
120 TestUtils.setField(manager, "serviceDirectory", testDirectory);
121
Brian Stankefb61df42016-07-25 11:47:51 -0400122 manager.activate();
123
124 manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
125 virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
126
127 topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
yoonseon214963b2016-11-21 15:41:07 -0800128 topologyProvider = new DefaultVirtualNetworkProvider();
Brian Stankefb61df42016-07-25 11:47:51 -0400129 topologyProvider.topologyService = topologyService;
130 topologyProvider.providerRegistry = virtualNetworkRegistry;
131 topologyProvider.activate();
132
133 setupVirtualNetworkTopology();
134 changed = new Semaphore(0, true);
135 }
136
137 @After
138 public void tearDown() {
139 topologyProvider.deactivate();
140 virtualNetworkManagerStore.deactivate();
141 manager.deactivate();
142 NetTestTools.injectEventDispatcher(manager, null);
143 }
144
145 /**
146 * Method to create the virtual network for further testing.
147 **/
148 private void setupVirtualNetworkTopology() {
149 virtualDevice1 =
150 manager.createVirtualDevice(virtualNetwork.id(), DID1);
151 virtualDevice2 =
152 manager.createVirtualDevice(virtualNetwork.id(), DID2);
153 virtualDevice3 =
154 manager.createVirtualDevice(virtualNetwork.id(), DID3);
155 virtualDevice4 =
156 manager.createVirtualDevice(virtualNetwork.id(), DID4);
157 virtualDevice5 =
158 manager.createVirtualDevice(virtualNetwork.id(), DID5);
159
160 cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
161 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700162 PortNumber.portNumber(1), cp1);
Brian Stankefb61df42016-07-25 11:47:51 -0400163
164 cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
165 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700166 PortNumber.portNumber(2), cp2);
Brian Stankefb61df42016-07-25 11:47:51 -0400167
168 cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
169 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700170 PortNumber.portNumber(3), cp3);
Brian Stankefb61df42016-07-25 11:47:51 -0400171
172 cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
173 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700174 PortNumber.portNumber(4), cp4);
Brian Stankefb61df42016-07-25 11:47:51 -0400175
176 cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
177 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700178 PortNumber.portNumber(5), cp5);
Brian Stankefb61df42016-07-25 11:47:51 -0400179
180 cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
181 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700182 PortNumber.portNumber(6), cp6);
Brian Stankefb61df42016-07-25 11:47:51 -0400183
184 cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
185 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700186 PortNumber.portNumber(7), cp7);
Brian Stankefb61df42016-07-25 11:47:51 -0400187
188 cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
189 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700190 PortNumber.portNumber(8), cp8);
Brian Stankefb61df42016-07-25 11:47:51 -0400191
192 cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
193 manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700194 PortNumber.portNumber(9), cp9);
Brian Stankefb61df42016-07-25 11:47:51 -0400195
196 VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
197 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
198 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
199 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
200 VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
201 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
202 VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
203 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
204 VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
205 virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
206 VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
207 virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
208
209 clusters = null;
210 }
211
212 /**
213 * Test isTraversable() method using a null source connect point.
214 */
215 @Test(expected = NullPointerException.class)
216 public void testIsTraversableNullSrc() {
217 // test the isTraversable() method with a null source connect point.
218 topologyProvider.isTraversable(null, cp3);
219 }
220
221 /**
222 * Test isTraversable() method using a null destination connect point.
223 */
224 @Test(expected = NullPointerException.class)
225 public void testIsTraversableNullDst() {
226 // test the isTraversable() method with a null destination connect point.
227 topologyProvider.isTraversable(cp1, null);
228 }
229
230 /**
231 * Test isTraversable() method.
232 */
233 @Test
234 public void testIsTraversable() {
235 // test the isTraversable() method.
236 assertTrue("These two connect points should be traversable.",
237 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
238 new ConnectPoint(cp3.elementId(), cp3.port())));
239 assertTrue("These two connect points should be traversable.",
240 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
241 new ConnectPoint(cp5.elementId(), cp5.port())));
242 assertFalse("These two connect points should not be traversable.",
yoonseon214963b2016-11-21 15:41:07 -0800243 topologyProvider.isTraversable(
244 new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)),
245 new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6))));
Brian Stankefb61df42016-07-25 11:47:51 -0400246 }
247
248 /**
249 * Test the topologyChanged() method.
250 */
251 @Test
252 public void testTopologyChanged() {
253 // Initial setup is two clusters of devices/links.
yoonseon214963b2016-11-21 15:41:07 -0800254 assertEquals("The cluster count did not match.", 2,
255 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400256
257 // Adding this link will join the two clusters together.
258 List<Event> reasons = new ArrayList<>();
259 VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7);
260 virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE);
261 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6);
262 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
263
264 reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link));
265 reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link2));
266 TopologyEvent event = new TopologyEvent(
267 TopologyEvent.Type.TOPOLOGY_CHANGED,
268 topologyService.currentTopology(),
269 reasons);
270
271 topologyProvider.topologyListener.event(event);
272
273 // Wait for the topology changed event, and that the topologyChanged method was called.
274 try {
275 if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
276 fail("Failed to wait for topology changed event.");
277 }
278 } catch (InterruptedException e) {
279 fail("Semaphore exception." + e.getMessage());
280 }
281
282 // Validate that the topology changed method received a single cluster of connect points.
283 // This means that the two previous clusters have now joined into a single cluster.
284 assertEquals("The cluster count did not match.", 1, this.clusters.size());
yoonseon214963b2016-11-21 15:41:07 -0800285 assertEquals("The cluster count did not match.", 1,
286 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400287
288 // Now remove the virtual link to split it back into two clusters.
289 manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst());
290 manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst());
yoonseon214963b2016-11-21 15:41:07 -0800291 assertEquals("The cluster count did not match.", 2,
292 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400293
294 reasons = new ArrayList<>();
295 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link));
296 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2));
297 event = new TopologyEvent(
298 TopologyEvent.Type.TOPOLOGY_CHANGED,
299 topologyService.currentTopology(),
300 reasons);
301
302 topologyProvider.topologyListener.event(event);
303
304 // Wait for the topology changed event, and that the topologyChanged method was called.
305 try {
306 if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
307 fail("Failed to wait for topology changed event.");
308 }
309 } catch (InterruptedException e) {
310 fail("Semaphore exception." + e.getMessage());
311 }
312
313 // Validate that the topology changed method received two clusters of connect points.
314 // This means that the single previous clusters has now split into two clusters.
315 assertEquals("The cluster count did not match.", 2, this.clusters.size());
316 }
317
318 /**
319 * Virtual network registry implementation for this test class.
320 */
321 private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry {
322 private VirtualNetworkProvider provider;
323
324 @Override
325 public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) {
326 this.provider = theProvider;
327 return new TestVirtualNetworkProviderService(theProvider);
328 }
329
330 @Override
331 public void unregister(VirtualNetworkProvider theProvider) {
332 this.provider = null;
333 }
334
335 @Override
336 public Set<ProviderId> getProviders() {
337 return null;
338 }
339 }
340
341
342 /**
343 * Virtual network provider service implementation for this test class.
344 */
345 private class TestVirtualNetworkProviderService
346 extends AbstractProviderService<VirtualNetworkProvider>
347 implements VirtualNetworkProviderService {
348
349 /**
350 * Constructor.
351 *
352 * @param provider virtual network test provider
353 */
354 protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) {
355 super(provider);
356 }
357
358 @Override
359 public void topologyChanged(Set<Set<ConnectPoint>> theClusters) {
360 clusters = theClusters;
361 changed.release();
362 }
363
364 @Override
yoonseon214963b2016-11-21 15:41:07 -0800365 public void tunnelUp(NetworkId networkId, ConnectPoint src,
366 ConnectPoint dst, TunnelId tunnelId) {
Brian Stankefb61df42016-07-25 11:47:51 -0400367 }
368
369 @Override
yoonseon214963b2016-11-21 15:41:07 -0800370 public void tunnelDown(NetworkId networkId, ConnectPoint src,
371 ConnectPoint dst, TunnelId tunnelId) {
Brian Stankefb61df42016-07-25 11:47:51 -0400372 }
373 }
374
375 /**
376 * Core service test class.
377 */
378 private class TestCoreService extends CoreServiceAdapter {
379
380 @Override
381 public IdGenerator getIdGenerator(String topic) {
382 return new IdGenerator() {
383 private AtomicLong counter = new AtomicLong(0);
384
385 @Override
386 public long getNewId() {
387 return counter.getAndIncrement();
388 }
389 };
390 }
391 }
392}