VOL-2901 Unit tests and necessary updates on stats manager
in the scope of VOL-2796
Change-Id: I95d6fd0241d2c54a5a122d58917c6dc45e5abcf7
diff --git a/api/src/main/java/org/opencord/cordmcast/CordMcastStatistics.java b/api/src/main/java/org/opencord/cordmcast/CordMcastStatistics.java
index 6bdb702..10c05af 100644
--- a/api/src/main/java/org/opencord/cordmcast/CordMcastStatistics.java
+++ b/api/src/main/java/org/opencord/cordmcast/CordMcastStatistics.java
@@ -28,9 +28,11 @@
private String sourceAddress;
//vlan id used in mcast event.
private VlanId vlanId;
+ private VlanId innerVlanId;
- public CordMcastStatistics(IpAddress groupAddress, String sourceAddresss, VlanId vlanId) {
+ public CordMcastStatistics(IpAddress groupAddress, String sourceAddresss, VlanId vlanId, VlanId innerVlanId) {
this.vlanId = vlanId;
+ this.innerVlanId = innerVlanId;
this.sourceAddress = sourceAddresss;
this.groupAddress = groupAddress;
}
@@ -58,4 +60,12 @@
public void setVlanId(VlanId vlanId) {
this.vlanId = vlanId;
}
+
+ public VlanId getInnerVlanId() {
+ return innerVlanId;
+ }
+
+ public void setInnerVlanId(VlanId innerVlanId) {
+ this.innerVlanId = innerVlanId;
+ }
}
diff --git a/api/src/main/java/org/opencord/cordmcast/CordMcastStatisticsService.java b/api/src/main/java/org/opencord/cordmcast/CordMcastStatisticsService.java
index 3ab6f09..9b9ba71 100644
--- a/api/src/main/java/org/opencord/cordmcast/CordMcastStatisticsService.java
+++ b/api/src/main/java/org/opencord/cordmcast/CordMcastStatisticsService.java
@@ -27,5 +27,11 @@
* To set current vlanValue in Statistics Service.
* @param vlanValue current vlan value.
*/
- public void setVlanValue(VlanId vlanValue);
+ void setVlanValue(VlanId vlanValue);
+
+ /**
+ * To set current innerVlanValue in Statistics Service.
+ * @param innerVlanValue current inner vlan value.
+ */
+ void setInnerVlanValue(VlanId innerVlanValue);
}
diff --git a/app/src/main/java/org/opencord/cordmcast/impl/CordMcast.java b/app/src/main/java/org/opencord/cordmcast/impl/CordMcast.java
index f1b9429..d107f05 100644
--- a/app/src/main/java/org/opencord/cordmcast/impl/CordMcast.java
+++ b/app/src/main/java/org/opencord/cordmcast/impl/CordMcast.java
@@ -241,7 +241,7 @@
log.error("Unable to parse configuration parameter for priority", ne);
priority = DEFAULT_PRIORITY;
}
- cordMcastStatisticsService.setVlanValue(assignedVlan());
+ feedStatsServiceWithVlanConfigValues();
}
@Deactivate
@@ -256,6 +256,14 @@
log.info("Stopped");
}
+ /**
+ * Updates the stats service with current VLAN config values.
+ */
+ private void feedStatsServiceWithVlanConfigValues() {
+ cordMcastStatisticsService.setVlanValue(assignedVlan());
+ cordMcastStatisticsService.setInnerVlanValue(assignedInnerVlan());
+ }
+
public void clearGroups() {
mcastLock();
try {
@@ -574,6 +582,7 @@
if (config.egressInnerVlan() != null) {
mcastInnerVlan = config.egressInnerVlan();
}
+ feedStatsServiceWithVlanConfigValues();
}
private class NextKey {
diff --git a/app/src/main/java/org/opencord/cordmcast/impl/CordMcastStatisticsManager.java b/app/src/main/java/org/opencord/cordmcast/impl/CordMcastStatisticsManager.java
index a5715f4..1044adc 100644
--- a/app/src/main/java/org/opencord/cordmcast/impl/CordMcastStatisticsManager.java
+++ b/app/src/main/java/org/opencord/cordmcast/impl/CordMcastStatisticsManager.java
@@ -78,6 +78,7 @@
private ScheduledExecutorService executor;
private VlanId vlanId;
+ private VlanId innerVlanId;
@Activate
public void activate(ComponentContext context) {
@@ -119,7 +120,7 @@
routes.forEach(route -> {
mcastData.add(new CordMcastStatistics(route.group(),
route.source().isEmpty() ? "*" : route.source().get().toString(),
- vlanId));
+ vlanId, innerVlanId));
});
return mcastData;
}
@@ -129,6 +130,11 @@
vlanId = vlanValue;
}
+ @Override
+ public void setInnerVlanValue(VlanId innerVlanValue) {
+ innerVlanId = innerVlanValue;
+ }
+
/**
* pushing mcast stat data as event.
*/
@@ -141,7 +147,9 @@
" | Source: " +
(mcastStats.getSourceAddress() != null ? mcastStats.getSourceAddress().toString() : "null") +
" | Vlan: " +
- (mcastStats.getVlanId() != null ? mcastStats.getVlanId().toString() : "null"));
+ (mcastStats.getVlanId() != null ? mcastStats.getVlanId().toString() : "null") +
+ " | InnerVlan: " +
+ (mcastStats.getInnerVlanId() != null ? mcastStats.getInnerVlanId().toString() : "null"));
});
post(new CordMcastStatisticsEvent(CordMcastStatisticsEvent.Type.STATUS_UPDATE, routeList));
}
diff --git a/app/src/test/java/org/opencord/cordmcast/impl/McastTest.java b/app/src/test/java/org/opencord/cordmcast/impl/McastTest.java
index a622e6d..9e64dca 100644
--- a/app/src/test/java/org/opencord/cordmcast/impl/McastTest.java
+++ b/app/src/test/java/org/opencord/cordmcast/impl/McastTest.java
@@ -36,7 +36,9 @@
import org.onosproject.net.HostId;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.store.service.StorageServiceAdapter;
@@ -71,51 +73,7 @@
@Before
public void setUp() {
- cordMcast = new CordMcast();
- cordMcastStatisticsManager = new CordMcastStatisticsManager();
-
- cordMcast.coreService = new MockCoreService();
- cordMcast.networkConfig = new TestNetworkConfigRegistry();
- cordMcast.flowObjectiveService = new MockFlowObjectiveService();
- cordMcast.mastershipService = new TestMastershipService();
- cordMcast.deviceService = new MockDeviceService();
- cordMcast.componentConfigService = new ComponentConfigAdapter();
- cordMcastStatisticsManager.componentConfigService = new ComponentConfigAdapter();
- cordMcastStatisticsManager.addListener(mockListener);
- cordMcast.sadisService = new MockSadisService();
- cordMcast.cordMcastStatisticsService = cordMcastStatisticsManager;
-
- cordMcast.storageService = EasyMock.createMock(StorageServiceAdapter.class);
- expect(cordMcast.storageService.consistentMapBuilder()).andReturn(new TestConsistentMap.Builder<>());
- replay(cordMcast.storageService);
-
- Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
- cfgDict.put("vlanEnabled", false);
- cfgDict.put("eventGenerationPeriodInSeconds", EVENT_GENERATION_PERIOD);
-
- cordMcast.componentConfigService = EasyMock.createNiceMock(ComponentConfigService.class);
- replay(cordMcast.componentConfigService);
-
- Set<McastRoute> route1Set = new HashSet<McastRoute>();
- route1Set.add(route1);
-
- cordMcast.mcastService = EasyMock.createNiceMock(MulticastRouteService.class);
- expect(cordMcast.mcastService.getRoutes()).andReturn(Sets.newHashSet());
- replay(cordMcast.mcastService);
-
- cordMcastStatisticsManager.mcastService = EasyMock.createNiceMock(MulticastRouteService.class);
- expect(cordMcastStatisticsManager.mcastService.getRoutes()).andReturn(route1Set).times(2);
- replay(cordMcastStatisticsManager.mcastService);
-
- TestUtils.setField(cordMcastStatisticsManager, "eventDispatcher", new TestEventDispatcher());
-
- ComponentContext componentContext = EasyMock.createMock(ComponentContext.class);
- expect(componentContext.getProperties()).andReturn(cfgDict).times(2);
- replay(componentContext);
- cordMcast.cordMcastStatisticsService = cordMcastStatisticsManager;
- cordMcastStatisticsManager.activate(componentContext);
-
- cordMcast.activate(componentContext);
+ //setup operation is handled by init() method in each test
}
@After
@@ -125,8 +83,61 @@
nextMap.clear();
}
+ private void init(boolean vlanEnabled, VlanId egressVlan, VlanId egressInnerVlan) {
+ cordMcast = new CordMcast();
+ cordMcastStatisticsManager = new CordMcastStatisticsManager();
+ cordMcast.coreService = new MockCoreService();
+
+ TestNetworkConfigRegistry testNetworkConfigRegistry = new TestNetworkConfigRegistry();
+ testNetworkConfigRegistry.setEgressVlan(egressVlan);
+ testNetworkConfigRegistry.setEgressInnerVlan(egressInnerVlan);
+ cordMcast.networkConfig = testNetworkConfigRegistry;
+
+ cordMcast.flowObjectiveService = new MockFlowObjectiveService();
+ cordMcast.mastershipService = new TestMastershipService();
+ cordMcast.deviceService = new MockDeviceService();
+ cordMcast.componentConfigService = new ComponentConfigAdapter();
+ cordMcastStatisticsManager.componentConfigService = new ComponentConfigAdapter();
+ cordMcastStatisticsManager.addListener(mockListener);
+ cordMcast.sadisService = new MockSadisService();
+ cordMcast.cordMcastStatisticsService = cordMcastStatisticsManager;
+
+ cordMcast.storageService = EasyMock.createMock(StorageServiceAdapter.class);
+ expect(cordMcast.storageService.consistentMapBuilder()).andReturn(new TestConsistentMap.Builder<>());
+ replay(cordMcast.storageService);
+
+ Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
+ cfgDict.put("vlanEnabled", vlanEnabled);
+ cfgDict.put("eventGenerationPeriodInSeconds", EVENT_GENERATION_PERIOD);
+
+ cordMcast.componentConfigService = EasyMock.createNiceMock(ComponentConfigService.class);
+ replay(cordMcast.componentConfigService);
+
+ Set<McastRoute> route1Set = new HashSet<McastRoute>();
+ route1Set.add(route1);
+
+ cordMcast.mcastService = EasyMock.createNiceMock(MulticastRouteService.class);
+ expect(cordMcast.mcastService.getRoutes()).andReturn(Sets.newHashSet());
+ replay(cordMcast.mcastService);
+
+ cordMcastStatisticsManager.mcastService = EasyMock.createNiceMock(MulticastRouteService.class);
+ expect(cordMcastStatisticsManager.mcastService.getRoutes()).andReturn(route1Set).times(2);
+ replay(cordMcastStatisticsManager.mcastService);
+
+ TestUtils.setField(cordMcastStatisticsManager, "eventDispatcher", new TestEventDispatcher());
+
+ ComponentContext componentContext = EasyMock.createMock(ComponentContext.class);
+ expect(componentContext.getProperties()).andReturn(cfgDict).times(2);
+ replay(componentContext);
+ cordMcast.cordMcastStatisticsService = cordMcastStatisticsManager;
+ cordMcastStatisticsManager.activate(componentContext);
+
+ cordMcast.activate(componentContext);
+ }
+
@Test
public void testAddingSinkEvent() throws InterruptedException {
+ init(false, null, null);
Set<ConnectPoint> sinks2Cp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B));
Map<HostId, Set<ConnectPoint>> sinks2 = ImmutableMap.of(HOST_ID_NONE, sinks2Cp);
@@ -160,12 +171,109 @@
IPCriterion ipCriterion = ipAddress(trafficSelector);
assertNotNull(ipCriterion);
assertTrue(MULTICAST_IP.equals(ipCriterion.ip().address()));
+ //checking the vlan criterion
+ TrafficSelector meta = forwardMap.get(DEVICE_ID_OF_A).meta();
+ VlanIdCriterion vlanId = vlanId(meta, Criterion.Type.VLAN_VID);
+ assertNull(vlanId); //since vlanEnabled flag is false
+ VlanIdCriterion innerVlanIdCriterion = vlanId(meta, Criterion.Type.INNER_VLAN_VID);
+ assertNull(innerVlanIdCriterion);
+ }
+ @Test
+ public void testAddingSinkEventVlanEnabled() throws InterruptedException {
+ // vlanEnabled is set to true and just egressVlan is set
+ init(true, VlanId.vlanId("4000"), null);
+
+ Set<ConnectPoint> sinks2Cp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B));
+ Map<HostId, Set<ConnectPoint>> sinks2 = ImmutableMap.of(HOST_ID_NONE, sinks2Cp);
+
+ //Adding the details to create different routes
+ previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+ currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks2);
+ // Creating new mcast event for adding sink
+ McastEvent event = new McastEvent(McastEvent.Type.SINKS_ADDED, previousSubject, currentSubject);
+ cordMcast.listener.event(event);
+ synchronized (forwardMap) {
+ forwardMap.wait(WAIT_TIMEOUT);
+ }
+ // ForwardMap will contain the operation "Add" in the flowObjective. None -> CP_B
+ assertNotNull(forwardMap.get(DEVICE_ID_OF_A));
+ assertTrue(forwardMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.ADD);
+
+ // Output port number will be PORT_B i.e. 16
+ Collection<TrafficTreatment> traffictreatMentCollection =
+ nextMap.get(DEVICE_ID_OF_A).next();
+ assertTrue(1 == traffictreatMentCollection.size());
+ OutputInstruction output = null;
+ for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+ output = outputPort(trafficTreatment);
+ }
+ assertNotNull(output);
+ assertTrue(PORT_B == output.port());
+ // Checking the group ip address
+ TrafficSelector trafficSelector = forwardMap.get(DEVICE_ID_OF_A).selector();
+ IPCriterion ipCriterion = ipAddress(trafficSelector);
+ assertNotNull(ipCriterion);
+ assertTrue(MULTICAST_IP.equals(ipCriterion.ip().address()));
+ //checking the vlan criteria
+ TrafficSelector meta = forwardMap.get(DEVICE_ID_OF_A).meta();
+ VlanIdCriterion vlanIdCriterion = vlanId(meta, Criterion.Type.VLAN_VID);
+ assertNotNull(vlanIdCriterion); //since vlanEnabled flag is true
+ assertEquals(cordMcast.assignedVlan(), vlanIdCriterion.vlanId());
+ VlanIdCriterion innerVlanIdCriterion = vlanId(meta, Criterion.Type.INNER_VLAN_VID);
+ assertNull(innerVlanIdCriterion);
+ }
+
+ @Test
+ public void testAddingSinkEventInnerVlanEnabled() throws InterruptedException {
+ // vlanEnabled is set to true and egressVlan & egressInnerVlan are set
+ init(true, VlanId.vlanId("4000"), VlanId.vlanId("1000"));
+
+ Set<ConnectPoint> sinks2Cp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B));
+ Map<HostId, Set<ConnectPoint>> sinks2 = ImmutableMap.of(HOST_ID_NONE, sinks2Cp);
+
+ //Adding the details to create different routes
+ previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks);
+ currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, sources, sinks2);
+ // Creating new mcast event for adding sink
+ McastEvent event = new McastEvent(McastEvent.Type.SINKS_ADDED, previousSubject, currentSubject);
+ cordMcast.listener.event(event);
+ synchronized (forwardMap) {
+ forwardMap.wait(WAIT_TIMEOUT);
+ }
+
+ // ForwardMap will contain the operation "Add" in the flowObjective. None -> CP_B
+ assertNotNull(forwardMap.get(DEVICE_ID_OF_A));
+ assertTrue(forwardMap.get(DEVICE_ID_OF_A).op() == Objective.Operation.ADD);
+
+ // Output port number will be PORT_B i.e. 16
+ Collection<TrafficTreatment> traffictreatMentCollection =
+ nextMap.get(DEVICE_ID_OF_A).next();
+ assertTrue(1 == traffictreatMentCollection.size());
+ OutputInstruction output = null;
+ for (TrafficTreatment trafficTreatment : traffictreatMentCollection) {
+ output = outputPort(trafficTreatment);
+ }
+ assertNotNull(output);
+ assertTrue(PORT_B == output.port());
+ // Checking the group ip address
+ TrafficSelector trafficSelector = forwardMap.get(DEVICE_ID_OF_A).selector();
+ IPCriterion ipCriterion = ipAddress(trafficSelector);
+ assertNotNull(ipCriterion);
+ assertTrue(MULTICAST_IP.equals(ipCriterion.ip().address()));
+ //checking the vlan criteria
+ TrafficSelector meta = forwardMap.get(DEVICE_ID_OF_A).meta();
+ VlanIdCriterion vlanIdCriterion = vlanId(meta, Criterion.Type.VLAN_VID);
+ assertNotNull(vlanIdCriterion); //since vlanEnabled flag is true
+ assertEquals(cordMcast.assignedVlan(), vlanIdCriterion.vlanId());
+ VlanIdCriterion innerVlanIdCriterion = vlanId(meta, Criterion.Type.INNER_VLAN_VID);
+ assertNotNull(innerVlanIdCriterion);
+ assertEquals(cordMcast.assignedInnerVlan(), innerVlanIdCriterion.vlanId());
}
@Test
public void testAddToExistingSinkEvent() throws InterruptedException {
-
+ init(false, null, null);
// Adding first sink (none --> CP_B)
testAddingSinkEvent();
@@ -195,7 +303,7 @@
@Test
public void testRemoveSinkEvent() throws InterruptedException {
-
+ init(false, null, null);
testAddToExistingSinkEvent();
// Handling the mcast event for removing sink.
Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_B, CONNECT_POINT_C));
@@ -226,7 +334,7 @@
@Test
public void testRemoveLastSinkEvent() throws InterruptedException {
-
+ init(false, null, null);
testRemoveSinkEvent();
// Handling the mcast event for removing sink.
Set<ConnectPoint> sinksCp = new HashSet<ConnectPoint>(Arrays.asList(CONNECT_POINT_C));
@@ -255,7 +363,7 @@
@Test
public void testUnkownOltDevice() throws InterruptedException {
-
+ init(false, null, null);
// Configuration of mcast event for unknown olt device
final DeviceId deviceIdOfB = DeviceId.deviceId("of:1");
@@ -283,7 +391,7 @@
@Test
public void testRouteAddedEvent() throws InterruptedException {
-
+ init(false, null, null);
//Adding the details to create different routes
previousSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
currentSubject = McastRouteUpdate.mcastRouteUpdate(route1, emptySource, sinks);
@@ -299,7 +407,7 @@
@Test
public void testRouteRemovedEvent() throws InterruptedException {
-
+ init(false, null, null);
testRouteAddedEvent();
//Adding the details to create different routes
@@ -316,7 +424,7 @@
@Test
public void testSourceAddedEvent() throws InterruptedException {
-
+ init(false, null, null);
// Adding route before adding source.
testRouteAddedEvent();
@@ -334,7 +442,7 @@
@Test
public void testSourcesRemovedEvent() throws InterruptedException {
-
+ init(false, null, null);
testSourceAddedEvent();
//Adding the details to create different routes
@@ -350,6 +458,7 @@
@Test
public void mcastTestEventGeneration() throws InterruptedException {
+ init(false, VlanId.vlanId("4000"), VlanId.NONE);
//fetching route details used to push CordMcastStatisticsEvent.
IpAddress testGroup = route1.group();
String testSource = route1.source().isEmpty() ? "*" : route1.source().get().toString();
diff --git a/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java b/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java
index 986c175..4ae2825 100644
--- a/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java
+++ b/app/src/test/java/org/opencord/cordmcast/impl/McastTestBase.java
@@ -54,6 +54,7 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
@@ -164,14 +165,22 @@
* Mocks the McastConfig class to return vlan id value.
*/
static class MockMcastConfig extends McastConfig {
+ private VlanId egressVlan;
+ private VlanId egressInnerVlan;
+
+ public MockMcastConfig(VlanId egressVlan, VlanId egressInnerVlan) {
+ this.egressVlan = egressVlan;
+ this.egressInnerVlan = egressInnerVlan;
+ }
+
@Override
public VlanId egressVlan() {
- return VlanId.vlanId("4000");
+ return egressVlan;
}
@Override
public VlanId egressInnerVlan() {
- return VlanId.NONE;
+ return egressInnerVlan;
}
}
@@ -181,9 +190,21 @@
@SuppressWarnings("unchecked")
static final class TestNetworkConfigRegistry
extends NetworkConfigRegistryAdapter {
+
+ private VlanId egressVlan = VlanId.vlanId("4000");
+ private VlanId egressInnerVlan = VlanId.NONE;
+
+ public void setEgressVlan(VlanId egressVlan) {
+ this.egressVlan = egressVlan;
+ }
+
+ public void setEgressInnerVlan(VlanId egressInnerVlan) {
+ this.egressInnerVlan = egressInnerVlan;
+ }
+
@Override
public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
- McastConfig mcastConfig = new MockMcastConfig();
+ McastConfig mcastConfig = new MockMcastConfig(egressVlan, egressInnerVlan);
return (C) mcastConfig;
}
}
@@ -293,4 +314,16 @@
return (IPCriterion) ipCriterion;
}
+ public VlanIdCriterion vlanId(TrafficSelector trafficSelector, Criterion.Type type) {
+ Set<Criterion> criterionSet = trafficSelector.criteria();
+ Iterator<Criterion> it = criterionSet.iterator();
+ VlanIdCriterion criterion = null;
+ while (it.hasNext()) {
+ Criterion criteria = it.next();
+ if (type == criteria.type()) {
+ criterion = (VlanIdCriterion) criteria;
+ }
+ }
+ return criterion;
+ }
}