updating flow-sync-perf.py and adding new generate_flows script
diff --git a/perf-scripts/flow-sync-perf.py b/perf-scripts/flow-sync-perf.py
index 00476d3..9549da5 100755
--- a/perf-scripts/flow-sync-perf.py
+++ b/perf-scripts/flow-sync-perf.py
@@ -10,6 +10,7 @@
 
 import csv
 import os
+import sys
 from time import sleep, strftime
 from subprocess import Popen, call, check_output, PIPE
 from mininet.net import Mininet
@@ -25,8 +26,10 @@
   call( 'apt-get install -y python-pexpect', stdout=PIPE, shell=True )
   import pexpect
 
+ONOS_HOME = '..'
+
 # Verify that tcpkill is installed
-if Popen( 'which tcpkill', shell=True).communicate():
+if not Popen( 'which tcpkill', stdout=PIPE, shell=True).communicate():
   print '* Installing tcpkill'
   call( 'apt-get install -y dsniff', stdout=PIPE, shell=True )
 
@@ -60,24 +63,21 @@
   return results
 
 def startNet(net):
-  tail = Popen( "exec tail -0f ../onos-logs/onos.onosdev1.log", stdout=PIPE, shell=True )
-  print 'waiting'
-  #tail = pexpect.spawn( 'tail -0f ../onos-logs/onos.onosdev1.log' )
+  tail = pexpect.spawn( 'tail -0f %s/onos-logs/onos.onosdev1.log' % ONOS_HOME )
   net.start()
-  #index = tail.expect(['Sync time (ms)', pexpect.TIMEOUT])
-  #if index == 1:
-  #  print '* ONOS not started'
-  #  exit(1)
-  print 'done'
-  waitForResult(tail)
-  tail.kill()
+  index = tail.expect(['Sync time \(ms\)', pexpect.EOF, pexpect.TIMEOUT])
+  if index >= 1:
+    print '* ONOS not started'
+    net.stop()
+    exit(1)
+  tail.terminate()
 
 def dumpFlows():
   return check_output( 'ovs-ofctl dump-flows s1', shell=True )
 
 def addFlowsToONOS(n):
-  call( 'web/generate_flows.py 1 %d > /tmp/flows.txt' % n, shell=True )
-  call( 'web/add_flow.py -m onos -f /tmp/flows.txt', shell=True )
+  call( './generate_flows.py 1 %d > /tmp/flows.txt' % n, shell=True )
+  call( '%s/web/add_flow.py -m onos -f /tmp/flows.txt' % ONOS_HOME, shell=True )
   while True:
     output = check_output( 'ovs-ofctl dump-flows s1', shell=True )
     lines = len(output.split('\n'))
@@ -86,7 +86,7 @@
     sleep(1)
   count = 0
   while True:
-    output = pexpect.spawn( 'web/get_flow.py all' )
+    output = pexpect.spawn( '%s/web/get_flow.py all' % ONOS_HOME )
     while count < n:
       if output.expect(['FlowEntry', pexpect.EOF], timeout=2000) == 1:
         break
@@ -95,7 +95,7 @@
     sleep(5)
 
 def removeFlowsFromONOS():
-  call( 'web/delete_flow.py all', shell=True )
+  call( '%s/web/delete_flow.py all' % ONOS_HOME, shell=True )
   while True:
     output = check_output( 'ovs-ofctl dump-flows s1', shell=True )
     lines = len(output.split('\n'))
@@ -103,7 +103,7 @@
       break
     sleep(1)
   while True:
-    output = pexpect.spawn( 'web/get_flow.py all' )
+    output = pexpect.spawn( '%s/web/get_flow.py all' % ONOS_HOME )
     if output.expect(['FlowEntry', pexpect.EOF], timeout=2000) == 1:
       break
     sleep(5)
@@ -112,7 +112,7 @@
 # ----------------- Running the test and output  -------------------------
 def test(i, fn):
   # Start tailing the onos log
-  tail = pexpect.spawn( "tail -0f ../onos-logs/onos.onosdev1.log" )
+  tail = pexpect.spawn( "tail -0f %s/onos-logs/onos.onosdev1.log" % ONOS_HOME )
   # disconnect the switch from the controller using tcpkill
   tcp  = Popen( 'exec tcpkill -i lo -9 port 6633 > /dev/null 2>&1', shell=True )
   # wait until the switch has been disconnected
@@ -124,12 +124,19 @@
   # end tcpkill process to reconnect the switch to the controller
   tcp.terminate()
   tail.expect('Sync time \(ms\):', timeout=6000)
+  tail.expect('([\d.]+,?)+\s')
   print tail.match.group(0)
-  print tail.match.after
   tail.terminate()
   sleep(3)
