Multiple clients for stresstool 19/18919/5
authorMaros Marsalek <mmarsale@cisco.com>
Wed, 29 Apr 2015 14:37:04 +0000 (16:37 +0200)
committerMaros Marsalek <mmarsale@cisco.com>
Wed, 29 Apr 2015 14:37:04 +0000 (16:37 +0200)
Added new parameter(--thread-amount) for stresstool that splits edits
between multiple threads.

Change-Id: I87a81a5442e32833c0c49dfd98b6475f8e699a2b
Signed-off-by: Tomas Cere <tcere@cisco.com>
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/AsyncExecutionStrategy.java
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/Parameters.java
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java [new file with mode: 0644]
opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/SyncExecutionStrategy.java

index 7b60a17827dfe388b3775c83800bac803f1ddc7a..af352b1c2e8e28d1b338c7fab9377d72860c97e7 100644 (file)
@@ -30,24 +30,26 @@ class AsyncExecutionStrategy implements ExecutionStrategy {
     private final List<NetconfMessage> preparedMessages;
     private final NetconfDeviceCommunicator sessionListener;
     private final List<Integer> editBatches;
+    private final int editAmount;
 
     public AsyncExecutionStrategy(final Parameters params, final List<NetconfMessage> editConfigMsgs, final NetconfDeviceCommunicator sessionListener) {
         this.params = params;
         this.preparedMessages = editConfigMsgs;
         this.sessionListener = sessionListener;
-        this.editBatches = countEditBatchSizes(params);
+        this.editBatches = countEditBatchSizes(params, editConfigMsgs.size());
+        editAmount = editConfigMsgs.size();
     }
 
-    private static List<Integer> countEditBatchSizes(final Parameters params) {
+    private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
         final List<Integer> editBatches = Lists.newArrayList();
-        if (params.editBatchSize != params.editCount) {
-            final int fullBatches = params.editCount / params.editBatchSize;
+        if (params.editBatchSize != amount) {
+            final int fullBatches = amount / params.editBatchSize;
             for (int i = 0; i < fullBatches; i++) {
                 editBatches.add(params.editBatchSize);
             }
 
-            if (params.editCount % params.editBatchSize != 0) {
-                editBatches.add(params.editCount % params.editBatchSize);
+            if (amount % params.editBatchSize != 0) {
+                editBatches.add(amount % params.editBatchSize);
             }
         } else {
             editBatches.add(params.editBatchSize);
@@ -96,6 +98,6 @@ class AsyncExecutionStrategy implements ExecutionStrategy {
             }
         }
 
-        Preconditions.checkState(responseCounter.get() == params.editCount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
+        Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
     }
 }
index 72031079019fca044f323a014b58844fce1e9b53..8a9a915a08d4ef4a62c5d9a5326a78f20b758873 100644 (file)
@@ -55,6 +55,9 @@ public class Parameters {
     @Arg(dest = "tcp-header")
     public String tcpHeader;
 
+    @Arg(dest = "thread-amount")
+    public int threadAmount;
+
     static ArgumentParser getParser() {
         final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
 
@@ -130,6 +133,11 @@ public class Parameters {
                 .required(false)
                 .dest("tcp-header");
 
+        parser.addArgument("--thread-amount")
+                .type(Integer.class)
+                .setDefault(1)
+                .dest("thread-amount");
+
         // TODO add get-config option instead of edit + commit
         // TODO different edit config content
 
index 6bf50d2c5a0070e4273d19d11cf843e974d569a4..0e87604cc5d6216034bf401d3f324ac38065ce0b 100644 (file)
@@ -20,28 +20,23 @@ import com.google.common.io.Files;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
-import io.netty.util.concurrent.GlobalEventExecutor;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
+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 net.sourceforge.argparse4j.inf.ArgumentParser;
 import net.sourceforge.argparse4j.inf.ArgumentParserException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.CommitInput;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfigInput;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -80,6 +75,7 @@ public final class StressClient {
                             "        <target>\n" +
                             "            <candidate/>\n" +
                             "        </target>\n" +
+                            "        <default-operation>none</default-operation>" +
                             "        <config/>\n" +
                             "    </edit-config>\n" +
                             "</rpc>");
@@ -95,19 +91,35 @@ public final class StressClient {
         final Parameters params = parseArgs(args, Parameters.getParser());
         params.validate();
 
-        // Wait 5 seconds to allow for debugging/profiling
-        try {
-            Thread.sleep(5000);
-        } catch (final InterruptedException e) {
-            throw new RuntimeException(e);
-        }
+        // TODO remove
+//        try {
+//            Thread.sleep(10000);
+//        } catch (final InterruptedException e) {
+//            e.printStackTrace();
+//        }
 
         final ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
         root.setLevel(params.debug ? Level.DEBUG : Level.INFO);
 
+        int threadAmount = params.threadAmount;
+        LOG.info("thread amount: " + threadAmount);
+        int requestsPerThread = params.editCount / params.threadAmount;
+        LOG.info("requestsPerThread: " + requestsPerThread);
+        int leftoverRequests = params.editCount % params.threadAmount;
+        LOG.info("leftoverRequests: " + leftoverRequests);
+
+
         LOG.info("Preparing messages");
         // Prepare all msgs up front
-        final List<NetconfMessage> preparedMessages = Lists.newArrayListWithCapacity(params.editCount);
+        final List<List<NetconfMessage>> allPreparedMessages = new ArrayList<>(threadAmount);
+        for (int i = 0; i < threadAmount; i++) {
+            if (i != threadAmount - 1) {
+                allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread));
+            } else {
+                allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread + leftoverRequests));
+            }
+        }
+
 
         final String editContentString;
         try {
@@ -116,63 +128,51 @@ public final class StressClient {
             throw new IllegalArgumentException("Cannot read content of " + params.editContent);
         }
 
-        for (int i = 0; i < params.editCount; i++) {
-            final Document msg = XmlUtil.createDocumentCopy(editBlueprint);
-            msg.getDocumentElement().setAttribute("message-id", Integer.toString(i));
-            final NetconfMessage netconfMessage = new NetconfMessage(msg);
-
-            final Element editContentElement;
-            try {
-                // Insert message id where needed
-                String specificEditContent =
-                        editContentString.replaceAll(MSG_ID_PLACEHOLDER_REGEX, Integer.toString(i));
-
-                // Insert physical address where needed
-                specificEditContent =
-                        specificEditContent.replaceAll(PHYS_ADDR_PLACEHOLDER_REGEX, getMac(i));
-
-                editContentElement = XmlUtil.readXmlToElement(specificEditContent);
-                final Node config = ((Element) msg.getDocumentElement().getElementsByTagName("edit-config").item(0)).
-                        getElementsByTagName("config").item(0);
-                config.appendChild(msg.importNode(editContentElement, true));
-            } catch (final IOException | SAXException e) {
-                throw new IllegalArgumentException("Edit content file is unreadable", e);
+        for (int i = 0; i < threadAmount; i++) {
+            final List<NetconfMessage> preparedMessages = allPreparedMessages.get(i);
+            int padding = 0;
+            if (i == threadAmount - 1) {
+                padding = leftoverRequests;
+            }
+            for (int j = 0; j < requestsPerThread + padding; j++) {
+                LOG.debug("id: " + (i * requestsPerThread + j));
+                preparedMessages.add(prepareMessage(i * requestsPerThread + j, editContentString));
             }
-
-            preparedMessages.add(netconfMessage);
-
         }
 
-
         final NioEventLoopGroup nioGroup = new NioEventLoopGroup();
         final Timer timer = new HashedWheelTimer();
 
         final NetconfClientDispatcherImpl netconfClientDispatcher = configureClientDispatcher(params, nioGroup, timer);
 
-        final NetconfDeviceCommunicator sessionListener = getSessionListener(params.getInetAddress());
-
-        final NetconfClientConfiguration cfg = getNetconfClientConfiguration(params, sessionListener);
-
-        LOG.info("Connecting to netconf server {}:{}", params.ip, params.port);
-        final NetconfClientSession netconfClientSession;
-        try {
-            netconfClientSession = netconfClientDispatcher.createClient(cfg).get();
-        } catch (final InterruptedException e) {
-            throw new RuntimeException(e);
-        } catch (final ExecutionException e) {
-            throw new RuntimeException("Unable to connect", e);
+        final List<StressClientCallable> callables = new ArrayList<>(threadAmount);
+        for (List<NetconfMessage> messages : allPreparedMessages) {
+            callables.add(new StressClientCallable(params, netconfClientDispatcher, messages));
         }
 
+        final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount);
+
         LOG.info("Starting stress test");
         final Stopwatch started = Stopwatch.createStarted();
-        getExecutionStrategy(params, preparedMessages, sessionListener).invoke();
+        try {
+            final List<Future<Boolean>> futures = executorService.invokeAll(callables);
+            for (Future<Boolean> future : futures) {
+                try {
+                    future.get(4L, TimeUnit.MINUTES);
+                } catch (ExecutionException | TimeoutException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+            executorService.shutdownNow();
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Unable to execute requests", e);
+        }
         started.stop();
 
         LOG.info("FINISHED. Execution time: {}", started);
         LOG.info("Requests per second: {}", (params.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
 
         // Cleanup
-        netconfClientSession.close();
         timer.stop();
         try {
             nioGroup.shutdownGracefully().get(20L, TimeUnit.SECONDS);
@@ -181,29 +181,28 @@ public final class StressClient {
         }
     }
 
-    private static String getMac(final int i) {
-        final String hex = Integer.toHexString(i);
-        final Iterable<String> macGroups = Splitter.fixedLength(2).split(hex);
+    private static NetconfMessage prepareMessage(final int id, final String editContentString) {
+        final Document msg = XmlUtil.createDocumentCopy(editBlueprint);
+        msg.getDocumentElement().setAttribute("message-id", Integer.toString(id));
+        final NetconfMessage netconfMessage = new NetconfMessage(msg);
 
-        final int additional = 6 - Iterables.size(macGroups);
-        final ArrayList<String> additionalGroups = Lists.newArrayListWithCapacity(additional);
-        for (int j = 0; j < additional; j++) {
-            additionalGroups.add("00");
+        final Element editContentElement;
+        try {
+            // Insert message id where needed
+            String specificEditContent = editContentString.replaceAll(MSG_ID_PLACEHOLDER_REGEX, Integer.toString(id));
+
+            specificEditContent =
+                    specificEditContent.replaceAll(PHYS_ADDR_PLACEHOLDER_REGEX, getMac(id));
+
+            editContentElement = XmlUtil.readXmlToElement(specificEditContent);
+            final Node config = ((Element) msg.getDocumentElement().getElementsByTagName("edit-config").item(0)).
+                    getElementsByTagName("config").item(0);
+            config.appendChild(msg.importNode(editContentElement, true));
+        } catch (final IOException | SAXException e) {
+            throw new IllegalArgumentException("Edit content file is unreadable", e);
         }
-        return Joiner.on(':').join(Iterables.concat(Iterables.transform(macGroups, new Function<String, String>() {
-            @Override
-            public String apply(final String input) {
-                return input.length() == 1 ? input + "0" : input;
-            }
-        }), additionalGroups));
-    }
 
-    private static ExecutionStrategy getExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
-        if(params.async) {
-            return new AsyncExecutionStrategy(params, preparedMessages, sessionListener);
-        } else {
-            return new SyncExecutionStrategy(params, preparedMessages, sessionListener);
-        }
+        return netconfMessage;
     }
 
     private static NetconfClientDispatcherImpl configureClientDispatcher(final Parameters params, final NioEventLoopGroup nioGroup, final Timer timer) {
@@ -224,29 +223,21 @@ public final class StressClient {
         return netconfClientDispatcher;
     }
 
-    private static NetconfClientConfiguration getNetconfClientConfiguration(final Parameters params, final NetconfDeviceCommunicator sessionListener) {
-        final NetconfClientConfigurationBuilder netconfClientConfigurationBuilder = NetconfClientConfigurationBuilder.create();
-        netconfClientConfigurationBuilder.withSessionListener(sessionListener);
-        netconfClientConfigurationBuilder.withAddress(params.getInetAddress());
-        if(params.tcpHeader != null) {
-            final String header = params.tcpHeader.replaceAll("\"", "").trim() + "\n";
-            netconfClientConfigurationBuilder.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader(null, null, null, null, null) {
-                @Override
-                public String toFormattedString() {
-                    LOG.debug("Sending TCP header {}", header);
-                    return header;
-                }
-            });
-        }
-        netconfClientConfigurationBuilder.withProtocol(params.ssh ? NetconfClientConfiguration.NetconfClientProtocol.SSH : NetconfClientConfiguration.NetconfClientProtocol.TCP);
-        netconfClientConfigurationBuilder.withConnectionTimeoutMillis(20000L);
-        netconfClientConfigurationBuilder.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
-        return netconfClientConfigurationBuilder.build();
-    }
+    private static String getMac(final int i) {
+        final String hex = Integer.toHexString(i);
+        final Iterable<String> macGroups = Splitter.fixedLength(2).split(hex);
 
-    static NetconfDeviceCommunicator getSessionListener(final InetSocketAddress inetAddress) {
-        final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> loggingRemoteDevice = new LoggingRemoteDevice();
-        return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", inetAddress), loggingRemoteDevice);
+        final int additional = 6 - Iterables.size(macGroups);
+        final ArrayList<String> additionalGroups = Lists.newArrayListWithCapacity(additional);
+        for (int j = 0; j < additional; j++) {
+            additionalGroups.add("00");
+        }
+        return Joiner.on(':').join(Iterables.concat(Iterables.transform(macGroups, new Function<String, String>() {
+            @Override
+            public String apply(final String input) {
+                return input.length() == 1 ? input + "0" : input;
+            }
+        }), additionalGroups));
     }
 
     private static Parameters parseArgs(final String[] args, final ArgumentParser parser) {
@@ -263,7 +254,7 @@ public final class StressClient {
     }
 
 
-    private static class LoggingRemoteDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
+    static class LoggingRemoteDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
         @Override
         public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities, final NetconfDeviceCommunicator netconfDeviceCommunicator) {
             LOG.info("Session established");
diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClientCallable.java
new file mode 100644 (file)
index 0000000..a4c5c57
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015 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
+ */
+
+package org.opendaylight.controller.netconf.test.tool.client.stress;
+
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
+import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
+import org.opendaylight.controller.sal.connect.api.RemoteDevice;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
+import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.protocol.framework.NeverReconnectStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StressClientCallable implements Callable<Boolean>{
+
+    private static final Logger LOG = LoggerFactory.getLogger(StressClientCallable.class);
+
+    private Parameters params;
+    private final NetconfDeviceCommunicator sessionListener;
+    private final NetconfClientDispatcherImpl netconfClientDispatcher;
+    private final NetconfClientConfiguration cfg;
+    private final NetconfClientSession netconfClientSession;
+    private final ExecutionStrategy executionStrategy;
+
+    public StressClientCallable(final Parameters params,
+                                final NetconfClientDispatcherImpl netconfClientDispatcher,
+                                final List<NetconfMessage> preparedMessages) {
+        this.params = params;
+        this.sessionListener = getSessionListener(params.getInetAddress());
+        this.netconfClientDispatcher = netconfClientDispatcher;
+        cfg = getNetconfClientConfiguration(this.params, this.sessionListener);
+
+        LOG.info("Connecting to netconf server {}:{}", params.ip, params.port);
+        try {
+            netconfClientSession = netconfClientDispatcher.createClient(cfg).get();
+        } catch (final InterruptedException e) {
+            throw new RuntimeException(e);
+        } catch (final ExecutionException e) {
+            throw new RuntimeException("Unable to connect", e);
+        }
+        executionStrategy = getExecutionStrategy(params, preparedMessages, sessionListener);
+    }
+
+    @Override
+    public Boolean call() throws Exception {
+        executionStrategy.invoke();
+        netconfClientSession.close();
+        return true;
+    }
+
+    private static ExecutionStrategy getExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
+        if(params.async) {
+            return new AsyncExecutionStrategy(params, preparedMessages, sessionListener);
+        } else {
+            return new SyncExecutionStrategy(params, preparedMessages, sessionListener);
+        }
+    }
+
+    private static NetconfDeviceCommunicator getSessionListener(final InetSocketAddress inetAddress) {
+        final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> loggingRemoteDevice = new StressClient.LoggingRemoteDevice();
+        return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", inetAddress), loggingRemoteDevice);
+    }
+
+    private static NetconfClientConfiguration getNetconfClientConfiguration(final Parameters params, final NetconfDeviceCommunicator sessionListener) {
+        final NetconfClientConfigurationBuilder netconfClientConfigurationBuilder = NetconfClientConfigurationBuilder.create();
+        netconfClientConfigurationBuilder.withSessionListener(sessionListener);
+        netconfClientConfigurationBuilder.withAddress(params.getInetAddress());
+        if(params.tcpHeader != null) {
+            final String header = params.tcpHeader.replaceAll("\"", "").trim() + "\n";
+            netconfClientConfigurationBuilder.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader(null, null, null, null, null) {
+                @Override
+                public String toFormattedString() {
+                    LOG.debug("Sending TCP header {}", header);
+                    return header;
+                }
+            });
+        }
+        netconfClientConfigurationBuilder.withProtocol(params.ssh ? NetconfClientConfiguration.NetconfClientProtocol.SSH : NetconfClientConfiguration.NetconfClientProtocol.TCP);
+        netconfClientConfigurationBuilder.withConnectionTimeoutMillis(20000L);
+        netconfClientConfigurationBuilder.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
+        return netconfClientConfigurationBuilder.build();
+    }
+}
index 34142a7f2a49d89a47d3529b9fe976c5e76743fb..40f39022e6b41e9424f46421cc38c2e5837ceff2 100644 (file)
@@ -31,24 +31,26 @@ class SyncExecutionStrategy implements ExecutionStrategy {
     private final List<NetconfMessage> preparedMessages;
     private final NetconfDeviceCommunicator sessionListener;
     private final List<Integer> editBatches;
+    private final int editAmount;
 
     public SyncExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
         this.params = params;
         this.preparedMessages = preparedMessages;
         this.sessionListener = sessionListener;
-        editBatches = countEditBatchSizes(params);
+        this.editBatches = countEditBatchSizes(params, preparedMessages.size());
+        editAmount = preparedMessages.size();
     }
 
-    private static List<Integer> countEditBatchSizes(final Parameters params) {
+    private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
         final List<Integer> editBatches = Lists.newArrayList();
-        if (params.editBatchSize != params.editCount) {
-            final int fullBatches = params.editCount / params.editBatchSize;
+        if (params.editBatchSize != amount) {
+            final int fullBatches = amount / params.editBatchSize;
             for (int i = 0; i < fullBatches; i++) {
                 editBatches.add(params.editBatchSize);
             }
 
-            if (params.editCount % params.editBatchSize != 0) {
-                editBatches.add(params.editCount % params.editBatchSize);
+            if (amount % params.editBatchSize != 0) {
+                editBatches.add(amount % params.editBatchSize);
             }
         } else {
             editBatches.add(params.editBatchSize);
@@ -82,7 +84,7 @@ class SyncExecutionStrategy implements ExecutionStrategy {
                     sessionListener.sendRequest(StressClient.COMMIT_MSG, StressClient.COMMIT_QNAME));
         }
 
-        Preconditions.checkState(responseCounter.get() == params.editCount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
+        Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
     }
 
     private void waitForResponse(AtomicInteger responseCounter, final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture) {