[ONOS-6248] VPLS refactoring
Change-Id: I8ffb2199ca108ad8dfe271681068636fc4af2a40
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java
deleted file mode 100644
index e5844fb..0000000
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.vpls;
-
-import com.google.common.collect.SetMultimap;
-import org.onlab.packet.VlanId;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.EncapsulationType;
-import org.onosproject.vpls.config.VplsConfigService;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Test adapter for VPLS configuration service.
- */
-public class VplsConfigServiceAdapter implements VplsConfigService {
- @Override
- public void addVpls(String vplsName, Set<String> ifaces, String encap) {}
-
- @Override
- public void removeVpls(String vplsName) {}
-
- @Override
- public void addIface(String vplsName, String iface) {}
-
- @Override
- public void setEncap(String vplsName, String encap) {}
-
- @Override
- public EncapsulationType encap(String vplsName) {
- return null;
- }
-
- @Override
- public void removeIface(String iface) {}
-
- @Override
- public void cleanVplsConfig() {}
-
- @Override
- public Set<String> vplsAffectedByApi() {
- return null;
- }
-
- @Override
- public Set<Interface> allIfaces() {
- return null;
- }
-
- @Override
- public Set<Interface> ifaces() {
- return null;
- }
-
- @Override
- public Set<Interface> ifaces(String vplsName) {
- return null;
- }
-
- @Override
- public Set<String> vplsNames() {
- return null;
- }
-
- @Override
- public Set<String> vplsNamesOld() {
- return null;
- }
-
- @Override
- public SetMultimap<String, Interface> ifacesByVplsName() {
- return null;
- }
-
- @Override
- public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan, ConnectPoint connectPoint) {
- return null;
- }
-
- @Override
- public Map<String, EncapsulationType> encapByVplsName() {
- return null;
- }
-}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java
new file mode 100644
index 0000000..7ee9292
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java
@@ -0,0 +1,537 @@
+/*
+ * 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.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentServiceAdapter;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.intent.VplsIntentUtility;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.EncapsulationType.NONE;
+import static org.onosproject.net.EncapsulationType.VLAN;
+
+/**
+ * Tests for {@link VplsIntentUtility}.
+ */
+public class VplsIntentTest extends VplsTest {
+
+ private Set<Host> hostsAvailable;
+ private IntentService intentService;
+ private InterfaceService interfaceService;
+
+ @Before
+ public void setUp() throws Exception {
+ idGenerator = new TestIdGenerator();
+ Intent.unbindIdGenerator(idGenerator);
+ Intent.bindIdGenerator(idGenerator);
+ hostsAvailable = Sets.newHashSet();
+ intentService = new TestIntentService();
+ interfaceService = createMock(InterfaceService.class);
+ interfaceService.addListener(anyObject(InterfaceListener.class));
+ expectLastCall().anyTimes();
+ addIfaceConfig();
+ }
+
+ @After
+ public void tearDown() {
+ Intent.unbindIdGenerator(idGenerator);
+ }
+
+ /**
+ * Creates the interface configuration:
+ * On devices 1 and 2 is configured an interface on port 1 with vlan 100.
+ * On device 3 is configured an interface on port 3 with no vlan.
+ * On devices 3 and 4 is configured an interface on port 1 with vlan 200.
+ * On device 4 is an interface configured on port 2 with vlan 400.
+ * On device 5 are configured two interfaces on port 1 and 2 with no vlan.
+ * On device 5 and 6 is configured an interface on port 1 with vlan 300.
+ */
+ private void addIfaceConfig() {
+ Set<Interface> interfaces = ImmutableSet.copyOf(AVAILABLE_INTERFACES);
+ Set<Interface> vlanOneSet = ImmutableSet.of(V100H1, V100H2);
+ Set<Interface> vlanTwoSet = ImmutableSet.of(V200H1, V200H2);
+ Set<Interface> vlanThreeSet = ImmutableSet.of(VNONEH1, VNONEH2);
+ Set<Interface> vlanFourSet = ImmutableSet.of(V400H1, VNONEH3);
+
+ AVAILABLE_INTERFACES.forEach(intf -> {
+ expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
+ .andReturn(Sets.newHashSet(intf)).anyTimes();
+ });
+ expect(interfaceService.getInterfacesByVlan(VLAN100))
+ .andReturn(vlanOneSet).anyTimes();
+ expect(interfaceService.getInterfacesByVlan(VLAN200))
+ .andReturn(vlanTwoSet).anyTimes();
+ expect(interfaceService.getInterfacesByVlan(VLAN300))
+ .andReturn(vlanThreeSet).anyTimes();
+ expect(interfaceService.getInterfacesByVlan(VLAN400))
+ .andReturn(vlanFourSet).anyTimes();
+ expect(interfaceService.getInterfacesByVlan(VlanId.NONE))
+ .andReturn(vlanFourSet).anyTimes();
+ expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+
+ replay(interfaceService);
+ }
+
+ /**
+ * Seven ports are configured with VLANs, while three ports are not. No hosts are
+ * registered by the HostService.
+ *
+ * The first three ports have an interface configured on VPLS 1,
+ * the other three on VPLS 2. Two ports are defined for VPLS 3, while
+ * the two remaining ports are configured on VPLS 4.
+ *
+ * The number of intents expected is 10: three for VPLS 1, three for VPLS 2,
+ * two for VPLS 3, two for VPLS 4. Eight MP2SP intents.
+ * Checks if the number of intents submitted to the intent framework is
+ * equal to the number of intents expected and if all intents are equivalent.
+ */
+ @Test
+ public void activateNoHosts() {
+ List<Intent> expectedIntents = Lists.newArrayList();
+ Set<FilteredConnectPoint> fcPoints;
+ Set<Interface> interfaces;
+
+ interfaces = ImmutableSet.of(V100H1, V200H1, V300H1);
+ VplsData vplsData = createVplsData(VPLS1, VLAN, interfaces);
+ Set<Intent> brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ brcIntents.forEach(intentService::submit);
+ fcPoints = buildFCPoints(interfaces);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
+
+ checkIntents(expectedIntents);
+
+ interfaces = ImmutableSet.of(V100H2, V200H2, V300H2);
+ vplsData = createVplsData(VPLS2, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ brcIntents.forEach(intentService::submit);
+ fcPoints = buildFCPoints(interfaces);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
+
+ checkIntents(expectedIntents);
+
+ interfaces = ImmutableSet.of(VNONEH1, VNONEH2);
+ vplsData = createVplsData(VPLS3, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ brcIntents.forEach(intentService::submit);
+ fcPoints = buildFCPoints(interfaces);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
+
+ checkIntents(expectedIntents);
+
+ interfaces = ImmutableSet.of(V400H1, VNONEH3);
+ vplsData = createVplsData(VPLS4, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ brcIntents.forEach(intentService::submit);
+ fcPoints = buildFCPoints(interfaces);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
+
+ checkIntents(expectedIntents);
+ }
+
+
+
+ /**
+ * Ten ports are configured with VLANs and ten hosts are registered by the
+ * HostService.
+ *
+ * The first three ports have an interface configured on VPLS 1,
+ * the other three on VPLS 2, two on VPLS3 and two on VPLS4.
+ *
+ * The number of intents expected is twenty: six
+ * for VPLS 1, six for VPLS 2. four for VPLS 3, four for VPLS 4.
+ * That is ten sp2mp intents, ten mp2sp intents. For VPLS 1
+ * IPs are added to demonstrate this doesn't influence the number of intents
+ * created. Checks if the number of intents submitted to the intent
+ * framework is equal to the number of intents expected and if all intents
+ * are equivalent.
+ */
+ @Test
+ public void tenInterfacesConfiguredHostsPresent() {
+ hostsAvailable.addAll(AVAILABLE_HOSTS);
+
+ List<Intent> expectedIntents = Lists.newArrayList();
+ Set<FilteredConnectPoint> fcPoints;
+ Set<Host> hosts;
+ Set<Interface> interfaces;
+ VplsData vplsData;
+ Set<Intent> brcIntents;
+ Set<Intent> uniIntents;
+
+ interfaces = ImmutableSet.of(V100H1, V200H1, V300H1);
+ fcPoints = buildFCPoints(interfaces);
+ hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
+ vplsData = createVplsData(VPLS1, VLAN, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+ brcIntents.forEach(intentService::submit);
+ uniIntents.forEach(intentService::submit);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
+ expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
+
+ interfaces = ImmutableSet.of(V100H2, V200H2, V300H2);
+ fcPoints = buildFCPoints(interfaces);
+ hosts = ImmutableSet.of(V100HOST2, V200HOST2, V300HOST2);
+ vplsData = createVplsData(VPLS2, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+ brcIntents.forEach(intentService::submit);
+ uniIntents.forEach(intentService::submit);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
+ expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS2, NONE));
+
+ interfaces = ImmutableSet.of(VNONEH1, VNONEH2);
+ fcPoints = buildFCPoints(interfaces);
+ hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
+ vplsData = createVplsData(VPLS3, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+ brcIntents.forEach(intentService::submit);
+ uniIntents.forEach(intentService::submit);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
+ expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
+
+ interfaces = ImmutableSet.of(V400H1, VNONEH3);
+ fcPoints = buildFCPoints(interfaces);
+ hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
+ vplsData = createVplsData(VPLS4, NONE, interfaces);
+ brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+ uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+ brcIntents.forEach(intentService::submit);
+ uniIntents.forEach(intentService::submit);
+ expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
+ expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
+
+ checkIntents(expectedIntents);
+ }
+
+ /**
+ * Generates a list of the expected sp2mp intents for a VPLS.
+ *
+ * @param fcPoints the filtered connect point
+ * @param name the name of the VPLS
+ * @param encap the encapsulation type
+ * @return the list of expected sp2mp intents for the given VPLS
+ */
+ private List<SinglePointToMultiPointIntent>
+ generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name, EncapsulationType encap) {
+ List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
+
+ fcPoints.forEach(point -> {
+ Set<FilteredConnectPoint> otherPoints =
+ fcPoints.stream()
+ .filter(fcp -> !fcp.equals(point))
+ .collect(Collectors.toSet());
+
+ Key brckey = buildKey(VplsIntentUtility.PREFIX_BROADCAST,
+ point.connectPoint(),
+ name,
+ MacAddress.BROADCAST);
+
+ intents.add(buildBrcIntent(brckey, point, otherPoints, encap));
+ });
+
+ return intents;
+ }
+
+ /**
+ * Generates a list of expected mp2sp intents for a given VPLS.
+ *
+ * @param fcPoints the filtered connect point
+ * @param hosts the hosts
+ * @param name the name of the VPLS
+ * @param encap the encapsulation type
+ * @return the list of expected mp2sp intents for the given VPLS
+ */
+ private List<MultiPointToSinglePointIntent>
+ generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts,
+ String name, EncapsulationType encap) {
+ List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
+
+ hosts.forEach(host -> {
+ FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
+
+ Set<FilteredConnectPoint> otherPoints =
+ fcPoints.stream()
+ .filter(fcp -> !fcp.equals(hostPoint))
+ .collect(Collectors.toSet());
+
+ Key uniKey = buildKey(VplsIntentUtility.PREFIX_UNICAST,
+ host.location(), name, host.mac());
+
+ intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host, encap));
+ });
+
+ return intents;
+ }
+
+ /**
+ * Checks if the number of intents submitted to the intent framework is equal
+ * to the number of intents expected and if all intents are equivalent.
+ *
+ * @param intents the list of intents expected
+ */
+ private void checkIntents(List<Intent> intents) {
+ assertEquals("The number of intents submitted differs from the number" +
+ " of intents expected. ",
+ intents.size(), intentService.getIntentCount());
+ for (Intent intentOne : intents) {
+ boolean found = false;
+ for (Intent intentTwo : intentService.getIntents()) {
+ if (intentOne.key().equals(intentTwo.key())) {
+ found = true;
+ assertTrue(format("The intent submitted is different from" +
+ " the intent expected. %s %s",
+ intentOne, intentTwo),
+ IntentUtils.intentsAreEqual(intentOne, intentTwo));
+ break;
+ }
+ }
+ assertTrue("The intent submitted is not equal to any of the expected" +
+ " intents. ", found);
+ }
+ }
+
+ /**
+ * Builds a broadcast intent.
+ *
+ * @param key the key to identify the intent
+ * @param src the ingress connect point
+ * @param dsts the egress connect points
+ * @return the generated single-point to multi-point intent
+ */
+ private SinglePointToMultiPointIntent buildBrcIntent(Key key,
+ FilteredConnectPoint src,
+ Set<FilteredConnectPoint> dsts,
+ EncapsulationType encap) {
+ SinglePointToMultiPointIntent.Builder intentBuilder;
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthDst(MacAddress.BROADCAST)
+ .build();
+ intentBuilder = SinglePointToMultiPointIntent.builder()
+ .appId(APPID)
+ .key(key)
+ .selector(selector)
+ .filteredIngressPoint(src)
+ .filteredEgressPoints(dsts)
+ .constraints(VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT)
+ .priority(PRIORITY_OFFSET);
+ VplsIntentUtility.setEncap(intentBuilder,
+ VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT,
+ encap);
+
+ return intentBuilder.build();
+ }
+
+ /**
+ * Builds a unicast intent.
+ *
+ * @param key the key to identify the intent
+ * @param srcs the ingress connect points
+ * @param dst the egress connect point
+ * @param host the destination Host
+ * @return the generated multi-point to single-point intent
+ */
+ private MultiPointToSinglePointIntent buildUniIntent(Key key,
+ Set<FilteredConnectPoint> srcs,
+ FilteredConnectPoint dst,
+ Host host,
+ EncapsulationType encap) {
+ MultiPointToSinglePointIntent.Builder intentBuilder;
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthDst(host.mac())
+ .build();
+ intentBuilder = MultiPointToSinglePointIntent.builder()
+ .appId(APPID)
+ .key(key)
+ .selector(selector)
+ .filteredIngressPoints(srcs)
+ .filteredEgressPoint(dst)
+ .constraints(VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT)
+ .priority(PRIORITY_OFFSET);
+ VplsIntentUtility.setEncap(intentBuilder,
+ VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT,
+ encap);
+
+ return intentBuilder.build();
+ }
+
+ /**
+ * Returns the filtered connect point associated to a given host.
+ *
+ * @param host the target host
+ * @param fcps the filtered connected points
+ * @return the filtered connect point associated to the given host; null
+ * otherwise
+ */
+ private FilteredConnectPoint getHostPoint(Host host,
+ Set<FilteredConnectPoint> fcps) {
+ return fcps.stream()
+ .filter(fcp -> fcp.connectPoint().equals(host.location()))
+ .filter(fcp -> {
+ VlanIdCriterion vlanCriterion =
+ (VlanIdCriterion) fcp.trafficSelector().
+ getCriterion(Criterion.Type.VLAN_VID);
+ return vlanCriterion == null ||
+ vlanCriterion.vlanId().equals(host.vlan());
+ })
+ .findFirst()
+ .orElse(null);
+ }
+
+ /**
+ * Computes a set of filtered connect points from a list of given interfaces.
+ *
+ * @param interfaces the interfaces to compute
+ * @return the set of filtered connect points
+ */
+ private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
+ // Build all filtered connected points in the VPLS
+ return interfaces
+ .stream()
+ .map(intf -> {
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder();
+ if (!intf.vlan().equals(VlanId.NONE)) {
+ selectorBuilder.matchVlanId(intf.vlan());
+ }
+ return new FilteredConnectPoint(intf.connectPoint(),
+ selectorBuilder.build());
+ })
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * Builds an intent Key either for a single-point to multi-point or
+ * multi-point to single-point intent, based on a prefix that defines
+ * the intent type, the connection point representing the source or the
+ * destination and the VLAN Id representing the VPLS.
+ *
+ * @param prefix the key prefix
+ * @param cPoint the ingress/egress connect point
+ * @param vplsName the VPLS name
+ * @param hostMac the ingress/egress MAC address
+ * @return the key to identify the intent
+ */
+ private Key buildKey(String prefix,
+ ConnectPoint cPoint,
+ String vplsName,
+ MacAddress hostMac) {
+ String keyString = vplsName +
+ DASH +
+ prefix +
+ DASH +
+ cPoint.deviceId() +
+ DASH +
+ cPoint.port() +
+ DASH +
+ hostMac;
+
+ return Key.of(keyString, APPID);
+ }
+
+ /**
+ * Creates VPLS data by given name, encapsulation type and network
+ * interfaces.
+ *
+ * @param name the VPLS name
+ * @param encap the encapsulation type
+ * @param interfaces the network interfaces
+ * @return the VPLS data
+ */
+ private VplsData createVplsData(String name, EncapsulationType encap,
+ Set<Interface> interfaces) {
+ VplsData vplsData = VplsData.of(name, encap);
+ vplsData.addInterfaces(interfaces);
+ return vplsData;
+ }
+
+ /**
+ * Represents a fake IntentService class that allows to store and retrieve
+ * intents without implementing the IntentService logic.
+ */
+ private class TestIntentService extends IntentServiceAdapter {
+ private Map<Key, Intent> intents;
+
+ public TestIntentService() {
+ intents = Maps.newHashMap();
+ }
+
+ @Override
+ public void submit(Intent intent) {
+ intents.put(intent.key(), intent);
+ }
+
+ @Override
+ public long getIntentCount() {
+ return intents.size();
+ }
+
+ @Override
+ public Iterable<Intent> getIntents() {
+ return intents.values();
+ }
+
+ @Override
+ public Intent getIntent(Key intentKey) {
+ for (Intent intent : intents.values()) {
+ if (intent.key().equals(intentKey)) {
+ return intent;
+ }
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
new file mode 100644
index 0000000..67128db
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2017-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.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.api.VplsOperationService;
+import org.onosproject.vpls.store.VplsStoreEvent;
+
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.EncapsulationType.*;
+import static org.onosproject.vpls.api.VplsData.VplsState.*;
+
+/**
+ * Test for {@link VplsManager}
+ */
+public class VplsManagerTest extends VplsTest {
+ private VplsManager vplsManager;
+ private TestVplsStore vplsStore = new TestVplsStore();
+ private TestHostService hostService = new TestHostService();
+ private TestInterfaceService interfaceService = new TestInterfaceService();
+ private TestVplsOperationService vplsOperationService = new TestVplsOperationService();
+
+ @Before
+ public void setup() {
+ vplsManager = new VplsManager();
+ vplsManager.hostService = hostService;
+ vplsManager.vplsStore = vplsStore;
+ vplsManager.operationService = vplsOperationService;
+ vplsManager.interfaceService = interfaceService;
+ vplsStore.clear();
+ vplsOperationService.clear();
+ vplsManager.activate();
+ }
+
+ @After
+ public void tearDown() {
+ vplsManager.deactivate();
+ }
+
+ /**
+ * Creates VPLS by given name and encapsulation type.
+ */
+ @Test
+ public void testCreateVpls() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ assertEquals(VPLS1, vplsData.name());
+ assertEquals(NONE, vplsData.encapsulationType());
+
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertEquals(vplsData.state(), ADDING);
+ }
+
+ /**
+ * Gets VPLS by VPLS name.
+ */
+ @Test
+ public void testGetVpls() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.state(ADDED);
+ vplsStore.addVpls(vplsData);
+
+ VplsData result = vplsManager.getVpls(VPLS1);
+ assertEquals(vplsData, result);
+
+ result = vplsManager.getVpls(VPLS2);
+ assertNull(result);
+ }
+
+ /**
+ * Removes a VPLS.
+ */
+ @Test
+ public void testRemoveVpls() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.removeVpls(vplsData);
+ assertEquals(vplsData.state(), REMOVING);
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNull(vplsData);
+ Collection<VplsData> allVpls = vplsStore.getAllVpls();
+ assertEquals(0, allVpls.size());
+ }
+
+ /**
+ * Removes all VPLS.
+ */
+ @Test
+ public void testRemoveAllVpls() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.state(ADDED);
+ vplsStore.addVpls(vplsData);
+
+ vplsData = VplsData.of(VPLS2, VLAN);
+ vplsData.state(ADDED);
+ vplsStore.addVpls(vplsData);
+
+ vplsManager.removeAllVpls();
+ assertEquals(0, vplsStore.getAllVpls().size());
+ }
+
+ /**
+ * Adds network interfaces one by one to a VPLS.
+ */
+ @Test
+ public void testAddInterface() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterface(vplsData, V100H1);
+ vplsManager.addInterface(vplsData, V100H2);
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+ assertEquals(vplsData.state(), UPDATING);
+ assertEquals(2, vplsData.interfaces().size());
+ assertTrue(vplsData.interfaces().contains(V100H1));
+ assertTrue(vplsData.interfaces().contains(V100H2));
+ }
+
+ /**
+ * Adds network interfaces to a VPLS.
+ */
+ @Test
+ public void testAddInterfaces() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+ assertEquals(vplsData.state(), UPDATING);
+ assertEquals(2, vplsData.interfaces().size());
+ assertTrue(vplsData.interfaces().contains(V100H1));
+ assertTrue(vplsData.interfaces().contains(V100H2));
+ }
+
+ /**
+ * Removes network interfaces one by one from a VPLS.
+ */
+ @Test
+ public void testRemoveInterface() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterface(vplsData, V100H1);
+ vplsManager.addInterface(vplsData, V100H2);
+ vplsManager.removeInterface(vplsData, V100H1);
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+ assertEquals(vplsData.state(), UPDATING);
+ assertEquals(1, vplsData.interfaces().size());
+ assertTrue(vplsData.interfaces().contains(V100H2));
+ }
+
+ /**
+ * Removes network interfaces from a VPLS.
+ */
+ @Test
+ public void testRemoveInterfaces() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterface(vplsData, V100H1);
+ vplsManager.addInterface(vplsData, V100H2);
+ vplsManager.removeInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+ assertEquals(vplsData.state(), UPDATING);
+ assertEquals(0, vplsData.interfaces().size());
+ }
+
+ /**
+ * Sets encapsulation type for a VPLS.
+ */
+ @Test
+ public void testSetEncapsulationType() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.setEncapsulationType(vplsData, EncapsulationType.VLAN);
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+ assertEquals(vplsData.state(), UPDATING);
+ assertEquals(vplsData.encapsulationType(), EncapsulationType.VLAN);
+ }
+
+ /**
+ * Adds hosts to a VPLS.
+ */
+ @Test
+ public void testAddHost() {
+ VplsData vplsData = VplsData.of(VPLS1, NONE);
+ vplsData.addInterface(V100H1);
+ vplsData.state(ADDED);
+ vplsStore.addVpls(vplsData);
+
+ HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+ hostService.postHostEvent(hostEvent);
+
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+
+ assertEquals(vplsData.state(), UPDATING);
+ }
+
+ /**
+ * Removes hosts from a VPLS.
+ */
+ @Test
+ public void testRemoveHost() {
+ VplsData vplsData = VplsData.of(VPLS1, NONE);
+ vplsData.addInterface(V100H1);
+ vplsData.state(ADDED);
+ vplsStore.addVpls(vplsData);
+
+ HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+ hostService.postHostEvent(hostEvent);
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertNotNull(vplsData);
+
+ assertEquals(vplsData.state(), UPDATING);
+ }
+
+ /**
+ * Pass different VPLS store event to store delegate.
+ * Include these cases:
+ * <ul>
+ * <li>VPLS added</li>
+ * <li>VPLS updated</li>
+ * <li>VPLS state updated</li>
+ * <li>VPLS removed</li>
+ * </ul>
+ */
+ @Test
+ public void testStoreDelegate() {
+ // Add
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ VplsStoreEvent event = new VplsStoreEvent(VplsStoreEvent.Type.ADD, vplsData);
+ vplsStore.delegate().notify(event);
+
+ VplsOperation vplsOperation = vplsOperationService.operation();
+ assertEquals(vplsOperation.op(), VplsOperation.Operation.ADD);
+ assertEquals(vplsOperation.vpls(), vplsData);
+ vplsOperationService.clear();
+
+ // Update info
+ vplsData.encapsulationType(EncapsulationType.VLAN);
+ vplsData.state(UPDATING);
+ event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+ vplsStore.delegate().notify(event);
+ vplsOperation = vplsOperationService.operation();
+ assertEquals(vplsOperation.op(), VplsOperation.Operation.UPDATE);
+ assertEquals(vplsOperation.vpls(), vplsData);
+ vplsOperationService.clear();
+
+ // Update state (no operation)
+ vplsData.state(VplsData.VplsState.ADDED);
+ event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+ vplsStore.delegate().notify(event);
+ vplsOperation = vplsOperationService.operation();
+ assertNull(vplsOperation);
+ vplsOperationService.clear();
+
+ // Remove
+ event = new VplsStoreEvent(VplsStoreEvent.Type.REMOVE, vplsData);
+ vplsStore.delegate().notify(event);
+ vplsOperation = vplsOperationService.operation();
+ assertEquals(vplsOperation.op(), VplsOperation.Operation.REMOVE);
+ assertEquals(vplsOperation.vpls(), vplsData);
+ vplsOperationService.clear();
+ }
+
+ /**
+ * Trigger host event listener by HOST_ADDED event.
+ */
+ @Test
+ public void hostAddEventTest() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterface(vplsData, V100H1);
+ HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+ hostService.postHostEvent(hostEvent);
+
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertEquals(UPDATING, vplsData.state());
+ }
+
+ /**
+ * Trigger host event listener by HOST_REMOVED event.
+ */
+ @Test
+ public void hostRemoveEventTest() {
+ VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+ vplsManager.addInterface(vplsData, V100H1);
+ HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+ hostService.postHostEvent(hostEvent);
+
+ vplsData = vplsStore.getVpls(VPLS1);
+ assertEquals(UPDATING, vplsData.state());
+ }
+
+ /**
+ * Test VPLS operation service.
+ * Stores last operation submitted by VPLS manager.
+ */
+ class TestVplsOperationService implements VplsOperationService {
+ VplsOperation operation;
+
+ @Override
+ public void submit(VplsOperation vplsOperation) {
+ this.operation = vplsOperation;
+ }
+
+ /**
+ * Clears the VPLS operation.
+ */
+ public void clear() {
+ operation = null;
+ }
+
+ /**
+ * Gets the latest VPLS operation.
+ * @return the latest VPLS operation.
+ */
+ public VplsOperation operation() {
+ return operation;
+ }
+ }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
index 412e937..2acc871 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
@@ -17,8 +17,6 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import org.junit.After;
@@ -30,8 +28,6 @@
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceListener;
-import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
@@ -39,122 +35,26 @@
import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.EncapsulationType;
import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.HostServiceAdapter;
-import org.onosproject.net.provider.ProviderId;
+import org.onosproject.vpls.api.VplsData;
import java.util.Collection;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
/**
- * Tests the the {@link VplsNeighbourHandler} class.
+ * Tests the the {@link VplsNeighbourHandler}.
*/
-public class VplsNeighbourHandlerTest {
+public class VplsNeighbourHandlerTest extends VplsTest {
private static final String IFACES_NOT_EXPECTED =
"The interfaces reached by the packet are not equal to the " +
"interfaces expected.";
-
- private static final DeviceId DID1 = getDeviceId(1);
- private static final DeviceId DID2 = getDeviceId(2);
- private static final DeviceId DID3 = getDeviceId(3);
- private static final DeviceId DID4 = getDeviceId(4);
- private static final DeviceId DID5 = getDeviceId(5);
-
- private static final PortNumber P1 = PortNumber.portNumber(1);
- private static final PortNumber P2 = PortNumber.portNumber(2);
- private static final PortNumber P3 = PortNumber.portNumber(3);
-
- private static final ConnectPoint OF1P1 = new ConnectPoint(DID1, P1);
- private static final ConnectPoint OF2P1 = new ConnectPoint(DID2, P1);
- private static final ConnectPoint OF3P1 = new ConnectPoint(DID3, P1);
- private static final ConnectPoint OF4P1 = new ConnectPoint(DID4, P1);
- private static final ConnectPoint OF4P2 = new ConnectPoint(DID4, P2);
- private static final ConnectPoint OF4P3 = new ConnectPoint(DID4, P3);
- private static final ConnectPoint OF5P1 = new ConnectPoint(DID5, P1);
- private static final ConnectPoint OF5P2 = new ConnectPoint(DID5, P2);
- private static final ConnectPoint OF5P3 = new ConnectPoint(DID5, P3);
-
- private static final String VPLS1 = "vpls1";
- private static final String VPLS2 = "vpls2";
- private static final String VPLS3 = "vpls3";
- private static final String VPLS4 = "vpls4";
-
- private static final VlanId VLAN100 = VlanId.vlanId("100");
- private static final VlanId VLAN200 = VlanId.vlanId("200");
- private static final VlanId VLAN300 = VlanId.vlanId("300");
- private static final VlanId VLAN400 = VlanId.vlanId("400");
- private static final VlanId VLAN_NONE = VlanId.NONE;
-
- private static final Interface V100H1 =
- new Interface("v100h1", OF1P1, null, null, VLAN100);
- private static final Interface V100H2 =
- new Interface("v100h2", OF4P1, null, null, VLAN100);
- private static final Interface V200H1 =
- new Interface("v200h1", OF4P2, null, null, VLAN200);
- private static final Interface V200H2 =
- new Interface("v200h2", OF2P1, null, null, VLAN200);
- private static final Interface V300H1 =
- new Interface("v300h1", OF3P1, null, null, VLAN300);
- private static final Interface V400H1 =
- new Interface("v400h1", OF5P1, null, null, VLAN400);
- private static final Interface VNONEH1 =
- new Interface("vNoneh1", OF5P2, null, null, VLAN_NONE);
- private static final Interface VNONEH2 =
- new Interface("vNoneh2", OF5P3, null, null, VLAN_NONE);
- private static final Interface VNONEH3 =
- new Interface("vNoneh3", OF4P3, null, null, VLAN_NONE);
-
- private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
- private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
- private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
- private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
- private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
- private static final MacAddress MAC6 = MacAddress.valueOf("00:00:00:00:00:06");
- private static final MacAddress MAC7 = MacAddress.valueOf("00:00:00:00:00:07");
- private static final MacAddress MAC8 = MacAddress.valueOf("00:00:00:00:00:08");
- private static final MacAddress MAC9 = MacAddress.valueOf("00:00:00:00:00:09");
-
- private static final ProviderId PID = new ProviderId("of", "foo");
-
- private final Host v100Host1 = makeHost(MAC1, VLAN100, OF1P1);
- private final Host v100Host2 = makeHost(MAC2, VLAN100, OF4P1);
- private final Host v200Host1 = makeHost(MAC3, VLAN200, OF4P2);
- private final Host v200Host2 = makeHost(MAC5, VLAN200, OF2P1);
- private final Host v300Host1 = makeHost(MAC4, VLAN300, OF3P1);
- private final Host v400Host1 = makeHost(MAC6, VLAN400, OF5P1);
- private final Host vNoneHost1 = makeHost(MAC7, VLAN_NONE, OF5P2);
- private final Host vNoneHost2 = makeHost(MAC8, VLAN_NONE, OF5P3);
- private final Host vNoneHost3 = makeHost(MAC9, VLAN_NONE, OF4P3);
-
- private final Set<Host> availableHosts = ImmutableSet.of(v100Host1,
- v100Host2,
- v200Host1,
- v300Host1,
- v200Host2,
- v400Host1,
- vNoneHost1,
- vNoneHost2,
- vNoneHost3);
-
- private final Set<Interface> availableInterfaces =
- ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1,
- V400H1, VNONEH1, VNONEH2, VNONEH3);
-
private VplsNeighbourHandler vplsNeighbourHandler;
-
private HostService hostService;
/**
@@ -167,29 +67,46 @@
@Before
public void setUp() {
vplsNeighbourHandler = new VplsNeighbourHandler();
- SetMultimap<String, Interface> ifacesByVpls =
- HashMultimap.create();
- ifacesByVpls.put(VPLS1, V100H1);
- ifacesByVpls.put(VPLS1, V200H1);
- ifacesByVpls.put(VPLS1, V300H1);
- ifacesByVpls.put(VPLS2, V100H2);
- ifacesByVpls.put(VPLS2, V200H2);
- ifacesByVpls.put(VPLS3, VNONEH1);
- ifacesByVpls.put(VPLS3, VNONEH2);
- ifacesByVpls.put(VPLS4, V400H1);
- ifacesByVpls.put(VPLS4, VNONEH3);
- HashMap<String, EncapsulationType> encap = Maps.newHashMap();
- vplsNeighbourHandler.vplsConfigService =
- new TestVplsConfigService(ifacesByVpls, encap);
- vplsNeighbourHandler.interfaceService =
- new TestInterfaceService();
- vplsNeighbourHandler.neighbourService =
- new TestNeighbourService();
hostService = new TestHostService();
+ vplsNeighbourHandler.vplsStore = new TestVplsStore();
+ vplsNeighbourHandler.interfaceService = new TestInterfaceService();
+ vplsNeighbourHandler.neighbourService = new TestNeighbourService();
+ vplsNeighbourHandler.coreService = new TestCoreService();
+ vplsNeighbourHandler.configService = new TestConfigService();
+
+ // Init VPLS store
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V200H1, V300H1));
+ vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+ vplsData = VplsData.of(VPLS2);
+ vplsData.addInterfaces(ImmutableSet.of(V100H2, V200H2));
+ vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+ vplsData = VplsData.of(VPLS3);
+ vplsData.addInterfaces(ImmutableSet.of(VNONEH1, VNONEH2));
+ vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+ vplsData = VplsData.of(VPLS4);
+ vplsData.addInterfaces(ImmutableSet.of(V400H1, VNONEH3));
+ vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+ vplsNeighbourHandler.activate();
+
}
@After
public void tearDown() {
+ vplsNeighbourHandler.deactivate();
+ }
+
+ /**
+ * Registers neighbour handler to all available interfaces.
+ */
+ @Test
+ public void testConfigNeighbourHandler() {
+ vplsNeighbourHandler.configNeighbourHandler();
+ assertEquals(9, vplsNeighbourHandler.neighbourService.getHandlerRegistrations().size());
}
/**
@@ -200,21 +117,21 @@
public void vpls1RequestMessage() {
// Request messages from v100h1 (VPLS 1) should be received by v200h1 and v300h1
TestMessageContext requestMessage =
- makeBroadcastRequestContext(v100Host1);
+ makeBroadcastRequestContext(V100HOST1);
Set<Interface> expectInterfaces = ImmutableSet.of(V200H1, V300H1);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
// Request messages from v200h1 (VPLS 1) should be received by v100h1 and v300h1
- requestMessage = makeBroadcastRequestContext(v200Host1);
+ requestMessage = makeBroadcastRequestContext(V200HOST1);
expectInterfaces = ImmutableSet.of(V100H1, V300H1);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
// Request from v300h1 (VPLS 1) should be received by v100h1 and v200h1
- requestMessage = makeBroadcastRequestContext(v300Host1);
+ requestMessage = makeBroadcastRequestContext(V300HOST1);
expectInterfaces = ImmutableSet.of(V100H1, V200H1);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
}
@@ -226,15 +143,15 @@
public void vpls2RequestMessage() {
// Request messages from v100h2 (VPLS 2) should be received by v200h2
TestMessageContext requestMessage =
- makeBroadcastRequestContext(v100Host2);
+ makeBroadcastRequestContext(V100HOST2);
Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
// Request messages from v200h2 (VPLS 2) should be received by v100h2
- requestMessage = makeBroadcastRequestContext(v200Host2);
+ requestMessage = makeBroadcastRequestContext(V200HOST2);
expectInterfaces = ImmutableSet.of(V100H2);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
}
@@ -246,17 +163,17 @@
*/
@Test
public void vpls3RequestMessage() {
- // Request messages from vNoneHost1 (VPLS 3) should be received by vNoneHost2
+ // Request messages from VNONEHOST1 (VPLS 3) should be received by VNONEHOST2
TestMessageContext requestMessage =
- makeBroadcastRequestContext(vNoneHost1);
+ makeBroadcastRequestContext(VNONEHOST1);
Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
// Request messages from vNoneh2 (VPLS 3) should be received by vNoneh1
- requestMessage = makeBroadcastRequestContext(vNoneHost2);
+ requestMessage = makeBroadcastRequestContext(VNONEHOST2);
expectInterfaces = ImmutableSet.of(VNONEH1);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
}
@@ -268,17 +185,17 @@
*/
@Test
public void vpls4RequestMessage() {
- // Request messages from v400Host1 (VPLS 4) should be received by vNoneHost3
+ // Request messages from V400HOST1 (VPLS 4) should be received by VNONEHOST3
TestMessageContext requestMessage =
- makeBroadcastRequestContext(v400Host1);
+ makeBroadcastRequestContext(V400HOST1);
Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
- // Request messages from vNoneHost3 (VPLS 4) should be received by v400Host1
- requestMessage = makeBroadcastRequestContext(vNoneHost3);
+ // Request messages from VNONEHOST3 (VPLS 4) should be received by V400HOST1
+ requestMessage = makeBroadcastRequestContext(VNONEHOST3);
expectInterfaces = ImmutableSet.of(V400H1);
- vplsNeighbourHandler.handleRequest(requestMessage);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
}
@@ -291,21 +208,21 @@
public void vpls1ReplyMessage() {
// Reply messages from v100h1 (VPLS 1) should be received by v200h1
TestMessageContext replyMessage =
- makeReplyContext(v100Host1, v200Host1);
+ makeReplyContext(V100HOST1, V200HOST1);
Set<Interface> expectInterfaces = ImmutableSet.of(V200H1);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply messages from v200h1 (VPLS 1) should be received by v300h1
- replyMessage = makeReplyContext(v200Host1, v300Host1);
+ replyMessage = makeReplyContext(V200HOST1, V300HOST1);
expectInterfaces = ImmutableSet.of(V300H1);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply messages from v300h1 (VPLS 1) should be received by v100h1
- replyMessage = makeReplyContext(v300Host1, v100Host1);
+ replyMessage = makeReplyContext(V300HOST1, V100HOST1);
expectInterfaces = ImmutableSet.of(V100H1);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
}
@@ -318,15 +235,15 @@
public void vpls2ReplyMessage() {
// Reply messages from v100h2 (VPLS 2) should be received by v200h2
TestMessageContext replyMessage =
- makeReplyContext(v100Host2, v200Host2);
+ makeReplyContext(V100HOST2, V200HOST2);
Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply messages from v200h2 (VPLS 2) should be received by v100h2
- replyMessage = makeReplyContext(v200Host2, v100Host2);
+ replyMessage = makeReplyContext(V200HOST2, V100HOST2);
expectInterfaces = ImmutableSet.of(V100H2);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
}
@@ -339,15 +256,15 @@
public void vpls3ReplyMessage() {
// Reply messages from vNoneh1 (VPLS 3) should be received by vNoneh2
TestMessageContext replyMessage =
- makeReplyContext(vNoneHost1, vNoneHost2);
+ makeReplyContext(VNONEHOST1, VNONEHOST2);
Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply messages from vNoneh2 (VPLS 3) should be received by vNoneh1
- replyMessage = makeReplyContext(vNoneHost2, vNoneHost1);
+ replyMessage = makeReplyContext(VNONEHOST2, VNONEHOST1);
expectInterfaces = ImmutableSet.of(VNONEH1);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
}
@@ -360,15 +277,15 @@
public void vpls4ReplyMessage() {
// Reply messages from v400h1 (VPLS 4) should be received by vNoneh3
TestMessageContext replyMessage =
- makeReplyContext(v400Host1, vNoneHost3);
+ makeReplyContext(V400HOST1, VNONEHOST3);
Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply messages from vNoneh3 (VPLS 4) should be received by v400h1
- replyMessage = makeReplyContext(vNoneHost3, v400Host1);
+ replyMessage = makeReplyContext(VNONEHOST3, V400HOST1);
expectInterfaces = ImmutableSet.of(V400H1);
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
}
@@ -381,52 +298,56 @@
public void wrongReplyMessage() {
// Reply message from v100h1 (VPLS 1) to v100h2 (VPLS 2).
// Forward results should be empty
- TestMessageContext replyMessage = makeReplyContext(v100Host1, v100Host2);
+ TestMessageContext replyMessage = makeReplyContext(V100HOST1, V100HOST2);
Set<Interface> expectInterfaces = ImmutableSet.of();
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply message from v200h2 (VPLS 2) to v300h1 (VPLS 1).
// Forward results should be empty
- replyMessage = makeReplyContext(v200Host2, v300Host1);
+ replyMessage = makeReplyContext(V200HOST2, V300HOST1);
expectInterfaces = ImmutableSet.of();
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply message from vNoneh1 (VPLS 3) to v400h1 (VPLS 4).
// Forward results should be empty
- replyMessage = makeReplyContext(vNoneHost1, v400Host1);
+ replyMessage = makeReplyContext(VNONEHOST1, V400HOST1);
expectInterfaces = ImmutableSet.of();
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
// Reply message from vNoneh3 (VPLS 4) to vNoneH2 (VPLS 3).
// Forward results should be empty
- replyMessage = makeReplyContext(vNoneHost3, vNoneHost2);
+ replyMessage = makeReplyContext(VNONEHOST3, VNONEHOST2);
expectInterfaces = ImmutableSet.of();
- vplsNeighbourHandler.handleReply(replyMessage, hostService);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
}
/**
- * Returns the device Id of the ith device.
- *
- * @param i the device to get the Id of
- * @return the device Id
+ * Sends reply and request message from a host which not related to any VPLS.
*/
- private static DeviceId getDeviceId(int i) {
- return DeviceId.deviceId("" + i);
+ @Test
+ public void testVplsNotfound() {
+ TestMessageContext replyMessage = makeReplyContext(V300HOST2, V100HOST1);
+ Set<Interface> expectInterfaces = ImmutableSet.of();
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
+ assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+ assertTrue(replyMessage.dropped());
+
+ TestMessageContext requestMessage = makeBroadcastRequestContext(V300HOST2);
+ ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
+ assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+ assertTrue(requestMessage.dropped());
}
- private Host makeHost(MacAddress mac, VlanId vlan, ConnectPoint cp) {
- return new DefaultHost(PID,
- HostId.hostId(mac, vlan),
- mac,
- vlan,
- new HostLocation(cp, 0),
- Sets.newHashSet());
- }
-
+ /**
+ * Generates broadcast request message context by given source host.
+ *
+ * @param host the source host
+ * @return the request message context
+ */
private TestMessageContext makeBroadcastRequestContext(Host host) {
return new TestMessageContext(host.location(),
host.mac(),
@@ -435,6 +356,13 @@
NeighbourMessageType.REQUEST);
}
+ /**
+ * Generates reply message context by given source and destination host.
+ *
+ * @param src the source host
+ * @param dst the destination host
+ * @return the reply message context
+ */
private TestMessageContext makeReplyContext(Host src, Host dst) {
return new TestMessageContext(src.location(),
src.mac(),
@@ -443,15 +371,16 @@
NeighbourMessageType.REPLY);
}
+ /**
+ * Test message context.
+ */
private class TestMessageContext implements NeighbourMessageContext {
-
-
private final NeighbourMessageType type;
private final MacAddress srcMac;
private final MacAddress dstMac;
private final ConnectPoint inPort;
private final VlanId vlanId;
-
+ private boolean dropped = false;
public Set<Interface> forwardResults;
/**
@@ -475,8 +404,8 @@
this.dstMac = dstMac;
this.vlanId = vlanId;
this.type = type;
-
this.forwardResults = Sets.newHashSet();
+ this.dropped = false;
}
@Override
@@ -518,6 +447,10 @@
public void forward(ConnectPoint outPort) {
}
+ /**
+ * Records all forward network interface information.
+ * @param outIntf output interface
+ */
@Override
public void forward(Interface outIntf) {
forwardResults.add(outIntf);
@@ -533,6 +466,7 @@
@Override
public void drop() {
+ this.dropped = true;
}
@Override
@@ -544,141 +478,16 @@
public NeighbourProtocol protocol() {
return null;
}
- }
- private class TestVplsConfigService extends VplsConfigServiceAdapter {
-
- private final SetMultimap<String, Interface> ifacesByVplsName;
-
- public TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
- HashMap<String, EncapsulationType> encapByVplsName) {
- this.ifacesByVplsName = ifacesByVplsName;
- }
-
- @Override
- public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
- if (!ifacesByVplsName.containsKey(vplsName)) {
- ifaceNames.forEach(ifaceName -> {
- availableInterfaces.forEach(iface -> {
- if (iface.name().equals(ifaceName)) {
- ifacesByVplsName.put(vplsName, iface);
- }
- });
- });
- }
- }
-
- @Override
- public void removeVpls(String vplsName) {
- if (ifacesByVplsName.containsKey(vplsName)) {
- ifacesByVplsName.removeAll(vplsName);
- }
- }
-
- @Override
- public void addIface(String vplsName, String ifaceName) {
- availableInterfaces.forEach(intf -> {
- if (intf.name().equals(ifaceName)) {
- ifacesByVplsName.put(vplsName, intf);
- }
- });
- }
-
- @Override
- public void removeIface(String ifaceName) {
- SetMultimap<String, Interface> toBeRemoved = HashMultimap.create();
- ifacesByVplsName.entries().forEach(e -> {
- if (e.getValue().name().equals(ifaceName)) {
- toBeRemoved.put(e.getKey(), e.getValue());
- }
- });
- toBeRemoved.entries()
- .forEach(e -> ifacesByVplsName.remove(e.getKey(),
- e.getValue()));
- }
-
- @Override
- public void cleanVplsConfig() {
- ifacesByVplsName.clear();
- }
-
- @Override
- public Set<Interface> allIfaces() {
- return ImmutableSet.copyOf(ifacesByVplsName.values());
- }
-
- @Override
- public Set<Interface> ifaces(String name) {
- return ifacesByVplsName.get(name)
- .stream()
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<String> vplsNames() {
- return ifacesByVplsName.keySet();
- }
-
- @Override
- public SetMultimap<String, Interface> ifacesByVplsName() {
- return ImmutableSetMultimap.copyOf(ifacesByVplsName);
- }
-
- @Override
- public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
- ConnectPoint connectPoint) {
- String vplsName =
- ifacesByVplsName.entries().stream()
- .filter(e -> e.getValue().connectPoint().equals(connectPoint))
- .filter(e -> e.getValue().vlan().equals(vlan))
- .map(Map.Entry::getKey)
- .findFirst()
- .orElse(null);
- SetMultimap<String, Interface> result = HashMultimap.create();
- if (vplsName != null &&
- ifacesByVplsName.containsKey(vplsName)) {
- ifacesByVplsName.get(vplsName)
- .forEach(intf -> result.put(vplsName, intf));
- return result;
- }
- return null;
+ public boolean dropped() {
+ return dropped;
}
}
- class TestHostService extends HostServiceAdapter {
- @Override
- public Set<Host> getHostsByMac(MacAddress mac) {
- return availableHosts.stream()
- .filter(host -> host.mac().equals(mac))
- .collect(Collectors.toSet());
- }
-
- @Override
- public Iterable<Host> getHosts() {
- return availableHosts;
- }
-
- @Override
- public Set<Host> getHostsByVlan(VlanId vlanId) {
- return availableHosts.stream()
- .filter(host -> host.vlan().equals(vlanId))
- .collect(Collectors.toSet());
- }
-
- @Override
- public int getHostCount() {
- return availableHosts.size();
- }
-
- @Override
- public Host getHost(HostId hostId) {
- return availableHosts.stream()
- .filter(host -> host.id().equals(hostId))
- .findFirst()
- .orElse(null);
- }
- }
-
+ /**
+ * Test neighbour service; records all registrations between neighbour
+ * message handler and interfaces.
+ */
private class TestNeighbourService implements NeighbourResolutionService {
private SetMultimap<ConnectPoint, NeighbourHandlerRegistration> handlerRegs;
@@ -732,6 +541,26 @@
return handlerRegs.asMap();
}
+ /**
+ * Sends neighbour message context to all handler which related to the
+ * context.
+ *
+ * @param context the neighbour message context
+ */
+ public void sendNeighourMessage(NeighbourMessageContext context) {
+ ConnectPoint connectPoint = context.inPort();
+ VlanId vlanId = context.vlan();
+ Collection<NeighbourHandlerRegistration> registrations = handlerRegs.get(connectPoint);
+ registrations.forEach(reg -> {
+ if (reg.intf().vlan().equals(vlanId)) {
+ reg.handler().handleMessage(context, hostService);
+ }
+ });
+ }
+
+ /**
+ * Test handler registration.
+ */
private class HandlerRegistration implements NeighbourHandlerRegistration {
private final Interface intf;
private final NeighbourMessageHandler handler;
@@ -767,65 +596,4 @@
}
}
}
-
- class TestInterfaceService implements InterfaceService {
-
- @Override
- public void addListener(InterfaceListener listener) {
- }
-
- @Override
- public void removeListener(InterfaceListener listener) {
- }
-
- @Override
- public Set<Interface> getInterfaces() {
- return availableInterfaces;
- }
-
- @Override
- public Interface getInterfaceByName(ConnectPoint connectPoint,
- String name) {
- return availableInterfaces.stream()
- .filter(intf -> intf.name().equals(name))
- .findFirst()
- .orElse(null);
- }
-
- @Override
- public Set<Interface> getInterfacesByPort(ConnectPoint port) {
- return availableInterfaces.stream()
- .filter(intf -> intf.connectPoint().equals(port))
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<Interface> getInterfacesByIp(IpAddress ip) {
- return availableInterfaces.stream()
- .filter(intf -> intf.ipAddressesList().contains(ip))
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<Interface> getInterfacesByVlan(VlanId vlan) {
- return availableInterfaces.stream()
- .filter(intf -> intf.vlan().equals(vlan))
- .collect(Collectors.toSet());
- }
-
- @Override
- public Interface getMatchingInterface(IpAddress ip) {
- return availableInterfaces.stream()
- .filter(intf -> intf.ipAddressesList().contains(ip))
- .findFirst()
- .orElse(null);
- }
-
- @Override
- public Set<Interface> getMatchingInterfaces(IpAddress ip) {
- return availableInterfaces.stream()
- .filter(intf -> intf.ipAddressesList().contains(ip))
- .collect(Collectors.toSet());
- }
- }
}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java
new file mode 100644
index 0000000..36ffda9
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2017-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.vpls;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.Leader;
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onlab.junit.TestTools.assertAfter;
+import static org.onlab.junit.TestTools.delay;
+
+/**
+ * Tests for {@link VplsOperationManager}.
+ */
+public class VplsOperationManagerTest extends VplsTest {
+
+ VplsOperationManager vplsOperationManager;
+ private static final int OPERATION_DELAY = 1000;
+ private static final int OPERATION_DURATION = 1500;
+
+ @Before
+ public void setup() {
+ if (idGenerator == null) {
+ idGenerator = new TestIdGenerator();
+ }
+ Intent.unbindIdGenerator(idGenerator);
+ Intent.bindIdGenerator(idGenerator);
+ vplsOperationManager = new VplsOperationManager();
+ vplsOperationManager.coreService = new TestCoreService();
+ vplsOperationManager.intentService = new TestIntentService();
+ vplsOperationManager.leadershipService = new TestLeadershipService();
+ vplsOperationManager.clusterService = new ClusterServiceAdapter();
+ vplsOperationManager.hostService = new TestHostService();
+ vplsOperationManager.vplsStore = new TestVplsStore();
+ vplsOperationManager.isLeader = true;
+ vplsOperationManager.activate();
+ }
+
+ @After
+ public void tearDown() {
+ vplsOperationManager.deactivate();
+ }
+
+ /**
+ * Sends leadership event to the manager and checks if the manager is
+ * leader or not.
+ */
+ @Test
+ public void testLeadershipEvent() {
+ vplsOperationManager.isLeader = false;
+ vplsOperationManager.localNodeId = NODE_ID_1;
+
+ // leader changed to self
+ Leader leader = new Leader(NODE_ID_1, 0, 0);
+ Leadership leadership = new Leadership(APP_NAME, leader, ImmutableList.of());
+ LeadershipEvent event = new LeadershipEvent(LeadershipEvent.Type.LEADER_CHANGED, leadership);
+ ((TestLeadershipService) vplsOperationManager.leadershipService).sendEvent(event);
+ assertTrue(vplsOperationManager.isLeader);
+
+ // leader changed to other
+ leader = new Leader(NODE_ID_2, 0, 0);
+ leadership = new Leadership(APP_NAME, leader, ImmutableList.of());
+ event = new LeadershipEvent(LeadershipEvent.Type.LEADER_CHANGED, leadership);
+ ((TestLeadershipService) vplsOperationManager.leadershipService).sendEvent(event);
+ assertFalse(vplsOperationManager.isLeader);
+ }
+
+ /**
+ * Submits an ADD operation to the operation manager; check if the VPLS
+ * store changed after a period.
+ */
+ @Test
+ public void testSubmitAddOperation() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+
+ vplsOperationManager.submit(vplsOperation);
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+ assertEquals(1, vplss.size());
+ VplsData result = vplss.iterator().next();
+
+ assertEquals(vplsData, result);
+ assertEquals(VplsData.VplsState.ADDED, result.state());
+
+ Set<Intent> intentsInstalled =
+ Sets.newHashSet(vplsOperationManager.intentService.getIntents());
+ assertEquals(4, intentsInstalled.size());
+ });
+ }
+
+ /**
+ * Submits an ADD operation to the operation manager; check the VPLS state
+ * from store if Intent install failed.
+ */
+ @Test
+ public void testSubmitAddOperationFail() {
+ vplsOperationManager.intentService = new AlwaysFailureIntentService();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ vplsOperationManager.submit(vplsOperation);
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+ assertEquals(1, vplss.size());
+ VplsData result = vplss.iterator().next();
+
+ assertEquals(vplsData, result);
+ assertEquals(VplsData.VplsState.FAILED, result.state());
+ });
+ }
+
+ /**
+ * Submits an REMOVE operation to the operation manager; check if the VPLS
+ * store changed after a period.
+ */
+ @Test
+ public void testSubmitRemoveOperation() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsData.state(VplsData.VplsState.REMOVING);
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+
+ vplsOperationManager.submit(vplsOperation);
+
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+ assertEquals(0, vplss.size());
+ });
+ }
+
+ /**
+ * Submits an UPDATE operation with VPLS interface update to the operation manager; check if the VPLS
+ * store changed after a period.
+ */
+ @Test
+ public void testSubmitUpdateOperation() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ vplsData.state(VplsData.VplsState.ADDED);
+ vplsOperationManager.vplsStore.addVpls(vplsData);
+
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsData.state(VplsData.VplsState.UPDATING);
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+
+ vplsOperationManager.submit(vplsOperation);
+
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+ VplsData result = vplss.iterator().next();
+ VplsData expected = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ expected.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ expected.state(VplsData.VplsState.ADDED);
+
+ assertEquals(1, vplss.size());
+ assertEquals(expected, result);
+
+ Set<Intent> intentsInstalled =
+ Sets.newHashSet(vplsOperationManager.intentService.getIntents());
+ assertEquals(4, intentsInstalled.size());
+ });
+ }
+
+ /**
+ * Submits an UPDATE operation with VPLS host update to the operation manager; check if the VPLS
+ * store changed after a period.
+ */
+ @Test
+ public void testSubmitUpdateHostOperation() {
+ vplsOperationManager.hostService = new EmptyHostService();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ vplsOperationManager.submit(vplsOperation);
+ delay(1000);
+ vplsOperationManager.hostService = new TestHostService();
+
+ vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsData.state(VplsData.VplsState.UPDATING);
+
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+
+ vplsOperationManager.submit(vplsOperation);
+
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+ VplsData result = vplss.iterator().next();
+ VplsData expected = VplsData.of(VPLS1);
+ expected.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ expected.state(VplsData.VplsState.ADDED);
+ assertEquals(1, vplss.size());
+ assertEquals(expected, result);
+
+ assertEquals(4, vplsOperationManager.intentService.getIntentCount());
+ });
+ }
+
+ /**
+ * Submits same operation twice to the manager; the manager should ignore
+ * duplicated operation.
+ */
+ @Test
+ public void testDuplicateOperationInQueue() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+
+ vplsOperationManager.submit(vplsOperation);
+ vplsOperationManager.submit(vplsOperation);
+ Deque<VplsOperation> opQueue = vplsOperationManager.pendingVplsOperations.get(VPLS1);
+ assertEquals(1, opQueue.size());
+
+ // Clear operation queue before scheduler process it
+ opQueue.clear();
+ }
+
+ /**
+ * Submits REMOVE operation after submits ADD operation; there should be no
+ * pending or running operation in the manager.
+ */
+ @Test
+ public void testDoNothingOperation() {
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ vplsOperationManager.submit(vplsOperation);
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ vplsOperationManager.submit(vplsOperation);
+ assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+ assertEquals(0, vplsOperationManager.pendingVplsOperations.size());
+
+ // Should not have any running operation
+ assertEquals(0, vplsOperationManager.runningOperations.size());
+ });
+ }
+
+ /**
+ * Optimize operations which don't need to be optimized.
+ */
+ @Test
+ public void testOptimizeOperationsNoOptimize() {
+ // empty queue
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsOperation vplsOperation =
+ VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertNull(vplsOperation);
+
+ // one operation
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsOperation = VplsOperation.of(vplsData, VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ VplsOperation result =
+ VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(vplsOperation, result);
+
+ }
+
+ /**
+ * Optimize operations with first is ADD operation and last is also ADD
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsAToA() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.ADD), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is ADD operation and last is REMOVE
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsAToR() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertNull(vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is ADD operation and last is UPDATE
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsAToU() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.ADD), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is REMOVE operation and last is ADD
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsRToA() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is REMOVE operation and last is also
+ * REMOVE operation.
+ */
+ @Test
+ public void testOptimizeOperationsRToR() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.REMOVE), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is REMOVE operation and last is UPDATE
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsRToU() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is UPDATE operation and last is ADD
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsUToA() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.ADD);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is UPDATE operation and last is REMOVE
+ * operation.
+ */
+ @Test
+ public void testOptimizeOperationsUToR() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.REMOVE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.REMOVE), vplsOperation);
+ }
+
+ /**
+ * Optimize operations with first is UPDATE operation and last is also
+ * UPDATE operation.
+ */
+ @Test
+ public void testOptimizeOperationsUToU() {
+ Deque<VplsOperation> operations = new ArrayDeque<>();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1));
+ VplsOperation vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsOperation = VplsOperation.of(vplsData,
+ VplsOperation.Operation.UPDATE);
+ operations.add(vplsOperation);
+ vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+ assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+ }
+
+ /**
+ * Test Intent service which always fail when submit or withdraw Intents.
+ */
+ class AlwaysFailureIntentService extends TestIntentService {
+ @Override
+ public void submit(Intent intent) {
+ intents.add(new IntentData(intent, IntentState.FAILED, new WallClockTimestamp()));
+ if (listener != null) {
+ IntentEvent event = IntentEvent.getEvent(IntentState.FAILED, intent).get();
+ listener.event(event);
+ }
+ }
+
+ @Override
+ public void withdraw(Intent intent) {
+ intents.forEach(intentData -> {
+ if (intentData.intent().key().equals(intent.key())) {
+ intentData.setState(IntentState.FAILED);
+
+ if (listener != null) {
+ IntentEvent event = IntentEvent.getEvent(IntentState.FAILED, intent).get();
+ listener.event(event);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Test host service without any hosts.
+ */
+ class EmptyHostService extends HostServiceAdapter {
+ @Override
+ public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+ return ImmutableSet.of();
+ }
+ }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
index 6dfcea5..716b331 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-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.
@@ -13,704 +13,213 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.vpls;
-import com.google.common.collect.HashMultimap;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.TestApplicationId;
-import org.onosproject.app.ApplicationService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipServiceAdapter;
+import org.onosproject.cluster.NodeId;
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.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.intentsync.IntentSynchronizationService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultHost;
import org.onosproject.net.DeviceId;
import org.onosproject.net.EncapsulationType;
-import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.PortNumber;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
import org.onosproject.net.host.HostServiceAdapter;
import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.IntentServiceAdapter;
-import org.onosproject.net.intent.IntentUtils;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.net.intent.IntentState;
import org.onosproject.net.provider.ProviderId;
-import org.onosproject.vpls.config.VplsConfigService;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vpls.api.Vpls;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.config.VplsAppConfig;
+import org.onosproject.vpls.config.VplsAppConfigTest;
+import org.onosproject.vpls.config.VplsConfig;
+import org.onosproject.vpls.store.VplsStoreAdapter;
+import org.onosproject.vpls.store.VplsStoreEvent;
+import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
-import static java.lang.String.format;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onosproject.net.EncapsulationType.NONE;
-import static org.onosproject.net.EncapsulationType.VLAN;
-import static org.onosproject.net.EncapsulationType.valueOf;
-import static org.onosproject.vpls.IntentInstaller.PARTIAL_FAILURE_CONSTRAINT;
-import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
-import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
-import static org.onosproject.vpls.IntentInstaller.setEncap;
-
/**
- * Tests for the {@link Vpls} class.
+ * Class provides data for VPLS testing.
*/
-public class VplsTest {
- private static final String APP_NAME = "org.onosproject.vpls";
- private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
- private static final String DASH = "-";
- private static final int PRIORITY_OFFSET = 1000;
- private static final String VPLS1 = "vpls1";
- private static final String VPLS2 = "vpls2";
- private static final String VPLS3 = "vpls3";
- private static final String VPLS4 = "vpls4";
+public abstract class VplsTest {
+ protected static final String APP_NAME = "org.onosproject.vpls";
+ protected static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
+ protected static final String DASH = "-";
+ protected static final int PRIORITY_OFFSET = 1000;
+ protected static final String VPLS1 = "vpls1";
+ protected static final String VPLS2 = "vpls2";
+ protected static final String VPLS3 = "vpls3";
+ protected static final String VPLS4 = "vpls4";
- private static final PortNumber P1 = PortNumber.portNumber(1);
- private static final PortNumber P2 = PortNumber.portNumber(2);
+ protected static final PortNumber P1 = PortNumber.portNumber(1);
+ protected static final PortNumber P2 = PortNumber.portNumber(2);
- private static final DeviceId DID1 = getDeviceId(1);
- private static final DeviceId DID2 = getDeviceId(2);
- private static final DeviceId DID3 = getDeviceId(3);
- private static final DeviceId DID4 = getDeviceId(4);
- private static final DeviceId DID5 = getDeviceId(5);
- private static final DeviceId DID6 = getDeviceId(6);
+ protected static final DeviceId DID1 = getDeviceId(1);
+ protected static final DeviceId DID2 = getDeviceId(2);
+ protected static final DeviceId DID3 = getDeviceId(3);
+ protected static final DeviceId DID4 = getDeviceId(4);
+ protected static final DeviceId DID5 = getDeviceId(5);
+ protected static final DeviceId DID6 = getDeviceId(6);
- private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
- private static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
- private static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
- private static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
- private static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
- private static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
- private static final ConnectPoint CP7 = new ConnectPoint(DID4, P2);
- private static final ConnectPoint CP8 = new ConnectPoint(DID3, P2);
- private static final ConnectPoint CP9 = new ConnectPoint(DID5, P1);
- private static final ConnectPoint CP10 = new ConnectPoint(DID5, P2);
+ protected static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
+ protected static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
+ protected static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
+ protected static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
+ protected static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
+ protected static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
+ protected static final ConnectPoint CP7 = new ConnectPoint(DID4, P2);
+ protected static final ConnectPoint CP8 = new ConnectPoint(DID3, P2);
+ protected static final ConnectPoint CP9 = new ConnectPoint(DID5, P1);
+ protected static final ConnectPoint CP10 = new ConnectPoint(DID5, P2);
- private static final VlanId VLAN100 = VlanId.vlanId((short) 100);
- private static final VlanId VLAN200 = VlanId.vlanId((short) 200);
- private static final VlanId VLAN300 = VlanId.vlanId((short) 300);
- private static final VlanId VLAN400 = VlanId.vlanId((short) 400);
- private static final VlanId VLAN_NONE = VlanId.NONE;
+ protected static final VlanId VLAN100 = VlanId.vlanId((short) 100);
+ protected static final VlanId VLAN200 = VlanId.vlanId((short) 200);
+ protected static final VlanId VLAN300 = VlanId.vlanId((short) 300);
+ protected static final VlanId VLAN400 = VlanId.vlanId((short) 400);
+ protected static final VlanId VLAN_NONE = VlanId.NONE;
- private static final MacAddress MAC1 = getMac(1);
- private static final MacAddress MAC2 = getMac(2);
- private static final MacAddress MAC3 = getMac(3);
- private static final MacAddress MAC4 = getMac(4);
- private static final MacAddress MAC5 = getMac(5);
- private static final MacAddress MAC6 = getMac(6);
- private static final MacAddress MAC7 = getMac(7);
- private static final MacAddress MAC8 = getMac(8);
- private static final MacAddress MAC9 = getMac(9);
- private static final MacAddress MAC10 = getMac(10);
- private static final MacAddress MAC11 = getMac(11);
+ protected static final MacAddress MAC1 = getMac(1);
+ protected static final MacAddress MAC2 = getMac(2);
+ protected static final MacAddress MAC3 = getMac(3);
+ protected static final MacAddress MAC4 = getMac(4);
+ protected static final MacAddress MAC5 = getMac(5);
+ protected static final MacAddress MAC6 = getMac(6);
+ protected static final MacAddress MAC7 = getMac(7);
+ protected static final MacAddress MAC8 = getMac(8);
+ protected static final MacAddress MAC9 = getMac(9);
+ protected static final MacAddress MAC10 = getMac(10);
+ protected static final MacAddress MAC11 = getMac(11);
- private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
- private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
+ protected static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
+ protected static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
- private static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
- private static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
- private static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
- private static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
- private static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
- private static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
- private static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
- private static final HostId HID8 = HostId.hostId(MAC8, VLAN400);
- private static final HostId HID9 = HostId.hostId(MAC9);
- private static final HostId HID10 = HostId.hostId(MAC10);
- private static final HostId HID11 = HostId.hostId(MAC11);
+ protected static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
+ protected static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
+ protected static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
+ protected static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
+ protected static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
+ protected static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
+ protected static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
+ protected static final HostId HID8 = HostId.hostId(MAC8, VLAN400);
+ protected static final HostId HID9 = HostId.hostId(MAC9);
+ protected static final HostId HID10 = HostId.hostId(MAC10);
+ protected static final HostId HID11 = HostId.hostId(MAC11);
- private static final ProviderId PID = new ProviderId("of", "foo");
+ protected static final ProviderId PID = new ProviderId("of", "foo");
- private static IdGenerator idGenerator;
+ protected static final NodeId NODE_ID_1 = new NodeId("Node1");
+ protected static final NodeId NODE_ID_2 = new NodeId("Node2");
- private static final Interface V100H1 =
+ protected static IdGenerator idGenerator;
+
+ protected static final Interface V100H1 =
new Interface("v100h1", CP1, null, null, VLAN100);
- private static final Interface V100H2 =
+ protected static final Interface V100H2 =
new Interface("v100h2", CP2, null, null, VLAN100);
- private static final Interface V200H1 =
+ protected static final Interface V200H1 =
new Interface("v200h1", CP3, null, null, VLAN200);
- private static final Interface V200H2 =
+ protected static final Interface V200H2 =
new Interface("v200h2", CP4, null, null, VLAN200);
- private static final Interface V300H1 =
+ protected static final Interface V300H1 =
new Interface("v300h1", CP5, null, null, VLAN300);
- private static final Interface V300H2 =
+ protected static final Interface V300H2 =
new Interface("v300h2", CP6, null, null, VLAN300);
- private static final Interface V400H1 =
+ protected static final Interface V400H1 =
new Interface("v400h1", CP7, null, null, VLAN400);
- private static final Interface VNONEH1 =
+ protected static final Interface VNONEH1 =
new Interface("vNoneh1", CP8, null, null, VLAN_NONE);
- private static final Interface VNONEH2 =
+ protected static final Interface VNONEH2 =
new Interface("vNoneh2", CP9, null, null, VLAN_NONE);
- private static final Interface VNONEH3 =
+ protected static final Interface VNONEH3 =
new Interface("vNoneh3", CP10, null, null, VLAN_NONE);
- private static final Host V100HOST1 =
+ protected static final Host V100HOST1 =
new DefaultHost(PID, HID1, MAC1, VLAN100,
getLocation(1), Collections.singleton(IP1));
- private static final Host V100HOST2 =
+ protected static final Host V100HOST2 =
new DefaultHost(PID, HID2, MAC2, VLAN100,
getLocation(2), Sets.newHashSet());
- private static final Host V200HOST1 =
+ protected static final Host V200HOST1 =
new DefaultHost(PID, HID3, MAC3, VLAN200,
getLocation(3), Collections.singleton(IP2));
- private static final Host V200HOST2 =
+ protected static final Host V200HOST2 =
new DefaultHost(PID, HID4, MAC4, VLAN200,
getLocation(4), Sets.newHashSet());
- private static final Host V300HOST1 =
+ protected static final Host V300HOST1 =
new DefaultHost(PID, HID5, MAC5, VLAN300,
getLocation(5), Sets.newHashSet());
- private static final Host V300HOST2 =
+ protected static final Host V300HOST2 =
new DefaultHost(PID, HID6, MAC6, VLAN300,
getLocation(6), Sets.newHashSet());
- private static final Host V300HOST3 =
+ protected static final Host V300HOST3 =
new DefaultHost(PID, HID7, MAC7, VLAN300,
getLocation(7), Sets.newHashSet());
- private static final Host V400HOST1 =
+ protected static final Host V400HOST1 =
new DefaultHost(PID, HID8, MAC8, VLAN400,
getLocation(4, 2), Sets.newHashSet());
- private static final Host VNONEHOST1 =
+ protected static final Host VNONEHOST1 =
new DefaultHost(PID, HID9, MAC9, VlanId.NONE,
getLocation(3, 2), Sets.newHashSet());
- private static final Host VNONEHOST2 =
+ protected static final Host VNONEHOST2 =
new DefaultHost(PID, HID10, MAC10, VlanId.NONE,
getLocation(5, 1), Sets.newHashSet());
- private static final Host VNONEHOST3 =
+ protected static final Host VNONEHOST3 =
new DefaultHost(PID, HID11, MAC11, VlanId.NONE,
getLocation(5, 2), Sets.newHashSet());
- private static final Set<Interface> AVAILABLE_INTERFACES =
+ protected static final Set<Interface> AVAILABLE_INTERFACES =
ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1, V300H2,
- V400H1, VNONEH1, VNONEH2);
+ V400H1, VNONEH1, VNONEH2, VNONEH3);
- private static final Set<Host> AVAILABLE_HOSTS =
+ protected static final Set<Host> AVAILABLE_HOSTS =
ImmutableSet.of(V100HOST1, V100HOST2, V200HOST1,
V200HOST2, V300HOST1, V300HOST2, V300HOST3,
VNONEHOST1, VNONEHOST2,
V400HOST1, VNONEHOST3);
- private SetMultimap<String, Interface> interfacesByVpls = HashMultimap.create();
-
- private ApplicationService applicationService;
- private CoreService coreService;
- private HostListener hostListener;
- private NetworkConfigService configService;
- private Set<Host> hostsAvailable;
- private HostService hostService;
- private IntentService intentService;
- private InterfaceService interfaceService;
- private VplsConfigService vplsConfigService;
- private Vpls vpls;
-
- @Before
- public void setUp() throws Exception {
- idGenerator = new TestIdGenerator();
- Intent.unbindIdGenerator(idGenerator);
- Intent.bindIdGenerator(idGenerator);
-
- applicationService = createMock(ApplicationService.class);
-
- configService = createMock(NetworkConfigService.class);
-
- coreService = createMock(CoreService.class);
- expect(coreService.registerApplication(APP_NAME))
- .andReturn(APPID);
- replay(coreService);
-
- hostsAvailable = Sets.newHashSet();
- hostService = new TestHostService(hostsAvailable);
-
- intentService = new TestIntentService();
-
- TestIntentSynchronizer intentSynchronizer =
- new TestIntentSynchronizer(intentService);
-
- interfaceService = createMock(InterfaceService.class);
- interfaceService.addListener(anyObject(InterfaceListener.class));
- expectLastCall().anyTimes();
- addIfaceConfig();
-
- interfacesByVpls.put(VPLS1, V100H1);
- interfacesByVpls.put(VPLS1, V200H1);
- interfacesByVpls.put(VPLS1, V300H1);
- interfacesByVpls.put(VPLS2, V100H2);
- interfacesByVpls.put(VPLS2, V200H2);
- interfacesByVpls.put(VPLS2, V300H2);
- interfacesByVpls.put(VPLS3, VNONEH1);
- interfacesByVpls.put(VPLS3, VNONEH2);
- interfacesByVpls.put(VPLS4, V400H1);
- interfacesByVpls.put(VPLS4, VNONEH3);
-
- Map<String, EncapsulationType> encapByVpls = new HashMap<>();
- encapByVpls.put(VPLS1, VLAN);
- encapByVpls.put(VPLS2, NONE);
- encapByVpls.put(VPLS3, NONE);
- encapByVpls.put(VPLS4, NONE);
-
- vplsConfigService = new TestVplsConfigService(interfacesByVpls, encapByVpls);
-
- vpls = new Vpls();
- vpls.applicationService = applicationService;
- vpls.coreService = coreService;
- vpls.hostService = hostService;
- vpls.vplsConfigService = vplsConfigService;
- vpls.intentService = intentService;
- vpls.interfaceService = interfaceService;
- vpls.configService = configService;
- vpls.intentSynchronizer = intentSynchronizer;
-
- }
-
- @After
- public void tearDown() {
- Intent.unbindIdGenerator(idGenerator);
- }
-
- /**
- * Creates the interface configuration:
- * On devices 1 and 2 is configured an interface on port 1 with vlan 100.
- * On device 3 is configured an interface on port 3 with no vlan.
- * On devices 3 and 4 is configured an interface on port 1 with vlan 200.
- * On device 4 is an interface configured on port 2 with vlan 400.
- * On device 5 are configured two interfaces on port 1 and 2 with no vlan.
- * On device 5 and 6 is configured an interface on port 1 with vlan 300.
- */
- private void addIfaceConfig() {
- Set<Interface> interfaces = ImmutableSet.copyOf(AVAILABLE_INTERFACES);
- Set<Interface> vlanOneSet = ImmutableSet.of(V100H1, V100H2);
- Set<Interface> vlanTwoSet = ImmutableSet.of(V200H1, V200H2);
- Set<Interface> vlanThreeSet = ImmutableSet.of(VNONEH1, VNONEH2);
- Set<Interface> vlanFourSet = ImmutableSet.of(V400H1, VNONEH3);
-
- AVAILABLE_INTERFACES.forEach(intf -> {
- expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
- .andReturn(Sets.newHashSet(intf)).anyTimes();
- });
- expect(interfaceService.getInterfacesByVlan(VLAN100))
- .andReturn(vlanOneSet).anyTimes();
- expect(interfaceService.getInterfacesByVlan(VLAN200))
- .andReturn(vlanTwoSet).anyTimes();
- expect(interfaceService.getInterfacesByVlan(VLAN300))
- .andReturn(vlanThreeSet).anyTimes();
- expect(interfaceService.getInterfacesByVlan(VLAN400))
- .andReturn(vlanFourSet).anyTimes();
- expect(interfaceService.getInterfacesByVlan(VlanId.NONE))
- .andReturn(vlanFourSet).anyTimes();
- expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-
- replay(interfaceService);
- }
-
- /**
- * Seven ports are configured with VLANs, while three ports are not. No hosts are
- * registered by the HostService.
- *
- * The first three ports have an interface configured on VPLS 1,
- * the other three on VPLS 2. Two ports are defined for VPLS 3, while
- * the two remaining ports are configured on VPLS 4.
- *
- * The number of intents expected is 10: three for VPLS 1, three for VPLS 2,
- * two for VPLS 3, two for VPLS 4. Eight MP2SP intents.
- * Checks if the number of intents submitted to the intent framework is
- * equal to the number of intents expected and if all intents are equivalent.
- */
- @Test
- public void activateNoHosts() {
- vpls.activate();
-
- List<Intent> expectedIntents = Lists.newArrayList();
- Set<FilteredConnectPoint> fcPoints;
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
-
- checkIntents(expectedIntents);
- }
-
- /**
- * Ten ports are configured with VLANs and ten hosts are registered by the
- * HostService.
- *
- * The first three ports have an interface configured on VPLS 1,
- * the other three on VPLS 2, two on VPLS3 and two on VPLS4.
- *
- * The number of intents expected is twenty: six
- * for VPLS 1, six for VPLS 2. four for VPLS 3, four for VPLS 4.
- * That is ten sp2mp intents, ten mp2sp intents. For VPLS 1
- * IPs are added to demonstrate this doesn't influence the number of intents
- * created. Checks if the number of intents submitted to the intent
- * framework is equal to the number of intents expected and if all intents
- * are equivalent.
- */
- @Test
- public void tenInterfacesConfiguredHostsPresent() {
- hostsAvailable.addAll(AVAILABLE_HOSTS);
-
- vpls.activate();
-
- List<Intent> expectedIntents = Lists.newArrayList();
- Set<FilteredConnectPoint> fcPoints;
- Set<Host> hosts;
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
- hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
- hosts = ImmutableSet.of(V100HOST2, V200HOST2, V300HOST2);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS2, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
- hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
- hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
-
- checkIntents(expectedIntents);
- }
-
- /**
- * Ten ports are configured; seven have VLANs and three do not.
- * Initially, no hosts are registered by the HostService.
- *
- * The first three ports have an interface configured on
- * VPLS 1, three have an interface configured on VPLS 2, two have an
- * interface configured on VPLS 3 and two have an interface configured
- * on VPLS 4, three have an interface configure. When the
- * module starts up, three hosts attached to device one, two and three -
- * port 1, are registered by the HostService and events are sent to the
- * application. sp2mp intents are created for all interfaces configured and
- * mp2sp intents are created only for the hosts attached.
- *
- * The number of intents expected is seventeen: six for VPLS 1,
- * three for VPLS 2, four for VPLS3 and four for VPLS4.
- * Ten sp2mp intents, seven mp2sp intents. IPs are added on the first two
- * hosts only to demonstrate this doesn't influence the number of intents
- * created.
- * An additional host is added on device seven - port 1, to demonstrate that
- * the application does not generate intents, even if the interface uses the
- * same VLAN Id of the other interfaces configured for the specifc VPLS.
- * Checks if the number of intents submitted to the intent framework is equal
- * to the number of intents expected and if all intents are equivalent.
- */
- @Test
- public void tenInterfacesThreeHostEventsSameVpls() {
- vpls.activate();
-
- List<Intent> expectedIntents = Lists.newArrayList();
- Set<FilteredConnectPoint> fcPoints;
- Set<Host> hosts;
-
- hostsAvailable.addAll(Sets.newHashSet(V100HOST1, V200HOST1,
- V300HOST1, V300HOST3,
- VNONEHOST1, VNONEHOST2,
- V400HOST1, VNONEHOST3));
- hostsAvailable.forEach(host ->
- hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
- hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
- hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
-
- fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
- hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
- expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
- expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
-
- checkIntents(expectedIntents);
- }
-
- /**
- * Generates a list of the expected sp2mp intents for a VPLS.
- *
- * @param fcPoints the filtered connect point
- * @param name the name of the VPLS
- * @param encap the encapsulation type
- * @return the list of expected sp2mp intents for the given VPLS
- */
- private List<SinglePointToMultiPointIntent>
- generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name, EncapsulationType encap) {
- List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
-
- fcPoints.forEach(point -> {
- Set<FilteredConnectPoint> otherPoints =
- fcPoints.stream()
- .filter(fcp -> !fcp.equals(point))
- .collect(Collectors.toSet());
-
- Key brckey = buildKey(PREFIX_BROADCAST,
- point.connectPoint(),
- name,
- MacAddress.BROADCAST);
-
- intents.add(buildBrcIntent(brckey, point, otherPoints, encap));
- });
-
- return intents;
- }
-
- /**
- * Generates a list of expected mp2sp intents for a given VPLS.
- *
- * @param fcPoints the filtered connect point
- * @param hosts the hosts
- * @param name the name of the VPLS
- * @param encap the encapsulation type
- * @return the list of expected mp2sp intents for the given VPLS
- */
- private List<MultiPointToSinglePointIntent>
- generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts,
- String name, EncapsulationType encap) {
- List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
-
- hosts.forEach(host -> {
- FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
-
- Set<FilteredConnectPoint> otherPoints =
- fcPoints.stream()
- .filter(fcp -> !fcp.equals(hostPoint))
- .collect(Collectors.toSet());
-
- Key uniKey = buildKey(PREFIX_UNICAST,
- host.location(), name, host.mac());
-
- intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host, encap));
- });
-
- return intents;
- }
-
- /**
- * Checks if the number of intents submitted to the intent framework is equal
- * to the number of intents expected and if all intents are equivalent.
- *
- * @param intents the list of intents expected
- */
- private void checkIntents(List<Intent> intents) {
- assertEquals("The number of intents submitted differs from the number" +
- " of intents expected. ",
- intents.size(), intentService.getIntentCount());
-
- for (Intent intentOne : intents) {
- boolean found = false;
- for (Intent intentTwo : intentService.getIntents()) {
- if (intentOne.key().equals(intentTwo.key())) {
- found = true;
- assertTrue(format("The intent submitted is different from" +
- " the intent expected. %s %s",
- intentOne, intentTwo),
- IntentUtils.intentsAreEqual(intentOne, intentTwo));
- break;
- }
- }
- assertTrue("The intent submitted is not equal to any of the expected" +
- " intents. ", found);
- }
- }
-
- /**
- * Builds a broadcast intent.
- *
- * @param key the key to identify the intent
- * @param src the ingress connect point
- * @param dsts the egress connect points
- * @return the generated single-point to multi-point intent
- */
- private SinglePointToMultiPointIntent buildBrcIntent(Key key,
- FilteredConnectPoint src,
- Set<FilteredConnectPoint> dsts,
- EncapsulationType encap) {
- SinglePointToMultiPointIntent.Builder intentBuilder;
-
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthDst(MacAddress.BROADCAST)
- .build();
-
- intentBuilder = SinglePointToMultiPointIntent.builder()
- .appId(APPID)
- .key(key)
- .selector(selector)
- .filteredIngressPoint(src)
- .filteredEgressPoints(dsts)
- .constraints(PARTIAL_FAILURE_CONSTRAINT)
- .priority(PRIORITY_OFFSET);
-
- setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
- return intentBuilder.build();
- }
-
- /**
- * Builds a unicast intent.
- *
- * @param key the key to identify the intent
- * @param srcs the ingress connect points
- * @param dst the egress connect point
- * @param host the destination Host
- * @return the generated multi-point to single-point intent
- */
- private MultiPointToSinglePointIntent buildUniIntent(Key key,
- Set<FilteredConnectPoint> srcs,
- FilteredConnectPoint dst,
- Host host,
- EncapsulationType encap) {
- MultiPointToSinglePointIntent.Builder intentBuilder;
-
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthDst(host.mac())
- .build();
-
- intentBuilder = MultiPointToSinglePointIntent.builder()
- .appId(APPID)
- .key(key)
- .selector(selector)
- .filteredIngressPoints(srcs)
- .filteredEgressPoint(dst)
- .constraints(PARTIAL_FAILURE_CONSTRAINT)
- .priority(PRIORITY_OFFSET);
-
- setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
- return intentBuilder.build();
- }
-
- /**
- * Returns the filtered connect point associated to a given host.
- *
- * @param host the target host
- * @param fcps the filtered connected points
- * @return the filtered connect point associated to the given host; null
- * otherwise
- */
- private FilteredConnectPoint getHostPoint(Host host,
- Set<FilteredConnectPoint> fcps) {
- return fcps.stream()
- .filter(fcp -> fcp.connectPoint().equals(host.location()))
- .filter(fcp -> {
- VlanIdCriterion vlanCriterion =
- (VlanIdCriterion) fcp.trafficSelector().
- getCriterion(Criterion.Type.VLAN_VID);
- return vlanCriterion == null ||
- vlanCriterion.vlanId().equals(host.vlan());
- })
- .findFirst()
- .orElse(null);
- }
-
- /**
- * Computes a set of filtered connect points from a list of given interfaces.
- *
- * @param interfaces the interfaces to compute
- * @return the set of filtered connect points
- */
- private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
- // Build all filtered connected points in the VPLS
- return interfaces
- .stream()
- .map(intf -> {
- TrafficSelector.Builder selectorBuilder =
- DefaultTrafficSelector.builder();
- if (!intf.vlan().equals(VlanId.NONE)) {
- selectorBuilder.matchVlanId(intf.vlan());
- }
- return new FilteredConnectPoint(intf.connectPoint(),
- selectorBuilder.build());
- })
- .collect(Collectors.toSet());
- }
-
- /**
- * Builds an intent Key either for a single-point to multi-point or
- * multi-point to single-point intent, based on a prefix that defines
- * the intent type, the connection point representing the source or the
- * destination and the VLAN Id representing the VPLS.
- *
- * @param prefix the key prefix
- * @param cPoint the ingress/egress connect point
- * @param vplsName the VPLS name
- * @param hostMac the ingress/egress MAC address
- * @return the key to identify the intent
- */
- private Key buildKey(String prefix,
- ConnectPoint cPoint,
- String vplsName,
- MacAddress hostMac) {
- String keyString = vplsName +
- DASH +
- prefix +
- DASH +
- cPoint.deviceId() +
- DASH +
- cPoint.port() +
- DASH +
- hostMac;
-
- return Key.of(keyString, APPID);
- }
/**
* Returns the device Id of the ith device.
@@ -718,38 +227,91 @@
* @param i the device to get the Id of
* @return the device Id
*/
- private static DeviceId getDeviceId(int i) {
+ protected static DeviceId getDeviceId(int i) {
return DeviceId.deviceId("" + i);
}
- private static MacAddress getMac(int n) {
+ /**
+ * Generates a mac address by given number.
+ *
+ * @param n the number to generate mac address
+ * @return the mac address
+ */
+ protected static MacAddress getMac(int n) {
return MacAddress.valueOf(String.format("00:00:00:00:00:%s", n));
}
- private static HostLocation getLocation(int i) {
+ /**
+ * Generates a host location by given device number.
+ *
+ * @param i the given number
+ * @return the host location
+ */
+ protected static HostLocation getLocation(int i) {
return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
}
- private static HostLocation getLocation(int d, int p) {
+ /**
+ * Generates host location by given device number and port number.
+ *
+ * @param d the device number
+ * @param p the port number
+ * @return the host location
+ */
+ protected static HostLocation getLocation(int d, int p) {
return new HostLocation(new ConnectPoint(getDeviceId(d),
PortNumber.portNumber(p)), 123L);
}
/**
- * Represents a fake IntentService class that allows to store and retrieve
- * intents without implementing the IntentService logic.
+ * Test core service; For generate test application ID.
*/
- private class TestIntentService extends IntentServiceAdapter {
+ public class TestCoreService extends CoreServiceAdapter {
+ @Override
+ public ApplicationId registerApplication(String name) {
+ return TestApplicationId.create(name);
+ }
+ }
- private Map<Key, Intent> intents;
+ /**
+ * Test intent service.
+ * Always install or withdraw success for any Intents.
+ */
+ public class TestIntentService extends IntentServiceAdapter {
+ IntentListener listener;
+ List<IntentData> intents;
public TestIntentService() {
- intents = Maps.newHashMap();
+ intents = Lists.newArrayList();
}
@Override
public void submit(Intent intent) {
- intents.put(intent.key(), intent);
+ intents.add(new IntentData(intent, IntentState.INSTALLED, new WallClockTimestamp()));
+ if (listener != null) {
+ IntentEvent.getEvent(IntentState.INSTALLED, intent).ifPresent(listener::event);
+
+ }
+ }
+
+ @Override
+ public void withdraw(Intent intent) {
+ intents.forEach(intentData -> {
+ if (intentData.intent().key().equals(intent.key())) {
+ intentData.setState(IntentState.WITHDRAWN);
+
+ if (listener != null) {
+ IntentEvent.getEvent(IntentState.WITHDRAWN, intent).ifPresent(listener::event);
+ }
+ }
+ });
+ }
+
+ @Override
+ public Iterable<Intent> getIntents() {
+ return intents.stream()
+ .map(IntentData::intent)
+ .collect(Collectors.toList());
}
@Override
@@ -758,52 +320,227 @@
}
@Override
- public Iterable<Intent> getIntents() {
- return intents.values();
+ public void addListener(IntentListener listener) {
+ this.listener = listener;
}
@Override
- public Intent getIntent(Key intentKey) {
- for (Intent intent : intents.values()) {
- if (intent.key().equals(intentKey)) {
- return intent;
- }
- }
- return null;
+ public void removeListener(IntentListener listener) {
+ this.listener = null;
}
}
/**
- * Represents a fake HostService class which allows to add hosts manually
- * in each test, when needed.
+ * Test leadership service.
*/
- private class TestHostService extends HostServiceAdapter {
+ public class TestLeadershipService extends LeadershipServiceAdapter {
+ LeadershipEventListener listener;
- private Set<Host> hosts;
-
- public TestHostService(Set<Host> hosts) {
- this.hosts = hosts;
+ @Override
+ public void addListener(LeadershipEventListener listener) {
+ this.listener = listener;
}
@Override
- public void addListener(HostListener listener) {
- VplsTest.this.hostListener = listener;
+ public void removeListener(LeadershipEventListener listener) {
+ this.listener = null;
+ }
+
+ /**
+ * Sends the leadership event to the listener.
+ *
+ * @param event the Intent event
+ */
+ public void sendEvent(LeadershipEvent event) {
+ if (listener != null && listener.isRelevant(event)) {
+ listener.event(event);
+ }
}
@Override
- public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
- return hosts.stream()
- .filter(h -> h.location().equals(connectPoint))
+ public NodeId getLeader(String path) {
+ return NODE_ID_1;
+ }
+ }
+
+ /**
+ * Test interface service; contains all interfaces which already generated.
+ */
+ public class TestInterfaceService implements InterfaceService {
+
+ @Override
+ public void addListener(InterfaceListener listener) {
+ }
+
+ @Override
+ public void removeListener(InterfaceListener listener) {
+ }
+
+ @Override
+ public Set<Interface> getInterfaces() {
+ return AVAILABLE_INTERFACES;
+ }
+
+ @Override
+ public Interface getInterfaceByName(ConnectPoint connectPoint,
+ String name) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.name().equals(name))
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.connectPoint().equals(port))
.collect(Collectors.toSet());
}
+ @Override
+ public Set<Interface> getInterfacesByIp(IpAddress ip) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.ipAddressesList().contains(ip))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<Interface> getInterfacesByVlan(VlanId vlan) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.vlan().equals(vlan))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Interface getMatchingInterface(IpAddress ip) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.ipAddressesList().contains(ip))
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public Set<Interface> getMatchingInterfaces(IpAddress ip) {
+ return AVAILABLE_INTERFACES.stream()
+ .filter(intf -> intf.ipAddressesList().contains(ip))
+ .collect(Collectors.toSet());
+ }
+ }
+
+ /**
+ * Test VPLS store.
+ */
+ public class TestVplsStore extends VplsStoreAdapter {
+ /**
+ * Clears the store.
+ */
+ public void clear() {
+ vplsDataMap.clear();
+ }
+
+ /**
+ * Gets the store delegate.
+ *
+ * @return the store delegate
+ */
+ public StoreDelegate<VplsStoreEvent> delegate() {
+ return this.delegate;
+ }
+ }
+
+ /**
+ * Test VPLS.
+ * Provides basic VPLS functionality and stores VPLS information.
+ */
+ public class TestVpls implements Vpls {
+ public Map<String, VplsData> testData;
+
+ public TestVpls() {
+ testData = Maps.newHashMap();
+ }
+
+ public void initSampleData() {
+ testData.clear();
+ VplsData vplsData = VplsData.of(VPLS1);
+ vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ vplsData.state(VplsData.VplsState.ADDED);
+ testData.put(VPLS1, vplsData);
+
+ vplsData = VplsData.of(VPLS2);
+ vplsData.addInterfaces(ImmutableSet.of(V200H1, V200H2));
+ vplsData.state(VplsData.VplsState.ADDED);
+ testData.put(VPLS2, vplsData);
+ }
+
+ @Override
+ public VplsData createVpls(String vplsName, EncapsulationType encapsulationType) {
+ VplsData vplsData = VplsData.of(vplsName, encapsulationType);
+ testData.put(vplsName, vplsData);
+ return vplsData;
+ }
+
+ @Override
+ public VplsData removeVpls(VplsData vplsData) {
+ if (!testData.containsKey(vplsData.name())) {
+ return null;
+ }
+
+ testData.remove(vplsData.name());
+ return vplsData;
+ }
+
+ @Override
+ public void addInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+ vplsData.addInterfaces(interfaces);
+ testData.put(vplsData.name(), vplsData);
+ }
+
+ @Override
+ public void addInterface(VplsData vplsData, Interface iface) {
+ vplsData.addInterface(iface);
+ testData.put(vplsData.name(), vplsData);
+ }
+
+ @Override
+ public void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType) {
+ vplsData.encapsulationType(encapsulationType);
+ testData.put(vplsData.name(), vplsData);
+ }
+
+ @Override
+ public VplsData getVpls(String vplsName) {
+ return testData.get(vplsName);
+ }
+
+ @Override
+ public Collection<VplsData> getAllVpls() {
+ return testData.values();
+ }
+
+ @Override
+ public Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+ vplsData.removeInterfaces(interfaces);
+ testData.put(vplsData.name(), vplsData);
+ return interfaces;
+ }
+
+ @Override
+ public Interface removeInterface(VplsData vplsData, Interface iface) {
+ vplsData.removeInterface(iface);
+ testData.put(vplsData.name(), vplsData);
+ return iface;
+ }
+
+ @Override
+ public void removeAllVpls() {
+ testData.clear();
+ }
}
/**
* Represents a fake IdGenerator class for intents.
*/
- private static class TestIdGenerator implements IdGenerator {
-
+ protected static class TestIdGenerator implements IdGenerator {
private final AtomicLong id = new AtomicLong(0);
@Override
@@ -814,170 +551,135 @@
}
/**
- * Test IntentSynchronizer that passes all intents straight through to the
- * intent service.
+ * Test host service; contains all hosts which already generated.
+ *
*/
- private class TestIntentSynchronizer implements IntentSynchronizationService {
+ public class TestHostService extends HostServiceAdapter {
- private final IntentService intentService;
+ private HostListener listener;
- /**
- * Creates a new intent test synchronizer.
- *
- * @param intentService intent service
- */
- public TestIntentSynchronizer(IntentService intentService) {
- this.intentService = intentService;
+ @Override
+ public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+ return AVAILABLE_HOSTS.stream()
+ .filter(host -> host.location().equals(connectPoint))
+ .collect(Collectors.toSet());
}
@Override
- public void submit(Intent intent) {
- intentService.submit(intent);
+ public Set<Host> getHostsByMac(MacAddress mac) {
+ return AVAILABLE_HOSTS.stream()
+ .filter(host -> host.mac().equals(mac))
+ .collect(Collectors.toSet());
}
@Override
- public void withdraw(Intent intent) {
- intentService.withdraw(intent);
+ public Iterable<Host> getHosts() {
+ return AVAILABLE_HOSTS;
}
@Override
- public void removeIntentsByAppId(ApplicationId applicationId) {
+ public Set<Host> getHostsByVlan(VlanId vlanId) {
+ return AVAILABLE_HOSTS.stream()
+ .filter(host -> host.vlan().equals(vlanId))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public int getHostCount() {
+ return AVAILABLE_HOSTS.size();
+ }
+
+ @Override
+ public Host getHost(HostId hostId) {
+ return AVAILABLE_HOSTS.stream()
+ .filter(host -> host.id().equals(hostId))
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public void addListener(HostListener listener) {
+ this.listener = listener;
+ }
+
+ public void postHostEvent(HostEvent hostEvent) {
+ this.listener.event(hostEvent);
}
}
/**
- * Represents a fake VplsConfigService class which is needed for testing.
+ * Test network configuration service.
*/
- private class TestVplsConfigService extends VplsConfigServiceAdapter {
+ public class TestConfigService extends NetworkConfigServiceAdapter {
+ public static final String EMPTY_JSON_TREE = "{}";
+ NetworkConfigListener listener;
+ VplsAppConfig vplsAppConfig;
- private final SetMultimap<String, Interface> ifacesByVplsName;
- private final Map<String, EncapsulationType> encapsByVplsName;
-
- private Set<String> vplsAffectByApi = new HashSet<>();
-
- TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
- Map<String, EncapsulationType> encapsByVplsName) {
- this.ifacesByVplsName = ifacesByVplsName;
- this.encapsByVplsName = encapsByVplsName;
+ @Override
+ public void addListener(NetworkConfigListener listener) {
+ this.listener = listener;
}
@Override
- public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
- if (!ifacesByVplsName.containsKey(vplsName)) {
- ifaceNames.forEach(ifaceName -> {
- AVAILABLE_INTERFACES.forEach(iface -> {
- if (iface.name().equals(ifaceName)) {
- ifacesByVplsName.put(vplsName, iface);
- }
- });
- });
- }
- if (!ifacesByVplsName.containsKey(vplsName)) {
- encapsByVplsName.put(vplsName, valueOf(encap));
+ public void removeListener(NetworkConfigListener listener) {
+ this.listener = null;
+ }
+
+ /**
+ * Sends network config event to listener.
+ *
+ * @param event the network config event
+ */
+ public void sendEvent(NetworkConfigEvent event) {
+ if (listener != null) {
+ listener.event(event);
}
}
- @Override
- public void removeVpls(String vplsName) {
- if (ifacesByVplsName.containsKey(vplsName)) {
- ifacesByVplsName.removeAll(vplsName);
+ /**
+ * Constructs test config service.
+ * Generates an VPLS configuration with sample VPLS configs.
+ */
+ public TestConfigService() {
+ vplsAppConfig = new VplsAppConfig();
+ final ObjectMapper mapper = new ObjectMapper();
+ final ConfigApplyDelegate delegate = new VplsAppConfigTest.MockCfgDelegate();
+ JsonNode tree = null;
+ try {
+ tree = new ObjectMapper().readTree(EMPTY_JSON_TREE);
+ } catch (IOException e) {
+ e.printStackTrace();
}
+ vplsAppConfig.init(APPID, APP_NAME, tree, mapper, delegate);
+ VplsConfig vplsConfig = new VplsConfig(VPLS1,
+ ImmutableSet.of(V100H1.name(), V100H2.name()),
+ EncapsulationType.NONE);
+ vplsAppConfig.addVpls(vplsConfig);
+ vplsConfig = new VplsConfig(VPLS2,
+ ImmutableSet.of(V200H1.name(), V200H2.name()),
+ EncapsulationType.VLAN);
+ vplsAppConfig.addVpls(vplsConfig);
+
+ }
+
+ /**
+ * Overrides VPLS config to the config service.
+ *
+ * @param vplsAppConfig the new VPLS config
+ */
+ public void setConfig(VplsAppConfig vplsAppConfig) {
+ this.vplsAppConfig = vplsAppConfig;
}
@Override
- public void addIface(String vplsName, String iface) {
- if (!ifacesByVplsName.containsKey(vplsName)) {
- AVAILABLE_INTERFACES.forEach(intf -> {
- if (intf.name().equals(iface)) {
- ifacesByVplsName.put(vplsName, intf);
- }
- });
- }
+ public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+ return (C) vplsAppConfig;
}
@Override
- public void setEncap(String vplsName, String encap) {
- encapsByVplsName.put(vplsName, EncapsulationType.enumFromString(encap));
- }
-
- @Override
- public void removeIface(String iface) {
- SetMultimap<String, Interface> search = HashMultimap.create(ifacesByVplsName);
- search.entries().forEach(e -> {
- if (e.getValue().name().equals(iface)) {
- ifacesByVplsName.remove(e.getKey(), iface);
- }
- });
- }
-
- @Override
- public void cleanVplsConfig() {
- ifacesByVplsName.clear();
- }
-
- @Override
- public EncapsulationType encap(String vplsName) {
- EncapsulationType encap = null;
- if (encapsByVplsName.containsKey(vplsName)) {
- encap = encapsByVplsName.get(vplsName);
- }
- return encap;
- }
-
- @Override
- public Set<String> vplsAffectedByApi() {
- Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectByApi);
-
- vplsAffectByApi.clear();
-
- return vplsNames;
- }
-
- @Override
- public Set<Interface> allIfaces() {
- return ifacesByVplsName.values()
- .stream()
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<Interface> ifaces(String name) {
- return ifacesByVplsName.get(name)
- .stream()
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<String> vplsNames() {
- return ifacesByVplsName.keySet();
- }
-
- @Override
- public Set<String> vplsNamesOld() {
- return ifacesByVplsName.keySet();
- }
-
- public SetMultimap<String, Interface> ifacesByVplsName() {
- return ImmutableSetMultimap.copyOf(ifacesByVplsName);
- }
-
- @Override
- public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
- ConnectPoint connectPoint) {
- String vplsName =
- ifacesByVplsName.entries().stream()
- .filter(e -> e.getValue().connectPoint().equals(connectPoint))
- .filter(e -> e.getValue().vlan().equals(vlan))
- .map(Map.Entry::getKey)
- .findFirst()
- .orElse(null);
- SetMultimap<String, Interface> result = HashMultimap.create();
- if (vplsName != null && ifacesByVplsName.containsKey(vplsName)) {
- ifacesByVplsName.get(vplsName)
- .forEach(intf -> result.put(vplsName, intf));
- return result;
- }
- return null;
+ public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
+ return (C) vplsAppConfig;
}
}
+
}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java
new file mode 100644
index 0000000..eeff5ef
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2017-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.vpls.cli;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test for {@link VplsCommand}.
+ */
+public class VplsCommandTest extends VplsTest {
+ private static final String NEW_LINE = "\n";
+ private static final String SHOW_ALL_RES = "----------------\n" +
+ "VPLS name: \u001B[1mvpls2\u001B[0m\n" +
+ "Associated interfaces: [v200h2, v200h1]\n" +
+ "Encapsulation: NONE\n" +
+ "State: ADDED\n" +
+ "----------------\n" +
+ "VPLS name: \u001B[1mvpls1\u001B[0m\n" +
+ "Associated interfaces: [v100h1, v100h2]\n" +
+ "Encapsulation: NONE\n" +
+ "State: ADDED\n" +
+ "----------------\n";
+ private static final String SHOW_ONE_RES = "VPLS name: \u001B[1mvpls1\u001B[0m\n" +
+ "Associated interfaces: [v100h1, v100h2]\n" +
+ "Encapsulation: NONE\n" +
+ "State: ADDED\n";
+ private static final String IFACE_ALREADY_USED =
+ "\u001B[31mInterface \u001B[1mv200h1\u001B[0m\u001B[31m already associated " +
+ "to VPLS \u001B[1mvpls2\u001B[0m\u001B[31m\u001B[0m\n";
+ private static final String LIST_OUTPUT = VPLS1 + NEW_LINE + VPLS2 + NEW_LINE;
+ VplsCommand vplsCommand;
+
+ @Before
+ public void setup() {
+ vplsCommand = new VplsCommand();
+ vplsCommand.vpls = new TestVpls();
+ vplsCommand.interfaceService = new TestInterfaceService();
+ }
+
+ /**
+ * Creates a new VPLS.
+ */
+ @Test
+ public void testCreate() {
+ vplsCommand.command = VplsCommandEnum.CREATE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.execute();
+ Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+ assertEquals(1, vplss.size());
+ VplsData result = vplss.iterator().next();
+ VplsData expected = VplsData.of(VPLS1, EncapsulationType.NONE);
+ assertEquals(expected, result);
+ }
+
+ /**
+ * Adds new network interface to a VPLS.
+ */
+ @Test
+ public void testAddIf() {
+ vplsCommand.create(VPLS1);
+
+ vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = V100H1.name();
+ vplsCommand.execute();
+
+ vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = V200H1.name();
+ vplsCommand.execute();
+
+ Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+ assertEquals(1, vplss.size());
+ VplsData result = vplss.iterator().next();
+ assertEquals(2, result.interfaces().size());
+ assertTrue(result.interfaces().contains(V100H1));
+ assertTrue(result.interfaces().contains(V200H1));
+ }
+
+ /**
+ * Removes network interface from a VPLS.
+ */
+ @Test
+ public void testRemIf() {
+ vplsCommand.create(VPLS1);
+ vplsCommand.addIface(VPLS1, V100H1.name());
+ vplsCommand.addIface(VPLS1, V200H1.name());
+
+ vplsCommand.command = VplsCommandEnum.REMOVE_IFACE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = V200H1.name();
+ vplsCommand.execute();
+
+ Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+ assertEquals(1, vplss.size());
+ VplsData result = vplss.iterator().next();
+ assertEquals(1, result.interfaces().size());
+ assertTrue(result.interfaces().contains(V100H1));
+ assertFalse(result.interfaces().contains(V200H1));
+ }
+
+ /**
+ * Lists all VPLS names.
+ */
+ @Test
+ public void testList() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ System.setOut(ps);
+ vplsCommand.command = VplsCommandEnum.LIST.toString();
+ vplsCommand.execute();
+ String result = baos.toString();
+
+ assertEquals(LIST_OUTPUT, result);
+ }
+
+ /**
+ * Sets encapsulation to a VPLS.
+ */
+ @Test
+ public void testSetEncap() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+
+ // Sets to NONE
+ vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = EncapsulationType.NONE.name();
+ vplsCommand.execute();
+ VplsData result = vplsCommand.vpls.getVpls(VPLS1);
+ assertEquals(result.encapsulationType(), EncapsulationType.NONE);
+
+ // Sets to VLAN
+ vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = EncapsulationType.VLAN.name();
+ vplsCommand.execute();
+ result = vplsCommand.vpls.getVpls(VPLS1);
+ assertEquals(result.encapsulationType(), EncapsulationType.VLAN);
+
+ // Sets to MPLS
+ vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = EncapsulationType.MPLS.name();
+ vplsCommand.execute();
+ result = vplsCommand.vpls.getVpls(VPLS1);
+ assertEquals(result.encapsulationType(), EncapsulationType.MPLS);
+ }
+
+ /**
+ * Deletes a VPLS.
+ */
+ @Test
+ public void testDelete() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ vplsCommand.command = VplsCommandEnum.DELETE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.execute();
+ Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+ assertEquals(1, vplss.size());
+ }
+
+ /**
+ * Shows all VPLS information.
+ */
+ @Test
+ public void testShowAll() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ System.setOut(ps);
+ vplsCommand.command = VplsCommandEnum.SHOW.toString();
+ vplsCommand.execute();
+ String result = baos.toString();
+ assertEquals(SHOW_ALL_RES, result);
+ }
+
+ /**
+ * Shows a VPLS information.
+ */
+ @Test
+ public void testShowOne() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ System.setOut(ps);
+ vplsCommand.command = VplsCommandEnum.SHOW.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.execute();
+ String result = baos.toString();
+ assertEquals(SHOW_ONE_RES, result);
+ }
+
+ /**
+ * Adds a network interface which already related to another VPLS to a VPLS.
+ */
+ @Test
+ public void testIfaceAssociated() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos);
+ System.setOut(ps);
+ vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+ vplsCommand.vplsName = VPLS1;
+ vplsCommand.optArg = V200H1.name();
+ vplsCommand.execute();
+
+ String result = baos.toString();
+ assertEquals(IFACE_ALREADY_USED, result);
+ }
+
+ /**
+ * Removes all VPLS.
+ */
+ @Test
+ public void testClean() {
+ ((TestVpls) vplsCommand.vpls).initSampleData();
+ vplsCommand.command = VplsCommandEnum.CLEAN.toString();
+ vplsCommand.execute();
+ Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+ assertEquals(0, vplss.size());
+ }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java
new file mode 100644
index 0000000..90d48df
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2017-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.vpls.cli.completer;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.console.CommandSessionHolder;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.cli.VplsCommandEnum;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+
+public class VplsCommandCompleterTest extends VplsTest {
+ private static final String VPLS_CMD = "vpls";
+ private TestCommandSession commandSession;
+
+ @Before
+ public void setup() {
+ commandSession = new TestCommandSession();
+ CommandSessionHolder.setSession(commandSession);
+ }
+
+ /**
+ * Test VPLS command completer.
+ */
+ @Test
+ public void testCommandCompleter() {
+ VplsCommandCompleter commandCompleter = new VplsCommandCompleter();
+ List<String> choices = commandCompleter.choices();
+ List<String> expected = VplsCommandEnum.toStringList();
+ assertEquals(expected, choices);
+ }
+
+ /**
+ * Test VPLS name completer.
+ */
+ @Test
+ public void testNameCompleter() {
+ VplsNameCompleter vplsNameCompleter = new VplsNameCompleter();
+ vplsNameCompleter.vpls = new TestVpls();
+ ((TestVpls) vplsNameCompleter.vpls).initSampleData();
+ List<String> choices = vplsNameCompleter.choices();
+ List<String> expected = ImmutableList.of(VPLS1, VPLS2);
+
+ // Can not ensure the order, use contains all instead of equals
+ assertEquals(choices.size(), expected.size());
+ assertTrue(choices.containsAll(expected));
+ }
+
+ /**
+ * Test VPLS option arguments completer.
+ */
+ @Test
+ public void testOptArgCompleter() {
+ VplsOptArgCompleter completer = new VplsOptArgCompleter();
+ completer.vpls = new TestVpls();
+ ((TestVpls) completer.vpls).initSampleData();
+ completer.interfaceService = new TestInterfaceService();
+
+ // Add interface to VPLS
+ commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.ADD_IFACE.toString(), VPLS1);
+
+ List<String> choices = completer.choices();
+ List<String> expected = ImmutableList.of(V300H1.name(),
+ V300H2.name(),
+ V400H1.name(),
+ VNONEH1.name(),
+ VNONEH2.name(),
+ VNONEH3.name());
+
+ // Can not ensure the order, use contains all instead of equals
+ assertEquals(choices.size(), expected.size());
+ assertTrue(choices.containsAll(expected));
+
+ // Removes interface from VPLS
+ commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.REMOVE_IFACE.toString(), VPLS1);
+ choices = completer.choices();
+ expected = completer.vpls.getVpls(VPLS1).interfaces().stream()
+ .map(Interface::name)
+ .collect(Collectors.toList());
+
+ // Can not ensure the order, use contains all instead of equals
+ assertEquals(choices.size(), expected.size());
+ assertTrue(choices.containsAll(expected));
+
+ // Sets encapsulation
+ commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.SET_ENCAP.toString(), VPLS1);
+ choices = completer.choices();
+ expected = Arrays.stream(EncapsulationType.values())
+ .map(Enum::toString)
+ .collect(Collectors.toList());
+
+ // Can not ensure the order, use contains all instead of equals
+ assertEquals(choices.size(), expected.size());
+ assertTrue(choices.containsAll(expected));
+ }
+
+ /**
+ * Test command session.
+ */
+ class TestCommandSession implements CommandSession {
+ ArgumentCompleter.ArgumentList argumentList;
+ public TestCommandSession() {
+ String[] emptyStringArr = new String[0];
+ argumentList = new ArgumentCompleter.ArgumentList(emptyStringArr,
+ 0,
+ 0,
+ 0);
+ }
+
+ /**
+ * Updates argument list for the command session.
+ *
+ * @param args new arguments
+ */
+ public void updateArguments(String... args) {
+ argumentList = new ArgumentCompleter.ArgumentList(args,
+ 0,
+ 0,
+ 0);
+ }
+
+ @Override
+ public Object execute(CharSequence charSequence) throws Exception {
+ return null;
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public InputStream getKeyboard() {
+ return null;
+ }
+
+ @Override
+ public PrintStream getConsole() {
+ return null;
+ }
+
+ @Override
+ public Object get(String s) {
+ return argumentList;
+ }
+
+ @Override
+ public void put(String s, Object o) {
+
+ }
+
+ @Override
+ public CharSequence format(Object o, int i) {
+ return null;
+ }
+
+ @Override
+ public Object convert(Class<?> aClass, Object o) {
+ return null;
+ }
+ }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
index b3ca89d..37e7598 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
@@ -246,19 +246,28 @@
vplsAppConfig.getVplsWithName(VPLS1).encap());
}
- private class MockCfgDelegate implements ConfigApplyDelegate {
-
+ public static class MockCfgDelegate implements ConfigApplyDelegate {
@Override
public void onApply(@SuppressWarnings("rawtypes") Config config) {
config.apply();
}
}
+ /**
+ * Creates a basic VPLS config.
+ *
+ * @return the VPLS config
+ */
private VplsConfig createInitialVpls() {
Set<String> ifaces = new HashSet<>(Arrays.asList(IF1, IF2, IF3));
return new VplsConfig(VPLS1, ifaces, EncapsulationType.NONE);
}
+ /**
+ * Creates another basic VPLS config.
+ *
+ * @return the VPLS config
+ */
private VplsConfig createNewVpls() {
Set<String> ifaces = new HashSet<>(Arrays.asList(IF4, IF5));
return new VplsConfig(NEWVPLS, ifaces, EncapsulationType.NONE);
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java
new file mode 100644
index 0000000..8baae6c
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017-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.vpls.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+public class VplsConfigManagerTest extends VplsTest {
+ VplsConfigManager vplsConfigManager;
+
+ @Before
+ public void setup() {
+ vplsConfigManager = new VplsConfigManager();
+ vplsConfigManager.configService = new TestConfigService();
+ vplsConfigManager.coreService = new TestCoreService();
+ vplsConfigManager.interfaceService = new TestInterfaceService();
+ vplsConfigManager.registry = new NetworkConfigRegistryAdapter();
+ vplsConfigManager.vpls = new TestVpls();
+ vplsConfigManager.leadershipService = new TestLeadershipService();
+
+ vplsConfigManager.activate();
+ }
+
+ @After
+ public void tearDown() {
+ vplsConfigManager.deactivate();
+ }
+
+ /**
+ * Reloads network configuration by sending a network config event.
+ */
+ @Test
+ public void testReloadConfig() {
+ NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+ null,
+ VplsAppConfig.class);
+ ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+ Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+ assertEquals(2, vplss.size());
+
+ VplsData expect = VplsData.of(VPLS1);
+ expect.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+ expect.state(VplsData.VplsState.ADDED);
+ assertTrue(vplss.contains(expect));
+
+ expect = VplsData.of(VPLS2, EncapsulationType.VLAN);
+ expect.addInterfaces(ImmutableSet.of(V200H1, V200H2));
+ expect.state(VplsData.VplsState.ADDED);
+ System.out.println(vplss);
+ assertTrue(vplss.contains(expect));
+ }
+
+ /**
+ * Sends a network config event with null network config.
+ */
+ @Test
+ public void testReloadNullConfig() {
+ ((TestConfigService) vplsConfigManager.configService).setConfig(null);
+ NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+ null,
+ VplsAppConfig.class);
+ ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+ Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+ assertEquals(0, vplss.size());
+ }
+
+ /**
+ * Updates VPLSs by sending new VPLS config.
+ */
+ @Test
+ public void testReloadConfigUpdateVpls() {
+ ((TestVpls) vplsConfigManager.vpls).initSampleData();
+
+ VplsAppConfig vplsAppConfig = new VplsAppConfig();
+ final ObjectMapper mapper = new ObjectMapper();
+ final ConfigApplyDelegate delegate = new VplsAppConfigTest.MockCfgDelegate();
+ JsonNode tree = null;
+ try {
+ tree = new ObjectMapper().readTree(TestConfigService.EMPTY_JSON_TREE);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ vplsAppConfig.init(APPID, APP_NAME, tree, mapper, delegate);
+ VplsConfig vplsConfig = new VplsConfig(VPLS1,
+ ImmutableSet.of(V100H1.name()),
+ EncapsulationType.MPLS);
+ vplsAppConfig.addVpls(vplsConfig);
+ ((TestConfigService) vplsConfigManager.configService).setConfig(vplsAppConfig);
+ NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+ null,
+ VplsAppConfig.class);
+ ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+ Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+ assertEquals(1, vplss.size());
+
+ VplsData expect = VplsData.of(VPLS1, EncapsulationType.MPLS);
+ expect.addInterfaces(ImmutableSet.of(V100H1));
+ expect.state(VplsData.VplsState.ADDED);
+ assertTrue(vplss.contains(expect));
+ }
+
+ /**
+ * Remvoes all VPLS by sending CONFIG_REMOVED event.
+ */
+ @Test
+ public void testRemoveConfig() {
+ NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_REMOVED,
+ null,
+ VplsAppConfig.class);
+ ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+ Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+ assertEquals(0, vplss.size());
+ }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java
new file mode 100644
index 0000000..bcc70af
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017-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.vpls.store;
+
+import com.google.common.collect.Maps;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsStore;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Test adapter for VPLS store.
+ */
+public class VplsStoreAdapter implements VplsStore {
+ protected Map<String, VplsData> vplsDataMap;
+ protected StoreDelegate<VplsStoreEvent> delegate;
+
+ public VplsStoreAdapter() {
+ vplsDataMap = Maps.newHashMap();
+ }
+
+ @Override
+ public void setDelegate(StoreDelegate<VplsStoreEvent> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void unsetDelegate(StoreDelegate<VplsStoreEvent> delegate) {
+ this.delegate = null;
+ }
+
+ @Override
+ public boolean hasDelegate() {
+ return this.delegate != null;
+ }
+
+ @Override
+ public void addVpls(VplsData vplsData) {
+ vplsDataMap.put(vplsData.name(), vplsData);
+ }
+
+ @Override
+ public void removeVpls(VplsData vplsData) {
+ vplsDataMap.remove(vplsData.name());
+ }
+
+ @Override
+ public void updateVpls(VplsData vplsData) {
+ vplsDataMap.put(vplsData.name(), vplsData);
+ }
+
+ @Override
+ public VplsData getVpls(String vplsName) {
+ return vplsDataMap.get(vplsName);
+ }
+
+ @Override
+ public Collection<VplsData> getAllVpls() {
+ return vplsDataMap.values();
+ }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java
new file mode 100644
index 0000000..31a2176
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-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.vpls.store;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.store.service.TestStorageService;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.config.VplsAppConfig;
+import org.onosproject.vpls.config.VplsConfig;
+
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.EncapsulationType.VLAN;
+
+public class VplsStoreTest extends VplsTest {
+ private DistributedVplsStore vplsStore;
+
+ @Before
+ public void setup() {
+ vplsStore = new DistributedVplsStore();
+ vplsStore.coreService = new TestCoreService();
+ vplsStore.storageService = new TestStorageService();
+ vplsStore.networkConfigService = new TestConfigService();
+ vplsStore.active();
+ }
+
+ @After
+ public void tearDown() {
+ vplsStore.deactive();
+ }
+
+ /**
+ * Adds a VPLS to the store; checks if config store is also updated.
+ */
+ @Test
+ public void testAddVpls() {
+ VplsData vplsData = VplsData.of(VPLS1, VLAN);
+ vplsStore.addVpls(vplsData);
+ Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+
+ assertEquals(1, vplsDataCollection.size());
+ assertTrue(vplsDataCollection.contains(vplsData));
+
+ VplsAppConfig storedConfig = vplsStore.networkConfigService
+ .getConfig(null, VplsAppConfig.class);
+ assertNotEquals(-1L, storedConfig.updateTime());
+
+ assertEquals(1, storedConfig.vplss().size());
+
+ VplsConfig vplsConfig = storedConfig.vplss().iterator().next();
+
+ assertEquals(VPLS1, vplsConfig.name());
+ assertEquals(0, vplsConfig.ifaces().size());
+ assertEquals(VLAN, vplsConfig.encap());
+ }
+
+ /**
+ * Removes a VPLS from store; checks if config store is also updated.
+ */
+ @Test
+ public void testRemoveVpls() {
+ VplsData vplsData = VplsData.of(VPLS1, VLAN);
+ vplsStore.addVpls(vplsData);
+ vplsStore.removeVpls(vplsData);
+
+ Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+ assertEquals(0, vplsDataCollection.size());
+
+ VplsAppConfig storedConfig = vplsStore.networkConfigService
+ .getConfig(null, VplsAppConfig.class);
+
+ assertNotEquals(-1L, storedConfig.updateTime());
+
+ assertEquals(0, storedConfig.vplss().size());
+ }
+
+ /**
+ * Updates a VPLS from store; checks if config store is also updated.
+ */
+ @Test
+ public void testUpdateVpls() {
+ VplsData vplsData = VplsData.of(VPLS1, VLAN);
+ vplsStore.addVpls(vplsData);
+ vplsData.addInterface(V100H1);
+ vplsData.addInterface(V100H2);
+ vplsStore.updateVpls(vplsData);
+
+ Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+ assertEquals(1, vplsDataCollection.size());
+ VplsData newVplsData = vplsDataCollection.iterator().next();
+
+ assertEquals(vplsData, newVplsData);
+
+ VplsAppConfig storedConfig = vplsStore.networkConfigService
+ .getConfig(null, VplsAppConfig.class);
+
+ assertNotEquals(-1L, storedConfig.updateTime());
+
+ assertEquals(1, storedConfig.vplss().size());
+
+ VplsConfig vplsConfig = storedConfig.vplss().iterator().next();
+
+ assertEquals(VPLS1, vplsConfig.name());
+ assertEquals(2, vplsConfig.ifaces().size());
+ assertTrue(vplsConfig.ifaces().contains(V100H1.name()));
+ assertTrue(vplsConfig.ifaces().contains(V100H2.name()));
+ assertEquals(VLAN, vplsConfig.encap());
+ }
+}