Bug-2342: Add stress test with more threads and start of testtool device. 04/13404/10
authorMarian Dubai <mdubai@cisco.com>
Thu, 4 Dec 2014 11:53:42 +0000 (12:53 +0100)
committerMarian Dubai <mdubai@cisco.com>
Mon, 15 Dec 2014 14:39:41 +0000 (14:39 +0000)
Change-Id: Ic8cadf339d330d9e165db4b0eafe8e8408601abd
Signed-off-by: Marian Dubai <mdubai@cisco.com>
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTestTool.java [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/resources/logback-test.xml
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/Main.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml

index 7218ac78726c7c7297e215d57211a8a749f70c8f..6e4c16d20fca36bf83c89b77c872aa1fe873c08b 100644 (file)
       <artifactId>netconf-ssh</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+       <groupId>${project.groupId}</groupId>
+       <artifactId>netconf-testtool</artifactId>
+       <version>${project.version}</version>
+       <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>netconf-ssh</artifactId>
index 5f316d11c1cc6e28210d3382d0a78ca23aa01dd6..bd8e2ed4df623f4c96051429f70cadc11ed9b17f 100644 (file)
@@ -41,8 +41,6 @@ import org.apache.sshd.server.session.ServerSession;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.auth.AuthProvider;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
@@ -116,7 +114,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     @Test
     public void testSecure() throws Exception {
         final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(new SimpleNetconfClientSessionListener()))) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(new SimpleNetconfClientSessionListener(), TLS_ADDRESS))) {
             NetconfMessage response = netconfClient.sendMessage(getGetConfig());
             assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
                     NetconfMessageUtil.isErrorMessage(response));
@@ -143,7 +141,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
 
         final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
         final NetconfDeviceCommunicator sessionListener = getSessionListener();
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(sessionListener))) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(sessionListener, TLS_ADDRESS))) {
 
             final AtomicInteger responseCounter = new AtomicInteger(0);
             final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
@@ -182,15 +180,15 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         }
     }
 
