blob: 3c9f5aaba51a816061e9cbab777974b72f321586 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* 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.opencord.igmpproxy.impl;
import static org.junit.Assert.assertEquals;
import static org.onlab.junit.TestTools.assertAfter;
import java.util.List;
import com.google.common.collect.Maps;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.VlanId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.net.flow.FlowRuleServiceAdapter;
import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
import org.onosproject.store.service.TestStorageService;
import org.opencord.igmpproxy.IgmpStatisticType;
import org.opencord.igmpproxy.IgmpStatisticsEvent;
import com.google.common.collect.Lists;
import org.opencord.igmpproxy.IgmpStatisticsEventListener;
/**
* Set of tests of the ONOS application component for IGMP Statistics.
*/
public class IgmpStatisticsTest extends IgmpManagerBase {
private static final int WAIT_TIMEOUT = 500;
private IgmpManager igmpManager;
private IgmpStatisticsManager igmpStatisticsManager;
private MockIgmpStatisticsEventListener mockListener = new MockIgmpStatisticsEventListener();
// Set up the IGMP application.
@Before
public void setUp() {
igmpManager = new IgmpManager();
igmpManager.igmpLeadershipService = new TestIgmpLeaderShipService();
igmpManager.coreService = new CoreServiceAdapter();
igmpManager.mastershipService = new MockMastershipService();
igmpManager.flowObjectiveService = new FlowObjectiveServiceAdapter();
igmpManager.deviceService = new MockDeviceService();
igmpManager.packetService = new MockPacketService();
igmpManager.flowRuleService = new FlowRuleServiceAdapter();
igmpManager.multicastService = new TestMulticastRouteService();
igmpManager.sadisService = new MockSadisService();
igmpManager.groupMemberStore = new TestGroupMemberStoreService();
StateMachineManager stateMachineService = new StateMachineManager();
stateMachineService.stateMachineStore = new TestStateMachineStoreService(Maps.newConcurrentMap());
stateMachineService.activate(new MockComponentContext());
igmpManager.stateMachineService = stateMachineService;
igmpStatisticsManager = new IgmpStatisticsManager();
igmpStatisticsManager.cfgService = new MockCfgService();
igmpStatisticsManager.addListener(mockListener);
TestUtils.setField(igmpStatisticsManager, "eventDispatcher", new TestEventDispatcher());
igmpStatisticsManager.storageService = new TestStorageService();
igmpStatisticsManager.leadershipManager = new TestIgmpLeaderShipService();
igmpStatisticsManager.clusterCommunicationService = new ClusterCommunicationServiceAdapter();
igmpStatisticsManager.activate(new MockComponentContext());
igmpManager.igmpStatisticsManager = this.igmpStatisticsManager;
// By default - we send query messages
StateMachineManager.sendQuery = true;
}
// Tear Down the IGMP application.
@After
public void tearDown() {
igmpStatisticsManager.removeListener(mockListener);
igmpStatisticsManager.deactivate();
igmpManager.stateMachineService.clearAllMaps();
}
//Test Igmp Statistics.
@Test
public void testIgmpStatistics() throws InterruptedException {
StateMachineManager.sendQuery = false;
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
//IGMPv3 Join
flagForPacket = false;
Ethernet igmpv3MembershipReportPkt = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
sendPacket(igmpv3MembershipReportPkt);
synchronized (savedPackets) {
savedPackets.wait(WAIT_TIMEOUT);
}
//Leave
flagForPacket = false;
Ethernet igmpv3LeavePkt = IgmpSender.getInstance().buildIgmpV3Leave(GROUP_IP, SOURCE_IP_OF_A);
sendPacket(igmpv3LeavePkt);
synchronized (savedPackets) {
savedPackets.wait(WAIT_TIMEOUT);
}
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals((long) 2, igmpStatisticsManager
.getStat(IgmpStatisticType.TOTAL_MSG_RECEIVED).longValue()));
assertEquals(1L, igmpStatisticsManager.getStat(IgmpStatisticType.IGMP_JOIN_REQ).longValue());
assertEquals(2L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_V3_MEMBERSHIP_REPORT).longValue());
assertEquals(1L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_SUCCESS_JOIN_RE_JOIN_REQ).longValue());
assertEquals(1L, igmpStatisticsManager
.getStat(IgmpStatisticType.UNCONFIGURED_GROUP_COUNTER).longValue());
assertEquals(2L, igmpStatisticsManager
.getStat(IgmpStatisticType.VALID_IGMP_PACKET_COUNTER).longValue());
assertEquals(1L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_CHANNEL_JOIN_COUNTER).longValue());
assertEquals(1L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_LEAVE_REQ).longValue());
assertEquals(2L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_MSG_RECEIVED).longValue());
assertEquals(2L, igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_VALID_CHECKSUM_COUNTER).longValue());
}
//Test packet with Unknown Multicast IpAddress
@Test
public void testIgmpUnknownMulticastIpAddress() throws InterruptedException {
StateMachineManager.sendQuery = false;
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
Ethernet firstPacket =
IgmpSender.getInstance().buildIgmpV3Join(UNKNOWN_GRP_IP, SOURCE_IP_OF_A);
// Sending first packet
sendPacket(firstPacket);
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals((long) 1, igmpStatisticsManager
.getStat(IgmpStatisticType.FAIL_JOIN_REQ_UNKNOWN_MULTICAST_IP_COUNTER).longValue()));
}
//Test Igmp Query Statistics.
@Test
public void testIgmpQueryStatistics() throws InterruptedException {
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
flagForQueryPacket = true;
//IGMPV3 Group Specific Membership Query packet
Ethernet igmpv3MembershipQueryPkt = IgmpSender.getInstance().
buildIgmpV3Query(GROUP_IP, SOURCE_IP_OF_A, VlanId.MAX_VLAN);
sendPacket(igmpv3MembershipQueryPkt);
//IGMPV3 General Membership Query packet
Ethernet igmpv3MembershipQueryPkt1 =
IgmpSender.getInstance().buildIgmpV3Query(Ip4Address.valueOf(0), SOURCE_IP_OF_A, VlanId.MAX_VLAN);
sendPacket(igmpv3MembershipQueryPkt1);
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals(igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_GRP_AND_SRC_SPESIFIC_MEMBERSHIP_QUERY).longValue(), 1));
assertEquals(igmpStatisticsManager
.getStat(IgmpStatisticType.IGMP_GENERAL_MEMBERSHIP_QUERY).longValue(), 1);
assertEquals(igmpStatisticsManager.getStat(IgmpStatisticType.CURRENT_GRP_NUMBER_COUNTER).longValue(), 1);
}
//Test Events
@Test
public void testIgmpStatisticsEvent() {
final int waitEventGeneration = igmpStatisticsManager.statisticsGenerationPeriodInSeconds * 1000;
//assert that event listened as the app activates
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals(mockListener.events.size(), 1));
assertAfter(waitEventGeneration / 2, waitEventGeneration, () ->
assertEquals(mockListener.events.size(), 2));
for (IgmpStatisticsEvent event : mockListener.events) {
assertEquals(event.type(), IgmpStatisticsEvent.Type.STATS_UPDATE);
}
}
//Test packet with Unknown Wrong Membership mode
@Test
public void testWrongIgmpPacket() throws InterruptedException {
StateMachineManager.sendQuery = false;
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
Ethernet firstPacket = buildWrongIgmpPacket(GROUP_IP, SOURCE_IP_OF_A);
// Sending first packet
sendPacket(firstPacket);
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals((long) 1, igmpStatisticsManager
.getStat(IgmpStatisticType.REPORTS_RX_WITH_WRONG_MODE_COUNTER).longValue()));
}
//Test packet with Unknown IGMP type.
@Test
public void testUnknownIgmpPacket() throws InterruptedException {
StateMachineManager.sendQuery = false;
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
Ethernet firstPacket = buildUnknownIgmpPacket(GROUP_IP, SOURCE_IP_OF_A);
// Sending first packet
sendPacket(firstPacket);
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals((long) 1, igmpStatisticsManager
.getStat(IgmpStatisticType.UNKNOWN_IGMP_TYPE_PACKETS_RX_COUNTER).longValue()));
}
//Test packet with Insufficient Permission.
@Test
public void testSufficientPermission() throws InterruptedException {
StateMachineManager.sendQuery = false;
flagForPermission = true;
igmpManager.networkConfig = new TestNetworkConfigRegistry(false);
igmpManager.activate();
Ethernet firstPacket = IgmpSender.getInstance().buildIgmpV3Join(GROUP_IP, SOURCE_IP_OF_A);
// Sending first packet
sendPacket(firstPacket);
assertAfter(WAIT_TIMEOUT, WAIT_TIMEOUT * 2, () ->
assertEquals((long) 1, igmpStatisticsManager
.getStat(IgmpStatisticType.FAIL_JOIN_REQ_INSUFF_PERMISSION_ACCESS_COUNTER).longValue()));
}
public class MockIgmpStatisticsEventListener implements IgmpStatisticsEventListener {
protected List<IgmpStatisticsEvent> events = Lists.newArrayList();
@Override
public void event(IgmpStatisticsEvent event) {
events.add(event);
}
}
}