8d20c20f5bbaa13bda3dc735d31d4730006363af
[bgpcep.git] / pcep / impl / src / test / java / org / opendaylight / protocol / pcep / impl / FiniteStateMachineTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.pcep.impl;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import io.netty.channel.Channel;
17 import io.netty.channel.ChannelFuture;
18 import io.netty.channel.ChannelHandler;
19 import io.netty.channel.ChannelPipeline;
20 import io.netty.channel.DefaultChannelPromise;
21 import io.netty.util.HashedWheelTimer;
22 import io.netty.util.concurrent.DefaultPromise;
23 import io.netty.util.concurrent.GlobalEventExecutor;
24
25 import java.net.InetSocketAddress;
26 import java.net.SocketAddress;
27 import java.util.Arrays;
28 import java.util.List;
29
30 import org.junit.After;
31 import org.junit.Before;
32 import org.junit.Ignore;
33 import org.junit.Test;
34 import org.mockito.Mock;
35 import org.mockito.MockitoAnnotations;
36 import org.mockito.invocation.InvocationOnMock;
37 import org.mockito.stubbing.Answer;
38 import org.opendaylight.protocol.pcep.spi.PCEPErrorMapping;
39 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Keepalive;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.KeepaliveBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Open;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.OpenBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OpenMessage;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.keepalive.message.KeepaliveMessageBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.message.OpenMessageBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObjectBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.Errors;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.ErrorsBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.SessionCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.session._case.SessionBuilder;
55 import org.opendaylight.yangtools.yang.binding.Notification;
56
57 import com.google.common.collect.Lists;
58
59 public class FiniteStateMachineTest {
60
61         private DefaultPCEPSessionNegotiator serverSession;
62
63         @Mock
64         private Channel clientListener;
65
66         @Mock
67         private ChannelPipeline pipeline;
68
69         @Mock
70         private SocketAddress address;
71
72         private final List<Notification> receivedMsgs = Lists.newArrayList();
73
74         private Open openmsg;
75
76         private Keepalive kamsg;
77
78         @Before
79         public void setUp() {
80                 MockitoAnnotations.initMocks(this);
81                 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(
82                                 (short) 1).build();
83                 this.serverSession = new DefaultPCEPSessionNegotiator(new HashedWheelTimer(), new DefaultPromise<PCEPSessionImpl>(GlobalEventExecutor.INSTANCE), this.clientListener, new SimpleSessionListener(), (short) 1, 20, localPrefs);
84                 final ChannelFuture future = new DefaultChannelPromise(this.clientListener);
85                 doAnswer(new Answer<Object>() {
86                         @Override
87                         public Object answer(final InvocationOnMock invocation) {
88                                 final Object[] args = invocation.getArguments();
89                                 FiniteStateMachineTest.this.receivedMsgs.add((Notification) args[0]);
90                                 return future;
91                         }
92                 }).when(this.clientListener).writeAndFlush(any(Notification.class));
93                 doReturn("TestingChannel").when(this.clientListener).toString();
94                 doReturn(this.pipeline).when(this.clientListener).pipeline();
95                 doReturn(this.address).when(this.clientListener).localAddress();
96                 doReturn(this.address).when(this.clientListener).remoteAddress();
97                 doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class));
98                 doReturn(true).when(this.clientListener).isActive();
99                 doReturn(mock(ChannelFuture.class)).when(this.clientListener).close();
100                 doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.clientListener).remoteAddress();
101                 doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.clientListener).localAddress();
102                 this.openmsg = new OpenBuilder().setOpenMessage(
103                                 new OpenMessageBuilder().setOpen(
104                                                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setDeadTimer(
105                                                                 (short) 45).setKeepalive((short) 15).build()).build()).build();
106                 this.kamsg = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
107         }
108
109         /**
110          * Both PCEs accept session characteristics. Also tests KeepAliveTimer and error message and when pce attempts to
111          * establish pce session for the 2nd time.
112          * 
113          * @throws Exception
114          */
115         @Test
116         public void testSessionCharsAccBoth() throws Exception {
117                 this.serverSession.channelActive(null);
118                 assertEquals(1, this.receivedMsgs.size());
119                 assertTrue(this.receivedMsgs.get(0) instanceof Open);
120                 this.serverSession.handleMessage(this.openmsg);
121                 assertEquals(2, this.receivedMsgs.size());
122                 assertTrue(this.receivedMsgs.get(1) instanceof Keepalive);
123                 this.serverSession.handleMessage(this.kamsg);
124                 assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.Finished);
125         }
126
127         /**
128          * Mock PCE does not accept session characteristics the first time.
129          * 
130          * @throws Exception
131          */
132         @Test
133         public void testSessionCharsAccMe() throws Exception {
134                 this.serverSession.channelActive(null);
135                 assertEquals(1, this.receivedMsgs.size());
136                 assertTrue(this.receivedMsgs.get(0) instanceof Open);
137                 this.serverSession.handleMessage(this.openmsg);
138                 assertEquals(2, this.receivedMsgs.size());
139                 assertTrue(this.receivedMsgs.get(1) instanceof Keepalive);
140                 this.serverSession.handleMessage(createErrorMessageWOpen(PCEPErrors.NON_ACC_NEG_SESSION_CHAR));
141                 assertEquals(3, this.receivedMsgs.size());
142                 assertTrue(this.receivedMsgs.get(2) instanceof Open);
143                 this.serverSession.handleMessage(this.kamsg);
144                 assertEquals(this.serverSession.getState(), DefaultPCEPSessionNegotiator.State.Finished);
145         }
146
147         private Pcerr createErrorMessageWOpen(final PCEPErrors e) {
148                 final PCEPErrorMapping maping = PCEPErrorMapping.getInstance();
149                 return new PcerrBuilder().setPcerrMessage(
150                                 new PcerrMessageBuilder().setErrorType(
151                                                 new SessionCaseBuilder().setSession(
152                                                                 new SessionBuilder().setOpen(
153                                                                                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setKeepalive(
154                                                                                                 (short) 1).build()).build()).build()).setErrors(
155                                                 Arrays.asList(new ErrorsBuilder().setErrorObject(
156                                                                 new ErrorObjectBuilder().setType(maping.getFromErrorsEnum(e).type).setValue(
157                                                                                 maping.getFromErrorsEnum(e).value).build()).build())).build()).build();
158         }
159
160         /**
161          * Sending different PCEP Message than Open in session establishment phase.
162          * 
163          * @throws Exception
164          */
165         @Test
166         public void testErrorOneOne() throws Exception {
167                 this.serverSession.channelActive(null);
168                 assertEquals(1, this.receivedMsgs.size());
169                 assertTrue(this.receivedMsgs.get(0) instanceof Open);
170                 this.serverSession.handleMessage(this.kamsg);
171                 for (final Notification m : this.receivedMsgs) {
172                         if (m instanceof Pcerr) {
173                                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
174                                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
175                                 assertEquals(new Short((short) 1), obj.getErrorObject().getValue());
176                         }
177                 }
178         }
179
180         /**
181          * KeepWaitTimer expired.
182          * 
183          * @throws Exception
184          */
185         @Test
186         public void testErrorOneSeven() throws Exception {
187                 this.serverSession.channelActive(null);
188                 assertEquals(1, this.receivedMsgs.size());
189                 assertTrue(this.receivedMsgs.get(0) instanceof Open);
190                 this.serverSession.handleMessage(this.openmsg);
191                 Thread.sleep(1000);
192                 for (final Notification m : this.receivedMsgs) {
193                         if (m instanceof Pcerr) {
194                                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
195                                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
196                                 assertEquals(new Short((short) 7), obj.getErrorObject().getValue());
197                         }
198                 }
199         }
200
201         /************* Tests commented because of their long duration (tested timers) **************/
202
203         /**
204          * OpenWait timer expired.
205          * 
206          * @throws InterruptedException
207          */
208         @Test
209         @Ignore
210         public void testErrorOneTwo() throws InterruptedException {
211                 this.serverSession.channelActive(null);
212                 assertEquals(1, this.receivedMsgs.size());
213                 assertTrue(this.receivedMsgs.get(0) instanceof OpenMessage);
214                 Thread.sleep(60 * 1000);
215                 for (final Notification m : this.receivedMsgs) {
216                         if (m instanceof Pcerr) {
217                                 final Errors obj = ((Pcerr) m).getPcerrMessage().getErrors().get(0);
218                                 assertEquals(new Short((short) 1), obj.getErrorObject().getType());
219                                 assertEquals(new Short((short) 2), obj.getErrorObject().getValue());
220                         }
221                 }
222         }
223
224         @Test
225         @Ignore
226         public void testUnknownMessage() throws InterruptedException {
227                 final SimpleSessionListener client = new SimpleSessionListener();
228                 final PCEPSessionImpl s = new PCEPSessionImpl(new HashedWheelTimer(), client, 5, this.clientListener, this.openmsg.getOpenMessage().getOpen(), this.openmsg.getOpenMessage().getOpen());
229                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
230                 assertEquals(1, s.unknownMessagesTimes.size());
231                 Thread.sleep(10000);
232                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
233                 assertEquals(2, s.unknownMessagesTimes.size());
234                 Thread.sleep(10000);
235                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
236                 assertEquals(3, s.unknownMessagesTimes.size());
237                 Thread.sleep(20000);
238                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
239                 assertEquals(4, s.unknownMessagesTimes.size());
240                 Thread.sleep(30000);
241                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
242                 assertEquals(3, s.unknownMessagesTimes.size());
243                 Thread.sleep(10000);
244                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
245                 assertEquals(3, s.unknownMessagesTimes.size());
246                 Thread.sleep(5000);
247                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
248                 assertEquals(4, s.unknownMessagesTimes.size());
249                 Thread.sleep(1000);
250                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
251                 assertEquals(5, s.unknownMessagesTimes.size());
252                 Thread.sleep(1000);
253                 s.handleMalformedMessage(PCEPErrors.CAPABILITY_NOT_SUPPORTED);
254                 synchronized (client) {
255                         while (client.up) {
256                                 try {
257                                         client.wait();
258                                 } catch (final InterruptedException e) {
259                                         e.printStackTrace();
260                                 }
261                         }
262                 }
263                 assertTrue(!client.up);
264         }
265
266         @After
267         public void tearDown() {
268         }
269 }