blob: ba0adda5301ece239ba2e3a00fdaf38ee16145eb [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;
Brian Stanke11f6d532016-07-05 16:17:59 -040028import org.onosproject.TestApplicationId;
29import org.onosproject.common.event.impl.TestEventDispatcher;
30import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.core.CoreServiceAdapter;
33import org.onosproject.core.IdGenerator;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080034import org.onosproject.net.TenantId;
Brian Stanke11f6d532016-07-05 16:17:59 -040035import org.onosproject.incubator.net.virtual.VirtualDevice;
36import org.onosproject.incubator.net.virtual.VirtualLink;
37import org.onosproject.incubator.net.virtual.VirtualNetwork;
38import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
Yoonseon Han9e043792017-05-03 15:43:33 -070039import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -040040import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080041import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
42import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualIntentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -040043import org.onosproject.net.ConnectPoint;
44import org.onosproject.net.DefaultPort;
45import org.onosproject.net.EncapsulationType;
46import org.onosproject.net.Link;
47import org.onosproject.net.NetTestTools;
48import org.onosproject.net.Port;
49import org.onosproject.net.PortNumber;
50import org.onosproject.net.TestDeviceParams;
51import org.onosproject.net.intent.Constraint;
52import org.onosproject.net.intent.FakeIntentManager;
53import org.onosproject.net.intent.FlowRuleIntent;
54import org.onosproject.net.intent.Intent;
55import org.onosproject.net.intent.IntentCompiler;
56import org.onosproject.net.intent.IntentEvent;
57import org.onosproject.net.intent.IntentExtensionService;
58import org.onosproject.net.intent.IntentListener;
Brian Stanke11f6d532016-07-05 16:17:59 -040059import org.onosproject.net.intent.IntentService;
60import org.onosproject.net.intent.IntentState;
61import org.onosproject.net.intent.IntentTestsMocks;
62import org.onosproject.net.intent.Key;
63import org.onosproject.net.intent.MockIdGenerator;
Ray Milkey39f78b62018-01-05 15:17:37 -080064import org.onosproject.net.intent.PathIntent;
Brian Stanke11f6d532016-07-05 16:17:59 -040065import org.onosproject.net.intent.TestableIntentService;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070066import org.onosproject.net.intent.WorkPartitionService;
67import org.onosproject.net.intent.WorkPartitionServiceAdapter;
Brian Stanke11f6d532016-07-05 16:17:59 -040068import org.onosproject.net.intent.constraint.EncapsulationConstraint;
69import org.onosproject.store.service.TestStorageService;
70
71import java.util.ArrayList;
72import java.util.Collections;
73import java.util.List;
74import java.util.concurrent.Semaphore;
75import java.util.concurrent.TimeUnit;
76import java.util.concurrent.atomic.AtomicLong;
77
Ray Milkey094a1352018-01-22 14:03:54 -080078import static org.junit.Assert.assertEquals;
79import static org.junit.Assert.assertNotNull;
80import static org.junit.Assert.assertTrue;
81import static org.junit.Assert.fail;
Brian Stanke11f6d532016-07-05 16:17:59 -040082
83/**
84 * Junit tests for VirtualNetworkIntentService.
85 */
Thomas Vachuskad832fc52017-01-11 13:13:06 -080086@Ignore("deprecated prototype implementation")
yoonseon214963b2016-11-21 15:41:07 -080087public class VirtualNetworkIntentManagerTest extends TestDeviceParams {
Brian Stanke11f6d532016-07-05 16:17:59 -040088
89 private final String tenantIdValue1 = "TENANT_ID1";
90 private static final ApplicationId APP_ID =
Brian Stanke682c19e2016-08-02 09:41:40 -040091 new TestApplicationId("MyAppId");
Brian Stanke11f6d532016-07-05 16:17:59 -040092
93 private ConnectPoint cp1;
94 private ConnectPoint cp2;
95 private ConnectPoint cp3;
96 private ConnectPoint cp4;
97 private ConnectPoint cp5;
98 private ConnectPoint cp6;
99 private VirtualLink link1;
100 private VirtualLink link2;
101 private VirtualLink link3;
102 private VirtualLink link4;
103 private VirtualLink link5;
104 private VirtualLink link6;
105
106 private VirtualNetworkManager manager;
107 private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
Yoonseon Han9e043792017-05-03 15:43:33 -0700108 private VirtualNetworkIntentStore intentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -0400109 private CoreService coreService;
110 private TestableIntentService intentService = new FakeIntentManager();
yoonseon214963b2016-11-21 15:41:07 -0800111 private VirtualNetworkIntentManager vnetIntentService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400112 private TestIntentCompiler compiler = new TestIntentCompiler();
113 private IntentExtensionService intentExtensionService;
Madan Jampani3b8101a2016-09-15 13:22:01 -0700114 private WorkPartitionService workPartitionService;
Brian Stanke11f6d532016-07-05 16:17:59 -0400115 private ServiceDirectory testDirectory;
116 private TestListener listener = new TestListener();
Brian Stanke11f6d532016-07-05 16:17:59 -0400117 private static final int MAX_WAIT_TIME = 5;
118 private static final int MAX_PERMITS = 1;
119 private static Semaphore created;
120 private static Semaphore withdrawn;
121 private static Semaphore purged;
122
123 @Before
124 public void setUp() throws Exception {
125 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
Yoonseon Han9e043792017-05-03 15:43:33 -0700126 intentStore = new SimpleVirtualIntentStore();
Brian Stanke11f6d532016-07-05 16:17:59 -0400127
yoonseon214963b2016-11-21 15:41:07 -0800128 coreService = new VirtualNetworkIntentManagerTest.TestCoreService();
Brian Stanke11f6d532016-07-05 16:17:59 -0400129
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700130 MockIdGenerator.cleanBind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400131
yoonseonc6a69272017-01-12 18:22:20 -0800132 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
Brian Stanke11f6d532016-07-05 16:17:59 -0400133 TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
134 virtualNetworkManagerStore.activate();
135
136 manager = new VirtualNetworkManager();
137 manager.store = virtualNetworkManagerStore;
138 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
Brian Stanke11f6d532016-07-05 16:17:59 -0400139 intentService.addListener(listener);
140
141 // Register a compiler and an installer both setup for success.
142 intentExtensionService = intentService;
143 intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
144
145 created = new Semaphore(0, true);
146 withdrawn = new Semaphore(0, true);
147 purged = new Semaphore(0, true);
148
Madan Jampani3b8101a2016-09-15 13:22:01 -0700149 workPartitionService = new WorkPartitionServiceAdapter();
Brian Stanke11f6d532016-07-05 16:17:59 -0400150 testDirectory = new TestServiceDirectory()
151 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
152 .add(IntentService.class, intentService)
Madan Jampani3b8101a2016-09-15 13:22:01 -0700153 .add(WorkPartitionService.class, workPartitionService);
yoonseonc6a69272017-01-12 18:22:20 -0800154 TestUtils.setField(manager, "serviceDirectory", testDirectory);
155
156 manager.activate();
Brian Stanke11f6d532016-07-05 16:17:59 -0400157 }
158
159 @After
160 public void tearDown() {
161 virtualNetworkManagerStore.deactivate();
162 manager.deactivate();
163 NetTestTools.injectEventDispatcher(manager, null);
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700164 MockIdGenerator.unbind();
Brian Stanke11f6d532016-07-05 16:17:59 -0400165 intentService.removeListener(listener);
166 created = null;
167 withdrawn = null;
168 purged = null;
169 }
170
171 /**
172 * Method to create the virtual network for further testing.
173 *
174 * @return virtual network
175 */
176 private VirtualNetwork setupVirtualNetworkTopology() {
177 manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
178 VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
179 VirtualDevice virtualDevice1 =
180 manager.createVirtualDevice(virtualNetwork.id(), DID1);
181 VirtualDevice virtualDevice2 =
182 manager.createVirtualDevice(virtualNetwork.id(), DID2);
183 VirtualDevice virtualDevice3 =
184 manager.createVirtualDevice(virtualNetwork.id(), DID3);
185 VirtualDevice virtualDevice4 =
186 manager.createVirtualDevice(virtualNetwork.id(), DID4);
187
188 Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400189 cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700190 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);
Brian Stanke11f6d532016-07-05 16:17:59 -0400191
192 Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400193 cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700194 manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);
Brian Stanke11f6d532016-07-05 16:17:59 -0400195
196 Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400197 cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700198 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);
Brian Stanke11f6d532016-07-05 16:17:59 -0400199
200 Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400201 cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700202 manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);
Brian Stanke11f6d532016-07-05 16:17:59 -0400203
204 Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400205 cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700206 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);
Brian Stanke11f6d532016-07-05 16:17:59 -0400207
208 Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
Brian Stanke11f6d532016-07-05 16:17:59 -0400209 cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
Yoonseon Han6c603892016-09-01 11:52:21 -0700210 manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);
Brian Stanke11f6d532016-07-05 16:17:59 -0400211
212 link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
213 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
214 link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
215 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
216 link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
217 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
218 link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
219 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
220
yoonseonc6a69272017-01-12 18:22:20 -0800221 vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
Yoonseon Han9e043792017-05-03 15:43:33 -0700222 vnetIntentService.intentStore = intentStore;
Brian Stanke11f6d532016-07-05 16:17:59 -0400223 return virtualNetwork;
224 }
225
226 /**
227 * Tests the submit(), withdraw(), and purge() methods.
228 */
229 @Test
230 public void testCreateAndRemoveIntent() {
231 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
232
233 Key intentKey = Key.of("test", APP_ID);
234
235 List<Constraint> constraints = new ArrayList<>();
236 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
237
238 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
239 .networkId(virtualNetwork.id())
240 .key(intentKey)
241 .appId(APP_ID)
242 .ingressPoint(cp1)
243 .egressPoint(cp5)
244 .constraints(constraints)
245 .build();
246 // Test the submit() method.
247 vnetIntentService.submit(virtualIntent);
248
249 // Wait for the both intents to go into an INSTALLED state.
250 try {
251 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
252 fail("Failed to wait for intent to get installed.");
253 }
254 } catch (InterruptedException e) {
255 fail("Semaphore exception during intent installation." + e.getMessage());
256 }
257
258 // Test the getIntentState() method
259 assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
260 vnetIntentService.getIntentState(virtualIntent.key()));
261
262 // Test the withdraw() method.
263 vnetIntentService.withdraw(virtualIntent);
264 // Wait for the both intents to go into a WITHDRAWN state.
265 try {
266 if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
267 fail("Failed to wait for intent to get withdrawn.");
268 }
269 } catch (InterruptedException e) {
270 fail("Semaphore exception during intent withdrawal." + e.getMessage());
271 }
272
273 // Test the getIntentState() method
274 assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
275 vnetIntentService.getIntentState(virtualIntent.key()));
276
277 // Test the purge() method.
278 vnetIntentService.purge(virtualIntent);
279 // Wait for the both intents to be removed/purged.
280 try {
281 if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
282 fail("Failed to wait for intent to get purged.");
283 }
284 } catch (InterruptedException e) {
285 fail("Semaphore exception during intent purging." + e.getMessage());
286 }
287
288 }
289
290 /**
291 * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
292 * isLocal() methods.
293 */
294 @Test
295 public void testGetIntents() {
296 VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
297
298 Key intentKey = Key.of("test", APP_ID);
299
300 List<Constraint> constraints = new ArrayList<>();
301 constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
302
303 VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
304 .networkId(virtualNetwork.id())
305 .key(intentKey)
306 .appId(APP_ID)
307 .ingressPoint(cp1)
308 .egressPoint(cp5)
309 .constraints(constraints)
310 .build();
311 // Test the submit() method.
312 vnetIntentService.submit(virtualIntent);
313
314 // Wait for the both intents to go into an INSTALLED state.
315 try {
316 if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
317 fail("Failed to wait for intent to get installed.");
318 }
319 } catch (InterruptedException e) {
320 fail("Semaphore exception during intent installation." + e.getMessage());
321 }
322
323 // Test the getIntents() method
324 assertEquals("The intents size did not match as expected.", 1,
325 Iterators.size(vnetIntentService.getIntents().iterator()));
326
327 // Test the getIntent() method
328 assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
329
330 // Test the getIntentData() method
331 assertEquals("The intent data size did not match as expected.", 1,
332 Iterators.size(vnetIntentService.getIntentData().iterator()));
333
334 // Test the getIntentCount() method
335 assertEquals("The intent count did not match as expected.", 1,
336 vnetIntentService.getIntentCount());
337
338 // Test the isLocal() method
339 assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
340
341 }
342
343 /**
344 * Test listener to listen for intent events.
345 */
346 private static class TestListener implements IntentListener {
347
348 @Override
349 public void event(IntentEvent event) {
350 switch (event.type()) {
351 case INSTALLED:
352 // Release one permit on the created semaphore since the Intent event was received.
Yoonseon Han9e043792017-05-03 15:43:33 -0700353// virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
Brian Stanke11f6d532016-07-05 16:17:59 -0400354 created.release();
355 break;
356 case WITHDRAWN:
357 // Release one permit on the removed semaphore since the Intent event was received.
Yoonseon Han9e043792017-05-03 15:43:33 -0700358// virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
Brian Stanke11f6d532016-07-05 16:17:59 -0400359 withdrawn.release();
360 break;
361 case PURGED:
362 // Release one permit on the purged semaphore since the Intent event was received.
363 purged.release();
364 break;
365 default:
366 break;
367 }
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
389 private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
390 @Override
391 public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
392 return Lists.newArrayList(new MockInstallableIntent());
393 }
394 }
395
396 private static class MockInstallableIntent extends FlowRuleIntent {
397
398 public MockInstallableIntent() {
Ray Milkey39f78b62018-01-05 15:17:37 -0800399 super(APP_ID, null, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)),
400 Collections.emptyList(), PathIntent.ProtectionType.PRIMARY, null);
Brian Stanke11f6d532016-07-05 16:17:59 -0400401 }
402 }
Yoonseon Han9e043792017-05-03 15:43:33 -0700403
404// private void addOrUpdateIntent(Intent intent, IntentState state) {
405// checkNotNull(intent, "Intent cannot be null");
406// IntentData intentData = intentStore.(intent.key());
407// if (intentData == null) {
408// intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
409// } else {
410// intentData = new IntentData(intent, state, intentData.version());
411// }
412// intentKeyIntentDataMap.put(intent.key(), intentData);
413// }
Brian Stanke11f6d532016-07-05 16:17:59 -0400414}