Fix for APPC-1271
Replaced slow running tests which wait for timeout
Testing time reduced from 22 seconds to 0.5 seconds
Improved tests and line coverage increased from 26% to 96%
Issue-ID: APPC-1271
Change-Id: I88713e5c819e5ce1bf695f6de3834db7c3007285
Signed-off-by: Joss Armstrong <joss.armstrong@ericsson.com>
diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml
index 03143c5..b26a826 100644
--- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml
+++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml
@@ -191,7 +191,12 @@
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
-
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/onap/appc/adapter/netconf/jsch/NetconfClientJsch.java b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/onap/appc/adapter/netconf/jsch/NetconfClientJsch.java
index 92569d5..03c33d8 100644
--- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/onap/appc/adapter/netconf/jsch/NetconfClientJsch.java
+++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/onap/appc/adapter/netconf/jsch/NetconfClientJsch.java
@@ -5,6 +5,8 @@
* Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2018 Ericsson
* =============================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +31,8 @@
import com.jcraft.jsch.Session;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.List;
import java.util.Properties;
@@ -62,7 +66,7 @@
String password = connectionDetails.getPassword();
try {
JSch.setLogger(new JSchLogger());
- JSch jsch = new JSch();
+ JSch jsch = getJSch();
session = jsch.getSession(EncryptionTool.getInstance().decrypt(username), host, port);
session.setPassword(EncryptionTool.getInstance().decrypt(password));
session.setConfig("StrictHostKeyChecking", "no");
@@ -131,10 +135,9 @@
private void createConnection(NetconfConnectionDetails connectionDetails) throws APPCException {
try {
-// session.setServerAliveCountMax(0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
channel = session.openChannel("subsystem");
((ChannelSubsystem)channel).setSubsystem("netconf");
- netconfAdapter = new NetconfAdapter(channel.getInputStream(), channel.getOutputStream());
+ netconfAdapter = getNetconfAdapter(channel.getInputStream(), channel.getOutputStream());
channel.connect(CHANNEL_CONNECT_TIMEOUT);
hello(connectionDetails.getCapabilities());
} catch(Exception e) {
@@ -146,7 +149,7 @@
private void hello(List<String> capabilities) throws IOException {
String helloIn = netconfAdapter.receiveMessage();
if(helloIn == null) {
- throw new IOException("Expected hello message, but nothing received error from netconf device");
+ throw new IOException("Expected hello message, but nothing received from netconf device");
}
if(helloIn.contains("<rpc-error>")) {
throw new IOException("Expected hello message, but received error from netconf device:\n" + helloIn);
@@ -172,4 +175,12 @@
throw new IOException("Error response from netconf device: \n" + response);
}
}
+
+ protected JSch getJSch() {
+ return new JSch();
+ }
+
+ protected NetconfAdapter getNetconfAdapter(InputStream inputStream, OutputStream outputStream) throws IOException {
+ return new NetconfAdapter(inputStream, outputStream);
+ }
}
diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/onap/appc/adapter/netconf/jsch/TestNetconfClientJsch.java b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/onap/appc/adapter/netconf/jsch/TestNetconfClientJsch.java
index fb44763..088c5a0 100644
--- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/onap/appc/adapter/netconf/jsch/TestNetconfClientJsch.java
+++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/onap/appc/adapter/netconf/jsch/TestNetconfClientJsch.java
@@ -4,6 +4,8 @@
* ================================================================================
* Copyright (C) 2018 Samsung
* ================================================================================
+ * Modifications Copyright (C) 2018 Ericsson
+ * ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -21,78 +23,172 @@
package org.onap.appc.adapter.netconf.jsch;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.isA;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.junit.Assert.assertEquals;
+import com.jcraft.jsch.ChannelSubsystem;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
-import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
-import org.onap.appc.adapter.netconf.ConnectionDetails;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
import org.onap.appc.adapter.netconf.NetconfConnectionDetails;
import org.onap.appc.adapter.netconf.internal.NetconfAdapter;
import org.onap.appc.exceptions.APPCException;
-
+import org.powermock.reflect.Whitebox;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.List;
import java.util.Properties;
public class TestNetconfClientJsch {
NetconfClientJsch netconfClientJsch;
+ private Session mockSession;
+ private JSch mockJSch;
+ private ChannelSubsystem mockChannel;
+ private InputStream mockInputStream;
+ private OutputStream mockOutputStream;
+ private NetconfAdapter mockNetconfAdapter;
+
+ @Rule
+ public ExpectedException expectedEx = ExpectedException.none();
@Before
public void SetUp() {
- netconfClientJsch = new NetconfClientJsch();
+ netconfClientJsch = Mockito.spy(new NetconfClientJsch());
}
- @Test (expected = APPCException.class)
- public void testConnect() throws APPCException, IOException {
+ private void setupForConnectTests() throws JSchException, IOException {
+ mockSession = Mockito.mock(Session.class);
+ mockJSch = Mockito.mock(JSch.class);
+ mockChannel = Mockito.mock(ChannelSubsystem.class);
+ mockInputStream = Mockito.mock(InputStream.class);
+ mockOutputStream = Mockito.mock(OutputStream.class);
+ mockNetconfAdapter = Mockito.mock(NetconfAdapter.class);
+ Mockito.doReturn(mockJSch).when(netconfClientJsch).getJSch();
+ Mockito.doReturn(mockSession).when(mockJSch).getSession(Mockito.anyString(),
+ Mockito.anyString(), Mockito.anyInt());
+ Mockito.doReturn(mockChannel).when(mockSession).openChannel("subsystem");
+ Mockito.doReturn(mockInputStream).when(mockChannel).getInputStream();
+ Mockito.doReturn(mockOutputStream).when(mockChannel).getOutputStream();
+ Mockito.doReturn(mockNetconfAdapter).when(netconfClientJsch)
+ .getNetconfAdapter(Mockito.any(InputStream.class), Mockito.any(OutputStream.class));
+ }
+
+ @Test
+ public void testConnect() throws APPCException, IOException, JSchException {
+ setupForConnectTests();
+ Mockito.doReturn("<hello>").when(mockNetconfAdapter).receiveMessage();
NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
connectionDetails.setHost("test");
connectionDetails.setPort(8080);
connectionDetails.setUsername("test");
connectionDetails.setPassword("test");
+ List<String> capabilities = Arrays.asList(
+ "<capability>urn:ietf:params:netconf:base:1.1</capability>\r\n");
+ connectionDetails.setCapabilities(capabilities);
Properties additionalProperties = new Properties();
additionalProperties.setProperty("testKey1", "testParam1");
connectionDetails.setAdditionalProperties(additionalProperties);
+ netconfClientJsch.connect(connectionDetails);
+ Mockito.verify(mockNetconfAdapter).sendMessage(
+ Mockito.contains("<capability>urn:ietf:params:netconf:base:1.1</capability>"));
+ }
+ @Test
+ public void testConnectNullMessage() throws JSchException, IOException, APPCException {
+ setupForConnectTests();
+ NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
+ expectedEx.expect(APPCException.class);
+ expectedEx.expectMessage("Cannot establish connection to server");
netconfClientJsch.connect(connectionDetails);
}
- @Test (expected = NullPointerException.class)
- public void testExchangeMessage() throws APPCException, IOException {
- String message = "test";
-
- netconfClientJsch.exchangeMessage(message);
+ @Test
+ public void testConnectNullMessageNonNullResponse()
+ throws JSchException, IOException, APPCException {
+ setupForConnectTests();
+ Mockito.doReturn("NOT NULL RESPONSE").when(mockNetconfAdapter).receiveMessage();
+ Mockito.doThrow(new JSchException()).when(mockChannel).connect(10000);
+ NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
+ expectedEx.expect(APPCException.class);
+ expectedEx.expectCause(allOf(isA(RuntimeException.class),
+ hasProperty("message", is("Error closing netconf device"))));
+ netconfClientJsch.connect(connectionDetails);
}
- @Test (expected = NullPointerException.class)
- public void testConfigure() throws APPCException, IOException {
- String message = "test";
-
- netconfClientJsch.configure(message);
+ @Test
+ public void testConnectErrorMessage() throws JSchException, IOException, APPCException {
+ setupForConnectTests();
+ Mockito.doReturn("<rpc-error>").when(mockNetconfAdapter).receiveMessage();
+ NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
+ expectedEx.expect(APPCException.class);
+ expectedEx
+ .expectCause(allOf(isA(RuntimeException.class),
+ hasProperty("cause", allOf(isA(IOException.class),
+ hasProperty("message",
+ containsString("Error response from netconf device:")),
+ hasProperty("message", containsString("<rpc-error>"))
+ ))));
+ netconfClientJsch.connect(connectionDetails);
}
- @Test (expected = NullPointerException.class)
- public void testConfigureOk() throws APPCException, IOException {
- String message = "<ok/>";
-
- netconfClientJsch.configure(message);
+ @Test
+ public void testConnectWithSuccessfulDisconnect()
+ throws JSchException, IOException, APPCException {
+ setupForConnectTests();
+ Mockito.doThrow(new JSchException()).when(mockChannel).connect(10000);
+ Mockito.doReturn("<ok/>").when(mockNetconfAdapter).receiveMessage();
+ NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails();
+ expectedEx.expect(APPCException.class);
+ expectedEx.expectCause(allOf(isA(APPCException.class),
+ hasProperty("message", is(JSchException.class.getName()))));
+ netconfClientJsch.connect(connectionDetails);
}
- @Test (expected = NullPointerException.class)
- public void testConfigureNull() throws APPCException, IOException {
- String message = null;
-
- netconfClientJsch.configure(message);
+ @Test
+ public void testGetConfiguration() throws IOException, APPCException {
+ mockNetconfAdapter = Mockito.mock(NetconfAdapter.class);
+ Whitebox.setInternalState(netconfClientJsch, "netconfAdapter", mockNetconfAdapter);
+ Mockito.doReturn("TEST RETURN VALUE").when(mockNetconfAdapter).receiveMessage();
+ assertEquals("TEST RETURN VALUE", netconfClientJsch.getConfiguration());
}
- @Test (expected = NullPointerException.class)
- public void testGetConfigure() throws APPCException, IOException {
-
+ @Test
+ public void testGetConfigurationExceptionFlow() throws IOException, APPCException {
+ mockNetconfAdapter = Mockito.mock(NetconfAdapter.class);
+ Whitebox.setInternalState(netconfClientJsch, "netconfAdapter", mockNetconfAdapter);
+ Mockito.doThrow(new IOException()).when(mockNetconfAdapter).receiveMessage();
+ expectedEx.expect(APPCException.class);
+ expectedEx.expectMessage(IOException.class.getName());
netconfClientJsch.getConfiguration();
}
@Test
- public void testDisconnect() throws APPCException, IOException {
+ public void testConfigure() throws IOException, APPCException {
+ mockNetconfAdapter = Mockito.mock(NetconfAdapter.class);
+ Whitebox.setInternalState(netconfClientJsch, "netconfAdapter", mockNetconfAdapter);
+ Mockito.doReturn("<ok/>").when(mockNetconfAdapter).receiveMessage();
+ netconfClientJsch.configure(null);
+ Mockito.verify(netconfClientJsch).exchangeMessage(null);
+ }
- netconfClientJsch.disconnect();
+ @Test
+ public void testConfigureExceptionFlow() throws IOException, APPCException {
+ mockNetconfAdapter = Mockito.mock(NetconfAdapter.class);
+ Whitebox.setInternalState(netconfClientJsch, "netconfAdapter", mockNetconfAdapter);
+ Mockito.doThrow(new IOException()).when(mockNetconfAdapter).receiveMessage();
+ expectedEx.expect(APPCException.class);
+ expectedEx.expectMessage(IOException.class.getName());
+ netconfClientJsch.configure(null);
}
}