blob: f87dccbdcdbd9e8bd97a741217bc136d350e94db [file] [log] [blame]
package org.onosproject.pcep.controller.impl;
import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
import static org.onosproject.pcep.controller.PcepLspSyncAction.UNSTABLE;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelConfig;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelSubscription;
import org.onosproject.incubator.net.tunnel.Tunnel.Type;
import org.onosproject.net.Annotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.Path;
import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepEventListener;
import org.onosproject.pcep.controller.PcepLspSyncAction;
import org.onosproject.pcep.controller.PcepPacketStats;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepInitiateMsg;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMessageReader;
import org.onosproject.pcepio.protocol.PcepVersion;
import com.google.common.collect.ImmutableSet;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class PcepClientControllerImplTest {
PcepClientControllerImpl controllerImpl = new PcepClientControllerImpl();
TunnelService tunnelService = new MockTunnelService();
private PcepEventListener listener;
private Channel channel;
@Before
public void startUp() {
controllerImpl.tunnelService = tunnelService;
listener = new PcepEventListenerAdapter();
controllerImpl.addEventListener(listener);
channel = new MockChannel();
}
@After
public void tearDown() {
controllerImpl.removeEventListener(listener);
listener = null;
controllerImpl.tunnelService = null;
}
@Test
public void tunnelProviderAddedTest1() throws PcepParseException, PcepOutOfBoundMessageException {
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x50, 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, // SRP object
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x24, // LSP object
0x00, 0x00, 0x10, (byte) 0xAB,
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path tlv
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05,
0x05, 0x05, 0x05,
0x07, 0x10, 0x00, 0x14, // ERO object
0x01, 0x08, (byte) 0x01, 0x01, // ERO IPv4 sub objects
0x01, 0x01, 0x04, 0x00,
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00, };
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(reportMsg);
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
PcepClientImpl pc = new PcepClientImpl();
PcepPacketStats pktStats = new PcepPacketStatsImpl();
pc.init(pccId, PcepVersion.PCEP_1, pktStats);
pc.setChannel(channel);
pc.setAgent(controllerImpl.agent);
pc.setConnected(true);
pc.setCapability(new ClientCapability(true, true, true, true, true));
controllerImpl.agent.addConnectedClient(pccId, pc);
controllerImpl.processClientMessage(pccId, message);
pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
pc.setLabelDbSyncStatus(PcepSyncStatus.IN_SYNC);
pc.setLabelDbSyncStatus(PcepSyncStatus.SYNCED);
List<PcepMessage> deleteMsgs = ((MockChannel) channel).msgsWritten();
assertThat(deleteMsgs.size(), is(1));
for (PcepMessage msg : deleteMsgs) {
assertThat(((PcepInitiateMsg) msg).getPcInitiatedLspRequestList().getFirst().getSrpObject().getRFlag(),
is(true));
}
}
@Test
public void tunnelProviderAddedTest2() throws PcepParseException, PcepOutOfBoundMessageException {
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x50, 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, // SRP object
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x24, 0x00, // LSP object
0x00, 0x10, (byte) 0xAB,
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path tlv
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05,
0x05, 0x05, 0x05,
0x07, 0x10, 0x00, 0x14, // ERO object
0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00, };
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(reportMsg);
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
PcepClientImpl pc = new PcepClientImpl();
PcepPacketStats pktStats = new PcepPacketStatsImpl();
pc.init(pccId, PcepVersion.PCEP_1, pktStats);
pc.setChannel(channel);
pc.setAgent(controllerImpl.agent);
pc.setConnected(true);
pc.setCapability(new ClientCapability(true, true, true, true, true));
controllerImpl.agent.addConnectedClient(pccId, pc);
controllerImpl.processClientMessage(pccId, message);
pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
pc.setLabelDbSyncStatus(PcepSyncStatus.IN_SYNC);
pc.setLabelDbSyncStatus(PcepSyncStatus.SYNCED);
}
class PcepEventListenerAdapter implements PcepEventListener {
public List<PcepMessage> handledMsg = new ArrayList<>();
public List<Tunnel> tunnelsToBeUpdatedToNw = new ArrayList<>();
public List<Tunnel> deletedFromNwTunnels = new ArrayList<>();
@Override
public void handleMessage(PccId pccId, PcepMessage msg) {
handledMsg.add(msg);
}
@Override
public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
if (endOfSyncAction == SEND_UPDATE) {
tunnelsToBeUpdatedToNw.add(tunnel);
return;
} else if (endOfSyncAction == UNSTABLE) {
deletedFromNwTunnels.add(tunnel);
}
}
}
class MockChannel implements Channel {
private List<PcepMessage> msgOnWire = new ArrayList<>();
@Override
public ChannelFuture write(Object o) {
if (o instanceof List<?>) {
@SuppressWarnings("unchecked")
List<PcepMessage> msgs = (List<PcepMessage>) o;
for (PcepMessage msg : msgs) {
if (msg instanceof PcepInitiateMsg) {
msgOnWire.add(msg);
}
}
}
return null;
}
public List<PcepMessage> msgsWritten() {
return msgOnWire;
}
@Override
public int compareTo(Channel o) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Integer getId() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFactory getFactory() {
// TODO Auto-generated method stub
return null;
}
@Override
public Channel getParent() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelConfig getConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelPipeline getPipeline() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isOpen() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isBound() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isConnected() {
// TODO Auto-generated method stub
return false;
}
@Override
public SocketAddress getLocalAddress() {
// TODO Auto-generated method stub
return null;
}
@Override
public SocketAddress getRemoteAddress() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture write(Object message, SocketAddress remoteAddress) {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture bind(SocketAddress localAddress) {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture connect(SocketAddress remoteAddress) {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture disconnect() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture unbind() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture close() {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture getCloseFuture() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getInterestOps() {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isReadable() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isWritable() {
// TODO Auto-generated method stub
return false;
}
@Override
public ChannelFuture setInterestOps(int interestOps) {
// TODO Auto-generated method stub
return null;
}
@Override
public ChannelFuture setReadable(boolean readable) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean getUserDefinedWritability(int index) {
// TODO Auto-generated method stub
return false;
}
@Override
public void setUserDefinedWritability(int index, boolean isWritable) {
// TODO Auto-generated method stub
}
@Override
public Object getAttachment() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setAttachment(Object attachment) {
// TODO Auto-generated method stub
}
}
class MockTunnelService implements TunnelService {
private HashMap<TunnelId, Tunnel> tunnelIdAsKeyStore = new HashMap<TunnelId, Tunnel>();
private int tunnelIdCounter = 0;
@Override
public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
TunnelId tunnelId = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
Tunnel tunnelToInsert = new DefaultTunnel(tunnel.providerId(), tunnel.src(), tunnel.dst(), tunnel.type(),
tunnel.state(), tunnel.groupId(), tunnelId, tunnel.tunnelName(),
path, tunnel.annotations());
tunnelIdAsKeyStore.put(tunnelId, tunnelToInsert);
return tunnelId;
}
@Override
public Tunnel queryTunnel(TunnelId tunnelId) {
for (TunnelId tunnelIdKey : tunnelIdAsKeyStore.keySet()) {
if (tunnelIdKey.equals(tunnelId)) {
return tunnelIdAsKeyStore.get(tunnelId);
}
}
return null;
}
@Override
public Collection<Tunnel> queryTunnel(TunnelEndPoint src, TunnelEndPoint dst) {
Collection<Tunnel> result = new HashSet<Tunnel>();
Tunnel tunnel = null;
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
tunnel = tunnelIdAsKeyStore.get(tunnelId);
if ((null != tunnel) && (src.equals(tunnel.src())) && (dst.equals(tunnel.dst()))) {
result.add(tunnel);
}
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public Collection<Tunnel> queryTunnel(Tunnel.Type type) {
Collection<Tunnel> result = new HashSet<Tunnel>();
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
result.add(tunnelIdAsKeyStore.get(tunnelId));
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public Collection<Tunnel> queryAllTunnels() {
Collection<Tunnel> result = new HashSet<Tunnel>();
for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
result.add(tunnelIdAsKeyStore.get(tunnelId));
}
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
@Override
public void addListener(TunnelListener listener) {
// TODO Auto-generated method stub
}
@Override
public void removeListener(TunnelListener listener) {
// TODO Auto-generated method stub
}
@Override
public Tunnel borrowTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelName tunnelName,
Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public Collection<Tunnel> borrowTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
Type type, Annotations... annotations) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelId tunnelId, Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelName tunnelName, Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst, Type type,
Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean returnTunnel(ApplicationId consumerId, TunnelEndPoint src, TunnelEndPoint dst,
Annotations... annotations) {
// TODO Auto-generated method stub
return false;
}
@Override
public Collection<TunnelSubscription> queryTunnelSubscription(ApplicationId consumerId) {
// TODO Auto-generated method stub
return null;
}
@Override
public int tunnelCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
// TODO Auto-generated method stub
return null;
}
}
}