2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.impl.connection;
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;
46 @RunWith(MockitoJUnitRunner.class)
47 public class HandshakeManagerImplTest {
49 private static final Logger LOG = LoggerFactory.getLogger(HandshakeManagerImplTest.class);
51 private HandshakeManagerImpl handshakeManager;
53 private ConnectionAdapter adapter;
55 private ErrorHandler errorHandler;
57 private HandshakeListener handshakeListener;
59 private DeviceConnectionRateLimiter deviceConnectionRateLimiter;
61 private RpcResult<GetFeaturesOutput> resultFeatures;
63 private final long helloXid = 42L;
65 private int expectedErrors = 0;
67 private static final int DEVICE_CONNECTION_RATE_LIMIT_PER_MIN = 0;
70 * invoked before every test method.
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);
79 resultFeatures = RpcResultBuilder.success(new GetFeaturesOutputBuilder().build()).build();
81 Mockito.when(adapter.hello(Matchers.any(HelloInput.class)))
82 .thenReturn(Futures.immediateFuture(RpcResultBuilder.success((Void) null).build()));
86 * invoked after each test method.
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);
97 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(Matchers.any(Throwable.class));
102 * {@link org.opendaylight.openflowplugin.openflow.md.core
103 * .HandshakeManagerImpl#proposeCommonBitmapVersion(java.util.List)}.
106 public void testProposeCommonBitmapVersion() {
108 = new Boolean[][]{{true, true, true, false, false, false}, {true, true, true, false, false}};
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);
122 * {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeNextVersion(short)}.
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};
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],
137 handshakeManager.proposeNextVersion((short) 0);
138 Assert.fail("there should be no proposition for this version");
139 } catch (Exception e) {
144 //////// Version Negotiation Tests //////////////
147 * Test of version negotiation Where switch version = 1.0.
151 public void testVersionNegotiation10() throws Exception {
152 LOG.debug("testVersionNegotiation10");
153 Short version = OFConstants.OFP_VERSION_1_0;
155 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
156 .thenReturn(Futures.immediateFuture(resultFeatures));
158 handshakeManager.shake(null);
160 handshakeManager.shake(createHelloMessage(version, helloXid).build());
162 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
166 * Test of version negotiation Where switch version = 1.0.
170 public void testVersionNegotiation10SwitchStarts() throws Exception {
171 LOG.debug("testVersionNegotiation10-ss");
172 Short version = OFConstants.OFP_VERSION_1_0;
174 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
175 .thenReturn(Futures.immediateFuture(resultFeatures));
177 handshakeManager.shake(createHelloMessage(version, helloXid).build());
179 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
183 * Test of version negotiation Where switch version < 1.0.
184 * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
187 public void testVersionNegotiation00() throws Exception {
188 LOG.debug("testVersionNegotiation00");
190 Short version = (short) 0x00;
192 handshakeManager.shake(createHelloMessage(version, helloXid).build());
194 Mockito.verify(handshakeListener, Mockito.never())
195 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
199 * Test of version negotiation Where switch version < 1.0.
200 * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
203 public void testVersionNegotiation00SwitchStarts() throws Exception {
204 LOG.debug("testVersionNegotiation00-ss");
206 Short version = (short) 0x00;
208 handshakeManager.shake(null);
210 handshakeManager.shake(createHelloMessage(version, helloXid).build());
212 Mockito.verify(handshakeListener, Mockito.never())
213 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
217 * Test of version negotiation Where 1.0 < switch version < 1.3.
221 public void testVersionNegotiation11() throws Exception {
222 LOG.debug("testVersionNegotiation11");
223 Short version = (short) 0x02;
224 Short expVersion = (short) 0x01;
226 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
227 .thenReturn(Futures.immediateFuture(resultFeatures));
229 handshakeManager.shake(createHelloMessage(version, helloXid).build());
231 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
233 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
237 * Test of version negotiation Where 1.0 < switch version < 1.3.
240 public void testVersionNegotiation11SwitchStarts() throws Exception {
241 LOG.debug("testVersionNegotiation11-ss");
242 final Short version = (short) 0x02;
243 final Short expVersion = (short) 0x01;
245 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
246 .thenReturn(Futures.immediateFuture(resultFeatures));
248 handshakeManager.shake(null);
250 handshakeManager.shake(createHelloMessage(version, helloXid).build());
252 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
254 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
258 * Test of version negotiation Where switch version = 1.3.
262 public void testVersionNegotiation13() throws Exception {
263 LOG.debug("testVersionNegotiation13");
264 Short version = OFConstants.OFP_VERSION_1_3;
266 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
267 .thenReturn(Futures.immediateFuture(resultFeatures));
269 handshakeManager.shake(createHelloMessage(version, helloXid).build());
271 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
275 * Test of version negotiation Where switch version = 1.3.
279 public void testVersionNegotiation13SwitchStarts() throws Exception {
280 LOG.debug("testVersionNegotiation13-ss");
281 Short version = OFConstants.OFP_VERSION_1_3;
283 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
284 .thenReturn(Futures.immediateFuture(resultFeatures));
286 handshakeManager.shake(null);
288 handshakeManager.shake(createHelloMessage(version, helloXid).build());
290 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
294 * Test of version negotiation Where switch version >= 1.3.
298 public void testVersionNegotiation15() throws Exception {
299 LOG.debug("testVersionNegotiation15");
300 Short version = (short) 0x06;
301 Short expVersion = OFConstants.OFP_VERSION_1_3;
303 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
304 .thenReturn(Futures.immediateFuture(resultFeatures));
306 handshakeManager.shake(createHelloMessage(version, helloXid).build());
308 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
310 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
314 * Test of version negotiation Where switch version >= 1.3.
318 public void testVersionNegotiation15SwitchStart() throws Exception {
319 LOG.debug("testVersionNegotiation15-ss");
320 Short version = (short) 0x06;
321 Short expVersion = OFConstants.OFP_VERSION_1_3;
323 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
324 .thenReturn(Futures.immediateFuture(resultFeatures));
326 handshakeManager.shake(createHelloMessage(version, helloXid).build());
328 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
330 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
334 * Test of version negotiation Where switch version > 1.3.
338 public void testVersionNegotiation15_MultipleCall() throws Exception {
339 LOG.debug("testVersionNegotiation15_MultipleCall");
340 Short version = (short) 0x06;
343 handshakeManager.shake(createHelloMessage(version, helloXid).build());
345 handshakeManager.shake(createHelloMessage(version, helloXid).build());
347 Mockito.verify(handshakeListener, Mockito.never())
348 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
352 * Test of version negotiation Where switch version > 1.3.
356 public void testVersionNegotiation15_MultipleCallSwitchStarts() throws Exception {
357 LOG.debug("testVersionNegotiation15_MultipleCall-ss");
358 Short version = (short) 0x06;
361 handshakeManager.shake(null);
363 handshakeManager.shake(createHelloMessage(version, helloXid).build());
365 handshakeManager.shake(createHelloMessage(version, helloXid).build());
367 Mockito.verify(handshakeListener, Mockito.never())
368 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
372 * Test of version negotiation Where bitmap version {0x05,0x01}.
376 public void testVersionNegotiation10InBitmap() throws Exception {
377 LOG.debug("testVersionNegotiation10InBitmap");
378 Short version = OFConstants.OFP_VERSION_1_0;
379 handshakeManager.setUseVersionBitmap(true);
381 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
382 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
384 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
385 .thenReturn(Futures.immediateFuture(resultFeatures));
387 handshakeManager.shake(helloMessage.build());
389 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
393 * Test of version negotiation Where bitmap version {0x05,0x01}.
397 public void testVersionNegotiation10InBitmapSwitchStarts() throws Exception {
398 LOG.debug("testVersionNegotiation10InBitmap-ss");
399 Short version = OFConstants.OFP_VERSION_1_0;
400 handshakeManager.setUseVersionBitmap(true);
402 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
403 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
405 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
406 .thenReturn(Futures.immediateFuture(resultFeatures));
408 handshakeManager.shake(null);
410 handshakeManager.shake(helloMessage.build());
412 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
416 * Test of version negotiation Where bitmap version {0x05,0x04}.
420 public void testVersionNegotiation13InBitmap() throws Exception {
421 LOG.debug("testVersionNegotiation13InBitmap");
422 Short version = OFConstants.OFP_VERSION_1_3;
423 handshakeManager.setUseVersionBitmap(true);
425 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
426 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
428 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
429 .thenReturn(Futures.immediateFuture(resultFeatures));
431 handshakeManager.shake(helloMessage.build());
433 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
437 * Test of version negotiation Where bitmap version {0x05,0x04}.
441 public void testVersionNegotiation13InBitmapSwitchFirst() throws Exception {
442 LOG.debug("testVersionNegotiation13InBitmap-ss");
443 Short version = OFConstants.OFP_VERSION_1_3;
444 handshakeManager.setUseVersionBitmap(true);
446 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
447 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
449 Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
450 .thenReturn(Futures.immediateFuture(resultFeatures));
452 handshakeManager.shake(null);
454 handshakeManager.shake(helloMessage.build());
456 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
460 * Test of version negotiation Where bitmap version {0x05,0x02}.
464 public void testVersionNegotiationNoCommonVersionInBitmap() throws Exception {
465 LOG.debug("testVersionNegotiationNoCommonVersionInBitmap");
466 Short version = (short) 0x05;
468 handshakeManager.setUseVersionBitmap(true);
470 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
471 addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
473 handshakeManager.shake(helloMessage.build());
475 Mockito.verify(handshakeListener, Mockito.never())
476 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
480 * Test of version negotiation Where bitmap version {0x05,0x02}.
484 public void testVersionNegotiationNoCommonVersionInBitmapSwitchStarts() throws Exception {
485 LOG.debug("testVersionNegotiationNoCommonVersionInBitmap-ss");
486 Short version = (short) 0x05;
488 handshakeManager.setUseVersionBitmap(true);
490 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
491 addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
493 handshakeManager.shake(null);
495 handshakeManager.shake(helloMessage.build());
497 Mockito.verify(handshakeListener, Mockito.never())
498 .onHandshakeSuccessful(Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
503 * Creates hello message.
505 * @param ofpVersion10 version
506 * @param helloXid hello xid
509 private static HelloMessageBuilder createHelloMessage(short ofpVersion10, long helloXid) {
510 return new HelloMessageBuilder().setVersion(ofpVersion10).setXid(helloXid);
514 * Adds version bitmap.
515 * @param versionOrder version order
516 * @param helloBuilder hello builder
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();
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);
534 booleanList.add(false);
537 elementsBuilder.setType(HelloElementType.forValue(1));
538 elementsBuilder.setVersionBitmap(booleanList);
539 elementList.add(elementsBuilder.build());
542 helloBuilder.setElements(elementList);