blob: 666b0ad43ae0cd1ba68bad8cb7b247995a77cc7d [file] [log] [blame]
Thanuj Ravindranath926e3162016-01-26 09:44:08 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Thanuj Ravindranath926e3162016-01-26 09:44:08 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Yuta HIGUCHIe3ae8212017-04-20 10:18:41 -070016package org.onosproject.netconf.ctl.impl;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053017
18import org.easymock.EasyMock;
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030022import org.onlab.osgi.ComponentContextAdapter;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053023import org.onlab.packet.IpAddress;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030024import org.onosproject.cfg.ComponentConfigAdapter;
25import org.onosproject.cfg.ComponentConfigService;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053026import org.onosproject.net.DeviceId;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070027import org.onosproject.net.device.DeviceService;
28import org.onosproject.net.key.DeviceKeyService;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053029import org.onosproject.netconf.NetconfDevice;
30import org.onosproject.netconf.NetconfDeviceFactory;
31import org.onosproject.netconf.NetconfDeviceInfo;
32import org.onosproject.netconf.NetconfDeviceListener;
33import org.onosproject.netconf.NetconfDeviceOutputEvent;
34import org.onosproject.netconf.NetconfDeviceOutputEventListener;
35import org.onosproject.netconf.NetconfException;
36import org.onosproject.netconf.NetconfSession;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030037import org.osgi.service.component.ComponentContext;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053038
39import java.lang.reflect.Field;
Andreas Papazois4752cfa2016-04-25 14:52:12 +030040import java.util.Dictionary;
41import java.util.Enumeration;
Andrea Campanella86294db2016-03-07 11:42:49 -080042import java.util.HashSet;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053043import java.util.Map;
44import java.util.Optional;
Andrea Campanella86294db2016-03-07 11:42:49 -080045import java.util.Set;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053046
47import static org.hamcrest.Matchers.*;
48import static org.junit.Assert.*;
49
50/**
51 * Unit tests for the Netconf controller implementation test.
52 */
53public class NetconfControllerImplTest {
Andrea Campanella7e6200a2016-03-21 09:48:40 -070054
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053055 NetconfControllerImpl ctrl;
56
57 //DeviceInfo
58 NetconfDeviceInfo deviceInfo1;
59 NetconfDeviceInfo deviceInfo2;
60 NetconfDeviceInfo badDeviceInfo3;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070061 NetconfDeviceInfo deviceInfoIpV6;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053062
63 //Devices & DeviceId
64 NetconfDevice device1;
65 DeviceId deviceId1;
66 NetconfDevice device2;
67 DeviceId deviceId2;
68
69 //Events
70 NetconfDeviceOutputEvent eventForDeviceInfo1;
71 NetconfDeviceOutputEvent eventForDeviceInfo2;
72
73 private Map<DeviceId, NetconfDevice> reflectedDeviceMap;
74 private NetconfDeviceOutputEventListener reflectedDownListener;
75
76 //Test Device IP addresses and ports
77 private static final String DEVICE_1_IP = "10.10.10.11";
78 private static final String DEVICE_2_IP = "10.10.10.12";
79 private static final String BAD_DEVICE_IP = "10.10.10.13";
Andrea Campanella7e6200a2016-03-21 09:48:40 -070080 private static final String DEVICE_IPV6 = "2001:db8::1";
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053081
82 private static final int DEVICE_1_PORT = 11;
83 private static final int DEVICE_2_PORT = 12;
84 private static final int BAD_DEVICE_PORT = 13;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070085 private static final int IPV6_DEVICE_PORT = 14;
86
Andreas Papazois4752cfa2016-04-25 14:52:12 +030087 private static ComponentConfigService cfgService = new ComponentConfigAdapter();
Andrea Campanella7e6200a2016-03-21 09:48:40 -070088 private static DeviceService deviceService = new NetconfDeviceServiceMock();
89 private static DeviceKeyService deviceKeyService = new NetconfDeviceKeyServiceMock();
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053090
Andreas Papazois4752cfa2016-04-25 14:52:12 +030091 private final ComponentContext context = new MockComponentContext();
Thanuj Ravindranath926e3162016-01-26 09:44:08 +053092
93 @Before
94 public void setUp() throws Exception {
95 ctrl = new NetconfControllerImpl();
96 ctrl.deviceFactory = new TestNetconfDeviceFactory();
Andreas Papazois4752cfa2016-04-25 14:52:12 +030097 ctrl.cfgService = cfgService;
Andrea Campanella7e6200a2016-03-21 09:48:40 -070098 ctrl.deviceService = deviceService;
99 ctrl.deviceKeyService = deviceKeyService;
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530100
101 //Creating mock devices
102 deviceInfo1 = new NetconfDeviceInfo("device1", "001", IpAddress.valueOf(DEVICE_1_IP), DEVICE_1_PORT);
103 deviceInfo2 = new NetconfDeviceInfo("device2", "002", IpAddress.valueOf(DEVICE_2_IP), DEVICE_2_PORT);
104 badDeviceInfo3 = new NetconfDeviceInfo("device3", "003", IpAddress.valueOf(BAD_DEVICE_IP), BAD_DEVICE_PORT);
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700105 deviceInfoIpV6 = new NetconfDeviceInfo("deviceIpv6", "004", IpAddress.valueOf(DEVICE_IPV6), IPV6_DEVICE_PORT);
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530106
107 device1 = new TestNetconfDevice(deviceInfo1);
108 deviceId1 = deviceInfo1.getDeviceId();
109 device2 = new TestNetconfDevice(deviceInfo2);
110 deviceId2 = deviceInfo2.getDeviceId();
111
112 //Adding to the map for testing get device calls.
113 Field field1 = ctrl.getClass().getDeclaredField("netconfDeviceMap");
114 field1.setAccessible(true);
115 reflectedDeviceMap = (Map<DeviceId, NetconfDevice>) field1.get(ctrl);
116 reflectedDeviceMap.put(deviceId1, device1);
117 reflectedDeviceMap.put(deviceId2, device2);
118
119 //Creating mock events for testing NetconfDeviceOutputEventListener
120 Field field2 = ctrl.getClass().getDeclaredField("downListener");
121 field2.setAccessible(true);
122 reflectedDownListener = (NetconfDeviceOutputEventListener) field2.get(ctrl);
123
124 eventForDeviceInfo1 = new NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.DEVICE_NOTIFICATION, null,
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700125 null, Optional.of(1), deviceInfo1);
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530126 eventForDeviceInfo2 = new NetconfDeviceOutputEvent(NetconfDeviceOutputEvent.Type.DEVICE_UNREGISTERED, null,
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700127 null, Optional.of(2), deviceInfo2);
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530128 }
129
130 @After
131 public void tearDown() {
132 ctrl.deactivate();
133 }
134
135 /**
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300136 * Test initialization of component configuration.
137 */
138 @Test
139 public void testActivate() {
Sean Condon334ad692016-12-13 17:56:56 +0000140 assertEquals("Incorrect NetConf connect timeout, should be default",
141 5, ctrl.netconfConnectTimeout);
142 assertEquals("Incorrect NetConf reply timeout, should be default",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700143 5, ctrl.netconfReplyTimeout);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300144 ctrl.activate(null);
Sean Condon334ad692016-12-13 17:56:56 +0000145 assertEquals("Incorrect NetConf connect timeout, should be default",
146 5, ctrl.netconfConnectTimeout);
147 assertEquals("Incorrect NetConf reply timeout, should be default",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700148 5, ctrl.netconfReplyTimeout);
149 }
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300150
151 /**
152 * Test modification of component configuration.
153 */
154 @Test
155 public void testModified() {
Sean Condon334ad692016-12-13 17:56:56 +0000156 assertEquals("Incorrect NetConf connect timeout, should be default",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700157 5, ctrl.netconfConnectTimeout);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300158 assertEquals("Incorrect NetConf session timeout, should be default",
159 5, ctrl.netconfReplyTimeout);
160 ctrl.modified(context);
Sean Condon334ad692016-12-13 17:56:56 +0000161 assertEquals("Incorrect NetConf connect timeout, should be default",
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700162 2, ctrl.netconfConnectTimeout);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300163 assertEquals("Incorrect NetConf session timeout",
164 1, ctrl.netconfReplyTimeout);
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700165 assertEquals("ethz-ssh2", ctrl.sshLibrary);
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300166 }
167
168 /**
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530169 * Test to add DeviceListeners,
170 * and also to check whether the netconfDeviceListeners set is
171 * updating or not which was present in NetconfControllerImpl class.
172 */
173 @Test
174 public void testAddRemoveDeviceListener() {
175 NetconfDeviceListener deviceListener1 = EasyMock.createMock(NetconfDeviceListener.class);
176 NetconfDeviceListener deviceListener2 = EasyMock.createMock(NetconfDeviceListener.class);
177 NetconfDeviceListener deviceListener3 = EasyMock.createMock(NetconfDeviceListener.class);
178
179 ctrl.addDeviceListener(deviceListener1);
180 ctrl.addDeviceListener(deviceListener2);
181 ctrl.addDeviceListener(deviceListener3);
182 assertThat("Incorrect number of listeners", ctrl.netconfDeviceListeners, hasSize(3));
183 assertThat("Not matching listeners", ctrl.netconfDeviceListeners, hasItems(deviceListener1,
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700184 deviceListener2, deviceListener3));
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530185
186 ctrl.removeDeviceListener(deviceListener1);
187 assertThat("Incorrect number of listeners", ctrl.netconfDeviceListeners, hasSize(2));
188 assertThat("Not matching listeners", ctrl.netconfDeviceListeners, hasItems(deviceListener2, deviceListener3));
189 }
190
191 @Test
Andrea Campanella86294db2016-03-07 11:42:49 -0800192 public void testGetNetconfDevices() {
193 Set<DeviceId> devices = new HashSet<>();
194 devices.add(deviceId1);
195 devices.add(deviceId2);
196 assertTrue("Incorrect devices", ctrl.getNetconfDevices().containsAll(devices));
197 }
198
199 @Test
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530200 public void testGetNetconfDevice() {
201 NetconfDevice fetchedDevice1 = ctrl.getNetconfDevice(deviceId1);
202 assertThat("Incorrect device fetched", fetchedDevice1, is(device1));
203
204 NetconfDevice fetchedDevice2 = ctrl.getNetconfDevice(deviceId2);
205 assertThat("Incorrect device fetched", fetchedDevice2, is(device2));
206 }
207
208 @Test
209 public void testGetNetconfDeviceWithIPPort() {
210 NetconfDevice fetchedDevice1 = ctrl.getNetconfDevice(IpAddress.valueOf(DEVICE_1_IP), DEVICE_1_PORT);
211 assertEquals("Incorrect device fetched", fetchedDevice1.getDeviceInfo().ip(), device1.getDeviceInfo().ip());
212
213 NetconfDevice fetchedDevice2 = ctrl.getNetconfDevice(IpAddress.valueOf(DEVICE_2_IP), DEVICE_2_PORT);
214 assertEquals("Incorrect device fetched", fetchedDevice2.getDeviceInfo().ip(), device2.getDeviceInfo().ip());
215 }
216
217 /**
218 * Check for bad device connection. In this case the device map shouldn't get modified.
219 */
220 @Test(expected = NetconfException.class)
221 public void testConnectBadDevice() throws Exception {
222 reflectedDeviceMap.clear();
223 try {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700224 ctrl.connectDevice(badDeviceInfo3.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530225 } finally {
226 assertEquals("Incorrect device connection", 0, ctrl.getDevicesMap().size());
227 }
228 }
229
230 /**
231 * Check for correct device connection. In this case the device map get modified.
232 */
233 @Test
234 public void testConnectCorrectDevice() throws Exception {
235 reflectedDeviceMap.clear();
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700236 ctrl.connectDevice(deviceInfo1.getDeviceId());
237 ctrl.connectDevice(deviceInfo2.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530238 assertTrue("Incorrect device connection", ctrl.getDevicesMap().containsKey(deviceId1));
239 assertTrue("Incorrect device connection", ctrl.getDevicesMap().containsKey(deviceId2));
240 assertEquals("Incorrect device connection", 2, ctrl.getDevicesMap().size());
241 }
242
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700243 /**
244 * Check for correct ipv6 device connection. In this case the device map get modified.
245 */
246 @Test
247 public void testConnectCorrectIpv6Device() throws Exception {
248 reflectedDeviceMap.clear();
249 ctrl.connectDevice(deviceInfoIpV6.getDeviceId());
250 assertTrue("Incorrect device connection", ctrl.getDevicesMap()
251 .containsKey(deviceInfoIpV6.getDeviceId()));
252 assertEquals("Incorrect device connection", 1, ctrl.getDevicesMap().size());
253 }
254
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530255
256 /**
257 * Check for connect devices already added to the map.
258 */
259 @Test
260 public void testConnectAlreadyExistingDevice() throws Exception {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700261 NetconfDevice alreadyExistingDevice1 = ctrl.connectDevice(deviceInfo1.getDeviceId());
262 NetconfDevice alreadyExistingDevice2 = ctrl.connectDevice(deviceInfo2.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530263 assertEquals("Incorrect device connection", alreadyExistingDevice1.getDeviceInfo().getDeviceId(),
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700264 deviceInfo1.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530265 assertEquals("Incorrect device connection", alreadyExistingDevice2.getDeviceInfo().getDeviceId(),
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700266 deviceInfo2.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530267 }
268
269 /**
Andrea Campanella86294db2016-03-07 11:42:49 -0800270 * Check that disconnectDevice actually disconnects the device and removes it.
271 */
272 @Test
273 public void testDisconnectDevice() throws Exception {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700274 ctrl.disconnectDevice(deviceInfo1.getDeviceId(), true);
Andrea Campanella86294db2016-03-07 11:42:49 -0800275 assertFalse("Incorrect device removal", ctrl.getDevicesMap().containsKey(deviceId1));
276 }
277
278 /**
279 * Checks that disconnectDevice actually disconnects the device and removes it.
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530280 */
281 @Test
282 public void testRemoveDevice() throws Exception {
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700283 ctrl.removeDevice(deviceInfo1.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530284 assertFalse("Incorrect device removal", ctrl.getDevicesMap().containsKey(deviceId1));
285 }
286
287 /**
288 * Test to get the connected device map.
289 */
290 @Test
291 public void testGetDevicesMap() {
292 assertEquals("Incorrect device map size", 2, ctrl.getDevicesMap().size());
293 }
294
295 /**
296 * Test to check whether the DeviceDownEventListener removes the device from the map when session
297 * for a particular device getting closed.
298 */
299 @Test
300 public void testDeviceDownEventListener() throws Exception {
301 reflectedDeviceMap.clear();
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700302 ctrl.connectDevice(deviceInfo1.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530303 boolean result1 = reflectedDownListener.isRelevant(eventForDeviceInfo2);
304 assertFalse("Irrelevant Device Event", result1);
305 assertEquals("Incorrect device map size", 1, ctrl.getDevicesMap().size());
306 reflectedDownListener.event(eventForDeviceInfo1);
307 assertEquals("Incorrect device map size", 1, ctrl.getDevicesMap().size());
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700308 ctrl.connectDevice(deviceInfo2.getDeviceId());
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530309 boolean result2 = reflectedDownListener.isRelevant(eventForDeviceInfo2);
310 assertTrue("Irrelevant Device Event", result2);
311 assertEquals("Incorrect device map size", 2, ctrl.getDevicesMap().size());
312 reflectedDownListener.event(eventForDeviceInfo2);
313 assertEquals("Incorrect device map size", 1, ctrl.getDevicesMap().size());
314 }
315
316 /**
317 * Mock NetconfDeviceFactory class.
318 */
319 private class TestNetconfDeviceFactory implements NetconfDeviceFactory {
320
321 @Override
322 public NetconfDevice createNetconfDevice(NetconfDeviceInfo netconfDeviceInfo) throws NetconfException {
323 return new TestNetconfDevice(netconfDeviceInfo);
324 }
325 }
326
327 /**
328 * Mock NetconfDeviceImpl class, used for creating test devices.
329 */
330 protected class TestNetconfDevice implements NetconfDevice {
331 private NetconfDeviceInfo netconfDeviceInfo;
332 private boolean deviceState = false;
333 private NetconfSession netconfSession;
334
335 public TestNetconfDevice(NetconfDeviceInfo deviceInfo) throws NetconfException {
336 netconfDeviceInfo = deviceInfo;
Andrea Campanella7e6200a2016-03-21 09:48:40 -0700337 if (!badDeviceInfo3.getDeviceId().equals(deviceInfo.getDeviceId())) {
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530338 netconfSession = EasyMock.createMock(NetconfSession.class);
339 deviceState = true;
340 } else {
341 throw new NetconfException("Cannot create Connection and Session");
342 }
343 }
344
345 @Override
346 public boolean isActive() {
347 return deviceState;
348 }
349
350 @Override
351 public NetconfSession getSession() {
352 return netconfSession;
353 }
354
355 @Override
356 public void disconnect() {
357 deviceState = false;
358 netconfSession = null;
359 }
360
361 @Override
362 public NetconfDeviceInfo getDeviceInfo() {
363 return netconfDeviceInfo;
364 }
365
366 }
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300367
368 private class MockComponentContext extends ComponentContextAdapter {
369 @Override
370 public Dictionary getProperties() {
371 return new MockDictionary();
372 }
373 }
374
375 private class MockDictionary extends Dictionary {
376
377 @Override
378 public int size() {
379 return 0;
380 }
381
382 @Override
383 public boolean isEmpty() {
384 return false;
385 }
386
387 @Override
388 public Enumeration keys() {
389 return null;
390 }
391
392 @Override
393 public Enumeration elements() {
394 return null;
395 }
396
397 @Override
398 public Object get(Object key) {
Sean Condon334ad692016-12-13 17:56:56 +0000399 if (key.equals("netconfConnectTimeout")) {
400 return "2";
401 } else if (key.equals("netconfReplyTimeout")) {
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300402 return "1";
Andrea Campanella7bbe7b12017-05-03 16:03:38 -0700403 } else if (key.equals("sshLibrary")) {
404 return "ethz-ssh2";
Andreas Papazois4752cfa2016-04-25 14:52:12 +0300405 }
406 return null;
407 }
408
409 @Override
410 public Object put(Object key, Object value) {
411 return null;
412 }
413
414 @Override
415 public Object remove(Object key) {
416 return null;
417 }
418 }
Thanuj Ravindranath926e3162016-01-26 09:44:08 +0530419}