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