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