Post "Clustering optimization" updates
[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 com.google.common.collect.Lists;
11 import com.google.common.util.concurrent.Futures;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.junit.After;
15 import org.junit.Assert;
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.mockito.ArgumentCaptor;
20 import org.mockito.Matchers;
21 import org.mockito.Mock;
22 import org.mockito.Mockito;
23 import org.mockito.runners.MockitoJUnitRunner;
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.opendaylight.yangtools.yang.common.RpcResultBuilder;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * testing handshake
45  */
46 @RunWith(MockitoJUnitRunner.class)
47 public class HandshakeManagerImplTest {
48
49     private static final Logger LOG = LoggerFactory
50             .getLogger(HandshakeManagerImplTest.class);
51
52     private HandshakeManagerImpl handshakeManager;
53     @Mock
54     private ConnectionAdapter adapter;
55     @Mock
56     private ErrorHandler errorHandler;
57     @Mock
58     private HandshakeListener handshakeListener;
59
60     private RpcResult<GetFeaturesOutput> resultFeatures;
61
62     private long helloXid = 42L;
63
64     private int expectedErrors = 0;
65
66     /**
67      * invoked before every test method
68      */
69     @Before
70     public void setUp() {
71         handshakeManager = new HandshakeManagerImpl(adapter, OFConstants.OFP_VERSION_1_3,
72                 ConnectionConductor.versionOrder);
73         handshakeManager.setErrorHandler(errorHandler);
74         handshakeManager.setHandshakeListener(handshakeListener);
75         handshakeManager.setUseVersionBitmap(false);
76
77         resultFeatures = RpcResultBuilder.success(new GetFeaturesOutputBuilder().build()).build();
78
79         Mockito.when(adapter.hello(Matchers.any(HelloInput.class)))
80             .thenReturn(Futures.immediateFuture(
81                     RpcResultBuilder.success((Void) null).build()));
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(null);
163
164         handshakeManager.shake(createHelloMessage(version, helloXid).build());
165
166         Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
167     }
168
169     /**
170      * Test of version negotiation Where switch version = 1.0
171      *
172      * @throws Exception
173      */
174     @Test
175     public void testVersionNegotiation10SwitchStarts() throws Exception {
176         LOG.debug("testVersionNegotiation10-ss");
177         Short version = OFConstants.OFP_VERSION_1_0;
178
179         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
180             .thenReturn(Futures.immediateFuture(resultFeatures));
181
182         handshakeManager.shake(createHelloMessage(version, helloXid).build());
183
184         Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
185     }
186
187     /**
188      * Test of version negotiation Where switch version < 1.0
189      * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
190      * @throws Exception
191      */
192     @Test
193     public void testVersionNegotiation00() throws Exception {
194         LOG.debug("testVersionNegotiation00");
195         expectedErrors = 1;
196         Short version = (short) 0x00;
197
198         handshakeManager.shake(createHelloMessage(version, helloXid).build());
199
200         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
201                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
202     }
203
204     /**
205      * Test of version negotiation Where switch version < 1.0
206      * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
207      * @throws Exception
208      */
209     @Test
210     public void testVersionNegotiation00SwitchStarts() throws Exception {
211         LOG.debug("testVersionNegotiation00-ss");
212         expectedErrors = 1;
213         Short version = (short) 0x00;
214
215         handshakeManager.shake(null);
216
217         handshakeManager.shake(createHelloMessage(version, helloXid).build());
218
219         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
220                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
221     }
222
223     /**
224      * Test of version negotiation Where 1.0 < switch version < 1.3
225      *
226      * @throws Exception
227      */
228     @Test
229     public void testVersionNegotiation11() throws Exception {
230         LOG.debug("testVersionNegotiation11");
231         Short version = (short) 0x02;
232         Short expVersion = (short) 0x01;
233
234         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
235             .thenReturn(Futures.immediateFuture(resultFeatures));
236
237         handshakeManager.shake(createHelloMessage(version, helloXid).build());
238
239         handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
240
241         Mockito.verify(handshakeListener).onHandshakeSuccessful(
242                 resultFeatures.getResult(), expVersion);
243     }
244
245     /**
246      * Test of version negotiation Where 1.0 < switch version < 1.3
247      *
248      * @throws Exception
249      */
250     @Test
251     public void testVersionNegotiation11SwitchStarts() throws Exception {
252         LOG.debug("testVersionNegotiation11-ss");
253         Short version = (short) 0x02;
254         Short expVersion = (short) 0x01;
255
256         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
257             .thenReturn(Futures.immediateFuture(resultFeatures));
258
259         handshakeManager.shake(null);
260
261         handshakeManager.shake(createHelloMessage(version, helloXid).build());
262
263         handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
264
265         Mockito.verify(handshakeListener).onHandshakeSuccessful(
266                 resultFeatures.getResult(), expVersion);
267     }
268
269     /**
270      * Test of version negotiation Where switch version = 1.3
271      *
272      * @throws Exception
273      */
274     @Test
275     public void testVersionNegotiation13() throws Exception {
276         LOG.debug("testVersionNegotiation13");
277         Short version = OFConstants.OFP_VERSION_1_3;
278
279         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
280             .thenReturn(Futures.immediateFuture(resultFeatures));
281
282         handshakeManager.shake(createHelloMessage(version, helloXid).build());
283
284         Mockito.verify(handshakeListener).onHandshakeSuccessful(
285                 resultFeatures.getResult(), version);
286     }
287
288     /**
289      * Test of version negotiation Where switch version = 1.3
290      *
291      * @throws Exception
292      */
293     @Test
294     public void testVersionNegotiation13SwitchStarts() throws Exception {
295         LOG.debug("testVersionNegotiation13-ss");
296         Short version = OFConstants.OFP_VERSION_1_3;
297
298         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
299             .thenReturn(Futures.immediateFuture(resultFeatures));
300
301         handshakeManager.shake(null);
302
303         handshakeManager.shake(createHelloMessage(version, helloXid).build());
304
305         Mockito.verify(handshakeListener).onHandshakeSuccessful(
306                 resultFeatures.getResult(), version);
307     }
308
309     /**
310      * Test of version negotiation Where switch version >= 1.3
311      *
312      * @throws Exception
313      */
314     @Test
315     public void testVersionNegotiation15() throws Exception {
316         LOG.debug("testVersionNegotiation15");
317         Short version = (short) 0x06;
318         Short expVersion =  OFConstants.OFP_VERSION_1_3;
319
320         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
321             .thenReturn(Futures.immediateFuture(resultFeatures));
322
323         handshakeManager.shake(createHelloMessage(version, helloXid).build());
324
325         handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
326
327         Mockito.verify(handshakeListener).onHandshakeSuccessful(
328                 resultFeatures.getResult(), expVersion);
329     }
330
331     /**
332      * Test of version negotiation Where switch version >= 1.3
333      *
334      * @throws Exception
335      */
336     @Test
337     public void testVersionNegotiation15SwitchStart() throws Exception {
338         LOG.debug("testVersionNegotiation15-ss");
339         Short version = (short) 0x06;
340         Short expVersion =  OFConstants.OFP_VERSION_1_3;
341
342         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
343             .thenReturn(Futures.immediateFuture(resultFeatures));
344
345         handshakeManager.shake(createHelloMessage(version, helloXid).build());
346
347         handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
348
349         Mockito.verify(handshakeListener).onHandshakeSuccessful(
350                 resultFeatures.getResult(), expVersion);
351     }
352
353     /**
354      * Test of version negotiation Where switch version > 1.3
355      *
356      * @throws Exception
357      */
358     @Test
359     public void testVersionNegotiation15_MultipleCall() throws Exception {
360         LOG.debug("testVersionNegotiation15_MultipleCall");
361         Short version = (short) 0x06;
362         expectedErrors = 1;
363
364         handshakeManager.shake(createHelloMessage(version, helloXid).build());
365
366         handshakeManager.shake(createHelloMessage(version, helloXid).build());
367
368         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
369                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
370     }
371
372     /**
373      * Test of version negotiation Where switch version > 1.3
374      *
375      * @throws Exception
376      */
377     @Test
378     public void testVersionNegotiation15_MultipleCallSwitchStarts() throws Exception {
379         LOG.debug("testVersionNegotiation15_MultipleCall-ss");
380         Short version = (short) 0x06;
381         expectedErrors = 1;
382
383         handshakeManager.shake(null);
384
385         handshakeManager.shake(createHelloMessage(version, helloXid).build());
386
387         handshakeManager.shake(createHelloMessage(version, helloXid).build());
388
389         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
390                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
391     }
392
393     /**
394      * Test of version negotiation Where bitmap version {0x05,0x01}
395      *
396      * @throws Exception
397      */
398     @Test
399     public void testVersionNegotiation10InBitmap() throws Exception {
400         LOG.debug("testVersionNegotiation10InBitmap");
401         Short version = OFConstants.OFP_VERSION_1_0;
402         handshakeManager.setUseVersionBitmap(true);
403
404         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
405         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
406
407         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
408             .thenReturn(Futures.immediateFuture(resultFeatures));
409
410         handshakeManager.shake(helloMessage.build());
411
412         Mockito.verify(handshakeListener).onHandshakeSuccessful(
413                 resultFeatures.getResult(), version);
414     }
415
416     /**
417      * Test of version negotiation Where bitmap version {0x05,0x01}
418      *
419      * @throws Exception
420      */
421     @Test
422     public void testVersionNegotiation10InBitmapSwitchStarts() throws Exception {
423         LOG.debug("testVersionNegotiation10InBitmap-ss");
424         Short version = OFConstants.OFP_VERSION_1_0;
425         handshakeManager.setUseVersionBitmap(true);
426
427         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
428         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
429
430         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
431             .thenReturn(Futures.immediateFuture(resultFeatures));
432
433         handshakeManager.shake(null);
434
435         handshakeManager.shake(helloMessage.build());
436
437         Mockito.verify(handshakeListener).onHandshakeSuccessful(
438                 resultFeatures.getResult(), version);
439     }
440
441     /**
442      * Test of version negotiation Where bitmap version {0x05,0x04}
443      *
444      * @throws Exception
445      */
446     @Test
447     public void testVersionNegotiation13InBitmap() throws Exception {
448         LOG.debug("testVersionNegotiation13InBitmap");
449         Short version = OFConstants.OFP_VERSION_1_3;
450         handshakeManager.setUseVersionBitmap(true);
451
452         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
453         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
454
455         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
456             .thenReturn(Futures.immediateFuture(resultFeatures));
457
458         handshakeManager.shake(helloMessage.build());
459
460         Mockito.verify(handshakeListener).onHandshakeSuccessful(
461                 resultFeatures.getResult(), version);
462     }
463
464     /**
465      * Test of version negotiation Where bitmap version {0x05,0x04}
466      *
467      * @throws Exception
468      */
469     @Test
470     public void testVersionNegotiation13InBitmapSwitchFirst() throws Exception {
471         LOG.debug("testVersionNegotiation13InBitmap-ss");
472         Short version = OFConstants.OFP_VERSION_1_3;
473         handshakeManager.setUseVersionBitmap(true);
474
475         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
476         addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
477
478         Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
479             .thenReturn(Futures.immediateFuture(resultFeatures));
480
481         handshakeManager.shake(null);
482
483         handshakeManager.shake(helloMessage.build());
484
485         Mockito.verify(handshakeListener).onHandshakeSuccessful(
486                 resultFeatures.getResult(), version);
487     }
488
489     /**
490      * Test of version negotiation Where bitmap version {0x05,0x02}
491      *
492      * @throws Exception
493      */
494     @Test
495     public void testVersionNegotiationNoCommonVersionInBitmap() throws Exception {
496         LOG.debug("testVersionNegotiationNoCommonVersionInBitmap");
497         Short version = (short) 0x05;
498         expectedErrors = 1;
499         handshakeManager.setUseVersionBitmap(true);
500
501         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
502         addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
503
504         handshakeManager.shake(helloMessage.build());
505
506         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
507                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
508     }
509
510     /**
511      * Test of version negotiation Where bitmap version {0x05,0x02}
512      *
513      * @throws Exception
514      */
515     @Test
516     public void testVersionNegotiationNoCommonVersionInBitmapSwitchStarts() throws Exception {
517         LOG.debug("testVersionNegotiationNoCommonVersionInBitmap-ss");
518         Short version = (short) 0x05;
519         expectedErrors = 1;
520         handshakeManager.setUseVersionBitmap(true);
521
522         HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
523         addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
524
525         handshakeManager.shake(null);
526
527         handshakeManager.shake(helloMessage.build());
528
529         Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
530                 Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
531     }
532
533
534     /**
535      * @param ofpVersion10
536      * @param helloXid
537      * @return
538      */
539     private static HelloMessageBuilder createHelloMessage(short ofpVersion10, long helloXid) {
540         return new HelloMessageBuilder().setVersion(ofpVersion10).setXid(helloXid);
541     }
542
543     /**
544      * @param versionOrder
545      * @param helloBuilder
546      * @return
547      */
548     private static HelloMessageBuilder addVersionBitmap(List<Short> versionOrder,
549             HelloMessageBuilder helloBuilder) {
550         short highestVersion = versionOrder.get(0);
551         int elementsCount = highestVersion / Integer.SIZE;
552         ElementsBuilder elementsBuilder = new ElementsBuilder();
553
554         List<Elements> elementList = new ArrayList<>();
555         int orderIndex = versionOrder.size();
556         int value = versionOrder.get(--orderIndex);
557         for (int index = 0; index <= elementsCount; index++) {
558             List<Boolean> booleanList = new ArrayList<>();
559             for (int i = 0; i < Integer.SIZE; i++) {
560                 if (value == ((index * Integer.SIZE) + i)) {
561                     booleanList.add(true);
562                     value = (orderIndex == 0) ? highestVersion : versionOrder.get(--orderIndex);
563                 } else {
564                     booleanList.add(false);
565                 }
566             }
567             elementsBuilder.setType(HelloElementType.forValue(1));
568             elementsBuilder.setVersionBitmap(booleanList);
569             elementList.add(elementsBuilder.build());
570         }
571
572         helloBuilder.setElements(elementList);
573         return helloBuilder;
574     }
575
576 }