blob: 55232d10b4eea1a5bce98dbc20e42170fbe7a92e [file] [log] [blame]
/*
* 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.WorkPartitionService;
import org.onosproject.net.intent.WorkPartitionServiceAdapter;
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.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 IdGenerator idGenerator = new MockIdGenerator();
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();
Intent.unbindIdGenerator(idGenerator);
Intent.bindIdGenerator(idGenerator);
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);
Intent.unbindIdGenerator(idGenerator);
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());
}
}
}