blob: 9d6e5473d6cfcaeb943f7995bd4f562b482d76d2 [file] [log] [blame]
Brian Stanke11f6d532016-07-05 16:17:59 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Brian Stanke11f6d532016-07-05 16:17:59 -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
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;
Yoonseon Han9e043792017-05-03 15:43:33 -070040import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -040041import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
42import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
Yoonseon Han9e043792017-05-03 15:43:33 -070043import org.onosproject.incubator.store.virtual.impl.SimpleVirtualIntentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -040044import org.onosproject.net.ConnectPoint;
45import org.onosproject.net.DefaultPort;
46import org.onosproject.net.EncapsulationType;
47import org.onosproject.net.Link;
48import org.onosproject.net.NetTestTools;
49import org.onosproject.net.Port;
50import org.onosproject.net.PortNumber;
51import org.onosproject.net.TestDeviceParams;
52import org.onosproject.net.intent.Constraint;
53import org.onosproject.net.intent.FakeIntentManager;
54import org.onosproject.net.intent.FlowRuleIntent;
55import org.onosproject.net.intent.Intent;
56import org.onosproject.net.intent.IntentCompiler;
57import org.onosproject.net.intent.IntentEvent;
58import org.onosproject.net.intent.IntentExtensionService;
59import org.onosproject.net.intent.IntentListener;
Brian Stanke11f6d532016-07-05 16:17:59 -040060import org.onosproject.net.intent.IntentService;
61import org.onosproject.net.intent.IntentState;
62import org.onosproject.net.intent.IntentTestsMocks;
63import org.onosproject.net.intent.Key;
64import org.onosproject.net.intent.MockIdGenerator;
Ray Milkey39f78b62018-01-05 15:17:37 -080065import org.onosproject.net.intent.PathIntent;
Brian Stanke11f6d532016-07-05 16:17:59 -040066import org.onosproject.net.intent.TestableIntentService;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070067import org.onosproject.net.intent.WorkPartitionService;
68import org.onosproject.net.intent.WorkPartitionServiceAdapter;
Brian Stanke11f6d532016-07-05 16:17:59 -040069import org.onosproject.net.intent.constraint.EncapsulationConstraint;
70import org.onosproject.store.service.TestStorageService;
71
72import java.util.ArrayList;
73import java.util.Collections;
74import java.util.List;
75import java.util.concurrent.Semaphore;
76import java.util.concurrent.TimeUnit;
77import java.util.concurrent.atomic.AtomicLong;
78
79import static org.junit.Assert.*;
80
81/**
82 * Junit tests for VirtualNetworkIntentService.
83 */
Thomas Vachuskad832fc52017-01-11 13:13:06 -080084@Ignore("deprecated prototype implementation")
yoonseon214963b2016-11-21 15:41:07 -080085public class VirtualNetworkIntentManagerTest extends TestDeviceParams {
Brian Stanke11f6d532016-07-05 16:17:59 -040086
87 private final String tenantIdValue1 = "TENANT_ID1";
88 private static final ApplicationId APP_ID =
Brian Stanke682c19e2016-08-02 09:41:40 -040089 new TestApplicationId("MyAppId");
Brian Stanke11f6d532016-07-05 16:17:59 -040090
91 private ConnectPoint cp1;
92 private ConnectPoint cp2;
93 private ConnectPoint cp3;
94 private ConnectPoint cp4;
95 private ConnectPoint cp5;
96 private ConnectPoint cp6;
97 private VirtualLink link1;
98 private VirtualLink link2;
99 private VirtualLink link3;
100 private VirtualLink link4;
101 private VirtualLink link5;
102 private VirtualLink link6;
103
104 private VirtualNetworkManager manager;
105 private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
Yoonseon Han9e043792017-05-03 15:43:33 -0700106 private VirtualNetworkIntentStore intentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -0400107 private CoreService coreService;
108 private TestableIntentService intentService = new FakeIntentManager();
yoonseon214963b2016-11-21 15:41:07 -0800109 private VirtualNetworkIntentManager vnetIntentService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400110 private TestIntentCompiler compiler = new TestIntentCompiler();
111 private IntentExtensionService intentExtensionService;
Madan Jampani3b8101a2016-09-15 13:22:01 -0700112 private WorkPartitionService workPartitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400113 private ServiceDirectory testDirectory;
114 private TestListener listener = new TestListener();
Brian Stanke11f6d532016-07-05 16:17:59 -0400115 private static final int MAX_WAIT_TIME = 5;
116 private static final int MAX_PERMITS = 1;
117 private static Semaphore created;
118 private static Semaphore withdrawn;
119 private static Semaphore purged;
120
121 @Before
122 public void setUp() throws Exception {
123 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
Yoonseon Han9e043792017-05-03 15:43:33 -0700124 intentStore = new SimpleVirtualIntentStore();
Brian Stanke11f6d532016-07-05 16:17:59 -0400125
yoonseon214963b2016-11-21 15:41:07 -0800126 coreService = new VirtualNetworkIntentManagerTest.TestCoreService();
Brian Stanke11f6d532016-07-05 16:17:59 -0400127
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700128 MockIdGenerator.cleanBind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400129
yoonseonc6a69272017-01-12 18:22:20 -0800130 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
Brian Stanke11f6d532016-07-05 16:17:59 -0400131 TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
132 virtualNetworkManagerStore.activate();
133
134 manager = new VirtualNetworkManager();
135 manager.store = virtualNetworkManagerStore;
136 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
Brian Stanke11f6d532016-07-05 16:17:59 -0400137 intentService.addListener(listener);
138
139 // Register a compiler and an installer both setup for success.
140 intentExtensionService = intentService;
141 intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
142
143 created = new Semaphore(0, true);
144 withdrawn = new Semaphore(0, true);
145 purged = new Semaphore(0, true);
146
Madan Jampani3b8101a2016-09-15 13:22:01 -0700147 workPartitionService = new WorkPartitionServiceAdapter();
Brian Stanke11f6d532016-07-05 16:17:59 -0400148 testDirectory = new TestServiceDirectory()
149 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
150 .add(IntentService.class, intentService)
Madan Jampani3b8101a2016-09-15 13:22:01 -0700151 .add(WorkPartitionService.class, workPartitionService);
Brian Stanke11f6d532016-07-05 16:17:59 -0400152 BaseResource.setServiceDirectory(testDirectory);
yoonseonc6a69272017-01-12 18:22:20 -0800153 TestUtils.setField(manager, "serviceDirectory", testDirectory);
154
155 manager.activate();
Brian Stanke11f6d532016-07-05 16:17:59 -0400156 }
157
158 @After
159 public void tearDown() {
160 virtualNetworkManagerStore.deactivate();
161 manager.deactivate();
162 NetTestTools.injectEventDispatcher(manager, null);
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700163 MockIdGenerator.unbind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400164 intentService.removeListener(listener);
165 created = null;
166 withdrawn = null;
167 purged = null;
168 }
169
170 /**
171 * Method to create the virtual network for further testing.
172 *
173 * @return virtual network
174 */
175 private VirtualNetwork setupVirtualNetworkTopology() {
176 manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
177 VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
178 VirtualDevice virtualDevice1 =
179 manager.createVirtualDevice(virtualNetwork.id(), DID1);
180 VirtualDevice virtualDevice2 =
181 manager.createVirtualDevice(virtualNetwork.id(), DID2);
182 VirtualDevice virtualDevice3 =
183 manager.createVirtualDevice(virtualNetwork.id(), DID3);
184 VirtualDevice virtualDevice4 =
185 manager.createVirtualDevice(virtualNetwork.id(), DID4);
186
187 Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400188 cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700189 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);
Brian Stanke11f6d532016-07-05 16:17:59 -0400190
191 Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400192 cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700193 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);
Brian Stanke11f6d532016-07-05 16:17:59 -0400194
195 Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400196 cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700197 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);
Brian Stanke11f6d532016-07-05 16:17:59 -0400198
199 Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400200 cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700201 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);
Brian Stanke11f6d532016-07-05 16:17:59 -0400202
203 Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400204 cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700205 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);
Brian Stanke11f6d532016-07-05 16:17:59 -0400206
207 Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400208 cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700209 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);
Brian Stanke11f6d532016-07-05 16:17:59 -0400210
211 link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
212 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
213 link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
214 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
215 link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
216 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
217 link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
218 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
219
yoonseonc6a69272017-01-12 18:22:20 -0800220 vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
Yoonseon Han9e043792017-05-03 15:43:33 -0700221 vnetIntentService.intentStore = intentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -0400222 return virtualNetwork;
223 }
224
225 /**
226 * Tests the submit(), withdraw(), and purge() methods.
227 */
228 @Test
229 public void testCreateAndRemoveIntent() {
230 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
231
232 Key intentKey = Key.of("test", APP_ID);
233
234 List<Constraint> constraints = new ArrayList<>();
235 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
236
237 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
238 .networkId(virtualNetwork.id())
239 .key(intentKey)
240 .appId(APP_ID)
241 .ingressPoint(cp1)
242 .egressPoint(cp5)
243 .constraints(constraints)
244 .build();
245 // Test the submit() method.
246 vnetIntentService.submit(virtualIntent);
247
248 // Wait for the both intents to go into an INSTALLED state.
249 try {
250 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
251 fail("Failed to wait for intent to get installed.");
252 }
253 } catch (InterruptedException e) {
254 fail("Semaphore exception during intent installation." + e.getMessage());
255 }
256
257 // Test the getIntentState() method
258 assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
259 vnetIntentService.getIntentState(virtualIntent.key()));
260
261 // Test the withdraw() method.
262 vnetIntentService.withdraw(virtualIntent);
263 // Wait for the both intents to go into a WITHDRAWN state.
264 try {
265 if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
266 fail("Failed to wait for intent to get withdrawn.");
267 }
268 } catch (InterruptedException e) {
269 fail("Semaphore exception during intent withdrawal." + e.getMessage());
270 }
271
272 // Test the getIntentState() method
273 assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
274 vnetIntentService.getIntentState(virtualIntent.key()));
275
276 // Test the purge() method.
277 vnetIntentService.purge(virtualIntent);
278 // Wait for the both intents to be removed/purged.
279 try {
280 if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
281 fail("Failed to wait for intent to get purged.");
282 }
283 } catch (InterruptedException e) {
284 fail("Semaphore exception during intent purging." + e.getMessage());
285 }
286
287 }
288
289 /**
290 * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
291 * isLocal() methods.
292 */
293 @Test
294 public void testGetIntents() {
295 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
296
297 Key intentKey = Key.of("test", APP_ID);
298
299 List<Constraint> constraints = new ArrayList<>();
300 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
301
302 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
303 .networkId(virtualNetwork.id())
304 .key(intentKey)
305 .appId(APP_ID)
306 .ingressPoint(cp1)
307 .egressPoint(cp5)
308 .constraints(constraints)
309 .build();
310 // Test the submit() method.
311 vnetIntentService.submit(virtualIntent);
312
313 // Wait for the both intents to go into an INSTALLED state.
314 try {
315 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
316 fail("Failed to wait for intent to get installed.");
317 }
318 } catch (InterruptedException e) {
319 fail("Semaphore exception during intent installation." + e.getMessage());
320 }
321
322 // Test the getIntents() method
323 assertEquals("The intents size did not match as expected.", 1,
324 Iterators.size(vnetIntentService.getIntents().iterator()));
325
326 // Test the getIntent() method
327 assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
328
329 // Test the getIntentData() method
330 assertEquals("The intent data size did not match as expected.", 1,
331 Iterators.size(vnetIntentService.getIntentData().iterator()));
332
333 // Test the getIntentCount() method
334 assertEquals("The intent count did not match as expected.", 1,
335 vnetIntentService.getIntentCount());
336
337 // Test the isLocal() method
338 assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
339
340 }
341
342 /**
343 * Test listener to listen for intent events.
344 */
345 private static class TestListener implements IntentListener {
346
347 @Override
348 public void event(IntentEvent event) {
349 switch (event.type()) {
350 case INSTALLED:
351 // Release one permit on the created semaphore since the Intent event was received.
Yoonseon Han9e043792017-05-03 15:43:33 -0700352// virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
Brian Stanke11f6d532016-07-05 16:17:59 -0400353 created.release();
354 break;
355 case WITHDRAWN:
356 // Release one permit on the removed semaphore since the Intent event was received.
Yoonseon Han9e043792017-05-03 15:43:33 -0700357// virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
Brian Stanke11f6d532016-07-05 16:17:59 -0400358 withdrawn.release();
359 break;
360 case PURGED:
361 // Release one permit on the purged semaphore since the Intent event was received.
362 purged.release();
363 break;
364 default:
365 break;
366 }
367 }
368 }
369
370 /**
371 * Core service test class.
372 */
373 private class TestCoreService extends CoreServiceAdapter {
374
375 @Override
376 public IdGenerator getIdGenerator(String topic) {
377 return new IdGenerator() {
378 private AtomicLong counter = new AtomicLong(0);
379
380 @Override
381 public long getNewId() {
382 return counter.getAndIncrement();
383 }
384 };
385 }
386 }
387
388 private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
389 @Override
390 public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
391 return Lists.newArrayList(new MockInstallableIntent());
392 }
393 }
394
395 private static class MockInstallableIntent extends FlowRuleIntent {
396
397 public MockInstallableIntent() {
Ray Milkey39f78b62018-01-05 15:17:37 -0800398 super(APP_ID, null, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)),
399 Collections.emptyList(), PathIntent.ProtectionType.PRIMARY, null);
Brian Stanke11f6d532016-07-05 16:17:59 -0400400 }
401 }
Yoonseon Han9e043792017-05-03 15:43:33 -0700402
403// private void addOrUpdateIntent(Intent intent, IntentState state) {
404// checkNotNull(intent, "Intent cannot be null");
405// IntentData intentData = intentStore.(intent.key());
406// if (intentData == null) {
407// intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
408// } else {
409// intentData = new IntentData(intent, state, intentData.version());
410// }
411// intentKeyIntentDataMap.put(intent.key(), intentData);
412// }
Brian Stanke11f6d532016-07-05 16:17:59 -0400413}