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