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 static org.mockito.ArgumentMatchers.any;
11 import static org.mockito.ArgumentMatchers.anyShort;
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;
49 @RunWith(MockitoJUnitRunner.class)
50 public class HandshakeManagerImplTest {
52 private static final Logger LOG = LoggerFactory.getLogger(HandshakeManagerImplTest.class);
54 private HandshakeManagerImpl handshakeManager;
56 private ConnectionAdapter adapter;
58 private ErrorHandler errorHandler;
60 private HandshakeListener handshakeListener;
62 private DeviceConnectionRateLimiter deviceConnectionRateLimiter;
64 private RpcResult<GetFeaturesOutput> resultFeatures;
66 private final long helloXid = 42L;
68 private int expectedErrors = 0;
70 private static final int DEVICE_CONNECTION_RATE_LIMIT_PER_MIN = 0;
73 * invoked before every test method.
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);
82 resultFeatures = RpcResultBuilder.success(new GetFeaturesOutputBuilder().build()).build();
84 Mockito.when(adapter.hello(any(HelloInput.class)))
85 .thenReturn(Futures.immediateFuture(RpcResultBuilder.success((HelloOutput) null).build()));
89 * invoked after each test method.
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);
100 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(any(Throwable.class));
105 * {@link org.opendaylight.openflowplugin.openflow.md.core
106 * .HandshakeManagerImpl#proposeCommonBitmapVersion(java.util.List)}.
109 public void testProposeCommonBitmapVersion() {
111 = new Boolean[][]{{true, true, true, false, false, false}, {true, true, true, false, false}};
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);
125 * {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeNextVersion(short)}.
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};
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],
140 handshakeManager.proposeNextVersion((short) 0);
141 Assert.fail("there should be no proposition for this version");
142 } catch (Exception e) {
147 //////// Version Negotiation Tests //////////////
150 * Test of version negotiation Where switch version = 1.0.
154 public void testVersionNegotiation10() {
155 LOG.debug("testVersionNegotiation10");
156 Short version = OFConstants.OFP_VERSION_1_0;
158 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
159 .thenReturn(Futures.immediateFuture(resultFeatures));
161 handshakeManager.shake(null);
163 handshakeManager.shake(createHelloMessage(version, helloXid).build());
165 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
169 * Test of version negotiation Where switch version = 1.0.
173 public void testVersionNegotiation10SwitchStarts() {
174 LOG.debug("testVersionNegotiation10-ss");
175 Short version = OFConstants.OFP_VERSION_1_0;
177 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
178 .thenReturn(Futures.immediateFuture(resultFeatures));
180 handshakeManager.shake(createHelloMessage(version, helloXid).build());
182 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
186 * Test of version negotiation Where switch version < 1.0.
187 * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
190 public void testVersionNegotiation00() {
191 LOG.debug("testVersionNegotiation00");
193 Short version = (short) 0x00;
195 handshakeManager.shake(createHelloMessage(version, helloXid).build());
197 Mockito.verify(handshakeListener, Mockito.never())
198 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
202 * Test of version negotiation Where switch version < 1.0.
203 * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful
206 public void testVersionNegotiation00SwitchStarts() {
207 LOG.debug("testVersionNegotiation00-ss");
209 Short version = (short) 0x00;
211 handshakeManager.shake(null);
213 handshakeManager.shake(createHelloMessage(version, helloXid).build());
215 Mockito.verify(handshakeListener, Mockito.never())
216 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
220 * Test of version negotiation Where 1.0 < switch version < 1.3.
224 public void testVersionNegotiation11() {
225 LOG.debug("testVersionNegotiation11");
226 Short version = (short) 0x02;
227 Short expVersion = (short) 0x01;
229 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
230 .thenReturn(Futures.immediateFuture(resultFeatures));
232 handshakeManager.shake(createHelloMessage(version, helloXid).build());
234 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
236 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
240 * Test of version negotiation Where 1.0 < switch version < 1.3.
243 public void testVersionNegotiation11SwitchStarts() {
244 LOG.debug("testVersionNegotiation11-ss");
245 final Short version = (short) 0x02;
246 final Short expVersion = (short) 0x01;
248 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
249 .thenReturn(Futures.immediateFuture(resultFeatures));
251 handshakeManager.shake(null);
253 handshakeManager.shake(createHelloMessage(version, helloXid).build());
255 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
257 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
261 * Test of version negotiation Where switch version = 1.3.
265 public void testVersionNegotiation13() {
266 LOG.debug("testVersionNegotiation13");
267 Short version = OFConstants.OFP_VERSION_1_3;
269 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
270 .thenReturn(Futures.immediateFuture(resultFeatures));
272 handshakeManager.shake(createHelloMessage(version, helloXid).build());
274 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
278 * Test of version negotiation Where switch version = 1.3.
282 public void testVersionNegotiation13SwitchStarts() {
283 LOG.debug("testVersionNegotiation13-ss");
284 Short version = OFConstants.OFP_VERSION_1_3;
286 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
287 .thenReturn(Futures.immediateFuture(resultFeatures));
289 handshakeManager.shake(null);
291 handshakeManager.shake(createHelloMessage(version, helloXid).build());
293 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
297 * Test of version negotiation Where switch version >= 1.3.
301 public void testVersionNegotiation15() {
302 LOG.debug("testVersionNegotiation15");
303 Short version = (short) 0x06;
304 Short expVersion = OFConstants.OFP_VERSION_1_3;
306 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
307 .thenReturn(Futures.immediateFuture(resultFeatures));
309 handshakeManager.shake(createHelloMessage(version, helloXid).build());
311 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
313 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
317 * Test of version negotiation Where switch version >= 1.3.
321 public void testVersionNegotiation15SwitchStart() {
322 LOG.debug("testVersionNegotiation15-ss");
323 Short version = (short) 0x06;
324 Short expVersion = OFConstants.OFP_VERSION_1_3;
326 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
327 .thenReturn(Futures.immediateFuture(resultFeatures));
329 handshakeManager.shake(createHelloMessage(version, helloXid).build());
331 handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
333 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), expVersion);
337 * Test of version negotiation Where switch version > 1.3.
341 public void testVersionNegotiation15_MultipleCall() {
342 LOG.debug("testVersionNegotiation15_MultipleCall");
343 Short version = (short) 0x06;
346 handshakeManager.shake(createHelloMessage(version, helloXid).build());
348 handshakeManager.shake(createHelloMessage(version, helloXid).build());
350 Mockito.verify(handshakeListener, Mockito.never())
351 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
355 * Test of version negotiation Where switch version > 1.3.
359 public void testVersionNegotiation15_MultipleCallSwitchStarts() {
360 LOG.debug("testVersionNegotiation15_MultipleCall-ss");
361 Short version = (short) 0x06;
364 handshakeManager.shake(null);
366 handshakeManager.shake(createHelloMessage(version, helloXid).build());
368 handshakeManager.shake(createHelloMessage(version, helloXid).build());
370 Mockito.verify(handshakeListener, Mockito.never())
371 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
375 * Test of version negotiation Where bitmap version {0x05,0x01}.
379 public void testVersionNegotiation10InBitmap() {
380 LOG.debug("testVersionNegotiation10InBitmap");
381 Short version = OFConstants.OFP_VERSION_1_0;
382 handshakeManager.setUseVersionBitmap(true);
384 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
385 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
387 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
388 .thenReturn(Futures.immediateFuture(resultFeatures));
390 handshakeManager.shake(helloMessage.build());
392 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
396 * Test of version negotiation Where bitmap version {0x05,0x01}.
400 public void testVersionNegotiation10InBitmapSwitchStarts() {
401 LOG.debug("testVersionNegotiation10InBitmap-ss");
402 Short version = OFConstants.OFP_VERSION_1_0;
403 handshakeManager.setUseVersionBitmap(true);
405 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
406 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
408 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
409 .thenReturn(Futures.immediateFuture(resultFeatures));
411 handshakeManager.shake(null);
413 handshakeManager.shake(helloMessage.build());
415 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
419 * Test of version negotiation Where bitmap version {0x05,0x04}.
423 public void testVersionNegotiation13InBitmap() {
424 LOG.debug("testVersionNegotiation13InBitmap");
425 Short version = OFConstants.OFP_VERSION_1_3;
426 handshakeManager.setUseVersionBitmap(true);
428 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
429 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
431 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
432 .thenReturn(Futures.immediateFuture(resultFeatures));
434 handshakeManager.shake(helloMessage.build());
436 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
440 * Test of version negotiation Where bitmap version {0x05,0x04}.
444 public void testVersionNegotiation13InBitmapSwitchFirst() {
445 LOG.debug("testVersionNegotiation13InBitmap-ss");
446 Short version = OFConstants.OFP_VERSION_1_3;
447 handshakeManager.setUseVersionBitmap(true);
449 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
450 addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
452 Mockito.when(adapter.getFeatures(any(GetFeaturesInput.class)))
453 .thenReturn(Futures.immediateFuture(resultFeatures));
455 handshakeManager.shake(null);
457 handshakeManager.shake(helloMessage.build());
459 Mockito.verify(handshakeListener).onHandshakeSuccessful(resultFeatures.getResult(), version);
463 * Test of version negotiation Where bitmap version {0x05,0x02}.
467 public void testVersionNegotiationNoCommonVersionInBitmap() {
468 LOG.debug("testVersionNegotiationNoCommonVersionInBitmap");
469 Short version = (short) 0x05;
471 handshakeManager.setUseVersionBitmap(true);
473 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
474 addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
476 handshakeManager.shake(helloMessage.build());
478 Mockito.verify(handshakeListener, Mockito.never())
479 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
483 * Test of version negotiation Where bitmap version {0x05,0x02}.
487 public void testVersionNegotiationNoCommonVersionInBitmapSwitchStarts() {
488 LOG.debug("testVersionNegotiationNoCommonVersionInBitmap-ss");
489 Short version = (short) 0x05;
491 handshakeManager.setUseVersionBitmap(true);
493 HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
494 addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
496 handshakeManager.shake(null);
498 handshakeManager.shake(helloMessage.build());
500 Mockito.verify(handshakeListener, Mockito.never())
501 .onHandshakeSuccessful(any(GetFeaturesOutput.class), anyShort());
506 * Creates hello message.
508 * @param ofpVersion10 version
509 * @param helloXid hello xid
512 private static HelloMessageBuilder createHelloMessage(short ofpVersion10, long helloXid) {
513 return new HelloMessageBuilder().setVersion(ofpVersion10).setXid(helloXid);
517 * Adds version bitmap.
518 * @param versionOrder version order
519 * @param helloBuilder hello builder
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();
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);
537 booleanList.add(false);
540 elementsBuilder.setType(HelloElementType.forValue(1));
541 elementsBuilder.setVersionBitmap(booleanList);
542 elementList.add(elementsBuilder.build());
545 helloBuilder.setElements(elementList);