Bug 1764 - moved Session related interfaces to openflowplugin-api
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / HandshakeManagerImplTest.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.openflowplugin.openflow.md.core;
9
10 import java.util.ArrayList;
11 import java.util.List;
12
13 import org.junit.After;
14 import org.junit.Assert;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.mockito.ArgumentCaptor;
19 import org.mockito.Matchers;
20 import org.mockito.Mock;
21 import org.mockito.Mockito;
22 import org.mockito.runners.MockitoJUnitRunner;
23 import org.opendaylight.controller.sal.common.util.Futures;
24 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
25 import org.opendaylight.openflowplugin.api.OFConstants;
26 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
27 import org.opendaylight.openflowplugin.api.openflow.md.core.ErrorHandler;
28 import org.opendaylight.openflowplugin.api.openflow.md.core.HandshakeListener;
29 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.ElementsBuilder;
38 import org.opendaylight.yangtools.yang.common.RpcResult;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import com.google.common.collect.Lists;
43
44 /**
45  * testing handshake
46  */
47 @RunWith(MockitoJUnitRunner.class)
48 public class HandshakeManagerImplTest {
49     
50     private static final Logger LOG = LoggerFactory
51             .getLogger(HandshakeManagerImplTest.class);
52     
53     private HandshakeManagerImpl handshakeManager;
54     @Mock
55     private ConnectionAdapter adapter;
56     @Mock
57     private ErrorHandler errorHandler;
58     @Mock
59     private HandshakeListener handshakeListener;
60
61     private RpcResult<GetFeaturesOutput> resultFeatures;
62
63     private long helloXid = 42L;
64
65     private int expectedErrors = 0;
66     
67     /**
68      * invoked before every test method
69      */
70     @Before
71     public void setUp() {
72         handshakeManager = new HandshakeManagerImpl(adapter, OFConstants.OFP_VERSION_1_3, 
73                 ConnectionConductor.versionOrder);
74         handshakeManager.setErrorHandler(errorHandler);
75         handshakeManager.setHandshakeListener(handshakeListener);
76         handshakeManager.setUseVersionBitmap(false);
77         
78         resultFeatures = RpcResultsUtil.createRpcResult(true, new GetFeaturesOutputBuilder().build(), null);
79         
80         Mockito.when(adapter.hello(Matchers.any(HelloInput.class)))
81             .thenReturn(Futures.immediateFuture(RpcResultsUtil.createRpcResult(true, (Void) null, null)));
82     }
83     
84     /**
85      * invoked after each test method
86      */
87     @After
88     public void teardown() {
89         // logging errors if occurred
90         ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
91         Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
92                 errorCaptor.capture(), Matchers.any(SessionContext.class));
93         for (Throwable problem : errorCaptor.getAllValues()) {
94             LOG.warn(problem.getMessage(), problem);
95         }
96         
97         Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
98                 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
99     }
100
101     /**
102      * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeCommonBitmapVersion(java.util.List)}.
103      */
104     @Test
105     public void testProposeCommonBitmapVersion() {
106         Boolean[][] versions = new Boolean[][] {
107                 {true, true, true, false, false, false},
108                 {true, true, true, false, false}
109         };
110         
111         for (Boolean[] verasionList : versions) {
112             ElementsBuilder elementsBuilder = new ElementsBuilder();
113             elementsBuilder.setVersionBitmap(Lists.newArrayList(verasionList));
114             Elements element = elementsBuilder.build();
115             List<Elements> elements = Lists.newArrayList(element );
116             Short proposal = handshakeManager.proposeCommonBitmapVersion(elements);
117             Assert.assertEquals(Short.valueOf((short)1), proposal);
118         }
119     }
120
121     /**
122      * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeNextVersion(short)}.
123      */
124     @Test
125     public void testProposeNextVersion() {
126         short[] remoteVer = new short[] { 0x05, 0x04, 0x03, 0x02, 0x01, 0x8f,
127                 0xff };
128         short[] expectedProposal = new short[] { 0x04, 0x04, 0x01, 0x01, 0x01,
129                 0x04, 0x04 };
130
131         for (int i = 0; i < remoteVer.length; i++) {
132             short actualProposal = handshakeManager
133                     .proposeNextVersion(remoteVer[i]);
134             Assert.assertEquals(
135                     String.format("proposing for version: %04x", remoteVer[i]),
136                     expectedProposal[i], actualProposal);
137         }
138
139         try {
140             handshakeManager.proposeNextVersion((short) 0);
141             Assert.fail("there should be no proposition for this version");
142         } catch (Exception e) {
143             // expected
144         }
145     }
146
147     //////// Version Negotiation Tests //////////////
148     
149     /**
150      * Test of version negotiation Where switch version = 1.0
151      *
152      * @throws Exception
153      */
154     @Test
155     public void testVersionNegotiation10() throws Exception {
156         LOG.debug("testVersionNegotiation10");
157         Short version = OFConstants.OFP_VERSION_1_0;
158         
159         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
160             .thenReturn(Futures.immediateFuture(resultFeatures));
161         
162         handshakeManager.shake();
163         
164         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
165         handshakeManager.shake();
166         
167         Mockito.verify(handshakeListener).onHandshakeSuccessfull(resultFeatures.getResult(), version);
168     }
169     
170     /**
171      * Test of version negotiation Where switch version = 1.0
172      *
173      * @throws Exception
174      */
175     @Test
176     public void testVersionNegotiation10SwitchStarts() throws Exception {
177         LOG.debug("testVersionNegotiation10-ss");
178         Short version = OFConstants.OFP_VERSION_1_0;
179         
180         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
181             .thenReturn(Futures.immediateFuture(resultFeatures));
182         
183         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
184         handshakeManager.shake();
185         
186         Mockito.verify(handshakeListener).onHandshakeSuccessfull(resultFeatures.getResult(), version);
187     }
188
189     /**
190      * Test of version negotiation Where switch version < 1.0
191      * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful 
192      * @throws Exception
193      */
194     @Test
195     public void testVersionNegotiation00() throws Exception {
196         LOG.debug("testVersionNegotiation00");
197         expectedErrors = 1;
198         Short version = (short) 0x00;
199         
200         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
201         handshakeManager.shake();
202         
203         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
204                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
205     }
206     
207     /**
208      * Test of version negotiation Where switch version < 1.0
209      * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful 
210      * @throws Exception
211      */
212     @Test
213     public void testVersionNegotiation00SwitchStarts() throws Exception {
214         LOG.debug("testVersionNegotiation00-ss");
215         expectedErrors = 1;
216         Short version = (short) 0x00;
217         
218         handshakeManager.shake();
219         
220         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
221         handshakeManager.shake();
222         
223         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
224                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
225     }
226
227     /**
228      * Test of version negotiation Where 1.0 < switch version < 1.3
229      *
230      * @throws Exception
231      */
232     @Test
233     public void testVersionNegotiation11() throws Exception {
234         LOG.debug("testVersionNegotiation11");
235         Short version = (short) 0x02;
236         Short expVersion = (short) 0x01;
237     
238         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
239             .thenReturn(Futures.immediateFuture(resultFeatures));
240         
241         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
242         handshakeManager.shake();
243         
244         handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
245         handshakeManager.shake();
246         
247         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
248                 resultFeatures.getResult(), expVersion);
249     }
250     
251     /**
252      * Test of version negotiation Where 1.0 < switch version < 1.3
253      *
254      * @throws Exception
255      */
256     @Test
257     public void testVersionNegotiation11SwitchStarts() throws Exception {
258         LOG.debug("testVersionNegotiation11-ss");
259         Short version = (short) 0x02;
260         Short expVersion = (short) 0x01;
261     
262         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
263             .thenReturn(Futures.immediateFuture(resultFeatures));
264         
265         handshakeManager.shake();
266         
267         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
268         handshakeManager.shake();
269         
270         handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
271         handshakeManager.shake();
272         
273         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
274                 resultFeatures.getResult(), expVersion);
275     }
276
277     /**
278      * Test of version negotiation Where switch version = 1.3
279      *
280      * @throws Exception
281      */
282     @Test
283     public void testVersionNegotiation13() throws Exception {
284         LOG.debug("testVersionNegotiation13");
285         Short version = OFConstants.OFP_VERSION_1_3;
286         
287         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
288             .thenReturn(Futures.immediateFuture(resultFeatures));
289         
290         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
291         handshakeManager.shake();
292         
293         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
294                 resultFeatures.getResult(), version);
295     }
296     
297     /**
298      * Test of version negotiation Where switch version = 1.3
299      *
300      * @throws Exception
301      */
302     @Test
303     public void testVersionNegotiation13SwitchStarts() throws Exception {
304         LOG.debug("testVersionNegotiation13-ss");
305         Short version = OFConstants.OFP_VERSION_1_3;
306         
307         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
308             .thenReturn(Futures.immediateFuture(resultFeatures));
309         
310         handshakeManager.shake();
311         
312         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
313         handshakeManager.shake();
314     
315         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
316                 resultFeatures.getResult(), version);
317     }
318
319     /**
320      * Test of version negotiation Where switch version >= 1.3
321      *
322      * @throws Exception
323      */
324     @Test
325     public void testVersionNegotiation15() throws Exception {
326         LOG.debug("testVersionNegotiation15");
327         Short version = (short) 0x06;
328         Short expVersion =  OFConstants.OFP_VERSION_1_3;
329         
330         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
331             .thenReturn(Futures.immediateFuture(resultFeatures));
332     
333         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
334         handshakeManager.shake();
335         
336         handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
337         handshakeManager.shake();
338         
339         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
340                 resultFeatures.getResult(), expVersion);
341     }
342     
343     /**
344      * Test of version negotiation Where switch version >= 1.3
345      *
346      * @throws Exception
347      */
348     @Test
349     public void testVersionNegotiation15SwitchStart() throws Exception {
350         LOG.debug("testVersionNegotiation15-ss");
351         Short version = (short) 0x06;
352         Short expVersion =  OFConstants.OFP_VERSION_1_3;
353         
354         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
355             .thenReturn(Futures.immediateFuture(resultFeatures));
356     
357         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
358         handshakeManager.shake();
359         
360         handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
361         handshakeManager.shake();
362         
363         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
364                 resultFeatures.getResult(), expVersion);
365     }
366
367     /**
368      * Test of version negotiation Where switch version > 1.3
369      *
370      * @throws Exception
371      */
372     @Test
373     public void testVersionNegotiation15_MultipleCall() throws Exception {
374         LOG.debug("testVersionNegotiation15_MultipleCall");
375         Short version = (short) 0x06;
376         expectedErrors = 1;
377     
378         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
379         handshakeManager.shake();
380         
381         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
382         handshakeManager.shake();
383         
384         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
385                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
386     }
387     
388     /**
389      * Test of version negotiation Where switch version > 1.3
390      *
391      * @throws Exception
392      */
393     @Test
394     public void testVersionNegotiation15_MultipleCallSwitchStarts() throws Exception {
395         LOG.debug("testVersionNegotiation15_MultipleCall-ss");
396         Short version = (short) 0x06;
397         expectedErrors = 1;
398     
399         handshakeManager.shake();
400         
401         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
402         handshakeManager.shake();
403         
404         handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
405         handshakeManager.shake();
406         
407         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
408                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
409     }
410
411     /**
412      * Test of version negotiation Where bitmap version {0x05,0x01}
413      *
414      * @throws Exception
415      */
416     @Test
417     public void testVersionNegotiation10InBitmap() throws Exception {
418         LOG.debug("testVersionNegotiation10InBitmap");
419         Short version = OFConstants.OFP_VERSION_1_0;
420         handshakeManager.setUseVersionBitmap(true);
421
422         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
423         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
424     
425         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
426             .thenReturn(Futures.immediateFuture(resultFeatures));
427         
428         handshakeManager.setReceivedHello(helloMessage.build());
429         handshakeManager.shake();
430         
431         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
432                 resultFeatures.getResult(), version);
433     }
434     
435     /**
436      * Test of version negotiation Where bitmap version {0x05,0x01}
437      *
438      * @throws Exception
439      */
440     @Test
441     public void testVersionNegotiation10InBitmapSwitchStarts() throws Exception {
442         LOG.debug("testVersionNegotiation10InBitmap-ss");
443         Short version = OFConstants.OFP_VERSION_1_0;
444         handshakeManager.setUseVersionBitmap(true);
445
446         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
447         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
448     
449         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
450             .thenReturn(Futures.immediateFuture(resultFeatures));
451         
452         handshakeManager.shake();
453         
454         handshakeManager.setReceivedHello(helloMessage.build());
455         handshakeManager.shake();
456         
457         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
458                 resultFeatures.getResult(), version);
459     }
460
461     /**
462      * Test of version negotiation Where bitmap version {0x05,0x04}
463      *
464      * @throws Exception
465      */
466     @Test
467     public void testVersionNegotiation13InBitmap() throws Exception {
468         LOG.debug("testVersionNegotiation13InBitmap");
469         Short version = OFConstants.OFP_VERSION_1_3;
470         handshakeManager.setUseVersionBitmap(true);
471
472         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
473         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
474     
475         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
476             .thenReturn(Futures.immediateFuture(resultFeatures));
477     
478         handshakeManager.setReceivedHello(helloMessage.build());
479         handshakeManager.shake();
480     
481         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
482                 resultFeatures.getResult(), version);
483     }
484     
485     /**
486      * Test of version negotiation Where bitmap version {0x05,0x04}
487      *
488      * @throws Exception
489      */
490     @Test
491     public void testVersionNegotiation13InBitmapSwitchFirst() throws Exception {
492         LOG.debug("testVersionNegotiation13InBitmap-ss");
493         Short version = OFConstants.OFP_VERSION_1_3;
494         handshakeManager.setUseVersionBitmap(true);
495
496         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
497         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
498     
499         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
500             .thenReturn(Futures.immediateFuture(resultFeatures));
501     
502         handshakeManager.shake();
503         
504         handshakeManager.setReceivedHello(helloMessage.build());
505         handshakeManager.shake();
506     
507         Mockito.verify(handshakeListener).onHandshakeSuccessfull(
508                 resultFeatures.getResult(), version);
509     }
510
511     /**
512      * Test of version negotiation Where bitmap version {0x05,0x02}
513      *
514      * @throws Exception
515      */
516     @Test
517     public void testVersionNegotiationNoCommonVersionInBitmap() throws Exception {
518         LOG.debug("testVersionNegotiationNoCommonVersionInBitmap");
519         Short version = (short) 0x05;
520         expectedErrors = 1;
521         handshakeManager.setUseVersionBitmap(true);
522         
523         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
524         addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
525         
526         handshakeManager.setReceivedHello(helloMessage.build());
527         handshakeManager.shake();
528         
529         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
530                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
531     }
532     
533     /**
534      * Test of version negotiation Where bitmap version {0x05,0x02}
535      *
536      * @throws Exception
537      */
538     @Test
539     public void testVersionNegotiationNoCommonVersionInBitmapSwitchStarts() throws Exception {
540         LOG.debug("testVersionNegotiationNoCommonVersionInBitmap-ss");
541         Short version = (short) 0x05;
542         expectedErrors = 1;
543         handshakeManager.setUseVersionBitmap(true);
544         
545         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
546         addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
547         
548         handshakeManager.shake();
549         
550         handshakeManager.setReceivedHello(helloMessage.build());
551         handshakeManager.shake();
552         
553         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
554                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
555     }
556
557
558     /**
559      * @param ofpVersion10
560      * @param helloXid
561      * @return
562      */
563     private static HelloMessageBuilder createHelloMessage(short ofpVersion10, long helloXid) {
564         return new HelloMessageBuilder().setVersion(ofpVersion10).setXid(helloXid);
565     }
566     
567     /**
568      * @param versionOrder
569      * @param helloBuilder
570      * @return
571      */
572     private static HelloMessageBuilder addVersionBitmap(List<Short> versionOrder, 
573             HelloMessageBuilder helloBuilder) {
574         short highestVersion = versionOrder.get(0);
575         int elementsCount = highestVersion / Integer.SIZE;
576         ElementsBuilder elementsBuilder = new ElementsBuilder();
577
578         List<Elements> elementList = new ArrayList<>();
579         int orderIndex = versionOrder.size();
580         int value = versionOrder.get(--orderIndex);
581         for (int index = 0; index <= elementsCount; index++) {
582             List<Boolean> booleanList = new ArrayList<>();
583             for (int i = 0; i < Integer.SIZE; i++) {
584                 if (value == ((index * Integer.SIZE) + i)) {
585                     booleanList.add(true);
586                     value = (orderIndex == 0) ? highestVersion : versionOrder.get(--orderIndex);
587                 } else {
588                     booleanList.add(false);
589                 }
590             }
591             elementsBuilder.setType(HelloElementType.forValue(1));
592             elementsBuilder.setVersionBitmap(booleanList);
593             elementList.add(elementsBuilder.build());
594         }
595
596         helloBuilder.setElements(elementList);
597         return helloBuilder;
598     }
599
600 }