Bug 2231 - Secure transport for PCEP
[bgpcep.git] / pcep / impl / src / test / java / org / opendaylight / protocol / pcep / impl / FiniteStateMachineTest.java
index 0d5d774d08dc6a4f2ee98bda469522e98285b117..4cb597b1aaf515e16d4182e396ccb6038b3e8714 100644 (file)
@@ -9,94 +9,37 @@ package org.opendaylight.protocol.pcep.impl;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.Lists;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.DefaultChannelPromise;
-import io.netty.util.HashedWheelTimer;
+
 import io.netty.util.concurrent.DefaultPromise;
 import io.netty.util.concurrent.GlobalEventExecutor;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.List;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.yang.pcep.impl.Tls;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Keepalive;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.KeepaliveBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.OpenBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Starttls;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OpenMessage;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.keepalive.message.KeepaliveMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.message.OpenMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.Errors;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
-public class FiniteStateMachineTest {
+public class FiniteStateMachineTest extends AbstractPCEPSessionTest {
 
     private DefaultPCEPSessionNegotiator serverSession;
-
-    @Mock
-    private Channel clientListener;
-
-    @Mock
-    private ChannelPipeline pipeline;
-
-    @Mock
-    private SocketAddress address;
-
-    private final List<Notification> receivedMsgs = Lists.newArrayList();
-
-    private Open openmsg;
-
-    private Keepalive kamsg;
+    private DefaultPCEPSessionNegotiator tlsSessionNegotiator;
 
     @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open localPrefs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setKeepalive(
+    public void setup() {
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open localPrefs = new OpenBuilder().setKeepalive(
                 (short) 1).build();
-        this.serverSession = new DefaultPCEPSessionNegotiator(new HashedWheelTimer(), new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE), this.clientListener, new SimpleSessionListener(), (short) 1, 20, localPrefs);
-        final ChannelFuture future = new DefaultChannelPromise(this.clientListener);
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(final InvocationOnMock invocation) {
-                final Object[] args = invocation.getArguments();
-                FiniteStateMachineTest.this.receivedMsgs.add((Notification) args[0]);
-                return future;
-            }
-        }).when(this.clientListener).writeAndFlush(any(Notification.class));
-        doReturn("TestingChannel").when(this.clientListener).toString();
-        doReturn(this.pipeline).when(this.clientListener).pipeline();
-        doReturn(this.address).when(this.clientListener).localAddress();
-        doReturn(this.address).when(this.clientListener).remoteAddress();
-        doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class));
-        doReturn(true).when(this.clientListener).isActive();
-        doReturn(mock(ChannelFuture.class)).when(this.clientListener).close();
-        doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.clientListener).remoteAddress();
-        doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.clientListener).localAddress();
-        this.openmsg = new OpenBuilder().setOpenMessage(
-                new OpenMessageBuilder().setOpen(
-                        new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setDeadTimer(
-                                (short) 45).setKeepalive((short) 15).build()).build()).build();
-        this.kamsg = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
+        this.serverSession = new DefaultPCEPSessionNegotiator(new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE),
+                this.channel, this.listener, (short) 1, 20, localPrefs);
+        this.tlsSessionNegotiator = new DefaultPCEPSessionNegotiator(new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE),
+                this.channel, this.listener, (short) 1, 20, localPrefs, new Tls());
     }
 
     /**
@@ -108,13 +51,73 @@ public class FiniteStateMachineTest {
     @Test
     public void testSessionCharsAccBoth() throws Exception {
         this.serverSession.channelActive(null);
-        assertEquals(1, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(0) instanceof Open);
-        this.serverSession.handleMessage(this.openmsg);
-        assertEquals(2, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(1) instanceof Keepalive);
-        this.serverSession.handleMessage(this.kamsg);
-        assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.Finished);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Open);
+        this.serverSession.handleMessage(this.openMsg);
+        assertEquals(2, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(1) instanceof Keepalive);
+        this.serverSession.handleMessage(this.kaMsg);
+        assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.FINISHED);
+    }
+
+    /**
+     * Establish PCEPS TLS connection with peer
+     */
+    @Test
+    public void testEstablishTLS() {
+        final DefaultPCEPSessionNegotiator negotiator = new DefaultPCEPSessionNegotiator(new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE),
+                this.channel, this.listener, (short) 1, 20, new OpenBuilder().setKeepalive((short) 1).build(),
+                SslContextFactoryTest.createTlsConfig());
+        negotiator.channelActive(null);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Starttls);
+        assertEquals(DefaultPCEPSessionNegotiator.State.START_TLS_WAIT, negotiator.getState());
+        negotiator.handleMessage(this.startTlsMsg);
+        assertEquals(DefaultPCEPSessionNegotiator.State.OPEN_WAIT, negotiator.getState());
+        assertEquals(2, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(1) instanceof Open);
+        negotiator.handleMessage(this.openMsg);
+        assertEquals(DefaultPCEPSessionNegotiator.State.KEEP_WAIT, negotiator.getState());
+    }
+
+    /**
+     * As Tls is not configured properly, PCE will send error PCEPErrors.NOT_POSSIBLE_WITHOUT_TLS
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testFailedToEstablishTLS() throws Exception {
+        this.tlsSessionNegotiator.channelActive(null);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Starttls);
+        assertEquals(DefaultPCEPSessionNegotiator.State.START_TLS_WAIT, this.tlsSessionNegotiator.getState());
+        this.tlsSessionNegotiator.handleMessage(this.startTlsMsg);
+        assertEquals(2, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(1) instanceof Pcerr);
+        final Errors obj = ((Pcerr) this.msgsSend.get(1)).getPcerrMessage().getErrors().get(0);
+        assertEquals(PCEPErrors.NOT_POSSIBLE_WITHOUT_TLS.getErrorType(), obj.getErrorObject().getType().shortValue());
+        assertEquals(PCEPErrors.NOT_POSSIBLE_WITHOUT_TLS.getErrorValue(), obj.getErrorObject().getValue().shortValue());
+        assertEquals(DefaultPCEPSessionNegotiator.State.FINISHED, this.tlsSessionNegotiator.getState());
+    }
+
+    /**
+     * As PCE does not receive expected message (StartTLS), error PCEPErrors.NON_STARTTLS_MSG_RCVD is send
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testTLSUnexpectedMessage() {
+        this.tlsSessionNegotiator.channelActive(null);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Starttls);
+        assertEquals(DefaultPCEPSessionNegotiator.State.START_TLS_WAIT, this.tlsSessionNegotiator.getState());
+        this.tlsSessionNegotiator.handleMessage(this.openMsg);
+        assertEquals(2, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(1) instanceof Pcerr);
+        final Errors obj = ((Pcerr) this.msgsSend.get(1)).getPcerrMessage().getErrors().get(0);
+        assertEquals(PCEPErrors.NON_STARTTLS_MSG_RCVD.getErrorType(), obj.getErrorObject().getType().shortValue());
+        assertEquals(PCEPErrors.NON_STARTTLS_MSG_RCVD.getErrorValue(), obj.getErrorObject().getValue().shortValue());
+        assertEquals(this.tlsSessionNegotiator.getState(), DefaultPCEPSessionNegotiator.State.FINISHED);
     }
 
     /**
@@ -125,17 +128,17 @@ public class FiniteStateMachineTest {
     @Test
     public void testSessionCharsAccMe() throws Exception {
         this.serverSession.channelActive(null);
-        assertEquals(1, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(0) instanceof Open);
-        Open remote = (Open) this.receivedMsgs.get(0);
-        this.serverSession.handleMessage(this.openmsg);
-        assertEquals(2, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(1) instanceof Keepalive);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Open);
+        final Open remote = (Open) this.msgsSend.get(0);
+        this.serverSession.handleMessage(this.openMsg);
+        assertEquals(2, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(1) instanceof Keepalive);
         this.serverSession.handleMessage(Util.createErrorMessage(PCEPErrors.NON_ACC_NEG_SESSION_CHAR, remote.getOpenMessage().getOpen()));
-        assertEquals(3, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(2) instanceof Open);
-        this.serverSession.handleMessage(this.kamsg);
-        assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.Finished);
+        assertEquals(3, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(2) instanceof Open);
+        this.serverSession.handleMessage(this.kaMsg);
+        assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.FINISHED);
     }
 
     /**
@@ -146,10 +149,10 @@ public class FiniteStateMachineTest {
     @Test
     public void testErrorOneOne() throws Exception {
         this.serverSession.channelActive(null);
-        assertEquals(1, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(0) instanceof Open);
-        this.serverSession.handleMessage(this.kamsg);
-        for (final Notification m : this.receivedMsgs) {
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Open);
+        this.serverSession.handleMessage(this.kaMsg);
+        for (final Notification m : this.msgsSend) {
             if (m instanceof Pcerr) {
                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
@@ -166,11 +169,11 @@ public class FiniteStateMachineTest {
     @Test
     public void testErrorOneSeven() throws Exception {
         this.serverSession.channelActive(null);
-        assertEquals(1, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(0) instanceof Open);
-        this.serverSession.handleMessage(this.openmsg);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof Open);
+        this.serverSession.handleMessage(this.openMsg);
         Thread.sleep(1000);
-        for (final Notification m : this.receivedMsgs) {
+        for (final Notification m : this.msgsSend) {
             if (m instanceof Pcerr) {
                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
@@ -190,10 +193,10 @@ public class FiniteStateMachineTest {
     @Ignore
     public void testErrorOneTwo() throws InterruptedException {
         this.serverSession.channelActive(null);
-        assertEquals(1, this.receivedMsgs.size());
-        assertTrue(this.receivedMsgs.get(0) instanceof OpenMessage);
+        assertEquals(1, this.msgsSend.size());
+        assertTrue(this.msgsSend.get(0) instanceof OpenMessage);
         Thread.sleep(60 * 1000);
-        for (final Notification m : this.receivedMsgs) {
+        for (final Notification m : this.msgsSend) {
             if (m instanceof Pcerr) {
                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
@@ -206,30 +209,30 @@ public class FiniteStateMachineTest {
     @Ignore
     public void testUnknownMessage() throws InterruptedException {
         final SimpleSessionListener client = new SimpleSessionListener();
-        final PCEPSessionImpl s = new PCEPSessionImpl(new HashedWheelTimer(), client, 5, this.clientListener, this.openmsg.getOpenMessage().getOpen(), this.openmsg.getOpenMessage().getOpen());
+        final PCEPSessionImpl s = new PCEPSessionImpl(client, 5, this.channel, this.openMsg.getOpenMessage().getOpen(), this.openMsg.getOpenMessage().getOpen());
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(1, s.unknownMessagesTimes.size());
+        assertEquals(1, s.getUnknownMessagesTimes().size());
         Thread.sleep(10000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(2, s.unknownMessagesTimes.size());
+        assertEquals(2, s.getUnknownMessagesTimes().size());
         Thread.sleep(10000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(3, s.unknownMessagesTimes.size());
+        assertEquals(3, s.getUnknownMessagesTimes().size());
         Thread.sleep(20000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(4, s.unknownMessagesTimes.size());
+        assertEquals(4, s.getUnknownMessagesTimes().size());
         Thread.sleep(30000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(3, s.unknownMessagesTimes.size());
+        assertEquals(3, s.getUnknownMessagesTimes().size());
         Thread.sleep(10000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(3, s.unknownMessagesTimes.size());
+        assertEquals(3, s.getUnknownMessagesTimes().size());
         Thread.sleep(5000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(4, s.unknownMessagesTimes.size());
+        assertEquals(4, s.getUnknownMessagesTimes().size());
         Thread.sleep(1000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
-        assertEquals(5, s.unknownMessagesTimes.size());
+        assertEquals(5, s.getUnknownMessagesTimes().size());
         Thread.sleep(1000);
         s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
         synchronized (client) {