blob: 4b7cf84eca3198f5ce1188848972cc29f0b9abee [file] [log] [blame]
Brian Stanke11f6d532016-07-05 16:17:59 -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 com.google.common.collect.Iterators;
20import com.google.common.collect.Lists;
21import org.junit.After;
22import org.junit.Before;
Thomas Vachuskad832fc52017-01-11 13:13:06 -080023import org.junit.Ignore;
Brian Stanke11f6d532016-07-05 16:17:59 -040024import org.junit.Test;
25import org.onlab.junit.TestUtils;
26import org.onlab.osgi.ServiceDirectory;
27import org.onlab.osgi.TestServiceDirectory;
28import org.onlab.rest.BaseResource;
29import org.onosproject.TestApplicationId;
30import org.onosproject.common.event.impl.TestEventDispatcher;
31import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
33import org.onosproject.core.CoreServiceAdapter;
34import org.onosproject.core.IdGenerator;
35import org.onosproject.incubator.net.virtual.TenantId;
36import org.onosproject.incubator.net.virtual.VirtualDevice;
37import org.onosproject.incubator.net.virtual.VirtualLink;
38import org.onosproject.incubator.net.virtual.VirtualNetwork;
39import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
40import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
41import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
42import org.onosproject.net.ConnectPoint;
43import org.onosproject.net.DefaultPort;
44import org.onosproject.net.EncapsulationType;
45import org.onosproject.net.Link;
46import org.onosproject.net.NetTestTools;
47import org.onosproject.net.Port;
48import org.onosproject.net.PortNumber;
49import org.onosproject.net.TestDeviceParams;
50import org.onosproject.net.intent.Constraint;
51import org.onosproject.net.intent.FakeIntentManager;
52import org.onosproject.net.intent.FlowRuleIntent;
53import org.onosproject.net.intent.Intent;
54import org.onosproject.net.intent.IntentCompiler;
55import org.onosproject.net.intent.IntentEvent;
56import org.onosproject.net.intent.IntentExtensionService;
57import org.onosproject.net.intent.IntentListener;
Brian Stanke11f6d532016-07-05 16:17:59 -040058import org.onosproject.net.intent.IntentService;
59import org.onosproject.net.intent.IntentState;
60import org.onosproject.net.intent.IntentTestsMocks;
61import org.onosproject.net.intent.Key;
62import org.onosproject.net.intent.MockIdGenerator;
63import org.onosproject.net.intent.TestableIntentService;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070064import org.onosproject.net.intent.WorkPartitionService;
65import org.onosproject.net.intent.WorkPartitionServiceAdapter;
Brian Stanke11f6d532016-07-05 16:17:59 -040066import org.onosproject.net.intent.constraint.EncapsulationConstraint;
67import org.onosproject.store.service.TestStorageService;
68
69import java.util.ArrayList;
70import java.util.Collections;
71import java.util.List;
72import java.util.concurrent.Semaphore;
73import java.util.concurrent.TimeUnit;
74import java.util.concurrent.atomic.AtomicLong;
75
76import static org.junit.Assert.*;
77
78/**
79 * Junit tests for VirtualNetworkIntentService.
80 */
Thomas Vachuskad832fc52017-01-11 13:13:06 -080081@Ignore("deprecated prototype implementation")
yoonseon214963b2016-11-21 15:41:07 -080082public class VirtualNetworkIntentManagerTest extends TestDeviceParams {
Brian Stanke11f6d532016-07-05 16:17:59 -040083
84 private final String tenantIdValue1 = "TENANT_ID1";
85 private static final ApplicationId APP_ID =
Brian Stanke682c19e2016-08-02 09:41:40 -040086 new TestApplicationId("MyAppId");
Brian Stanke11f6d532016-07-05 16:17:59 -040087
88 private ConnectPoint cp1;
89 private ConnectPoint cp2;
90 private ConnectPoint cp3;
91 private ConnectPoint cp4;
92 private ConnectPoint cp5;
93 private ConnectPoint cp6;
94 private VirtualLink link1;
95 private VirtualLink link2;
96 private VirtualLink link3;
97 private VirtualLink link4;
98 private VirtualLink link5;
99 private VirtualLink link6;
100
101 private VirtualNetworkManager manager;
102 private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
103 private CoreService coreService;
104 private TestableIntentService intentService = new FakeIntentManager();
yoonseon214963b2016-11-21 15:41:07 -0800105 private VirtualNetworkIntentManager vnetIntentService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400106 private TestIntentCompiler compiler = new TestIntentCompiler();
107 private IntentExtensionService intentExtensionService;
Madan Jampani3b8101a2016-09-15 13:22:01 -0700108 private WorkPartitionService workPartitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400109 private ServiceDirectory testDirectory;
110 private TestListener listener = new TestListener();
Brian Stanke11f6d532016-07-05 16:17:59 -0400111 private static final int MAX_WAIT_TIME = 5;
112 private static final int MAX_PERMITS = 1;
113 private static Semaphore created;
114 private static Semaphore withdrawn;
115 private static Semaphore purged;
116
117 @Before
118 public void setUp() throws Exception {
119 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
120
yoonseon214963b2016-11-21 15:41:07 -0800121 coreService = new VirtualNetworkIntentManagerTest.TestCoreService();
Brian Stanke11f6d532016-07-05 16:17:59 -0400122
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700123 MockIdGenerator.cleanBind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400124
yoonseonc6a69272017-01-12 18:22:20 -0800125 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
Brian Stanke11f6d532016-07-05 16:17:59 -0400126 TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
127 virtualNetworkManagerStore.activate();
128
129 manager = new VirtualNetworkManager();
130 manager.store = virtualNetworkManagerStore;
131 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
132 manager.intentService = intentService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400133 intentService.addListener(listener);
134
135 // Register a compiler and an installer both setup for success.
136 intentExtensionService = intentService;
137 intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
138
139 created = new Semaphore(0, true);
140 withdrawn = new Semaphore(0, true);
141 purged = new Semaphore(0, true);
142
Madan Jampani3b8101a2016-09-15 13:22:01 -0700143 workPartitionService = new WorkPartitionServiceAdapter();
Brian Stanke11f6d532016-07-05 16:17:59 -0400144 testDirectory = new TestServiceDirectory()
145 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
146 .add(IntentService.class, intentService)
Madan Jampani3b8101a2016-09-15 13:22:01 -0700147 .add(WorkPartitionService.class, workPartitionService);
Brian Stanke11f6d532016-07-05 16:17:59 -0400148 BaseResource.setServiceDirectory(testDirectory);
yoonseonc6a69272017-01-12 18:22:20 -0800149 TestUtils.setField(manager, "serviceDirectory", testDirectory);
150
151 manager.activate();
Brian Stanke11f6d532016-07-05 16:17:59 -0400152 }
153
154 @After
155 public void tearDown() {
156 virtualNetworkManagerStore.deactivate();
157 manager.deactivate();
158 NetTestTools.injectEventDispatcher(manager, null);
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700159 MockIdGenerator.unbind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400160 intentService.removeListener(listener);
161 created = null;
162 withdrawn = null;
163 purged = null;
164 }
165
166 /**
167 * Method to create the virtual network for further testing.
168 *
169 * @return virtual network
170 */
171 private VirtualNetwork setupVirtualNetworkTopology() {
172 manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
173 VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
174 VirtualDevice virtualDevice1 =
175 manager.createVirtualDevice(virtualNetwork.id(), DID1);
176 VirtualDevice virtualDevice2 =
177 manager.createVirtualDevice(virtualNetwork.id(), DID2);
178 VirtualDevice virtualDevice3 =
179 manager.createVirtualDevice(virtualNetwork.id(), DID3);
180 VirtualDevice virtualDevice4 =
181 manager.createVirtualDevice(virtualNetwork.id(), DID4);
182
183 Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400184 cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700185 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);
Brian Stanke11f6d532016-07-05 16:17:59 -0400186
187 Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400188 cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700189 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);
Brian Stanke11f6d532016-07-05 16:17:59 -0400190
191 Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400192 cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700193 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);
Brian Stanke11f6d532016-07-05 16:17:59 -0400194
195 Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400196 cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700197 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);
Brian Stanke11f6d532016-07-05 16:17:59 -0400198
199 Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400200 cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700201 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);
Brian Stanke11f6d532016-07-05 16:17:59 -0400202
203 Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400204 cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700205 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);
Brian Stanke11f6d532016-07-05 16:17:59 -0400206
207 link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
208 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
209 link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
210 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
211 link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
212 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
213 link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
214 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
215
yoonseonc6a69272017-01-12 18:22:20 -0800216 vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
Brian Stanke11f6d532016-07-05 16:17:59 -0400217 vnetIntentService.intentService = intentService;
218 vnetIntentService.store = virtualNetworkManagerStore;
Madan Jampani3b8101a2016-09-15 13:22:01 -0700219 vnetIntentService.partitionService = workPartitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400220 return virtualNetwork;
221 }
222
223 /**
224 * Tests the submit(), withdraw(), and purge() methods.
225 */
226 @Test
227 public void testCreateAndRemoveIntent() {
228 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
229
230 Key intentKey = Key.of("test", APP_ID);
231
232 List<Constraint> constraints = new ArrayList<>();
233 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
234
235 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
236 .networkId(virtualNetwork.id())
237 .key(intentKey)
238 .appId(APP_ID)
239 .ingressPoint(cp1)
240 .egressPoint(cp5)
241 .constraints(constraints)
242 .build();
243 // Test the submit() method.
244 vnetIntentService.submit(virtualIntent);
245
246 // Wait for the both intents to go into an INSTALLED state.
247 try {
248 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
249 fail("Failed to wait for intent to get installed.");
250 }
251 } catch (InterruptedException e) {
252 fail("Semaphore exception during intent installation." + e.getMessage());
253 }
254
255 // Test the getIntentState() method
256 assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
257 vnetIntentService.getIntentState(virtualIntent.key()));
258
259 // Test the withdraw() method.
260 vnetIntentService.withdraw(virtualIntent);
261 // Wait for the both intents to go into a WITHDRAWN state.
262 try {
263 if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
264 fail("Failed to wait for intent to get withdrawn.");
265 }
266 } catch (InterruptedException e) {
267 fail("Semaphore exception during intent withdrawal." + e.getMessage());
268 }
269
270 // Test the getIntentState() method
271 assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
272 vnetIntentService.getIntentState(virtualIntent.key()));
273
274 // Test the purge() method.
275 vnetIntentService.purge(virtualIntent);
276 // Wait for the both intents to be removed/purged.
277 try {
278 if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
279 fail("Failed to wait for intent to get purged.");
280 }
281 } catch (InterruptedException e) {
282 fail("Semaphore exception during intent purging." + e.getMessage());
283 }
284
285 }
286
287 /**
288 * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
289 * isLocal() methods.
290 */
291 @Test
292 public void testGetIntents() {
293 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
294
295 Key intentKey = Key.of("test", APP_ID);
296
297 List<Constraint> constraints = new ArrayList<>();
298 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
299
300 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
301 .networkId(virtualNetwork.id())
302 .key(intentKey)
303 .appId(APP_ID)
304 .ingressPoint(cp1)
305 .egressPoint(cp5)
306 .constraints(constraints)
307 .build();
308 // Test the submit() method.
309 vnetIntentService.submit(virtualIntent);
310
311 // Wait for the both intents to go into an INSTALLED state.
312 try {
313 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
314 fail("Failed to wait for intent to get installed.");
315 }
316 } catch (InterruptedException e) {
317 fail("Semaphore exception during intent installation." + e.getMessage());
318 }
319
320 // Test the getIntents() method
321 assertEquals("The intents size did not match as expected.", 1,
322 Iterators.size(vnetIntentService.getIntents().iterator()));
323
324 // Test the getIntent() method
325 assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
326
327 // Test the getIntentData() method
328 assertEquals("The intent data size did not match as expected.", 1,
329 Iterators.size(vnetIntentService.getIntentData().iterator()));
330
331 // Test the getIntentCount() method
332 assertEquals("The intent count did not match as expected.", 1,
333 vnetIntentService.getIntentCount());
334
335 // Test the isLocal() method
336 assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
337
338 }
339
340 /**
341 * Test listener to listen for intent events.
342 */
343 private static class TestListener implements IntentListener {
344
345 @Override
346 public void event(IntentEvent event) {
347 switch (event.type()) {
348 case INSTALLED:
349 // Release one permit on the created semaphore since the Intent event was received.
350 virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
351 created.release();
352 break;
353 case WITHDRAWN:
354 // Release one permit on the removed semaphore since the Intent event was received.
355 virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
356 withdrawn.release();
357 break;
358 case PURGED:
359 // Release one permit on the purged semaphore since the Intent event was received.
360 purged.release();
361 break;
362 default:
363 break;
364 }
365 }
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
386 private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
387 @Override
388 public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
389 return Lists.newArrayList(new MockInstallableIntent());
390 }
391 }
392
393 private static class MockInstallableIntent extends FlowRuleIntent {
394
395 public MockInstallableIntent() {
396 super(APP_ID, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)), Collections.emptyList());
397 }
398 }
399}