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