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