-    private NetconfMessage changeMessageId(final NetconfMessage getConfig, final int i) throws IOException, SAXException {
+    public static NetconfMessage changeMessageId(final NetconfMessage getConfig, final int i) throws IOException, SAXException {
         String s = XmlUtil.toString(getConfig.getDocument(), false);
         s = s.replace("101", Integer.toString(i));
         return new NetconfMessage(XmlUtil.readXmlToDocument(s));
     }
 
-    public NetconfClientConfiguration getClientConfiguration(final NetconfClientSessionListener sessionListener) throws IOException {
+    static NetconfClientConfiguration getClientConfiguration(final NetconfClientSessionListener sessionListener,final InetSocketAddress tlsAddress) throws IOException {
         final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
-        b.withAddress(TLS_ADDRESS);
+        b.withAddress(tlsAddress);
         // Using session listener from sal-netconf-connector since stress test cannot be performed with simple listener
         b.withSessionListener(sessionListener);
         b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
@@ -200,11 +198,8 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         return b.build();
     }
 
-    @Mock
-    private RemoteDevice<NetconfSessionCapabilities, NetconfMessage> mockedRemoteDevice;
-
-    private NetconfDeviceCommunicator getSessionListener() {
-        MockitoAnnotations.initMocks(this);
+    static NetconfDeviceCommunicator getSessionListener() {
+        RemoteDevice<NetconfSessionCapabilities, NetconfMessage> mockedRemoteDevice = mock(RemoteDevice.class);
         doNothing().when(mockedRemoteDevice).onRemoteSessionUp(any(NetconfSessionCapabilities.class), any(RemoteDeviceCommunicator.class));
         doNothing().when(mockedRemoteDevice).onRemoteSessionDown();
         return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test"), mockedRemoteDevice);
@@ -217,7 +212,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         return mockAuth;
     }
 
-    public AuthenticationHandler getAuthHandler() throws IOException {
+    public static AuthenticationHandler getAuthHandler() throws IOException {
         return new LoginPassword(USERNAME, PASSWORD);
     }
 
diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTestTool.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTestTool.java
new file mode 100644 (file)
index 0000000..0247273
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ */
+
+package org.opendaylight.controller.netconf.it;
+
+import static java.lang.Thread.sleep;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.opendaylight.controller.netconf.it.NetconfITSecureTest.getSessionListener;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
+import org.opendaylight.controller.netconf.test.tool.Main.Params;
+import org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class NetconfITSecureTestTool
+{
+
+    //set up port both for testool device and test
+    public static final int PORT = 17833;
+    private static final InetSocketAddress TLS_ADDRESS = new InetSocketAddress("127.0.0.1", PORT);
+
+    private String xmlFile = "netconfMessages/editConfig.xml";
+
+    private ExecutorService msgExec = Executors.newFixedThreadPool(8);
+
+    Collection<Future<?>> tasks = new LinkedList<Future<?>>();
+
+    final NetconfDeviceSimulator netconfDeviceSimulator = new NetconfDeviceSimulator();
+
+    @Before
+    public void setUp() throws Exception {
+
+        //Set up parameters for testtool device
+        Params params = new Params();
+        params.debug = true;
+        params.deviceCount = 1;
+        params.startingPort = PORT;
+        params.ssh = true;
+        params.exi = true;
+
+        final List<Integer> openDevices = netconfDeviceSimulator.start(params);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+
+    }
+
+    /**
+     * Test all requests are handled properly and no mismatch occurs in listener
+     */
+    @Test(timeout = 6*60*1000)
+    public void testSecureStress() throws Exception {
+
+        final int requests = 4000;
+
+        List<Future<?>> tasks = new ArrayList<>();
+
+        final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(), new HashedWheelTimer());
+
+        final NetconfDeviceCommunicator sessionListener = getSessionListener();
+
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, NetconfITSecureTest.getClientConfiguration(sessionListener, TLS_ADDRESS));)
+        {
+
+            final AtomicInteger responseCounter = new AtomicInteger(0);
+            final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
+
+            for (int i = 0; i < requests; i++) {
+
+                NetconfMessage getConfig = XmlFileLoader.xmlFileToNetconfMessage(xmlFile);
+
+                getConfig = NetconfITSecureTest.changeMessageId(getConfig,i);
+
+                Runnable worker = new NetconfITSecureTestToolRunnable(getConfig,i, sessionListener, futures, responseCounter);
+
+                tasks.add(msgExec.submit(worker));
+
+            }
+
+            msgExec.shutdown();
+
+            // Wait for every future
+            for (final Future<?> task : tasks){
+                try
+                {
+
+                    task.get(3, TimeUnit.MINUTES);
+                } catch (final TimeoutException e) {
+                    fail(String.format("Request %d is not responding", tasks.indexOf(task)));
+                }
+            }
+
+            for (final ListenableFuture<RpcResult<NetconfMessage>> future : futures) {
+                try {
+
+                    future.get(3, TimeUnit.MINUTES);
+                } catch (final TimeoutException e) {
+                    fail(String.format("Reply %d is not responding", futures.indexOf(future)));
+                }
+            }
+
+            sleep(5000);
+
+            assertEquals(requests, responseCounter.get());
+
+        }
+    }
+
+    class NetconfITSecureTestToolRunnable implements Runnable {
+
+        private NetconfMessage getConfig;
+        private int it;
+        private NetconfDeviceCommunicator sessionListener;
+        private List<ListenableFuture<RpcResult<NetconfMessage>>> futures;
+        private AtomicInteger responseCounter;
+
+        public NetconfITSecureTestToolRunnable(NetconfMessage getConfig, int it, NetconfDeviceCommunicator sessionListener, List<ListenableFuture<RpcResult<NetconfMessage>>> futures, AtomicInteger responseCounter){
+            this.getConfig = getConfig;
+            this.it = it;
+            this.sessionListener = sessionListener;
+            this.futures = futures;
+            this.responseCounter = responseCounter;
+        }
+
+        @Override
+        public void run(){
+
+            ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture;
+
+            netconfMessageFuture = sessionListener.sendRequest(getConfig, QName.create("namespace", "2012-12-12", "get"));
+
+            futures.add(netconfMessageFuture);
+            Futures.addCallback(netconfMessageFuture, new FutureCallback<RpcResult<NetconfMessage>>() {
+
+                    @Override
+                    public void onSuccess(final RpcResult<NetconfMessage> result) {
+
+                        if(result.isSuccessful()&result.getErrors().isEmpty()) {
+                            responseCounter.incrementAndGet();
+                        } else {
+
+                            fail(String.format("Message result not ok %s", result.getErrors().toString()));
+
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(final Throwable t) {
+
+                        fail(String.format("Message failed %s", Throwables.getStackTraceAsString(t)));
+
+                    }
+                }
+            );
+        }
+    }
+
+}
index 91fb805e6ab3f00a14096faea945eb0f4bad97b0..e9ee13d8b6a3c462f10d35a97e271369b0999c20 100644 (file)
@@ -6,8 +6,8 @@
         </encoder>
     </appender>
 
-  <logger name="org.opendaylight.controller.netconf" level="TRACE"/>
-  <logger name="org.opendaylight.controller.sal.connect.netconf" level="TRACE"/>
+  <logger name="org.opendaylight.controller.netconf" level="INFO"/>
+  <logger name="org.opendaylight.controller.sal.connect.netconf" level="DEBUG"/>
 
   <root level="error">
     <appender-ref ref="STDOUT" />
index e441c709ccabcdcc9a9659a0ca96add3c21a27f1..e52fce7ae03372cb676b7ed6b9fe813682ef34c3 100644 (file)
@@ -46,7 +46,7 @@ public final class Main {
 
     private static final Logger LOG = LoggerFactory.getLogger(Main.class);
 
-    static class Params {
+    public static class Params {
 
         @Arg(dest = "schemas-dir")
         public File schemasDir;
index 5dd5a90f7db9550cf4fbe677aea456cdcf821ecc..a0458c45e3a7a17ad92e77bdf06ac945b1eb4be9 100644 (file)
@@ -1,4 +1,4 @@
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<rpc message-id="101" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <edit-config>
         <target>
             <candidate/>