-  return []
-  #return [tail.match.group(x) for x in range(1,5)]
+  return tail.match.group(0).strip().split(',')
+
+def initResults(files):
+  headers = ['# of FEs', 'Flow IDs from Graph', 'FEs from Switch', 'Compare', 
+             'Read FE from graph', 'Extract FE', 'Push', 'Total' ]
+  for filename in files.values():
+    with open(filename, 'w') as csvfile:
+      writer = csv.writer(csvfile)
+      writer.writerow(headers)
 
 def outputResults(filename, n, results):
   results.insert(0, n)
@@ -142,6 +149,7 @@
   fileMap = { 'add':    os.path.join(resultDir, 'add.csv'),
               'delete': os.path.join(resultDir, 'delete.csv'),
               'sync':   os.path.join(resultDir, 'sync.csv') }
+  initResults(fileMap)
   # start Mininet
   topo = SingleSwitchTopo()
   net = Mininet(topo=topo, controller=RemoteController)
@@ -172,7 +180,10 @@
   setLogLevel( 'output' )
   resultDir = strftime( '%Y%m%d-%H%M%S' )
   os.mkdir( resultDir )
-  runPerf( resultDir, [1, 10, 100] )
+  tests = sys.argv[1:]
+  if not tests:
+    tests = [1, 10, 100, 1000, 10000]
+  runPerf( resultDir, tests )
 
 exit()
 
diff --git a/perf-scripts/generate_flows.py b/perf-scripts/generate_flows.py
new file mode 100755
index 0000000..11d9c19
--- /dev/null
+++ b/perf-scripts/generate_flows.py
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+# -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
+
+#
+# A script for generating a number of flows.
+#
+# The output of the script should be saved to a file, and the flows from
+# that file should be added by the following command:
+#
+#   web/add_flow.py -f filename
+# 
+# NOTE: Currently, some of the parameters fo the flows are hard-coded,
+# and all flows are between same source and destination DPID and ports
+# (differentiated by different matchSrcMac and matchDstMac).
+#
+
+import copy
+import pprint
+import os
+import sys
+import subprocess
+import json
+import argparse
+import io
+import time
+
+## Global Var ##
+
+DEBUG=0
+pp = pprint.PrettyPrinter(indent=4)
+
+## Worker Functions ##
+def log_error(txt):
+  print '%s' % (txt)
+
+def debug(txt):
+  if DEBUG:
+    print '%s' % (txt)
+
+
+if __name__ == "__main__":
+  usage_msg = "Generate a number of flows by using a pre-defined template.\n"
+  usage_msg = usage_msg + "\n"
+  usage_msg = usage_msg + "NOTE: This script is work-in-progress. Currently all flows are within same\n"
+  usage_msg = usage_msg + "pair of switch ports and contain auto-generated MAC-based matching conditions.\n"
+  usage_msg = usage_msg + "\n"
+  usage_msg = usage_msg + "Usage: %s <begin-flow-id> <end-flow-id>\n" % (sys.argv[0])
+  usage_msg = usage_msg + "\n"
+  usage_msg = usage_msg + "    The output should be saved to a file, and the flows should be installed\n"
+  usage_msg = usage_msg + "    by using the command './add_flow.py -f filename'\n"
+
+
+  # app.debug = False;
+
+  # Usage info
+  if len(sys.argv) > 1 and (sys.argv[1] == "-h" or sys.argv[1] == "--help"):
+    print(usage_msg)
+    exit(0)
+
+  # Check arguments
+  if len(sys.argv) < 3:
+    log_error(usage_msg)
+    exit(1)
+
+  # Extract the arguments
+  begin_flow_id = int(sys.argv[1], 0)
+  end_flow_id = int(sys.argv[2], 0)
+  if begin_flow_id > end_flow_id:
+    log_error(usage_msg)
+    exit(1)
+
+  #
+  # Do the work
+  #
+  # NOTE: Currently, up to 65536 flows are supported.
+  # More flows can be supported by iterating by, say, iterating over some of
+  # the other bytes of the autogenereated source/destination MAC addresses.
+  #
+  flow_id = begin_flow_id
+  idx = 0
+  while flow_id <= end_flow_id:
+    mac3 = idx / 255
+    mac4 = idx % 255
+    str_mac3 = "%0.2x" % mac3
+    str_mac4 = "%0.2x" % mac4
+    src_mac = "00:00:" + str_mac3 + ":" + str_mac4 + ":00:00";
+    dst_mac = "00:01:" + str_mac3 + ":" + str_mac4 + ":00:00";
+    print "%s FOOBAR 00:00:00:00:00:00:00:01 1 00:00:00:00:00:00:00:01 2 matchSrcMac %s matchDstMac %s" % (flow_id, src_mac, dst_mac)
+    flow_id = flow_id + 1
+    idx = idx + 1