2 * Copyright (c) 2015 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
9 package org.opendaylight.openflowplugin.impl.connection.listener;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.net.InetSocketAddress;
14 import org.junit.After;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.mockito.Matchers;
19 import org.mockito.Mock;
20 import org.mockito.Mockito;
21 import org.mockito.runners.MockitoJUnitRunner;
22 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
23 import org.opendaylight.openflowplugin.impl.connection.ConnectionContextImpl;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder;
33 import org.opendaylight.yangtools.yang.common.RpcResult;
34 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
37 * Testing basic bahavior of {@link SystemNotificationsListenerImpl}
39 @RunWith(MockitoJUnitRunner.class)
40 public class SystemNotificationsListenerImplTest {
42 public static final int SAFE_TIMEOUT = 1000;
44 private org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter connectionAdapter;
46 private FeaturesReply features;
47 private ConnectionContext connectionContext;
49 private SystemNotificationsListenerImpl systemNotificationsListener;
50 private ConnectionContextImpl connectionContextGolem;
51 private static final NodeId nodeId = new NodeId("OFP:TEST");
55 connectionContextGolem = new ConnectionContextImpl(connectionAdapter);
56 connectionContextGolem.changeStateToWorking();
57 connectionContextGolem.setNodeId(nodeId);
59 Mockito.when(connectionAdapter.getRemoteAddress()).thenReturn(
60 InetSocketAddress.createUnresolved("unit-odl.example.org", 4242));
61 connectionContext = Mockito.spy(connectionContextGolem);
62 Mockito.when(features.getAuxiliaryId()).thenReturn((short) 0);
64 Mockito.when(connectionContext.getConnectionAdapter()).thenReturn(connectionAdapter);
65 Mockito.when(connectionContext.getFeatures()).thenReturn(features);
67 systemNotificationsListener = new SystemNotificationsListenerImpl(connectionContext);
71 public void tearDown() throws Exception {
72 Mockito.verifyNoMoreInteractions(connectionContext);
76 * successful scenario - connection is on and closes without errors
81 public void testOnDisconnectEvent1() throws Exception {
82 Mockito.when(connectionAdapter.isAlive()).thenReturn(true);
83 Mockito.when(connectionAdapter.disconnect()).thenReturn(Futures.immediateFuture(Boolean.TRUE));
85 DisconnectEvent disconnectNotification = new DisconnectEventBuilder().setInfo("testing disconnect").build();
86 systemNotificationsListener.onDisconnectEvent(disconnectNotification);
88 verifyCommonInvocationsSubSet();
89 Mockito.verify(connectionContext).onConnectionClosed();
93 * broken scenario - connection is on but fails to close
98 public void testOnDisconnectEvent2() throws Exception {
99 Mockito.when(connectionAdapter.isAlive()).thenReturn(true);
100 Mockito.when(connectionAdapter.disconnect()).thenReturn(Futures.immediateFuture(Boolean.FALSE));
102 DisconnectEvent disconnectNotification = new DisconnectEventBuilder().setInfo("testing disconnect").build();
103 systemNotificationsListener.onDisconnectEvent(disconnectNotification);
105 verifyCommonInvocationsSubSet();
106 Mockito.verify(connectionContext).onConnectionClosed();
110 * successful scenario - connection is already down
115 public void testOnDisconnectEvent3() throws Exception {
116 connectionContextGolem.changeStateToTimeouting();
118 Mockito.when(connectionAdapter.isAlive()).thenReturn(true);
119 Mockito.when(connectionAdapter.disconnect()).thenReturn(Futures.<Boolean>immediateFailedFuture(new Exception("unit exception")));
121 DisconnectEvent disconnectNotification = new DisconnectEventBuilder().setInfo("testing disconnect").build();
122 systemNotificationsListener.onDisconnectEvent(disconnectNotification);
124 verifyCommonInvocationsSubSet();
125 Mockito.verify(connectionContext).onConnectionClosed();
129 * broken scenario - connection is on but throws error on close
134 public void testOnDisconnectEvent4() throws Exception {
135 Mockito.when(connectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.RIP);
136 Mockito.when(connectionAdapter.isAlive()).thenReturn(false);
138 DisconnectEvent disconnectNotification = new DisconnectEventBuilder().setInfo("testing disconnect").build();
139 systemNotificationsListener.onDisconnectEvent(disconnectNotification);
141 verifyCommonInvocationsSubSet();
142 Mockito.verify(connectionContext).onConnectionClosed();
146 * first encounter of idle event, echo received successfully
151 public void testOnSwitchIdleEvent1() throws Exception {
152 final SettableFuture<RpcResult<EchoOutput>> echoReply = SettableFuture.create();
153 Mockito.when(connectionAdapter.echo(Matchers.any(EchoInput.class))).thenReturn(echoReply);
155 SwitchIdleEvent notification = new SwitchIdleEventBuilder().setInfo("wake up, device sleeps").build();
156 systemNotificationsListener.onSwitchIdleEvent(notification);
158 // make sure that the idle notification processing thread started
159 Thread.sleep(SAFE_TIMEOUT);
160 EchoOutput echoReplyVal = new EchoOutputBuilder().build();
161 echoReply.set(RpcResultBuilder.success(echoReplyVal).build());
163 verifyCommonInvocations();
164 Mockito.verify(connectionAdapter, Mockito.timeout(SAFE_TIMEOUT)).echo(Matchers.any(EchoInput.class));
165 Mockito.verify(connectionAdapter, Mockito.never()).disconnect();
166 Mockito.verify(connectionContext).changeStateToTimeouting();
167 Mockito.verify(connectionContext).changeStateToWorking();
171 * first encounter of idle event, echo not receive
176 public void testOnSwitchIdleEvent2() throws Exception {
177 final SettableFuture<RpcResult<EchoOutput>> echoReply = SettableFuture.create();
178 Mockito.when(connectionAdapter.echo(Matchers.any(EchoInput.class))).thenReturn(echoReply);
179 Mockito.when(connectionAdapter.isAlive()).thenReturn(true);
180 Mockito.when(connectionAdapter.disconnect()).thenReturn(Futures.<Boolean>immediateFailedFuture(new Exception("unit exception")));
182 SwitchIdleEvent notification = new SwitchIdleEventBuilder().setInfo("wake up, device sleeps").build();
183 systemNotificationsListener.onSwitchIdleEvent(notification);
185 Thread.sleep(SystemNotificationsListenerImpl.MAX_ECHO_REPLY_TIMEOUT + SAFE_TIMEOUT);
187 verifyCommonInvocations();
188 Mockito.verify(connectionAdapter, Mockito.timeout(SAFE_TIMEOUT)).echo(Matchers.any(EchoInput.class));
189 Mockito.verify(connectionAdapter).disconnect();
190 Mockito.verify(connectionContext).changeStateToTimeouting();
191 Mockito.verify(connectionContext).closeConnection(true);
194 private void verifyCommonInvocations() {
195 verifyCommonInvocationsSubSet();
196 Mockito.verify(connectionContext, Mockito.timeout(SAFE_TIMEOUT).atLeastOnce()).getConnectionAdapter();
199 private void verifyCommonInvocationsSubSet() {
200 Mockito.verify(connectionContext, Mockito.timeout(SAFE_TIMEOUT).atLeastOnce()).getConnectionState();
201 Mockito.verify(connectionContext, Mockito.timeout(SAFE_TIMEOUT).atLeastOnce()).getFeatures();