blob: d23d132d9def1f533b3fef133122131bd92a7349 [file] [log] [blame]
Brian Stankefb61df42016-07-25 11:47:51 -04001/*
2 * Copyright 2016-present Open Networking Laboratory
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 */
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;
23import org.onosproject.common.event.impl.TestEventDispatcher;
24import org.onosproject.core.CoreService;
25import org.onosproject.core.CoreServiceAdapter;
26import org.onosproject.core.IdGenerator;
27import org.onosproject.event.Event;
28import org.onosproject.incubator.net.tunnel.TunnelId;
29import org.onosproject.incubator.net.virtual.NetworkId;
30import org.onosproject.incubator.net.virtual.TenantId;
31import org.onosproject.incubator.net.virtual.VirtualDevice;
32import org.onosproject.incubator.net.virtual.VirtualLink;
33import org.onosproject.incubator.net.virtual.VirtualNetwork;
yoonseon6b972c32016-12-06 16:45:03 -080034import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProvider;
35import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderRegistry;
36import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
yoonseon214963b2016-11-21 15:41:07 -080037import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager;
Brian Stankefb61df42016-07-25 11:47:51 -040038import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
39import org.onosproject.net.ConnectPoint;
Brian Stankefb61df42016-07-25 11:47:51 -040040import org.onosproject.net.Link;
41import org.onosproject.net.NetTestTools;
42import org.onosproject.net.PortNumber;
43import org.onosproject.net.TestDeviceParams;
44import org.onosproject.net.intent.FakeIntentManager;
45import org.onosproject.net.intent.TestableIntentService;
46import org.onosproject.net.link.LinkEvent;
47import org.onosproject.net.provider.AbstractProviderService;
48import org.onosproject.net.provider.ProviderId;
49import org.onosproject.net.topology.TopologyEvent;
50import org.onosproject.net.topology.TopologyService;
51import org.onosproject.store.service.TestStorageService;
52
53import java.util.ArrayList;
54import java.util.List;
55import java.util.Set;
56import java.util.concurrent.Semaphore;
57import java.util.concurrent.TimeUnit;
58import java.util.concurrent.atomic.AtomicLong;
59
60import static org.junit.Assert.*;
61
62/**
63 * Junit tests for VirtualNetworkTopologyProvider.
64 */
65public class VirtualNetworkTopologyProviderTest extends TestDeviceParams {
66
67 private final String tenantIdValue1 = "TENANT_ID1";
68
69 private VirtualNetwork virtualNetwork;
70 private VirtualDevice virtualDevice1;
71 private VirtualDevice virtualDevice2;
72 private VirtualDevice virtualDevice3;
73 private VirtualDevice virtualDevice4;
74 private VirtualDevice virtualDevice5;
75 private ConnectPoint cp1;
76 private ConnectPoint cp2;
77 private ConnectPoint cp3;
78 private ConnectPoint cp4;
79 private ConnectPoint cp5;
80 private ConnectPoint cp6;
81 private ConnectPoint cp7;
82 private ConnectPoint cp8;
83 private ConnectPoint cp9;
84
85 private VirtualNetworkManager manager;
86 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
87 private CoreService coreService;
yoonseon214963b2016-11-21 15:41:07 -080088 private DefaultVirtualNetworkProvider topologyProvider;
Brian Stankefb61df42016-07-25 11:47:51 -040089 private TopologyService topologyService;
90 private TestableIntentService intentService = new FakeIntentManager();
91 private final VirtualNetworkRegistryAdapter virtualNetworkRegistry = new VirtualNetworkRegistryAdapter();
92
93 private static final int MAX_WAIT_TIME = 5;
94 private static final int MAX_PERMITS = 1;
95 private static Semaphore changed;
96
97 private Set<Set<ConnectPoint>> clusters;
98
99 @Before
100 public void setUp() throws Exception {
101
102 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
103
104 coreService = new VirtualNetworkTopologyProviderTest.TestCoreService();
105
yoonseon214963b2016-11-21 15:41:07 -0800106 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
107 TestUtils.setField(virtualNetworkManagerStore, "storageService",
108 new TestStorageService());
Brian Stankefb61df42016-07-25 11:47:51 -0400109 virtualNetworkManagerStore.activate();
110
111 manager = new VirtualNetworkManager();
yoonseon214963b2016-11-21 15:41:07 -0800112 TestUtils.setField(manager, "store", virtualNetworkManagerStore);
113 TestUtils.setField(manager, "intentService", intentService);
Brian Stankefb61df42016-07-25 11:47:51 -0400114 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
115 manager.activate();
116
117 manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
118 virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
119
120 topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
yoonseon214963b2016-11-21 15:41:07 -0800121 topologyProvider = new DefaultVirtualNetworkProvider();
Brian Stankefb61df42016-07-25 11:47:51 -0400122 topologyProvider.topologyService = topologyService;
123 topologyProvider.providerRegistry = virtualNetworkRegistry;
124 topologyProvider.activate();
125
126 setupVirtualNetworkTopology();
127 changed = new Semaphore(0, true);
128 }
129
130 @After
131 public void tearDown() {
132 topologyProvider.deactivate();
133 virtualNetworkManagerStore.deactivate();
134 manager.deactivate();
135 NetTestTools.injectEventDispatcher(manager, null);
136 }
137
138 /**
139 * Method to create the virtual network for further testing.
140 **/
141 private void setupVirtualNetworkTopology() {
142 virtualDevice1 =
143 manager.createVirtualDevice(virtualNetwork.id(), DID1);
144 virtualDevice2 =
145 manager.createVirtualDevice(virtualNetwork.id(), DID2);
146 virtualDevice3 =
147 manager.createVirtualDevice(virtualNetwork.id(), DID3);
148 virtualDevice4 =
149 manager.createVirtualDevice(virtualNetwork.id(), DID4);
150 virtualDevice5 =
151 manager.createVirtualDevice(virtualNetwork.id(), DID5);
152
153 cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
154 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700155 PortNumber.portNumber(1), cp1);
Brian Stankefb61df42016-07-25 11:47:51 -0400156
157 cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
158 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700159 PortNumber.portNumber(2), cp2);
Brian Stankefb61df42016-07-25 11:47:51 -0400160
161 cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
162 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700163 PortNumber.portNumber(3), cp3);
Brian Stankefb61df42016-07-25 11:47:51 -0400164
165 cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
166 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700167 PortNumber.portNumber(4), cp4);
Brian Stankefb61df42016-07-25 11:47:51 -0400168
169 cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
170 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700171 PortNumber.portNumber(5), cp5);
Brian Stankefb61df42016-07-25 11:47:51 -0400172
173 cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
174 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700175 PortNumber.portNumber(6), cp6);
Brian Stankefb61df42016-07-25 11:47:51 -0400176
177 cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
178 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700179 PortNumber.portNumber(7), cp7);
Brian Stankefb61df42016-07-25 11:47:51 -0400180
181 cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
182 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700183 PortNumber.portNumber(8), cp8);
Brian Stankefb61df42016-07-25 11:47:51 -0400184
185 cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
186 manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
Yoonseon Han6c603892016-09-01 11:52:21 -0700187 PortNumber.portNumber(9), cp9);
Brian Stankefb61df42016-07-25 11:47:51 -0400188
189 VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
190 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
191 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
192 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
193 VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
194 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
195 VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
196 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
197 VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
198 virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
199 VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
200 virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
201
202 clusters = null;
203 }
204
205 /**
206 * Test isTraversable() method using a null source connect point.
207 */
208 @Test(expected = NullPointerException.class)
209 public void testIsTraversableNullSrc() {
210 // test the isTraversable() method with a null source connect point.
211 topologyProvider.isTraversable(null, cp3);
212 }
213
214 /**
215 * Test isTraversable() method using a null destination connect point.
216 */
217 @Test(expected = NullPointerException.class)
218 public void testIsTraversableNullDst() {
219 // test the isTraversable() method with a null destination connect point.
220 topologyProvider.isTraversable(cp1, null);
221 }
222
223 /**
224 * Test isTraversable() method.
225 */
226 @Test
227 public void testIsTraversable() {
228 // test the isTraversable() method.
229 assertTrue("These two connect points should be traversable.",
230 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
231 new ConnectPoint(cp3.elementId(), cp3.port())));
232 assertTrue("These two connect points should be traversable.",
233 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
234 new ConnectPoint(cp5.elementId(), cp5.port())));
235 assertFalse("These two connect points should not be traversable.",
yoonseon214963b2016-11-21 15:41:07 -0800236 topologyProvider.isTraversable(
237 new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)),
238 new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6))));
Brian Stankefb61df42016-07-25 11:47:51 -0400239 }
240
241 /**
242 * Test the topologyChanged() method.
243 */
244 @Test
245 public void testTopologyChanged() {
246 // Initial setup is two clusters of devices/links.
yoonseon214963b2016-11-21 15:41:07 -0800247 assertEquals("The cluster count did not match.", 2,
248 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400249
250 // Adding this link will join the two clusters together.
251 List<Event> reasons = new ArrayList<>();
252 VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7);
253 virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE);
254 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6);
255 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
256
257 reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link));
258 reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link2));
259 TopologyEvent event = new TopologyEvent(
260 TopologyEvent.Type.TOPOLOGY_CHANGED,
261 topologyService.currentTopology(),
262 reasons);
263
264 topologyProvider.topologyListener.event(event);
265
266 // Wait for the topology changed event, and that the topologyChanged method was called.
267 try {
268 if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
269 fail("Failed to wait for topology changed event.");
270 }
271 } catch (InterruptedException e) {
272 fail("Semaphore exception." + e.getMessage());
273 }
274
275 // Validate that the topology changed method received a single cluster of connect points.
276 // This means that the two previous clusters have now joined into a single cluster.
277 assertEquals("The cluster count did not match.", 1, this.clusters.size());
yoonseon214963b2016-11-21 15:41:07 -0800278 assertEquals("The cluster count did not match.", 1,
279 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400280
281 // Now remove the virtual link to split it back into two clusters.
282 manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst());
283 manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst());
yoonseon214963b2016-11-21 15:41:07 -0800284 assertEquals("The cluster count did not match.", 2,
285 topologyService.currentTopology().clusterCount());
Brian Stankefb61df42016-07-25 11:47:51 -0400286
287 reasons = new ArrayList<>();
288 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link));
289 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2));
290 event = new TopologyEvent(
291 TopologyEvent.Type.TOPOLOGY_CHANGED,
292 topologyService.currentTopology(),
293 reasons);
294
295 topologyProvider.topologyListener.event(event);
296
297 // Wait for the topology changed event, and that the topologyChanged method was called.
298 try {
299 if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
300 fail("Failed to wait for topology changed event.");
301 }
302 } catch (InterruptedException e) {
303 fail("Semaphore exception." + e.getMessage());
304 }
305
306 // Validate that the topology changed method received two clusters of connect points.
307 // This means that the single previous clusters has now split into two clusters.
308 assertEquals("The cluster count did not match.", 2, this.clusters.size());
309 }
310
311 /**
312 * Virtual network registry implementation for this test class.
313 */
314 private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry {
315 private VirtualNetworkProvider provider;
316
317 @Override
318 public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) {
319 this.provider = theProvider;
320 return new TestVirtualNetworkProviderService(theProvider);
321 }
322
323 @Override
324 public void unregister(VirtualNetworkProvider theProvider) {
325 this.provider = null;
326 }
327
328 @Override
329 public Set<ProviderId> getProviders() {
330 return null;
331 }
332 }
333
334
335 /**
336 * Virtual network provider service implementation for this test class.
337 */
338 private class TestVirtualNetworkProviderService
339 extends AbstractProviderService<VirtualNetworkProvider>
340 implements VirtualNetworkProviderService {
341
342 /**
343 * Constructor.
344 *
345 * @param provider virtual network test provider
346 */
347 protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) {
348 super(provider);
349 }
350
351 @Override
352 public void topologyChanged(Set<Set<ConnectPoint>> theClusters) {
353 clusters = theClusters;
354 changed.release();
355 }
356
357 @Override
yoonseon214963b2016-11-21 15:41:07 -0800358 public void tunnelUp(NetworkId networkId, ConnectPoint src,
359 ConnectPoint dst, TunnelId tunnelId) {
Brian Stankefb61df42016-07-25 11:47:51 -0400360 }
361
362 @Override
yoonseon214963b2016-11-21 15:41:07 -0800363 public void tunnelDown(NetworkId networkId, ConnectPoint src,
364 ConnectPoint dst, TunnelId tunnelId) {
Brian Stankefb61df42016-07-25 11:47:51 -0400365 }
366 }
367
368 /**
369 * Core service test class.
370 */
371 private class TestCoreService extends CoreServiceAdapter {
372
373 @Override
374 public IdGenerator getIdGenerator(String topic) {
375 return new IdGenerator() {
376 private AtomicLong counter = new AtomicLong(0);
377
378 @Override
379 public long getNewId() {
380 return counter.getAndIncrement();
381 }
382 };
383 }
384 }
385}