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