2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.provider.netconf.device.impl;
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.onosproject.provider.netconf.device.impl.NetconfDeviceProviderTestConstant.*;
23 import static org.slf4j.LoggerFactory.getLogger;
25 import java.io.IOException;
27 import java.net.URISyntaxException;
28 import java.util.Collection;
29 import java.util.Dictionary;
30 import java.util.List;
33 import java.util.concurrent.ConcurrentHashMap;
35 import org.easymock.EasyMock;
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Ignore;
39 import org.junit.Test;
40 import org.onlab.packet.ChassisId;
41 import org.onosproject.cfg.ComponentConfigService;
42 import org.onosproject.net.Device;
43 import org.onosproject.net.DeviceId;
44 import org.onosproject.net.MastershipRole;
45 import org.onosproject.net.device.DefaultDeviceDescription;
46 import org.onosproject.net.device.DeviceDescription;
47 import org.onosproject.net.device.DeviceProvider;
48 import org.onosproject.net.device.DeviceProviderRegistry;
49 import org.onosproject.net.device.DeviceProviderService;
50 import org.onosproject.net.device.PortDescription;
51 import org.onosproject.net.device.PortStatistics;
52 import org.onosproject.net.provider.ProviderId;
53 import org.osgi.service.component.ComponentContext;
54 import org.slf4j.Logger;
56 import com.tailf.jnc.JNCException;
59 * Test Case to Validate Netconf Device Provider.
61 public class NetconfDeviceProviderTest {
62 TestDeviceCreator create;
64 private final Logger log = getLogger(NetconfDeviceProviderTest.class);
66 private Map<DeviceId, NetconfDevice> netconfDeviceMap = new ConcurrentHashMap<DeviceId, NetconfDevice>();
68 private DeviceProviderService providerService;
70 private static final DeviceId DID1 = DeviceId.deviceId(DEVICE_ID);
72 private final NetconfDeviceProvider provider = new NetconfDeviceProvider();
73 private final TestDeviceRegistry registry = new TestDeviceRegistry();
75 private ComponentConfigService mockCfgService;
79 mockCfgService = EasyMock.createMock(ComponentConfigService.class);
80 provider.cfgService = mockCfgService;
81 provider.providerRegistry = registry;
84 @SuppressWarnings("unchecked")
85 private Dictionary<String, String> getDictionaryMockWithoutValues(ComponentContext componentContext) {
86 Dictionary<String, String> dictionary = EasyMock
87 .createMock(Dictionary.class);
88 expect(dictionary.get(DEV_CONFIG)).andReturn(NULL);
90 expect(componentContext.getProperties()).andReturn(dictionary);
94 @SuppressWarnings("unchecked")
95 private Dictionary<String, String> getDictionaryMockWithDeviceEntryNull(ComponentContext componentContext) {
96 Dictionary<String, String> dictionary = EasyMock
97 .createMock(Dictionary.class);
98 expect(dictionary.get(DEV_CONFIG)).andReturn(NULL_NULL);
100 expect(componentContext.getProperties()).andReturn(dictionary);
104 @SuppressWarnings("unchecked")
105 private Dictionary<String, String> getDictionaryMockDeviceEntryNumberFomatEx(ComponentContext componentContext) {
106 Dictionary<String, String> dictionary = EasyMock
107 .createMock(Dictionary.class);
108 expect(dictionary.get(DEV_CONFIG))
109 .andReturn(CONFIG_WITH_INVALID_ENTRY_NUMBER)
110 .andThrow(new NumberFormatException());
112 expect(componentContext.getProperties()).andReturn(dictionary);
116 @SuppressWarnings("unchecked")
117 private Dictionary<String, String> getDictionaryMockWithoutUsernameAndPassword(ComponentContext componentContext) {
118 Dictionary<String, String> dictionary = EasyMock
119 .createMock(Dictionary.class);
120 expect(dictionary.get(DEV_CONFIG)).andReturn(CONFIG_WITH_NULL_ENTRY);
122 expect(componentContext.getProperties()).andReturn(dictionary);
126 @SuppressWarnings("unchecked")
127 private Dictionary<String, String> getDictionaryMockWithDifferentDeviceState(ComponentContext componentContext) {
128 Dictionary<String, String> dictionary = EasyMock
129 .createMock(Dictionary.class);
130 expect(dictionary.get(DEV_CONFIG))
131 .andReturn(CONFIG_WITH_DIFFERENT_DEVICE_STATE);
133 expect(componentContext.getProperties()).andReturn(dictionary);
137 @SuppressWarnings("unchecked")
138 private Dictionary<String, String> getDictionaryMockDeviceWithArrayOutOFBoundEx(ComponentContext componentContext) {
139 Dictionary<String, String> dictionary = EasyMock
140 .createMock(Dictionary.class);
141 expect(dictionary.get(DEV_CONFIG))
142 .andReturn(CONFIG_WITH_ARRAY_OUT_OF_BOUNDEX)
143 .andThrow(new ArrayIndexOutOfBoundsException());
145 expect(componentContext.getProperties()).andReturn(dictionary);
149 @SuppressWarnings("unchecked")
150 private Dictionary<String, String> getDictionaryMockDeviceEntryForDeactivate(ComponentContext componentContext) {
151 Dictionary<String, String> dictionary = EasyMock
152 .createMock(Dictionary.class);
153 expect(dictionary.get(DEV_CONFIG))
154 .andReturn(CONFIG_ENTRY_FOR_DEACTIVATE)
155 .andThrow(new ArrayIndexOutOfBoundsException());
157 expect(componentContext.getProperties()).andReturn(dictionary);
162 @Test(expected = IOException.class)
163 public void testSSHAuthentication() throws IOException, JNCException {
164 TestDeviceCreator objForTestDev = new TestDeviceCreator(
175 public void tearDown() {
176 provider.providerRegistry = null;
177 provider.cfgService = null;
180 // To check if deviceCfgValue is empty or null
182 public void testActiveWithcomponentContextIsNull() {
184 ComponentContext componentContext = EasyMock
185 .createMock(ComponentContext.class);
186 getDictionaryMockWithoutValues(componentContext);
187 replay(componentContext);
188 provider.activate(componentContext);
191 // To check deviceEntry and device is null
193 public void testActiveWithDeviceEntryIsNull() {
195 ComponentContext componentContext = EasyMock
196 .createMock(ComponentContext.class);
197 getDictionaryMockWithDeviceEntryNull(componentContext);
198 replay(componentContext);
199 provider.activate(componentContext);
203 public void testActiveWithDeviceEntryWithoutUsernameAndPassword() {
205 ComponentContext componentContext = EasyMock
206 .createMock(ComponentContext.class);
207 getDictionaryMockWithoutUsernameAndPassword(componentContext);
208 replay(componentContext);
209 provider.activate(componentContext);
213 public void testActiveWithDeviceEntryWithNumberFomatEx() {
215 ComponentContext componentContext = EasyMock
216 .createMock(ComponentContext.class);
217 getDictionaryMockDeviceEntryNumberFomatEx(componentContext);
218 replay(componentContext);
219 provider.activate(componentContext);
223 public void testActiveWithDeviceEntryWithDifferentDeviceState() {
225 ComponentContext componentContext = EasyMock
226 .createMock(ComponentContext.class);
227 getDictionaryMockWithDifferentDeviceState(componentContext);
228 replay(componentContext);
229 provider.activate(componentContext);
233 public void testActiveWithDeviceEntryWithArrayOutOFBoundEx() {
235 ComponentContext componentContext = EasyMock
236 .createMock(ComponentContext.class);
237 getDictionaryMockDeviceWithArrayOutOFBoundEx(componentContext);
238 replay(componentContext);
239 provider.activate(componentContext);
243 public void isReachableWithInvalidDeviceId() {
244 assertFalse("Initially the Device ID Should not be reachable",
245 provider.isReachable(DID1));
246 NetconfDevice device = new NetconfDevice(NULL, ZERO, NULL, NULL);
247 provider.netconfDeviceMap.put(DID1, device);
248 assertFalse("Particular Device ID cannot be Reachable",
249 provider.isReachable(DID1));
253 public void testDeactivate() {
255 ComponentContext componentContext = EasyMock
256 .createMock(ComponentContext.class);
257 getDictionaryMockDeviceEntryForDeactivate(componentContext);
258 replay(componentContext);
259 testActiveWithDeviceEntryWithDifferentDeviceState();
260 provider.deactivate(componentContext);
263 private class TestDeviceCreator {
265 private NetconfDevice device;
266 private boolean createFlag;
268 public TestDeviceCreator(NetconfDevice device, boolean createFlag) {
269 this.device = device;
270 this.createFlag = createFlag;
273 public void run() throws JNCException, IOException {
275 log.info("Trying to create Device Info on ONOS core");
278 log.info("Trying to remove Device Info on ONOS core");
284 * For each Netconf Device, remove the entry from the device store.
286 private void removeDevices() {
287 if (device == null) {
288 log.warn("The Request Netconf Device is null, cannot proceed further");
292 DeviceId did = getDeviceId();
293 if (!netconfDeviceMap.containsKey(did)) {
294 log.error("BAD Request: 'Currently device is not discovered, "
295 + "so cannot remove/disconnect the device: "
296 + device.deviceInfo() + "'");
299 providerService.deviceDisconnected(did);
301 netconfDeviceMap.remove(did);
302 delay(EVENTINTERVAL);
303 } catch (URISyntaxException uriSyntaxExcpetion) {
304 log.error("Syntax Error while creating URI for the device: "
305 + device.deviceInfo()
306 + " couldn't remove the device from the store",
312 * Initialize Netconf Device object, and notify core saying device
315 private void advertiseDevices() throws JNCException, IOException {
317 if (device == null) {
318 log.warn("The Request Netconf Device is null, cannot proceed further");
322 DeviceId did = getDeviceId();
323 ChassisId cid = new ChassisId();
324 DeviceDescription desc = new DefaultDeviceDescription(
331 log.info("Persisting Device" + did.uri().toString());
333 netconfDeviceMap.put(did, device);
334 providerService.deviceConnected(did, desc);
335 log.info("Done with Device Info Creation on ONOS core. Device Info: "
336 + device.deviceInfo() + " " + did.uri().toString());
337 delay(EVENTINTERVAL);
338 } catch (URISyntaxException e) {
339 log.error("Syntax Error while creating URI for the device: "
340 + device.deviceInfo()
341 + " couldn't persist the device onto the store", e);
342 } catch (JNCException e) {
344 } catch (IOException e) {
346 } catch (Exception e) {
347 log.error("Error while initializing session for the device: "
348 + device.deviceInfo(), e);
352 private DeviceId getDeviceId() throws URISyntaxException {
353 String additionalSSP = new StringBuilder(device.getUsername())
354 .append(AT_THE_RATE).append(device.getSshHost())
355 .append(COLON).append(device.getSshPort()).toString();
356 DeviceId did = DeviceId.deviceId(new URI(SCHEME_NETCONF,
357 additionalSSP, null));
362 private class TestDeviceRegistry implements DeviceProviderRegistry {
365 public DeviceProviderService register(DeviceProvider provider) {
366 return new TestProviderService();
370 public void unregister(DeviceProvider provider) {
374 public Set<ProviderId> getProviders() {
378 private class TestProviderService implements DeviceProviderService {
381 public DeviceProvider provider() {
386 public void deviceConnected(DeviceId deviceId,
387 DeviceDescription deviceDescription) {
391 public void deviceDisconnected(DeviceId deviceId) {
396 public void updatePorts(DeviceId deviceId,
397 List<PortDescription> portDescriptions) {
402 public void portStatusChanged(DeviceId deviceId,
403 PortDescription portDescription) {
408 public void receivedRoleReply(DeviceId deviceId,
409 MastershipRole requested,
410 MastershipRole response) {
415 public void updatePortStatistics(DeviceId deviceId,
416 Collection<PortStatistics> portStatistics) {