2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.controller.alivenessmonitor.test;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertThat;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.argThat;
15 import static org.mockito.Mockito.any;
16 import static org.mockito.Mockito.doNothing;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.eq;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.times;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.when;
24 import com.google.common.base.Optional;
25 import com.google.common.util.concurrent.CheckedFuture;
26 import com.google.common.util.concurrent.Futures;
27 import java.util.Arrays;
28 import org.hamcrest.CoreMatchers;
29 import org.hamcrest.Description;
30 import org.hamcrest.Matcher;
31 import org.hamcrest.TypeSafeMatcher;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.ArgumentCaptor;
36 import org.mockito.Captor;
37 import org.mockito.Matchers;
38 import org.mockito.Mock;
39 import org.mockito.MockitoAnnotations;
40 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
41 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
42 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
43 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
44 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
45 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
46 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
47 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
48 import org.opendaylight.genius.alivenessmonitor.internal.AlivenessMonitor;
49 import org.opendaylight.genius.alivenessmonitor.internal.AlivenessProtocolHandler;
50 import org.opendaylight.genius.alivenessmonitor.internal.AlivenessProtocolHandlerARP;
51 import org.opendaylight.genius.alivenessmonitor.internal.AlivenessProtocolHandlerLLDP;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.EtherTypes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorPauseInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorPauseInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileDeleteInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileDeleteInputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStatus;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorUnpauseInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorUnpauseInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitoringMode;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntry;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411._interface.monitor.map.InterfaceMonitorEntryBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.InterfaceBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.configs.MonitoringInfo;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.configs.MonitoringInfoBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.params.DestinationBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.params.SourceBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.create.input.ProfileBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profiles.MonitorProfile;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profiles.MonitorProfileBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.start.input.ConfigBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitorid.key.map.MonitoridKeyEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitorid.key.map.MonitoridKeyEntryBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringState;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitoring.states.MonitoringStateBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
94 import org.opendaylight.yangtools.yang.binding.DataObject;
95 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
96 import org.opendaylight.yangtools.yang.common.RpcError;
97 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
98 import org.opendaylight.yangtools.yang.common.RpcResult;
99 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
101 public class AlivenessMonitorTest {
103 @Mock private DataBroker dataBroker;
104 @Mock private IdManagerService idManager;
105 @Mock private PacketProcessingService packetProcessingService;
106 @Mock private NotificationPublishService notificationPublishService;
107 @Mock private NotificationService notificationService;
108 @Mock private OdlInterfaceRpcService interfaceManager;
109 @Mock private OdlArputilService arpService;
110 private AlivenessMonitor alivenessMonitor;
111 private AlivenessProtocolHandler arpHandler;
112 private AlivenessProtocolHandler lldpHandler;
114 @Mock private ReadOnlyTransaction readTx;
115 @Mock private WriteTransaction writeTx;
116 @Mock private ReadWriteTransaction readWriteTx;
117 @Captor ArgumentCaptor<MonitoringState> stateCaptor;
119 private <T extends DataObject> Matcher<InstanceIdentifier<T>> isType(final Class<T> klass) {
120 return new TypeSafeMatcher<InstanceIdentifier<T>>() {
122 public void describeTo(Description desc) {
123 desc.appendText("Instance Identifier should have Target Type " + klass);
127 protected boolean matchesSafely(InstanceIdentifier<T> id) {
128 return id.getTargetType().equals(klass);
133 private Matcher<RpcError> hasErrorType(final ErrorType errorType) {
134 return new TypeSafeMatcher<RpcError>() {
136 public void describeTo(Description desc) {
137 desc.appendText("Error type do not match " + errorType);
141 protected boolean matchesSafely(RpcError error) {
142 return error.getErrorType().equals(errorType);
147 @SuppressWarnings("unchecked")
149 public void setUp() {
150 MockitoAnnotations.initMocks(this);
151 when(idManager.createIdPool(any(CreateIdPoolInput.class)))
152 .thenReturn(Futures.immediateFuture(RpcResultBuilder.<Void>success().build()));
154 alivenessMonitor = new AlivenessMonitor(dataBroker, idManager, notificationPublishService,
155 notificationService);
156 alivenessMonitor.start();
157 arpHandler = new AlivenessProtocolHandlerARP(dataBroker, interfaceManager, alivenessMonitor, arpService);
158 lldpHandler = new AlivenessProtocolHandlerLLDP(dataBroker, interfaceManager, alivenessMonitor,
159 packetProcessingService);
161 when(idManager.allocateId(any(AllocateIdInput.class)))
162 .thenReturn(Futures.immediateFuture(RpcResultBuilder.success(new AllocateIdOutputBuilder().setIdValue(mockId++).build()).build()));
163 when(idManager.releaseId(any(ReleaseIdInput.class))).thenReturn(Futures.immediateFuture(RpcResultBuilder.<Void>success().build()));
164 doReturn(readTx).when(dataBroker).newReadOnlyTransaction();
165 doReturn(writeTx).when(dataBroker).newWriteOnlyTransaction();
166 doReturn(readWriteTx).when(dataBroker).newReadWriteTransaction();
167 doNothing().when(writeTx).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
168 doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
169 doReturn(Futures.immediateCheckedFuture(null)).when(readWriteTx).submit();
173 public void tearDown() throws Exception {
174 alivenessMonitor.close();
178 public void testMonitorProfileCreate() throws Throwable {
179 MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder()
180 .setProfile(new ProfileBuilder().setFailureThreshold(10L)
181 .setMonitorInterval(10000L)
182 .setMonitorWindow(10L)
183 .setProtocolType(EtherTypes.Arp).build()).build();
184 doReturn(Futures.immediateCheckedFuture(Optional.absent()))
185 .when(readWriteTx).read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)));
186 doReturn(Futures.immediateCheckedFuture(null)).when(readWriteTx).submit();
187 RpcResult<MonitorProfileCreateOutput> output = alivenessMonitor.monitorProfileCreate(input).get();
188 assertTrue("Monitor Profile Create result", output.isSuccessful());
189 assertNotNull("Monitor Profile Output", output.getResult().getProfileId());
193 public void testMonitorProfileCreateAlreadyExist() throws Throwable {
194 MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().setProfile(new ProfileBuilder().setFailureThreshold(10L)
195 .setMonitorInterval(10000L).setMonitorWindow(10L).setProtocolType(EtherTypes.Arp).build()).build();
196 @SuppressWarnings("unchecked")
197 Optional<MonitorProfile> optionalProfile = (Optional<MonitorProfile>)mock(Optional.class);
198 CheckedFuture<Optional<MonitorProfile>, ReadFailedException> proFuture = Futures.immediateCheckedFuture(optionalProfile);
199 doReturn(true).when(optionalProfile).isPresent();
200 doReturn(proFuture).when(readWriteTx).read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)));
201 RpcResult<MonitorProfileCreateOutput> output = alivenessMonitor.monitorProfileCreate(input).get();
202 assertTrue("Monitor Profile Create result", output.isSuccessful());
203 assertThat(output.getErrors(), CoreMatchers.hasItem(hasErrorType(ErrorType.PROTOCOL)));
207 public void testMonitorStart() throws Throwable {
208 Long profileId = createProfile();
209 MonitorStartInput input = new MonitorStartInputBuilder().setConfig(new ConfigBuilder()
210 .setDestination(new DestinationBuilder().setEndpointType(getInterface("10.0.0.1")).build())
211 .setSource(new SourceBuilder().setEndpointType(getInterface("testInterface", "10.1.1.1")).build())
212 .setMode(MonitoringMode.OneOne)
213 .setProfileId(profileId).build()).build();
214 @SuppressWarnings("unchecked")
215 Optional<MonitorProfile> optionalProfile = Optional.of(getTestMonitorProfile());
216 CheckedFuture<Optional<MonitorProfile>, ReadFailedException> proFuture = Futures.immediateCheckedFuture(optionalProfile);
217 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)))).thenReturn(proFuture);
218 CheckedFuture<Optional<MonitoringInfo>, ReadFailedException> outFuture = Futures.immediateCheckedFuture(Optional.<MonitoringInfo>absent());
219 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringInfo.class)))).thenReturn(outFuture);
220 RpcResult<MonitorStartOutput> output = alivenessMonitor.monitorStart(input).get();
221 verify(idManager, times(2)).allocateId(any(AllocateIdInput.class));
222 assertTrue("Monitor start output result", output.isSuccessful());
223 assertNotNull("Monitor start output", output.getResult().getMonitorId());
227 public void testMonitorPause() throws Throwable {
228 MonitorPauseInput input = new MonitorPauseInputBuilder().setMonitorId(2L).build();
229 Optional<MonitorProfile> optProfile = Optional.of(getTestMonitorProfile());
230 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)))).
231 thenReturn(Futures.immediateCheckedFuture(optProfile));
232 Optional<MonitoringInfo> optInfo = Optional.of(new MonitoringInfoBuilder().setId(2L).setProfileId(1L).build());
233 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringInfo.class)))).
234 thenReturn(Futures.immediateCheckedFuture(optInfo));
235 Optional<MonitoringState> optState = Optional.of(new MonitoringStateBuilder().setStatus(MonitorStatus.Started).build());
236 when(readWriteTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringState.class)))).
237 thenReturn(Futures.immediateCheckedFuture(optState));
238 Optional<MonitoridKeyEntry> optMap = Optional.of(new MonitoridKeyEntryBuilder().setMonitorId(2L).setMonitorKey("Test monitor Key").build());
239 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoridKeyEntry.class)))).
240 thenReturn(Futures.immediateCheckedFuture(optMap));
241 alivenessMonitor.monitorPause(input).get();
242 verify(readWriteTx).merge(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringState.class)), stateCaptor.capture());
243 assertEquals(MonitorStatus.Paused, stateCaptor.getValue().getStatus());
247 public void testMonitorUnpause() throws Throwable {
248 MonitorUnpauseInput input = new MonitorUnpauseInputBuilder().setMonitorId(2L).build();
249 Optional<MonitoringState> optState = Optional.of(new MonitoringStateBuilder().setStatus(MonitorStatus.Paused).build());
250 when(readWriteTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringState.class)))).
251 thenReturn(Futures.immediateCheckedFuture(optState));
252 Optional<MonitoringInfo> optInfo = Optional.of(new MonitoringInfoBuilder().setId(2L).setProfileId(1L).build());
253 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringInfo.class)))).
254 thenReturn(Futures.immediateCheckedFuture(optInfo));
255 Optional<MonitorProfile> optProfile = Optional.of(getTestMonitorProfile());
256 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)))).
257 thenReturn(Futures.immediateCheckedFuture(optProfile));
258 Optional<MonitoridKeyEntry> optMap = Optional.of(new MonitoridKeyEntryBuilder().setMonitorId(2L).setMonitorKey("Test monitor Key").build());
259 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoridKeyEntry.class)))).
260 thenReturn(Futures.immediateCheckedFuture(optMap));
261 RpcResult<Void> result = alivenessMonitor.monitorUnpause(input).get();
262 verify(readWriteTx).merge(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringState.class)), stateCaptor.capture());
263 assertEquals(MonitorStatus.Started, stateCaptor.getValue().getStatus());
264 assertTrue("Monitor unpause rpc result", result.isSuccessful());
268 public void testMonitorStop() throws Throwable {
269 MonitorStopInput input = new MonitorStopInputBuilder().setMonitorId(2L).build();
270 Optional<MonitoringInfo> optInfo = Optional.of(
271 new MonitoringInfoBuilder().setSource(new SourceBuilder().setEndpointType(getInterface("testInterface", "10.1.1.1")).build()).build());
272 CheckedFuture<Optional<MonitoringInfo>, ReadFailedException> outFuture = Futures.immediateCheckedFuture(optInfo);
273 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoringInfo.class)))).thenReturn(outFuture);
274 Optional<MonitoridKeyEntry> optMap = Optional.of(new MonitoridKeyEntryBuilder().setMonitorId(2L).setMonitorKey("Test monitor Key").build());
275 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitoridKeyEntry.class)))).
276 thenReturn(Futures.immediateCheckedFuture(optMap));
277 Optional<MonitorProfile> optProfile = Optional.of(getTestMonitorProfile());
278 when(readTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)))).
279 thenReturn(Futures.immediateCheckedFuture(optProfile));
280 Optional<InterfaceMonitorEntry> optEntry = Optional.of(getInterfaceMonitorEntry());
281 when(readWriteTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(InterfaceMonitorEntry.class)))).
282 thenReturn(Futures.immediateCheckedFuture(optEntry));
283 RpcResult<Void> result = alivenessMonitor.monitorStop(input).get();
284 verify(idManager).releaseId(any(ReleaseIdInput.class));
285 verify(writeTx, times(2)).delete(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
286 assertTrue("Monitor stop rpc result", result.isSuccessful());
290 public void testMonitorProfileDelete() throws Throwable {
291 MonitorProfileDeleteInput input = new MonitorProfileDeleteInputBuilder().setProfileId(1L).build();
292 Optional<MonitorProfile> optProfile = Optional.of(getTestMonitorProfile());
293 when(readWriteTx.read(eq(LogicalDatastoreType.OPERATIONAL), argThat(isType(MonitorProfile.class)))).
294 thenReturn(Futures.immediateCheckedFuture(optProfile));
295 RpcResult<Void> result = alivenessMonitor.monitorProfileDelete(input).get();
296 verify(idManager).releaseId(any(ReleaseIdInput.class));
297 verify(readWriteTx).delete(eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<MonitorProfile>>any());
298 assertTrue("Monitor profile delete result", result.isSuccessful());
301 @SuppressWarnings("unchecked")
302 private long createProfile() throws Throwable{
303 MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().setProfile(new ProfileBuilder().setFailureThreshold(10L)
304 .setMonitorInterval(10000L).setMonitorWindow(10L).setProtocolType(EtherTypes.Arp).build()).build();
305 doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(readWriteTx).read(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
306 doReturn(Futures.immediateCheckedFuture(null)).when(readWriteTx).submit();
307 RpcResult<MonitorProfileCreateOutput> output = alivenessMonitor.monitorProfileCreate(input).get();
308 return output.getResult().getProfileId();
311 private MonitorProfile getTestMonitorProfile() {
312 return new MonitorProfileBuilder().setFailureThreshold(10L).setMonitorInterval(10000L)
313 .setMonitorWindow(10L).setProtocolType(EtherTypes.Arp).build();
316 private InterfaceMonitorEntry getInterfaceMonitorEntry() {
317 return new InterfaceMonitorEntryBuilder().setInterfaceName("test-interface").setMonitorIds(Arrays.asList(1L, 2L)).build();
320 private Interface getInterface(String ipAddress) {
321 return new InterfaceBuilder().setInterfaceIp(IpAddressBuilder.getDefaultInstance(ipAddress)).build();
324 private Interface getInterface(String interfaceName, String ipAddress) {
325 return new InterfaceBuilder().setInterfaceIp(IpAddressBuilder.getDefaultInstance(ipAddress)).setInterfaceName(interfaceName).build();