/* * Copyright 2016-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.incubator.net.virtual.impl; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.onlab.junit.TestUtils; import org.onlab.osgi.ServiceDirectory; import org.onlab.osgi.TestServiceDirectory; import org.onlab.rest.BaseResource; import org.onosproject.TestApplicationId; import org.onosproject.common.event.impl.TestEventDispatcher; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.core.CoreServiceAdapter; import org.onosproject.core.IdGenerator; import org.onosproject.incubator.net.virtual.TenantId; import org.onosproject.incubator.net.virtual.VirtualDevice; import org.onosproject.incubator.net.virtual.VirtualLink; import org.onosproject.incubator.net.virtual.VirtualNetwork; import org.onosproject.incubator.net.virtual.VirtualNetworkIntent; import org.onosproject.incubator.net.virtual.VirtualNetworkStore; import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DefaultPort; import org.onosproject.net.EncapsulationType; import org.onosproject.net.Link; import org.onosproject.net.NetTestTools; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.TestDeviceParams; import org.onosproject.net.intent.Constraint; import org.onosproject.net.intent.FakeIntentManager; import org.onosproject.net.intent.FlowRuleIntent; import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.IntentCompiler; import org.onosproject.net.intent.IntentEvent; import org.onosproject.net.intent.IntentExtensionService; import org.onosproject.net.intent.IntentListener; import org.onosproject.net.intent.IntentService; import org.onosproject.net.intent.IntentState; import org.onosproject.net.intent.IntentTestsMocks; import org.onosproject.net.intent.Key; import org.onosproject.net.intent.MockIdGenerator; import org.onosproject.net.intent.TestableIntentService; import org.onosproject.net.intent.WorkPartitionService; import org.onosproject.net.intent.WorkPartitionServiceAdapter; import org.onosproject.net.intent.constraint.EncapsulationConstraint; import org.onosproject.store.service.TestStorageService; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.*; /** * Junit tests for VirtualNetworkIntentService. */ @Ignore("deprecated prototype implementation") public class VirtualNetworkIntentManagerTest extends TestDeviceParams { private final String tenantIdValue1 = "TENANT_ID1"; private static final ApplicationId APP_ID = new TestApplicationId("MyAppId"); private ConnectPoint cp1; private ConnectPoint cp2; private ConnectPoint cp3; private ConnectPoint cp4; private ConnectPoint cp5; private ConnectPoint cp6; private VirtualLink link1; private VirtualLink link2; private VirtualLink link3; private VirtualLink link4; private VirtualLink link5; private VirtualLink link6; private VirtualNetworkManager manager; private static DistributedVirtualNetworkStore virtualNetworkManagerStore; private CoreService coreService; private TestableIntentService intentService = new FakeIntentManager(); private VirtualNetworkIntentManager vnetIntentService; private TestIntentCompiler compiler = new TestIntentCompiler(); private IntentExtensionService intentExtensionService; private WorkPartitionService workPartitionService; private ServiceDirectory testDirectory; private TestListener listener = new TestListener(); private static final int MAX_WAIT_TIME = 5; private static final int MAX_PERMITS = 1; private static Semaphore created; private static Semaphore withdrawn; private static Semaphore purged; @Before public void setUp() throws Exception { virtualNetworkManagerStore = new DistributedVirtualNetworkStore(); coreService = new VirtualNetworkIntentManagerTest.TestCoreService(); MockIdGenerator.cleanBind(); TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService); TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService()); virtualNetworkManagerStore.activate(); manager = new VirtualNetworkManager(); manager.store = virtualNetworkManagerStore; NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); manager.intentService = intentService; intentService.addListener(listener); // Register a compiler and an installer both setup for success. intentExtensionService = intentService; intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler); created = new Semaphore(0, true); withdrawn = new Semaphore(0, true); purged = new Semaphore(0, true); workPartitionService = new WorkPartitionServiceAdapter(); testDirectory = new TestServiceDirectory() .add(VirtualNetworkStore.class, virtualNetworkManagerStore) .add(IntentService.class, intentService) .add(WorkPartitionService.class, workPartitionService); BaseResource.setServiceDirectory(testDirectory); TestUtils.setField(manager, "serviceDirectory", testDirectory); manager.activate(); } @After public void tearDown() { virtualNetworkManagerStore.deactivate(); manager.deactivate(); NetTestTools.injectEventDispatcher(manager, null); MockIdGenerator.unbind(); intentService.removeListener(listener); created = null; withdrawn = null; purged = null; } /** * Method to create the virtual network for further testing. * * @return virtual network */ private VirtualNetwork setupVirtualNetworkTopology() { manager.registerTenantId(TenantId.tenantId(tenantIdValue1)); VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1)); VirtualDevice virtualDevice1 = manager.createVirtualDevice(virtualNetwork.id(), DID1); VirtualDevice virtualDevice2 = manager.createVirtualDevice(virtualNetwork.id(), DID2); VirtualDevice virtualDevice3 = manager.createVirtualDevice(virtualNetwork.id(), DID3); VirtualDevice virtualDevice4 = manager.createVirtualDevice(virtualNetwork.id(), DID4); Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true); cp1 = new ConnectPoint(virtualDevice1.id(), port1.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1); Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true); cp2 = new ConnectPoint(virtualDevice1.id(), port2.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2); Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true); cp3 = new ConnectPoint(virtualDevice2.id(), port3.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3); Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true); cp4 = new ConnectPoint(virtualDevice2.id(), port4.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4); Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true); cp5 = new ConnectPoint(virtualDevice3.id(), port5.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5); Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true); cp6 = new ConnectPoint(virtualDevice3.id(), port6.number()); manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6); link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3); virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE); link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1); virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE); link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5); virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE); link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4); virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE); vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id()); vnetIntentService.intentService = intentService; vnetIntentService.store = virtualNetworkManagerStore; vnetIntentService.partitionService = workPartitionService; return virtualNetwork; } /** * Tests the submit(), withdraw(), and purge() methods. */ @Test public void testCreateAndRemoveIntent() { VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(); Key intentKey = Key.of("test", APP_ID); List<Constraint> constraints = new ArrayList<>(); constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN)); VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder() .networkId(virtualNetwork.id()) .key(intentKey) .appId(APP_ID) .ingressPoint(cp1) .egressPoint(cp5) .constraints(constraints) .build(); // Test the submit() method. vnetIntentService.submit(virtualIntent); // Wait for the both intents to go into an INSTALLED state. try { if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { fail("Failed to wait for intent to get installed."); } } catch (InterruptedException e) { fail("Semaphore exception during intent installation." + e.getMessage()); } // Test the getIntentState() method assertEquals("The intent state did not match as expected.", IntentState.INSTALLED, vnetIntentService.getIntentState(virtualIntent.key())); // Test the withdraw() method. vnetIntentService.withdraw(virtualIntent); // Wait for the both intents to go into a WITHDRAWN state. try { if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { fail("Failed to wait for intent to get withdrawn."); } } catch (InterruptedException e) { fail("Semaphore exception during intent withdrawal." + e.getMessage()); } // Test the getIntentState() method assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN, vnetIntentService.getIntentState(virtualIntent.key())); // Test the purge() method. vnetIntentService.purge(virtualIntent); // Wait for the both intents to be removed/purged. try { if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { fail("Failed to wait for intent to get purged."); } } catch (InterruptedException e) { fail("Semaphore exception during intent purging." + e.getMessage()); } } /** * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(), * isLocal() methods. */ @Test public void testGetIntents() { VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(); Key intentKey = Key.of("test", APP_ID); List<Constraint> constraints = new ArrayList<>(); constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN)); VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder() .networkId(virtualNetwork.id()) .key(intentKey) .appId(APP_ID) .ingressPoint(cp1) .egressPoint(cp5) .constraints(constraints) .build(); // Test the submit() method. vnetIntentService.submit(virtualIntent); // Wait for the both intents to go into an INSTALLED state. try { if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) { fail("Failed to wait for intent to get installed."); } } catch (InterruptedException e) { fail("Semaphore exception during intent installation." + e.getMessage()); } // Test the getIntents() method assertEquals("The intents size did not match as expected.", 1, Iterators.size(vnetIntentService.getIntents().iterator())); // Test the getIntent() method assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key())); // Test the getIntentData() method assertEquals("The intent data size did not match as expected.", 1, Iterators.size(vnetIntentService.getIntentData().iterator())); // Test the getIntentCount() method assertEquals("The intent count did not match as expected.", 1, vnetIntentService.getIntentCount()); // Test the isLocal() method assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key())); } /** * Test listener to listen for intent events. */ private static class TestListener implements IntentListener { @Override public void event(IntentEvent event) { switch (event.type()) { case INSTALLED: // Release one permit on the created semaphore since the Intent event was received. virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED); created.release(); break; case WITHDRAWN: // Release one permit on the removed semaphore since the Intent event was received. virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN); withdrawn.release(); break; case PURGED: // Release one permit on the purged semaphore since the Intent event was received. purged.release(); break; default: break; } } } /** * Core service test class. */ private class TestCoreService extends CoreServiceAdapter { @Override public IdGenerator getIdGenerator(String topic) { return new IdGenerator() { private AtomicLong counter = new AtomicLong(0); @Override public long getNewId() { return counter.getAndIncrement(); } }; } } private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> { @Override public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) { return Lists.newArrayList(new MockInstallableIntent()); } } private static class MockInstallableIntent extends FlowRuleIntent { public MockInstallableIntent() { super(APP_ID, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)), Collections.emptyList()); } } }