Sanjay S
Committed by Gerrit Code Review

Added New Test Case to Validate Netconf Device Provider.

Change-Id: Ib92adcfe433580e400dd8c7ecb88a3328e47c31e
...@@ -58,6 +58,20 @@ ...@@ -58,6 +58,20 @@
58 <version>1.1.4</version> 58 <version>1.1.4</version>
59 <optional>true</optional> 59 <optional>true</optional>
60 </dependency> 60 </dependency>
61 + <dependency>
62 + <groupId>org.osgi</groupId>
63 + <artifactId>org.osgi.core</artifactId>
64 + </dependency>
65 + <dependency>
66 + <groupId>org.onosproject</groupId>
67 + <artifactId>onlab-junit</artifactId>
68 + <scope>test</scope>
69 + </dependency>
70 + <dependency>
71 + <groupId>org.easymock</groupId>
72 + <artifactId>easymock</artifactId>
73 + <scope>test</scope>
74 + </dependency>
61 </dependencies> 75 </dependencies>
62 76
63 <build> 77 <build>
......
...@@ -66,7 +66,7 @@ public class NetconfDeviceProvider extends AbstractProvider ...@@ -66,7 +66,7 @@ public class NetconfDeviceProvider extends AbstractProvider
66 66
67 private final Logger log = getLogger(NetconfDeviceProvider.class); 67 private final Logger log = getLogger(NetconfDeviceProvider.class);
68 68
69 - private Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<DeviceId, NetconfDevice>(); 69 + protected Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<DeviceId, NetconfDevice>();
70 70
71 private DeviceProviderService providerService; 71 private DeviceProviderService providerService;
72 72
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.provider.netconf.device.impl;
17 +
18 +import static org.easymock.EasyMock.expect;
19 +import static org.easymock.EasyMock.replay;
20 +import static org.junit.Assert.assertFalse;
21 +import static org.onlab.util.Tools.delay;
22 +import static org.slf4j.LoggerFactory.getLogger;
23 +
24 +import java.io.IOException;
25 +import java.net.URI;
26 +import java.net.URISyntaxException;
27 +import java.util.Collection;
28 +import java.util.Dictionary;
29 +import java.util.List;
30 +import java.util.Map;
31 +import java.util.Set;
32 +import java.util.concurrent.ConcurrentHashMap;
33 +
34 +import org.easymock.EasyMock;
35 +import org.junit.After;
36 +import org.junit.Before;
37 +import org.junit.Test;
38 +import org.onlab.packet.ChassisId;
39 +import org.onosproject.cfg.ComponentConfigService;
40 +import org.onosproject.net.Device;
41 +import org.onosproject.net.DeviceId;
42 +import org.onosproject.net.MastershipRole;
43 +import org.onosproject.net.device.DefaultDeviceDescription;
44 +import org.onosproject.net.device.DeviceDescription;
45 +import org.onosproject.net.device.DeviceProvider;
46 +import org.onosproject.net.device.DeviceProviderRegistry;
47 +import org.onosproject.net.device.DeviceProviderService;
48 +import org.onosproject.net.device.PortDescription;
49 +import org.onosproject.net.device.PortStatistics;
50 +import org.onosproject.net.provider.ProviderId;
51 +import org.osgi.service.component.ComponentContext;
52 +import org.slf4j.Logger;
53 +
54 +import com.tailf.jnc.JNCException;
55 +
56 +/**
57 + * Test Case to Validate Netconf Device Provider.
58 + *
59 + */
60 +public class NetconfDeviceProviderTest {
61 + // private NetconfDevice device;
62 +
63 + TestDeviceCreator create;
64 +
65 + private final Logger log = getLogger(NetconfDeviceProviderTest.class);
66 +
67 + private Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<DeviceId, NetconfDevice>();
68 +
69 + private DeviceProviderService providerService;
70 +
71 + private static final int EVENTINTERVAL = 5;
72 +
73 + private static final String SCHEME = "netconf";
74 +
75 + private static final DeviceId DID1 = DeviceId
76 + .deviceId("of:0000000000000001");
77 +
78 + private final NetconfDeviceProvider provider = new NetconfDeviceProvider();
79 + private final TestDeviceRegistry registry = new TestDeviceRegistry();
80 +
81 + private ComponentConfigService mockCfgService;
82 +
83 + @Before
84 + public void setUp() {
85 + mockCfgService = EasyMock.createMock(ComponentConfigService.class);
86 + provider.cfgService = mockCfgService;
87 + provider.providerRegistry = registry;
88 + }
89 +
90 + @SuppressWarnings("unchecked")
91 + private Dictionary<String, String> getDictionaryMock(ComponentContext componentContext) {
92 + Dictionary<String, String> dictionary = EasyMock
93 + .createMock(Dictionary.class);
94 + expect(dictionary.get("devConfigs"))
95 + .andReturn("cisco:cisco@10.18.11.14:22:active,"
96 + + "sanjay:b33rb3lly@10.18.24.122:2022:inactive");
97 + replay(dictionary);
98 + expect(componentContext.getProperties()).andReturn(dictionary);
99 + return dictionary;
100 + }
101 +
102 + @SuppressWarnings("unchecked")
103 + private Dictionary<String, String> getDictionaryMockWithoutValues(ComponentContext componentContext) {
104 + Dictionary<String, String> dictionary = EasyMock
105 + .createMock(Dictionary.class);
106 + expect(dictionary.get("devConfigs")).andReturn("");
107 + replay(dictionary);
108 + expect(componentContext.getProperties()).andReturn(dictionary);
109 + return dictionary;
110 + }
111 +
112 + @SuppressWarnings("unchecked")
113 + private Dictionary<String, String> getDictionaryMockWithDeviceEntryNull(ComponentContext componentContext) {
114 + Dictionary<String, String> dictionary = EasyMock
115 + .createMock(Dictionary.class);
116 + expect(dictionary.get("devConfigs")).andReturn("null,null");
117 + replay(dictionary);
118 + expect(componentContext.getProperties()).andReturn(dictionary);
119 + return dictionary;
120 + }
121 +
122 + @SuppressWarnings("unchecked")
123 + private Dictionary<String, String> getDictionaryMockDeviceEntryNumberFomatEx(ComponentContext componentContext) {
124 + Dictionary<String, String> dictionary = EasyMock
125 + .createMock(Dictionary.class);
126 + expect(dictionary.get("devConfigs"))
127 + .andReturn("cisco:cisco@10.18.11.14:cisco:active")
128 + .andThrow(new NumberFormatException());
129 + replay(dictionary);
130 + expect(componentContext.getProperties()).andReturn(dictionary);
131 + return dictionary;
132 + }
133 +
134 + @SuppressWarnings("unchecked")
135 + private Dictionary<String, String> getDictionaryMockWithoutUsernameAndPassword(ComponentContext componentContext) {
136 + Dictionary<String, String> dictionary = EasyMock
137 + .createMock(Dictionary.class);
138 + expect(dictionary.get("devConfigs"))
139 + .andReturn("null:null@null:0:active");
140 + replay(dictionary);
141 + expect(componentContext.getProperties()).andReturn(dictionary);
142 + return dictionary;
143 + }
144 +
145 + @SuppressWarnings("unchecked")
146 + private Dictionary<String, String> getDictionaryMockWithDifferentDeviceState(ComponentContext componentContext) {
147 + Dictionary<String, String> dictionary = EasyMock
148 + .createMock(Dictionary.class);
149 + expect(dictionary.get("devConfigs"))
150 + .andReturn("cisco:cisco@10.18.11.14:22:active,cisco:cisco@10.18.11.18:22:inactive,"
151 + + "cisco:cisco@10.18.11.14:22:invalid,cisco:cisco@10.18.11.14:22:null");
152 + replay(dictionary);
153 + expect(componentContext.getProperties()).andReturn(dictionary);
154 + return dictionary;
155 + }
156 +
157 + @SuppressWarnings("unchecked")
158 + private Dictionary<String, String> getDictionaryMockDeviceWithArrayOutOFBoundEx(ComponentContext componentContext) {
159 + Dictionary<String, String> dictionary = EasyMock
160 + .createMock(Dictionary.class);
161 + expect(dictionary.get("devConfigs"))
162 + .andReturn("@10.18.11.14:22:active")
163 + .andThrow(new ArrayIndexOutOfBoundsException());
164 + replay(dictionary);
165 + expect(componentContext.getProperties()).andReturn(dictionary);
166 + return dictionary;
167 + }
168 +
169 + @SuppressWarnings("unchecked")
170 + private Dictionary<String, String> getDictionaryMockDeviceEntryForDeactivate(ComponentContext componentContext) {
171 + Dictionary<String, String> dictionary = EasyMock
172 + .createMock(Dictionary.class);
173 + expect(dictionary.get("devConfigs"))
174 + .andReturn("netconf:cisco@10.18.11.14:22:active")
175 + .andThrow(new ArrayIndexOutOfBoundsException());
176 + replay(dictionary);
177 + expect(componentContext.getProperties()).andReturn(dictionary);
178 + return dictionary;
179 + }
180 +
181 + @Test(expected = IOException.class)
182 + public void testSSHAuthentication() throws IOException, JNCException {
183 + TestDeviceCreator objForTestDev = new TestDeviceCreator(
184 + new NetconfDevice(
185 + "10.18.14.19",
186 + 22,
187 + "cisco",
188 + "cisco"),
189 + true);
190 + objForTestDev.run();
191 + }
192 +
193 + @After
194 + public void tearDown() {
195 + provider.providerRegistry = null;
196 + provider.cfgService = null;
197 + }
198 +
199 + @Test
200 + public void testActiveWithComponentContext() {
201 +
202 + ComponentContext componentContext = EasyMock
203 + .createMock(ComponentContext.class);
204 + getDictionaryMock(componentContext);
205 + replay(componentContext);
206 + provider.activate(componentContext);
207 + }
208 +
209 + // To check if deviceCfgValue is empty or null
210 + @Test
211 + public void testActiveWithcomponentContextIsNull() {
212 +
213 + ComponentContext componentContext = EasyMock
214 + .createMock(ComponentContext.class);
215 + getDictionaryMockWithoutValues(componentContext);
216 + replay(componentContext);
217 + provider.activate(componentContext);
218 + }
219 +
220 + // To check deviceEntry and device is null
221 + @Test
222 + public void testActiveWithDeviceEntryIsNull() {
223 +
224 + ComponentContext componentContext = EasyMock
225 + .createMock(ComponentContext.class);
226 + getDictionaryMockWithDeviceEntryNull(componentContext);
227 + replay(componentContext);
228 + provider.activate(componentContext);
229 + }
230 +
231 + @Test
232 + public void testActiveWithDeviceEntryWithoutUsernameAndPassword() {
233 +
234 + ComponentContext componentContext = EasyMock
235 + .createMock(ComponentContext.class);
236 + getDictionaryMockWithoutUsernameAndPassword(componentContext);
237 + replay(componentContext);
238 + provider.activate(componentContext);
239 + }
240 +
241 + @Test
242 + public void testActiveWithDeviceEntryWithNumberFomatEx() {
243 +
244 + ComponentContext componentContext = EasyMock
245 + .createMock(ComponentContext.class);
246 + getDictionaryMockDeviceEntryNumberFomatEx(componentContext);
247 + replay(componentContext);
248 + provider.activate(componentContext);
249 + }
250 +
251 + @Test
252 + public void testActiveWithDeviceEntryWithDifferentDeviceState() {
253 +
254 + ComponentContext componentContext = EasyMock
255 + .createMock(ComponentContext.class);
256 + getDictionaryMockWithDifferentDeviceState(componentContext);
257 + replay(componentContext);
258 + provider.activate(componentContext);
259 + }
260 +
261 + @Test
262 + public void testActiveWithDeviceEntryWithArrayOutOFBoundEx() {
263 +
264 + ComponentContext componentContext = EasyMock
265 + .createMock(ComponentContext.class);
266 + getDictionaryMockDeviceWithArrayOutOFBoundEx(componentContext);
267 + replay(componentContext);
268 + provider.activate(componentContext);
269 + }
270 +
271 + @Test
272 + public void isReachableWithInvalidDeviceId() {
273 + assertFalse("Initially the Device ID Should not be reachable",
274 + provider.isReachable(DID1));
275 + NetconfDevice device = new NetconfDevice("", 0, "", "");
276 + provider.netconfDeviceMap.put(DID1, device);
277 + assertFalse("Particular Device ID cannot be Reachable",
278 + provider.isReachable(DID1));
279 + }
280 +
281 + @Test
282 + public void testDeactivate() {
283 +
284 + ComponentContext componentContext = EasyMock
285 + .createMock(ComponentContext.class);
286 + getDictionaryMockDeviceEntryForDeactivate(componentContext);
287 + replay(componentContext);
288 + testActiveWithComponentContext();
289 + provider.deactivate(componentContext);
290 + }
291 +
292 + private class TestDeviceCreator {
293 +
294 + private NetconfDevice device;
295 + private boolean createFlag;
296 +
297 + public TestDeviceCreator(NetconfDevice device, boolean createFlag) {
298 + this.device = device;
299 + this.createFlag = createFlag;
300 + }
301 +
302 + public void run() throws JNCException, IOException {
303 + if (createFlag) {
304 + log.info("Trying to create Device Info on ONOS core");
305 + advertiseDevices();
306 + } else {
307 + log.info("Trying to remove Device Info on ONOS core");
308 + removeDevices();
309 + }
310 + }
311 +
312 + /**
313 + * For each Netconf Device, remove the entry from the device store.
314 + * @throws URISyntaxException
315 + */
316 + private void removeDevices() {
317 + if (device == null) {
318 + log.warn("The Request Netconf Device is null, cannot proceed further");
319 + return;
320 + }
321 + try {
322 + DeviceId did = getDeviceId();
323 + if (!netconfDeviceMap.containsKey(did)) {
324 + log.error("BAD Request: 'Currently device is not discovered, "
325 + + "so cannot remove/disconnect the device: "
326 + + device.deviceInfo() + "'");
327 + return;
328 + }
329 + providerService.deviceDisconnected(did);
330 + device.disconnect();
331 + netconfDeviceMap.remove(did);
332 + delay(EVENTINTERVAL);
333 + } catch (URISyntaxException uriSyntaxExcpetion) {
334 + log.error("Syntax Error while creating URI for the device: "
335 + + device.deviceInfo()
336 + + " couldn't remove the device from the store",
337 + uriSyntaxExcpetion);
338 + }
339 + }
340 +
341 + /**
342 + * Initialize Netconf Device object, and notify core saying device
343 + * connected.
344 + */
345 + private void advertiseDevices() throws JNCException, IOException {
346 + try {
347 + if (device == null) {
348 + log.warn("The Request Netconf Device is null, cannot proceed further");
349 + return;
350 + }
351 + device.init();
352 + DeviceId did = getDeviceId();
353 + ChassisId cid = new ChassisId();
354 + DeviceDescription desc = new DefaultDeviceDescription(
355 + did.uri(),
356 + Device.Type.OTHER,
357 + "", "",
358 + "", "",
359 + cid);
360 + log.info("Persisting Device" + did.uri().toString());
361 +
362 + netconfDeviceMap.put(did, device);
363 + providerService.deviceConnected(did, desc);
364 + log.info("Done with Device Info Creation on ONOS core. Device Info: "
365 + + device.deviceInfo() + " " + did.uri().toString());
366 + delay(EVENTINTERVAL);
367 + } catch (URISyntaxException e) {
368 + log.error("Syntax Error while creating URI for the device: "
369 + + device.deviceInfo()
370 + + " couldn't persist the device onto the store", e);
371 + } catch (JNCException e) {
372 + throw e;
373 + } catch (IOException e) {
374 + throw e;
375 + } catch (Exception e) {
376 + log.error("Error while initializing session for the device: "
377 + + device.deviceInfo(), e);
378 + }
379 + }
380 +
381 + private DeviceId getDeviceId() throws URISyntaxException {
382 + String additionalSSP = new StringBuilder(device.getUsername())
383 + .append("@").append(device.getSshHost()).append(":")
384 + .append(device.getSshPort()).toString();
385 + DeviceId did = DeviceId.deviceId(new URI(SCHEME, additionalSSP,
386 + null));
387 + return did;
388 + }
389 + }
390 +
391 + private class TestDeviceRegistry implements DeviceProviderRegistry {
392 +
393 + @Override
394 + public DeviceProviderService register(DeviceProvider provider) {
395 + return new TestProviderService();
396 + }
397 +
398 + @Override
399 + public void unregister(DeviceProvider provider) {
400 + }
401 +
402 + @Override
403 + public Set<ProviderId> getProviders() {
404 + return null;
405 + }
406 +
407 + private class TestProviderService implements DeviceProviderService {
408 +
409 + public DeviceProvider provider() {
410 + return null;
411 + }
412 +
413 + public void deviceConnected(DeviceId deviceId,
414 + DeviceDescription deviceDescription) {
415 + }
416 +
417 + public void deviceDisconnected(DeviceId deviceId) {
418 +
419 + }
420 +
421 + public void updatePorts(DeviceId deviceId,
422 + List<PortDescription> portDescriptions) {
423 +
424 + }
425 +
426 + public void portStatusChanged(DeviceId deviceId,
427 + PortDescription portDescription) {
428 +
429 + }
430 +
431 + public void receivedRoleReply(DeviceId deviceId,
432 + MastershipRole requested,
433 + MastershipRole response) {
434 +
435 + }
436 +
437 + public void updatePortStatistics(DeviceId deviceId,
438 + Collection<PortStatistics> portStatistics) {
439 +
440 + }
441 + }
442 + }
443 +}