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