blob: 4106ef1b47130681c945b7a95c312021d6047830 [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.dhcpl2relay.impl;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.packet.DHCP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.UDP;
import org.onlab.packet.dhcp.DhcpOption;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
import org.onosproject.store.service.TestStorageService;
import org.opencord.dhcpl2relay.DhcpL2RelayEvent;
import org.opencord.dhcpl2relay.DhcpL2RelayStoreDelegate;
import org.opencord.dhcpl2relay.impl.packet.DhcpOption82;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import static org.easymock.EasyMock.createMock;
import static org.junit.Assert.assertEquals;
public class DhcpL2RelayTest extends DhcpL2RelayTestBase {
private DhcpL2Relay dhcpL2Relay;
private SimpleDhcpL2RelayCountersStore store;
ComponentConfigService mockConfigService =
createMock(ComponentConfigService.class);
/**
* Sets up the services required by the dhcpl2relay app.
*/
@Before
public void setUp() {
dhcpL2Relay = new DhcpL2Relay();
dhcpL2Relay.cfgService = new DhcpL2RelayConfigTest.TestNetworkConfigRegistry();
dhcpL2Relay.coreService = new MockCoreServiceAdapter();
dhcpL2Relay.flowObjectiveService = new FlowObjectiveServiceAdapter();
dhcpL2Relay.packetService = new MockPacketService();
dhcpL2Relay.componentConfigService = mockConfigService;
dhcpL2Relay.deviceService = new MockDeviceService();
dhcpL2Relay.sadisService = new MockSadisService();
dhcpL2Relay.hostService = new MockHostService();
dhcpL2Relay.mastershipService = new MockMastershipService();
dhcpL2Relay.dhcpL2RelayCounters = new MockDhcpL2RelayCountersStore();
dhcpL2Relay.storageService = new TestStorageService();
dhcpL2Relay.leadershipService = new LeadershipServiceAdapter();
TestUtils.setField(dhcpL2Relay, "eventDispatcher", new TestEventDispatcher());
dhcpL2Relay.refreshService = new MockExecutor(dhcpL2Relay.refreshService);
dhcpL2Relay.activate(new DhcpL2RelayTestBase.MockComponentContext());
store = new SimpleDhcpL2RelayCountersStore();
store.storageService = new TestStorageService();
store.leadershipService = new LeadershipServiceAdapter();
store.clusterService = new ClusterServiceAdapter();
store.clusterCommunicationService = new ClusterCommunicationServiceAdapter();
store.componentConfigService = mockConfigService;
TestUtils.setField(store, "eventDispatcher", new TestEventDispatcher());
store.activate(new MockComponentContext());
dhcpL2Relay.dhcpL2RelayCounters = this.store;
}
/**
* Tears down the dhcpL2Relay application.
*/
@After
public void tearDown() {
dhcpL2Relay.deactivate();
}
/**
* Tests the DHCP relay app by sending DHCP discovery Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpDiscover() throws Exception {
// (1) Sending DHCP discover packet
Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet discoverRelayed = (Ethernet) getPacket();
compareClientPackets(discoverPacket, discoverRelayed);
}
/**
* Tests the DHCP relay app by sending DHCP Request Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpRequest() throws Exception {
// (1) Sending DHCP discover packet
Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet requestRelayed = (Ethernet) getPacket();
compareClientPackets(requestPacket, requestRelayed);
}
/**
* Tests the DHCP relay app by sending DHCP Offer Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpOffer() {
// (1) Sending DHCP discover packet
Ethernet offerPacket = constructDhcpOfferPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet offerRelayed = (Ethernet) getPacket();
compareServerPackets(offerPacket, offerRelayed);
}
/**
* Tests the DHCP relay app by sending DHCP Ack Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpAck() {
Ethernet ackPacket = constructDhcpAckPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet ackRelayed = (Ethernet) getPacket();
compareServerPackets(ackPacket, ackRelayed);
}
/**
* Tests the DHCP relay app by sending DHCP Nak Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpNak() {
Ethernet nakPacket = constructDhcpNakPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
sendPacket(nakPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet nakRelayed = (Ethernet) getPacket();
compareServerPackets(nakPacket, nakRelayed);
}
/**
* Tests the DHCP relay app by sending DHCP Decline Packet.
*
* @throws Exception when an unhandled error occurs
*/
@Test
public void testDhcpDecline() {
Ethernet declinePacket = constructDhcpDeclinePacket(CLIENT_MAC);
sendPacket(declinePacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Ethernet declineRelayed = (Ethernet) getPacket();
compareClientPackets(declinePacket, declineRelayed);
}
/**
* Tests the DHCP global counters.
*/
@Test
public void testDhcpGlobalCounters() {
long discoveryValue = 0;
long offerValue = 0;
long requestValue = 0;
long ackValue = 0;
Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
Ethernet offerPacket = constructDhcpOfferPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
Ethernet ackPacket = constructDhcpAckPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Map<DhcpL2RelayCountersIdentifier, Long> countersMap = store.getCountersMap();
discoveryValue = countersMap.get(new DhcpL2RelayCountersIdentifier(DhcpL2RelayEvent.GLOBAL_COUNTER,
DhcpL2RelayCounterNames.valueOf("DHCPDISCOVER")));
offerValue = countersMap.get(new DhcpL2RelayCountersIdentifier(DhcpL2RelayEvent.GLOBAL_COUNTER,
DhcpL2RelayCounterNames.valueOf("DHCPOFFER")));
requestValue = countersMap.get(new DhcpL2RelayCountersIdentifier(DhcpL2RelayEvent.GLOBAL_COUNTER,
DhcpL2RelayCounterNames.valueOf("DHCPREQUEST")));
ackValue = countersMap.get(new DhcpL2RelayCountersIdentifier(DhcpL2RelayEvent.GLOBAL_COUNTER,
DhcpL2RelayCounterNames.valueOf("DHCPACK")));
assertEquals(1, discoveryValue);
assertEquals(1, offerValue);
assertEquals(1, requestValue);
assertEquals(1, ackValue);
}
/**
* Tests the DHCP per subscriber counters.
*
*/
@Test
public void testDhcpPerSubscriberCounters() {
long discoveryValue;
long offerValue;
long requestValue;
long ackValue;
Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
Ethernet offerPacket = constructDhcpOfferPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
Ethernet ackPacket = constructDhcpAckPacket(SERVER_MAC,
CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
Map<DhcpL2RelayCountersIdentifier, Long> countersMap = store.getCountersMap();
discoveryValue = countersMap.get(new DhcpL2RelayCountersIdentifier(CLIENT_ID_1,
DhcpL2RelayCounterNames.valueOf("DHCPDISCOVER")));
offerValue = countersMap.get(new DhcpL2RelayCountersIdentifier(CLIENT_ID_1,
DhcpL2RelayCounterNames.valueOf("DHCPOFFER")));
requestValue = countersMap.get(new DhcpL2RelayCountersIdentifier(CLIENT_ID_1,
DhcpL2RelayCounterNames.valueOf("DHCPREQUEST")));
ackValue = countersMap.get(new DhcpL2RelayCountersIdentifier(CLIENT_ID_1,
DhcpL2RelayCounterNames.valueOf("DHCPACK")));
assertEquals(1, discoveryValue);
assertEquals(1, offerValue);
assertEquals(1, requestValue);
assertEquals(1, ackValue);
}
public void compareClientPackets(Ethernet sent, Ethernet relayed) {
sent.setSourceMACAddress(OLT_MAC_ADDRESS);
sent.setQinQVID(CLIENT_S_TAG.toShort());
sent.setVlanID(CLIENT_C_TAG.toShort());
sent.setPriorityCode((byte) CLIENT_C_PBIT);
IPv4 ipv4Packet = (IPv4) sent.getPayload();
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
DhcpOption82 option82 = new DhcpOption82();
option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
DhcpOption option = new DhcpOption()
.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
.setData(option82.toByteArray())
.setLength(option82.length());
options.add(options.size() - 1, option);
dhcpPacket.setOptions(options);
assertEquals(sent, relayed);
}
public void compareServerPackets(Ethernet sent, Ethernet relayed) {
sent.setDestinationMACAddress(CLIENT_MAC);
sent.setQinQVID(NOT_PROVIDED);
sent.setQinQPriorityCode((byte) NOT_PROVIDED);
sent.setVlanID(CLIENT_C_TAG.toShort());
final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
Ethernet expectedPacket = null;
try {
expectedPacket = Ethernet.deserializer().deserialize(byteBuffer.array(),
0, byteBuffer.array().length);
} catch (Exception e) {
}
assertEquals(expectedPacket, relayed);
}
private class MockDhcpL2RelayCountersStore implements DhcpL2RelayCountersStore {
@Override
public void incrementCounter(String counterClass, DhcpL2RelayCounterNames counterType) {
}
@Override
public void setCounter(String counterClass, DhcpL2RelayCounterNames counterType, Long value) {
}
@Override
public DhcpL2RelayStatistics getCounters() {
return new DhcpL2RelayStatistics();
}
@Override
public void resetCounters(String counterClass) {
}
@Override
public void setDelegate(DhcpL2RelayStoreDelegate delegate) {
}
@Override
public void unsetDelegate(DhcpL2RelayStoreDelegate delegate) {
}
@Override
public boolean hasDelegate() {
return false;
}
}
}