minor fixes to add-test-flows

- Fix issue where each run keeps adding # of flows to add
- Ensure clean up is complete before next run starts

Change-Id: I58dc0eec8626f17aa8b81cc12a2a839444cd75f8
diff --git a/cli/src/main/java/org/onosproject/cli/net/AddTestFlowsCommand.java b/cli/src/main/java/org/onosproject/cli/net/AddTestFlowsCommand.java
index 1f69190..0757dbf 100644
--- a/cli/src/main/java/org/onosproject/cli/net/AddTestFlowsCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/AddTestFlowsCommand.java
@@ -32,6 +32,7 @@
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry.FlowEntryState;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
@@ -43,7 +44,9 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.base.Stopwatch;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Streams;
 
 /**
  * Installs bulk flows.
@@ -65,7 +68,6 @@
     String numOfRuns = null;
 
     @Override
-    @java.lang.SuppressWarnings("squid:S1148")
     protected void execute() {
         FlowRuleService flowService = get(FlowRuleService.class);
         DeviceService deviceService = get(DeviceService.class);
@@ -117,9 +119,17 @@
 
             }
         }
+        // close stages
+        rules.newStage();
+        remove.newStage();
 
         for (int i = 0; i < num; i++) {
+            printProgress("Run %d:", i);
             latch = new CountDownLatch(2);
+            final CountDownLatch addSuccess = new CountDownLatch(1);
+            printProgress("..batch add request");
+            Stopwatch add = Stopwatch.createStarted();
+
             flowService.apply(rules.build(new FlowRuleOperationsContext() {
 
                 private final Stopwatch timer = Stopwatch.createStarted();
@@ -128,6 +138,7 @@
                 public void onSuccess(FlowRuleOperations ops) {
 
                     timer.stop();
+                    printProgress("..add success");
                     results.add(timer.elapsed(TimeUnit.MILLISECONDS));
                     if (results.size() == num) {
                         if (outputJson()) {
@@ -137,21 +148,46 @@
                         }
                     }
                     latch.countDown();
+                    addSuccess.countDown();
                 }
             }));
 
+            try {
+                addSuccess.await();
+                // wait until all flows reaches ADDED state
+                while (!Streams.stream(flowService.getFlowEntriesById(appId))
+                        .allMatch(fr -> fr.state() == FlowEntryState.ADDED)) {
+                    Thread.sleep(100);
+                }
+                add.stop();
+                printProgress("..completed %d ± 100 ms", add.elapsed(TimeUnit.MILLISECONDS));
+            } catch (InterruptedException e1) {
+                printProgress("Interrupted");
+                Thread.currentThread().interrupt();
+            }
+
+            printProgress("..cleaning up");
             flowService.apply(remove.build(new FlowRuleOperationsContext() {
                 @Override
                 public void onSuccess(FlowRuleOperations ops) {
                     latch.countDown();
                 }
             }));
+
             try {
                 latch.await();
+                while (!Iterables.isEmpty(flowService.getFlowEntriesById(appId))) {
+                    Thread.sleep(500);
+                }
             } catch (InterruptedException e) {
-                e.printStackTrace();
+                printProgress("Interrupted.");
+                Thread.currentThread().interrupt();
             }
-
+        }
+        if (outputJson()) {
+            print("%s", json(new ObjectMapper(), true, results));
+        } else {
+            printTime(true, results);
         }
     }
 
@@ -165,10 +201,17 @@
         return result;
     }
 
+    private void printProgress(String format, Object... args) {
+        if (!outputJson()) {
+            print(format, args);
+        }
+    }
+
+
     private void printTime(boolean isSuccess, ArrayList<Long> elapsed) {
         print("Run is %s.", isSuccess ? "success" : "failure");
         for (int i = 0; i < elapsed.size(); i++) {
-            print("  Run %s : %s", i, elapsed.get(i));
+            print("  Run %s : %s ms", i, elapsed.get(i));
         }
     }
 }