blob: 6f533874e440b4520a70b271d6c529d48d4bdd27 [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;
39import org.onosproject.net.DefaultPort;
40import 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;
88 private VirtualNetworkTopologyProvider topologyProvider;
89 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
106 virtualNetworkManagerStore.setCoreService(coreService);
107 TestUtils.setField(coreService, "coreService", new VirtualNetworkTopologyProviderTest.TestCoreService());
108 TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
109 virtualNetworkManagerStore.activate();
110
111 manager = new VirtualNetworkManager();
112 manager.store = virtualNetworkManagerStore;
113 manager.intentService = intentService;
114 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);
121 topologyProvider = new VirtualNetworkTopologyProvider();
122 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(),
155 PortNumber.portNumber(1),
156 new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true));
157
158 cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
159 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
160 PortNumber.portNumber(2),
161 new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true));
162
163 cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
164 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
165 PortNumber.portNumber(3),
166 new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true));
167
168 cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
169 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
170 PortNumber.portNumber(4),
171 new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true));
172
173 cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
174 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
175 PortNumber.portNumber(5),
176 new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true));
177
178 cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
179 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
180 PortNumber.portNumber(6),
181 new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true));
182
183 cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
184 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
185 PortNumber.portNumber(7),
186 new DefaultPort(virtualDevice4, PortNumber.portNumber(7), true));
187
188 cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
189 manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
190 PortNumber.portNumber(8),
191 new DefaultPort(virtualDevice4, PortNumber.portNumber(8), true));
192
193 cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
194 manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
195 PortNumber.portNumber(9),
196 new DefaultPort(virtualDevice5, PortNumber.portNumber(9), true));
197
198 VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
199 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
200 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
201 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
202 VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
203 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
204 VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
205 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
206 VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
207 virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
208 VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
209 virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
210
211 clusters = null;
212 }
213
214 /**
215 * Test isTraversable() method using a null source connect point.
216 */
217 @Test(expected = NullPointerException.class)
218 public void testIsTraversableNullSrc() {
219 // test the isTraversable() method with a null source connect point.
220 topologyProvider.isTraversable(null, cp3);
221 }
222
223 /**
224 * Test isTraversable() method using a null destination connect point.
225 */
226 @Test(expected = NullPointerException.class)
227 public void testIsTraversableNullDst() {
228 // test the isTraversable() method with a null destination connect point.
229 topologyProvider.isTraversable(cp1, null);
230 }
231
232 /**
233 * Test isTraversable() method.
234 */
235 @Test
236 public void testIsTraversable() {
237 // test the isTraversable() method.
238 assertTrue("These two connect points should be traversable.",
239 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
240 new ConnectPoint(cp3.elementId(), cp3.port())));
241 assertTrue("These two connect points should be traversable.",
242 topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
243 new ConnectPoint(cp5.elementId(), cp5.port())));
244 assertFalse("These two connect points should not be traversable.",
245 topologyProvider.isTraversable(new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)),
246 new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6))));
247 }
248
249 /**
250 * Test the topologyChanged() method.
251 */
252 @Test
253 public void testTopologyChanged() {
254 // Initial setup is two clusters of devices/links.
255 assertEquals("The cluster count did not match.", 2, topologyService.currentTopology().clusterCount());
256
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());
285 assertEquals("The cluster count did not match.", 1, topologyService.currentTopology().clusterCount());
286
287 // Now remove the virtual link to split it back into two clusters.
288 manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst());
289 manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst());
290 assertEquals("The cluster count did not match.", 2, topologyService.currentTopology().clusterCount());
291
292 reasons = new ArrayList<>();
293 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link));
294 reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2));
295 event = new TopologyEvent(
296 TopologyEvent.Type.TOPOLOGY_CHANGED,
297 topologyService.currentTopology(),
298 reasons);
299
300 topologyProvider.topologyListener.event(event);
301
302 // Wait for the topology changed event, and that the topologyChanged method was called.
303 try {
304 if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
305 fail("Failed to wait for topology changed event.");
306 }
307 } catch (InterruptedException e) {
308 fail("Semaphore exception." + e.getMessage());
309 }
310
311 // Validate that the topology changed method received two clusters of connect points.
312 // This means that the single previous clusters has now split into two clusters.
313 assertEquals("The cluster count did not match.", 2, this.clusters.size());
314 }
315
316 /**
317 * Virtual network registry implementation for this test class.
318 */
319 private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry {
320 private VirtualNetworkProvider provider;
321
322 @Override
323 public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) {
324 this.provider = theProvider;
325 return new TestVirtualNetworkProviderService(theProvider);
326 }
327
328 @Override
329 public void unregister(VirtualNetworkProvider theProvider) {
330 this.provider = null;
331 }
332
333 @Override
334 public Set<ProviderId> getProviders() {
335 return null;
336 }
337 }
338
339
340 /**
341 * Virtual network provider service implementation for this test class.
342 */
343 private class TestVirtualNetworkProviderService
344 extends AbstractProviderService<VirtualNetworkProvider>
345 implements VirtualNetworkProviderService {
346
347 /**
348 * Constructor.
349 *
350 * @param provider virtual network test provider
351 */
352 protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) {
353 super(provider);
354 }
355
356 @Override
357 public void topologyChanged(Set<Set<ConnectPoint>> theClusters) {
358 clusters = theClusters;
359 changed.release();
360 }
361
362 @Override
363 public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
364 }
365
366 @Override
367 public void tunnelDown(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
368 }
369 }
370
371 /**
372 * Core service test class.
373 */
374 private class TestCoreService extends CoreServiceAdapter {
375
376 @Override
377 public IdGenerator getIdGenerator(String topic) {
378 return new IdGenerator() {
379 private AtomicLong counter = new AtomicLong(0);
380
381 @Override
382 public long getNewId() {
383 return counter.getAndIncrement();
384 }
385 };
386 }
387 }
388}