[WIP] ONOS-8091 Port python script and utilities to python3

Steps performed so far:
- Updated bash scripts and similar to explicitly invoke python3 (instead of python)
- Updated all python scripts using 2to3

Testing these changes will be a major headache because:
- different scripts are executed in different environments
  (e.g., Jenkins, cell servers, tutorial VMs, etc.)
- we don’t have control on all environments
- some environments we used to control have been dismissed
  (e.g., cell servers)

The approach for now is to focus on the essentials:
- Jenkins jobs for pre-merge and release

Test and fix everything else as the need arises.

Change-Id: I943e214760c9dea9a7ded0d47ef08adbc0ed0bec
diff --git a/tools/test/bin/atomix-gen-config b/tools/test/bin/atomix-gen-config
index c3c89ac..9b6efdd 100755
--- a/tools/test/bin/atomix-gen-config
+++ b/tools/test/bin/atomix-gen-config
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 usage: atomix-gen-config [-h] [-s PARTITION_SIZE] [-n NUM_PARTITIONS]
                          [node_ip] [filename] [node_ip [node_ip ...]]
@@ -158,4 +158,4 @@
     with open(filename, 'w') as f:
       f.write(output)
   else:
-    print output
+    print(output)
diff --git a/tools/test/bin/onos-dist-verify b/tools/test/bin/onos-dist-verify
index b5e997f..f9de74e 100755
--- a/tools/test/bin/onos-dist-verify
+++ b/tools/test/bin/onos-dist-verify
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 usage: onos-dist-verify [-h] [-n PRIMITIVE_NAME] [-p PARALLELISM]
                         [-c OPERATION_COUNT]
@@ -47,7 +47,7 @@
 try:
     import edn_format
 except ImportError:
-    print "No edn_format module found; use 'pip install edn_format'"
+    print("No edn_format module found; use 'pip install edn_format'")
     sys.exit(1)
 
 DEVNULL = open(os.devnull, 'w')
@@ -88,8 +88,8 @@
     node = nodes[0]
     try:
         subprocess.check_call(['onos', node, 'value-test', name, 'set', 'null'])
-    except subprocess.CalledProcessError, e:
-        print "Failed to reset test data"
+    except subprocess.CalledProcessError as e:
+        print("Failed to reset test data")
         sys.exit(1)
 
 
@@ -121,7 +121,7 @@
     try:
         knossos_path = os.environ['KNOSSOS_PATH']
     except KeyError:
-        print "KNOSSOS_PATH is not defined; skipping model checker"
+        print("KNOSSOS_PATH is not defined; skipping model checker")
     else:
         # Create and write a temporary file to be passed to the Knossos model checker.
         with NamedTemporaryFile(mode='w+', delete=False) as f:
@@ -133,12 +133,12 @@
             output = subprocess.check_output(['lein', 'run', '--model', 'cas-register', file_name], cwd=knossos_path)
             result = output.strip().split()[-1]
             if result == 'true':
-                print "\rHistory is linearizable! :-)"
+                print("\rHistory is linearizable! :-)")
                 exitcode = 0
             else:
-                print "\rHistory is not linearizable. :-("
+                print("\rHistory is not linearizable. :-(")
                 exitcode = 1
-        except subprocess.CalledProcessError, e:
+        except subprocess.CalledProcessError as e:
             exitcode = e.returncode
 
         # Remove the temporary file before exiting.
@@ -208,15 +208,14 @@
     def record(self, entry):
         """Records an entry in the history."""
         self.entries.append(entry)
-        print str(entry).strip() + '\r'
+        print(str(entry).strip() + '\r')
 
     def __str__(self):
         return edn_format.dumps([entry.format() for entry in self.entries])
 
 
-class HistoryEntry(object):
+class HistoryEntry(object, metaclass=ABCMeta):
     """History entry."""
-    __metaclass__ = ABCMeta
 
     @abstractmethod
     def format(self):
@@ -258,9 +257,8 @@
         ])
 
 
-class Runnable(object):
+class Runnable(object, metaclass=ABCMeta):
     """Base class for managing the lifecycle of a threaded test process."""
-    __metaclass__ = ABCMeta
 
     def __init__(self):
         self.thread = None
@@ -439,7 +437,7 @@
             try:
                 self.disruptors.append(getattr(self, name))
             except AttributeError:
-                print "Unknown disruptor %s" % (name,)
+                print("Unknown disruptor %s" % (name,))
                 sys.exit(1)
 
     def run(self):
diff --git a/tools/test/bin/onos-distributed-manager b/tools/test/bin/onos-distributed-manager
index 0d3b1c3..22a2da1 100755
--- a/tools/test/bin/onos-distributed-manager
+++ b/tools/test/bin/onos-distributed-manager
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
  Copyright 2017-present Open Networking Foundation
  Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,7 @@
 import subprocess
 import sys
 import os
-from httplib import OK, NOT_FOUND, BAD_REQUEST
+from http.client import OK, NOT_FOUND, BAD_REQUEST
 from subprocess import Popen
 
 from flask import Flask, jsonify, request
@@ -98,7 +98,7 @@
                 file.write(json.dumps(config))
                 file.close()
         except Exception as error:
-            print error
+            print(error)
             sys.exit()
 
     def load_from_file(self):
@@ -115,7 +115,7 @@
         pagereturn += "<br><h3> Status of Added controllers  </h3><br>"
         pagereturn += " Id,&emsp; Ip,&emsp; Port,&emsp; Is Active <br> "
 
-        for key in self.cluster_config["nodes"].keys():
+        for key in list(self.cluster_config["nodes"].keys()):
             pagereturn += self.cluster_config["nodes"][key]["id"] + ",&emsp; " + \
                           self.cluster_config["nodes"][key]["ip"] + ",&emsp; " + \
                           str(self.cluster_config["nodes"][key]["port"]) + ",&emsp; "
diff --git a/tools/test/bin/onos-gen-config b/tools/test/bin/onos-gen-config
index b73df39..e214d2f 100755
--- a/tools/test/bin/onos-gen-config
+++ b/tools/test/bin/onos-gen-config
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 usage: onos-gen-config [-h] [-s PARTITION_SIZE] [-n NUM_PARTITIONS]
                             [filename] [node_ip [node_ip ...]]
@@ -87,7 +87,7 @@
 
     args = parser.parse_args()
     node = args.node
-    print node
+    print(node)
     filename = args.filename
     nodes = get_nodes(args.nodes)
 
@@ -106,4 +106,4 @@
         with open(filename, 'w') as f:
             f.write(output)
     else:
-        print output
+        print(output)
diff --git a/tools/test/bin/onos-gen-default-cluster b/tools/test/bin/onos-gen-default-cluster
index e557eda..dc0522d 100755
--- a/tools/test/bin/onos-gen-default-cluster
+++ b/tools/test/bin/onos-gen-default-cluster
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 usage: onos-gen-default-cluster [-h] [-s PARTITION_SIZE] [-n NUM_PARTITIONS]
                             [filename] [node_ip [node_ip ...]]
@@ -91,4 +91,4 @@
         with open(filename, 'w') as f:
             f.write(output)
     else:
-        print output
+        print(output)
diff --git a/tools/test/bin/onos-generate-activate-all-scenario b/tools/test/bin/onos-generate-activate-all-scenario
index e55758f..5a3b8bf 100755
--- a/tools/test/bin/onos-generate-activate-all-scenario
+++ b/tools/test/bin/onos-generate-activate-all-scenario
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python3
 
 import sys
 
@@ -67,7 +67,7 @@
 if len(sys.argv) > 1:
     app_list_file = sys.argv[1]
 else:
-    print "Usage: onos-generate-activate-all-scenario file-name-of-app-list"
+    print("Usage: onos-generate-activate-all-scenario file-name-of-app-list")
     sys.exit()
 
 with open(app_list_file) as apps:
@@ -90,5 +90,5 @@
 
 scenario = scenario + SCENARIO_FOOTER
 
-print scenario
+print(scenario)
 
diff --git a/tools/test/bin/onos-oecfg b/tools/test/bin/onos-oecfg
index e709ce3..021b668 100755
--- a/tools/test/bin/onos-oecfg
+++ b/tools/test/bin/onos-oecfg
@@ -9,4 +9,4 @@
 APP=onos-app-oecfg
 JAR=$M2_REPO/org/onosproject/$APP/$ONOS_POM_VERSION/$APP-$ONOS_POM_VERSION.jar
 
-java -jar $JAR < $1 | python -mjson.tool
+java -jar $JAR < $1 | python3 -mjson.tool
diff --git a/tools/test/bin/onos-set-up-minimal-apps b/tools/test/bin/onos-set-up-minimal-apps
index 1d450eb..11fa6a4 100755
--- a/tools/test/bin/onos-set-up-minimal-apps
+++ b/tools/test/bin/onos-set-up-minimal-apps
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import subprocess
 import sys
diff --git a/tools/test/bin/onos-start-network b/tools/test/bin/onos-start-network
index e668b8d..86f3468 100755
--- a/tools/test/bin/onos-start-network
+++ b/tools/test/bin/onos-start-network
@@ -36,4 +36,4 @@
 $SCPCMD $ONOS_ROOT/tools/test/topos/* $ONOS_USER@[$OCN]:topos/
 
 echo "Starting Network."
-$SSHCMD -t $ONOS_USER@$OCN sudo python $topo $(env | sort | egrep "^OC[0-9]+" | cut -d= -f2)
+$SSHCMD -t $ONOS_USER@$OCN sudo python3 $topo $(env | sort | egrep "^OC[0-9]+" | cut -d= -f2)
diff --git a/tools/test/scenarios/bin/check-dhcp-netcfg.py b/tools/test/scenarios/bin/check-dhcp-netcfg.py
index c828c84..2786785 100755
--- a/tools/test/scenarios/bin/check-dhcp-netcfg.py
+++ b/tools/test/scenarios/bin/check-dhcp-netcfg.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
@@ -6,7 +6,7 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) < 3:
-    print "usage: find-dhcp-netcfg onos-node name1=value1 ..."
+    print("usage: find-dhcp-netcfg onos-node name1=value1 ...")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -15,7 +15,7 @@
                           ':8181/onos/v1/network/configuration/apps/org.onosproject.dhcp',
                           auth=HTTPBasicAuth('onos', 'rocks'))
 
-print cfgRequest.text
+print(cfgRequest.text)
 
 if cfgRequest.status_code != 200:
     sys.exit(1)
@@ -32,8 +32,8 @@
     value = pair[1]
 
     if dhcp[name] != value:
-        print name + " differs: expected " + value + " but found " + dhcp[name]
-        print cfgJson
+        print(name + " differs: expected " + value + " but found " + dhcp[name])
+        print(cfgJson)
         sys.exit(1)
 
 
diff --git a/tools/test/scenarios/bin/check-masters.py b/tools/test/scenarios/bin/check-masters.py
index dfe4df6..9e68cad 100755
--- a/tools/test/scenarios/bin/check-masters.py
+++ b/tools/test/scenarios/bin/check-masters.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import json
 import subprocess
@@ -6,7 +6,7 @@
 import time
 
 if len(sys.argv) != 2:
-    print "usage: check-masters {node}"
+    print("usage: check-masters {node}")
     sys.exit(1)
 
 node = sys.argv[1]
diff --git a/tools/test/scenarios/bin/create-flow.py b/tools/test/scenarios/bin/create-flow.py
index 9d709a0..a5bf9ba 100755
--- a/tools/test/scenarios/bin/create-flow.py
+++ b/tools/test/scenarios/bin/create-flow.py
@@ -1,5 +1,4 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 import requests
 
 from requests.auth import HTTPBasicAuth
@@ -8,7 +7,7 @@
 
 
 if len(sys.argv) != 6:
-    print "usage: create-flow onos-node name device in-port out-port"
+    print("usage: create-flow onos-node name device in-port out-port")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -47,11 +46,11 @@
                               params=payload)
 
 if flowRequest.status_code != 201:
-    print flowRequest.text
+    print(flowRequest.text)
     sys.exit(1)
 
 location = flowRequest.headers["location"]
-print "@stc " + name + "Location=" + location
+print("@stc " + name + "Location=" + location)
 sys.exit(0)
 
 
diff --git a/tools/test/scenarios/bin/create-intent.py b/tools/test/scenarios/bin/create-intent.py
index 4e5d4f6..aeb2492 100755
--- a/tools/test/scenarios/bin/create-intent.py
+++ b/tools/test/scenarios/bin/create-intent.py
@@ -1,5 +1,4 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 import requests
 
 from requests.auth import HTTPBasicAuth
@@ -8,7 +7,7 @@
 
 
 if len(sys.argv) != 7:
-    print "usage: create-intent onos-node name ingressDevice ingressPort egressDevice egressPort"
+    print("usage: create-intent onos-node name ingressDevice ingressPort egressDevice egressPort")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -38,11 +37,11 @@
                               data=intentJson)
 
 if intentRequest.status_code != 201:
-    print intentRequest.text
+    print(intentRequest.text)
     sys.exit(1)
 
 location = intentRequest.headers["location"]
-print "@stc " + name + "Location=" + location
+print("@stc " + name + "Location=" + location)
 sys.exit(0)
 
 
diff --git a/tools/test/scenarios/bin/delete-netcfg.py b/tools/test/scenarios/bin/delete-netcfg.py
index 6e309c2..410bc47 100755
--- a/tools/test/scenarios/bin/delete-netcfg.py
+++ b/tools/test/scenarios/bin/delete-netcfg.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 
@@ -8,7 +8,7 @@
 
 
 if len(sys.argv) != 3:
-    print "usage: delete-netcfg onos-node config-name"
+    print("usage: delete-netcfg onos-node config-name")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -18,7 +18,7 @@
                               auth=HTTPBasicAuth('onos', 'rocks'))
 
 if intentRequest.status_code != 204:
-    print intentRequest.text
+    print(intentRequest.text)
     sys.exit(1)
 
 sys.exit(0)
diff --git a/tools/test/scenarios/bin/execute-tapi-context-get-call.py b/tools/test/scenarios/bin/execute-tapi-context-get-call.py
index 22b1f27..7ddee28 100755
--- a/tools/test/scenarios/bin/execute-tapi-context-get-call.py
+++ b/tools/test/scenarios/bin/execute-tapi-context-get-call.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
@@ -7,14 +7,14 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) < 3:
-    print "usage: execute-tapi-context-get-call onos-node state"
+    print("usage: execute-tapi-context-get-call onos-node state")
     sys.exit(1)
 
 node = sys.argv[1]
 state = sys.argv[2] #if empty tapi context must be empty, if full it needs to contain all devices and ports
 
 if state != "empty" and len(sys.argv) == 3:
-    print "usage: execute-tapi-context-get-call onos-node full devices links ports"
+    print("usage: execute-tapi-context-get-call onos-node full devices links ports")
     sys.exit(1)
 
 request = 'http://' + node + ':8181/onos/restconf/data/tapi-common:context'
@@ -23,9 +23,9 @@
 if state == "empty":
     uuid = tapiContext['tapi-common:context']['tapi-topology:topology-context']['topology'][0]['uuid']
     if uuid == "":
-        print "empty uuid"
+        print("empty uuid")
         sys.exit(1)
-    print "@stc tapi topology uuid=" + uuid
+    print("@stc tapi topology uuid=" + uuid)
     sys.exit(0)
 
 if state == "full":
@@ -37,11 +37,11 @@
     port_num = 0
     for x in range(dev_num):
         port_num=port_num+len(tapiContext['tapi-common:context']['tapi-topology:topology-context']['topology'][0]['node'][x]['owned-node-edge-point'])
-    print "device\tlink\tport\n%i\t%i\t%i" % (dev_num, directed_link_num/2, port_num)
+    print("device\tlink\tport\n%i\t%i\t%i" % (dev_num, directed_link_num/2, port_num))
     assert devices == dev_num
     assert links == directed_link_num/2
     assert ports == port_num
-    print "Topology infomation checking passed."
+    print("Topology infomation checking passed.")
     sys.exit(0)
 
 sys.exit(1)
diff --git a/tools/test/scenarios/bin/execute-tapi-delete-call.py b/tools/test/scenarios/bin/execute-tapi-delete-call.py
index aa9abfc..f2cfbfe 100755
--- a/tools/test/scenarios/bin/execute-tapi-delete-call.py
+++ b/tools/test/scenarios/bin/execute-tapi-delete-call.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import sys
 import tapiHelper
@@ -6,16 +6,16 @@
 import requests
 
 if len(sys.argv) != 3 and len(sys.argv) != 4:
-    print "usage: execute-tapi-delete-call <onos-node> <deletion-type> [uuid]"
-    print "\t- <onos-node> is onos IP. 'localhost' is invalid."
-    print "\t- <deletion-type> is one of {line, client, both}, which mean line-side deletion, " \
-          "client-side deletion, and all deletion respectively."
-    print "\t- [uuid] is the created service uuid, which is optional. If uuid is empty, " \
-          "all connectivity services with <deletion-type> will be deleted."
-    print "\t  If [uuid] is not empty, and <deletion-type> is 'both', this script doesn't work."
-    print "\t  Otherwise, delete line-side or client-side connectivity with specific uuid."
-    print "For example, if we want to delete all client-side services on local host, the command should be:"
-    print "\t python execute-tapi-delete-call.py 127.0.0.1 client"
+    print("usage: execute-tapi-delete-call <onos-node> <deletion-type> [uuid]")
+    print("\t- <onos-node> is onos IP. 'localhost' is invalid.")
+    print("\t- <deletion-type> is one of {line, client, both}, which mean line-side deletion, " \
+          "client-side deletion, and all deletion respectively.")
+    print("\t- [uuid] is the created service uuid, which is optional. If uuid is empty, " \
+          "all connectivity services with <deletion-type> will be deleted.")
+    print("\t  If [uuid] is not empty, and <deletion-type> is 'both', this script doesn't work.")
+    print("\t  Otherwise, delete line-side or client-side connectivity with specific uuid.")
+    print("For example, if we want to delete all client-side services on local host, the command should be:")
+    print("\t python3 execute-tapi-delete-call.py 127.0.0.1 client")
     sys.exit(1)
 
 
@@ -55,8 +55,8 @@
 #
 def post_deletion(service_uuid, del_request):
     delete_input_json = json.dumps(tapi_deletion_input(service_uuid))
-    print "\nThe json content of deletion operation for connectivity service is \n\t\t%s." % \
-          delete_input_json
+    print("\nThe json content of deletion operation for connectivity service is \n\t\t%s." % \
+          delete_input_json)
     headers = {'Content-type': 'application/json'}
     resp = requests.post(del_request, data=delete_input_json, headers=headers, auth=('onos', 'rocks'))
     if resp.status_code != 200:
@@ -79,7 +79,7 @@
 try:
     services = context["tapi-connectivity:connectivity-context"]["connectivity-service"]
 except KeyError:
-    print "Warning - there is no connectivity service in ONOS (%s)." % node
+    print("Warning - there is no connectivity service in ONOS (%s)." % node)
     sys.exit(0)
 # 3. handle deletion requests according to <deletion-type> and [uuid]
 if serv_uuid is None:
@@ -93,13 +93,13 @@
            ((del_type == "client" or del_type == "both") and tapiHelper.is_dsr_media(sip)):
             json_resp = post_deletion(service["uuid"], delete_request)
             del_num += 1
-            print "Returns json string for deletion operations is\n %s\n" % json_resp
+            print("Returns json string for deletion operations is\n %s\n" % json_resp)
     if del_num == 0:
-        print "Warning - there is no %s-side connectivity servicein ONOS (%s)." % (del_type, node)
+        print("Warning - there is no %s-side connectivity servicein ONOS (%s)." % (del_type, node))
 else:
     # If [uuid] is not empty, check the <deletion-type>
     if del_type == "both":
-        print "Error - The option 'both' is illegal when [uuid] is assigned."
+        print("Error - The option 'both' is illegal when [uuid] is assigned.")
     else:
         is_del = False
         for service in services:
@@ -110,7 +110,7 @@
                    (del_type == "client" and tapiHelper.is_dsr_media(sip)):
                     json_resp = post_deletion(service["uuid"], delete_request)
                     is_del = True
-                    print "Returns json string for deletion operations is\n %s\n" % json_resp
+                    print("Returns json string for deletion operations is\n %s\n" % json_resp)
                     break
         if not is_del:
-            print "Warning - Cannot find %s-side connectivity service with service uuid %s." % (del_type, serv_uuid)
+            print("Warning - Cannot find %s-side connectivity service with service uuid %s." % (del_type, serv_uuid))
diff --git a/tools/test/scenarios/bin/execute-tapi-post-call.py b/tools/test/scenarios/bin/execute-tapi-post-call.py
index f6d419a..a0fe4c7 100755
--- a/tools/test/scenarios/bin/execute-tapi-post-call.py
+++ b/tools/test/scenarios/bin/execute-tapi-post-call.py
@@ -1,16 +1,15 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 import sys
 import tapiHelper
 import json
 
 if len(sys.argv) < 4:
-    print "usage: execute-tapi-post-call <onos-node> <context> <empty> [uuid]."
-    print "\t- If <empty> is \"empty\", it measn that it should be no devices, links or ports"
-    print "\t- Uuid is optional and defaults to empty"
-    print "\t- For example:\n\t\t- line-side connectivity creation: %s\n\t\t- client-side connectivity creation: %s" % \
-          ("python execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service line-side",
-           "python execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service client-side")
+    print("usage: execute-tapi-post-call <onos-node> <context> <empty> [uuid].")
+    print("\t- If <empty> is \"empty\", it measn that it should be no devices, links or ports")
+    print("\t- Uuid is optional and defaults to empty")
+    print("\t- For example:\n\t\t- line-side connectivity creation: %s\n\t\t- client-side connectivity creation: %s" % \
+          ("python3 execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service line-side",
+           "python3 execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service client-side"))
     sys.exit(1)
 
 node = sys.argv[1]
@@ -22,40 +21,40 @@
 else:
     uuid = sys.argv[4]
 # request example:
-# python execute-tapi-post-call.py localhost tapi-common:get-service-interface-point-list empty
+# python3 execute-tapi-post-call.py localhost tapi-common:get-service-interface-point-list empty
 if "get-connectivity-service-list" in context:
     connectivity_request = 'http://' + node + ':8181/onos/restconf/operations/' + context
     tapi_connection = tapiHelper.get_connection(connectivity_request, uuid)
     tapi_connection_json = tapi_connection.json()
-    print tapi_connection_json
+    print(tapi_connection_json)
     if not tapi_connection_json["tapi-connectivity:output"] and empty != "empty":
-       print "No connection was established"
+       print("No connection was established")
        sys.exit(0)
     if empty == "empty":
         if not tapi_connection_json["tapi-connectivity:output"]:
             sys.exit(0)
         else:
-            print "There exist some connectivities!!!"
+            print("There exist some connectivities!!!")
             sys.exit(1)
     if uuid == "":
         # verify empty connection
-        print tapi_connection_json
+        print(tapi_connection_json)
     elif uuid != "":
         # verify correct connection
         servs = tapi_connection_json["tapi-connectivity:output"]["service"]
         for s in range(len(servs)):
             if servs[s]['uuid'] == uuid:
-                print "Find service with uuid %s" % uuid
-                print servs[s]
+                print("Find service with uuid %s" % uuid)
+                print(servs[s])
                 sys.exit(0)
     else:
-        print "Invalid input for 3rd and 4th parameters."
+        print("Invalid input for 3rd and 4th parameters.")
         sys.exit(1)
     sys.exit(0)
 
 # test succeeds by using cmd:
-# python execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service line-side
-# python execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service client-side
+# python3 execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service line-side
+# python3 execute-tapi-post-call.py 127.0.0.1 tapi-connectivity:create-connectivity-service client-side
 if "create-connectivity-service" in context:
     context_request = 'http://' + node + ':8181/onos/restconf/data/tapi-common:context'
     connectivity_request = 'http://' + node + ':8181/onos/restconf/operations/' + context
@@ -65,8 +64,8 @@
         tapi_connection = tapiHelper.create_client_connection(context_request, connectivity_request)
     else:
         raise NotImplementedError("Not Implementation for option %s." % empty)
-    print "\nThe request context is:\t%s." % context
-    print "\nThe return message of the request is:\n\t\t%s " % json.dumps(tapi_connection.json())
+    print("\nThe request context is:\t%s." % context)
+    print("\nThe return message of the request is:\n\t\t%s " % json.dumps(tapi_connection.json()))
     sys.exit(0)
 
 sys.exit(1)
diff --git a/tools/test/scenarios/bin/find-device.py b/tools/test/scenarios/bin/find-device.py
index 430e18a..f222742 100755
--- a/tools/test/scenarios/bin/find-device.py
+++ b/tools/test/scenarios/bin/find-device.py
@@ -1,13 +1,13 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: find-device onos-node name device-id"
+    print("usage: find-device onos-node name device-id")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -15,21 +15,21 @@
 id = sys.argv[3]
 
 deviceRequest = requests.get('http://' + node + ':8181/onos/v1/devices/' +
-                             urllib.quote_plus(id),
+                             urllib.parse.quote_plus(id),
                              auth=HTTPBasicAuth('onos', 'rocks'))
 
 if deviceRequest.status_code != 200:
-    print deviceRequest.text
+    print(deviceRequest.text)
     sys.exit(1)
 
 deviceJson = deviceRequest.json()
 
-print "@stc " + name + "Id=" + deviceJson["id"]
-print "@stc " + name + "Type=" + deviceJson["type"]
-print "@stc " + name + "Available=" + str(deviceJson["available"])
+print("@stc " + name + "Id=" + deviceJson["id"])
+print("@stc " + name + "Type=" + deviceJson["type"])
+print("@stc " + name + "Available=" + str(deviceJson["available"]))
 channelId = deviceJson["annotations"]["channelId"]
 channelIdWords = channelId.split(':')
-print "@stc " + name + "IpAddress=" + channelIdWords[0]
+print("@stc " + name + "IpAddress=" + channelIdWords[0])
 
 sys.exit(0)
 
diff --git a/tools/test/scenarios/bin/find-flow.py b/tools/test/scenarios/bin/find-flow.py
index a2f2e4d..6d68020 100755
--- a/tools/test/scenarios/bin/find-flow.py
+++ b/tools/test/scenarios/bin/find-flow.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
@@ -6,7 +6,7 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: find-flow onos-node name device-id"
+    print("usage: find-flow onos-node name device-id")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -17,7 +17,7 @@
                             auth=HTTPBasicAuth('onos', 'rocks'))
 
 if flowsRequest.status_code != 200:
-    print flowsRequest.text
+    print(flowsRequest.text)
     sys.exit(1)
 
 flowsJson = flowsRequest.json()
@@ -28,9 +28,9 @@
             if criterion["type"] == 'IN_PORT' and criterion["port"] > 0:
                 for instruction in flow["treatment"]["instructions"]:
                     if instruction["port"] > 0 and instruction["type"] == 'OUTPUT':
-                        print "@stc " + name + "FlowState=" + flow["state"]
-                        print "@stc " + name + "FlowId=" + flow["id"]
-                        print "@stc " + name + "FlowPort=" + str(instruction["port"])
+                        print("@stc " + name + "FlowState=" + flow["state"])
+                        print("@stc " + name + "FlowId=" + flow["id"])
+                        print("@stc " + name + "FlowPort=" + str(instruction["port"]))
                         sys.exit(0)
 
 sys.exit(1)
diff --git a/tools/test/scenarios/bin/find-host.py b/tools/test/scenarios/bin/find-host.py
index e87a409..4c3aea5 100755
--- a/tools/test/scenarios/bin/find-host.py
+++ b/tools/test/scenarios/bin/find-host.py
@@ -1,13 +1,12 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: find-host onos-node name device-id"
+    print("usage: find-host onos-node name device-id")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -15,18 +14,18 @@
 id = sys.argv[3]
 
 hostRequest = requests.get('http://' + node + ':8181/onos/v1/hosts/' +
-                           urllib.quote_plus(id),
+                           urllib.parse.quote_plus(id),
                            auth=HTTPBasicAuth('onos', 'rocks'))
 
 if hostRequest.status_code != 200:
-    print hostRequest.text
+    print(hostRequest.text)
     sys.exit(1)
 
 hostJson = hostRequest.json()
 
-print "@stc " + name + "Id=" + hostJson["id"]
-print "@stc " + name + "Mac=" + hostJson["mac"]
-print "@stc " + name + "IpAddress=" + hostJson["ipAddresses"][0]
+print("@stc " + name + "Id=" + hostJson["id"])
+print("@stc " + name + "Mac=" + hostJson["mac"])
+print("@stc " + name + "IpAddress=" + hostJson["ipAddresses"][0])
 
 sys.exit(0)
 
diff --git a/tools/test/scenarios/bin/find-link-in-cluster.py b/tools/test/scenarios/bin/find-link-in-cluster.py
index 928531f..1eb6832 100755
--- a/tools/test/scenarios/bin/find-link-in-cluster.py
+++ b/tools/test/scenarios/bin/find-link-in-cluster.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
@@ -6,7 +6,7 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 9:
-    print "usage: find-link-in-cluster onos-node name cluster-id expected-length src-device-id src-port dst-device-id dst-port"
+    print("usage: find-link-in-cluster onos-node name cluster-id expected-length src-device-id src-port dst-device-id dst-port")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -24,29 +24,29 @@
                             auth=HTTPBasicAuth('onos', 'rocks'))
 
 if linksRequest.status_code != 200:
-    print linksRequest.text
+    print(linksRequest.text)
     sys.exit(1)
 
 linksJson = linksRequest.json()
 linksLength = len(linksJson["links"])
 
 if  linksLength != length:
-    print "Expected length {} but got {}".format(length, linksLength)
+    print("Expected length {} but got {}".format(length, linksLength))
     sys.exit(1)
 
 for link in linksJson["links"]:
     if srcDeviceId == link["src"]["device"] and srcPort == link["src"]["port"]:
         if dstDeviceId == link["dst"]["device"] and dstPort == link["dst"]["port"]:
-            print "@stc " + name + "SrcDevice=" + link["src"]["device"]
-            print "@stc " + name + "SrcPort=" + link["src"]["port"]
-            print "@stc " + name + "DstDevice=" + link["dst"]["device"]
-            print "@stc " + name + "DstPort=" + link["dst"]["port"]
-            print "@stc " + name + "Type=" + link["type"]
-            print "@stc " + name + "State=" + link["state"]
+            print("@stc " + name + "SrcDevice=" + link["src"]["device"])
+            print("@stc " + name + "SrcPort=" + link["src"]["port"])
+            print("@stc " + name + "DstDevice=" + link["dst"]["device"])
+            print("@stc " + name + "DstPort=" + link["dst"]["port"])
+            print("@stc " + name + "Type=" + link["type"])
+            print("@stc " + name + "State=" + link["state"])
             sys.exit(0)
 
-print "Could not find link from {}:{} to {}:{}"\
-    .format(srcDeviceId, srcPort, dstDeviceId, dstPort)
+print("Could not find link from {}:{} to {}:{}"\
+    .format(srcDeviceId, srcPort, dstDeviceId, dstPort))
 sys.exit(1)
 
 
diff --git a/tools/test/scenarios/bin/find-link.py b/tools/test/scenarios/bin/find-link.py
index 9ac6e35..6e83de7 100755
--- a/tools/test/scenarios/bin/find-link.py
+++ b/tools/test/scenarios/bin/find-link.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
@@ -6,7 +6,7 @@
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 7:
-    print "usage: find-link onos-node name src-device-id src-port dst-device-id dst-port"
+    print("usage: find-link onos-node name src-device-id src-port dst-device-id dst-port")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -22,7 +22,7 @@
                             auth=HTTPBasicAuth('onos', 'rocks'))
 
 if linksRequest.status_code != 200:
-    print linksRequest.text
+    print(linksRequest.text)
     sys.exit(1)
 
 linksJson = linksRequest.json()
@@ -30,12 +30,12 @@
 for link in linksJson["links"]:
     if srcDeviceId == link["src"]["device"]:
         if dstDeviceId == link["dst"]["device"]:
-            print "@stc " + name + "SrcDevice=" + link["src"]["device"]
-            print "@stc " + name + "SrcPort=" + link["src"]["port"]
-            print "@stc " + name + "DstDevice=" + link["dst"]["device"]
-            print "@stc " + name + "DstPort=" + link["dst"]["port"]
-            print "@stc " + name + "Type=" + link["type"]
-            print "@stc " + name + "State=" + link["state"]
+            print("@stc " + name + "SrcDevice=" + link["src"]["device"])
+            print("@stc " + name + "SrcPort=" + link["src"]["port"])
+            print("@stc " + name + "DstDevice=" + link["dst"]["device"])
+            print("@stc " + name + "DstPort=" + link["dst"]["port"])
+            print("@stc " + name + "Type=" + link["type"])
+            print("@stc " + name + "State=" + link["state"])
             sys.exit(0)
 
 sys.exit(1)
diff --git a/tools/test/scenarios/bin/find-topo-infrastructure.py b/tools/test/scenarios/bin/find-topo-infrastructure.py
index 6d1970f..de6a271 100755
--- a/tools/test/scenarios/bin/find-topo-infrastructure.py
+++ b/tools/test/scenarios/bin/find-topo-infrastructure.py
@@ -1,13 +1,13 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: find-topo-infrastructure onos-node name connect-point"
+    print("usage: find-topo-infrastructure onos-node name connect-point")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -15,16 +15,16 @@
 id = sys.argv[3]
 
 infrastructureRequest = requests.get('http://' + node + ':8181/onos/v1/topology/infrastructure/' +
-                           urllib.quote_plus(id),
+                           urllib.parse.quote_plus(id),
                            auth=HTTPBasicAuth('onos', 'rocks'))
 
 if infrastructureRequest.status_code != 200:
-    print infrastructureRequest.text
+    print(infrastructureRequest.text)
     sys.exit(1)
 
 infrastructureJson = infrastructureRequest.json()
 
-print "@stc " + name + "Infrastructure=" + str(infrastructureJson["infrastructure"])
+print("@stc " + name + "Infrastructure=" + str(infrastructureJson["infrastructure"]))
 
 sys.exit(0)
 
diff --git a/tools/test/scenarios/bin/mininet-p4-trellis b/tools/test/scenarios/bin/mininet-p4-trellis
index db19cc4..e964d0f 100755
--- a/tools/test/scenarios/bin/mininet-p4-trellis
+++ b/tools/test/scenarios/bin/mininet-p4-trellis
@@ -19,7 +19,7 @@
     echo \"cd ~/routing/trellis && \
         sudo -E env PYTHONPATH=/tmp/bmv2_py STRATUM_ROOT=${stratumRoot} \
             ONOS_WEB_USER=$ONOS_WEB_USER ONOS_WEB_PASS=$ONOS_WEB_PASS \
-        python trellisp4.py --onos-ip $OC1 --agent stratum\" \
+        python3 trellisp4.py --onos-ip $OC1 --agent stratum\" \
     > ${trellisp4Sh} && chmod +x ${trellisp4Sh}
 "
 
diff --git a/tools/test/scenarios/bin/onos-change-device-portstate b/tools/test/scenarios/bin/onos-change-device-portstate
index bc69d98..2dfbc9a 100755
--- a/tools/test/scenarios/bin/onos-change-device-portstate
+++ b/tools/test/scenarios/bin/onos-change-device-portstate
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 
@@ -8,7 +8,7 @@
 
 
 if len(sys.argv) != 5:
-    print "usage: change-device-portstate onos-node device-id port new_enabled_state"
+    print("usage: change-device-portstate onos-node device-id port new_enabled_state")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -23,7 +23,7 @@
                                data=payload)
 
 if change_request.status_code != 200:
-    print change_request.text
+    print(change_request.text)
     sys.exit(1)
 
 sys.exit(0)
diff --git a/tools/test/scenarios/bin/onos-find-and-check-map b/tools/test/scenarios/bin/onos-find-and-check-map
index b419ca1..46daf8c 100755
--- a/tools/test/scenarios/bin/onos-find-and-check-map
+++ b/tools/test/scenarios/bin/onos-find-and-check-map
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # -----------------------------------------------------------------------------
 # Invokes the ONOS CLI and looks for a 'maps' entry with the given name
@@ -9,7 +9,7 @@
 import sys
 
 if len(sys.argv) != 4:
-    print "usage: onos-find-and-check-map onos-node map-name should-be-zero"
+    print("usage: onos-find-and-check-map onos-node map-name should-be-zero")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -23,8 +23,8 @@
     foundMapName = map["name"]
     foundMapSize = map["size"]
 
-    print foundMapName
-    print foundMapSize
+    print(foundMapName)
+    print(foundMapSize)
 
     if foundMapName == mapName:
         if (shouldBeZero == 'yes' and foundMapSize == 0) or \
diff --git a/tools/test/scenarios/bin/post-netcfg.py b/tools/test/scenarios/bin/post-netcfg.py
index 6104f2c..6c3dcbc 100755
--- a/tools/test/scenarios/bin/post-netcfg.py
+++ b/tools/test/scenarios/bin/post-netcfg.py
@@ -1,12 +1,11 @@
-#! /usr/bin/env python
-
+#! /usr/bin/env python3
 import requests
 
 from requests.auth import HTTPBasicAuth
 import sys
 
 if len(sys.argv) != 3:
-    print "usage: post-netcfg onos-node json-file-name"
+    print("usage: post-netcfg onos-node json-file-name")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -20,7 +19,7 @@
                         data=configJson)
 
 if request.status_code != 200:
-    print request.text
+    print(request.text)
     sys.exit(1)
 
 sys.exit(0)
diff --git a/tools/test/scenarios/bin/query-cluster.py b/tools/test/scenarios/bin/query-cluster.py
index 0cac7ac..8d356b3 100755
--- a/tools/test/scenarios/bin/query-cluster.py
+++ b/tools/test/scenarios/bin/query-cluster.py
@@ -1,13 +1,13 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 4:
-    print "usage: query-cluster onos-node name cluster-number"
+    print("usage: query-cluster onos-node name cluster-number")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -19,15 +19,15 @@
                            auth=HTTPBasicAuth('onos', 'rocks'))
 
 if topoRequest.status_code != 200:
-    print topoRequest.text
+    print(topoRequest.text)
     sys.exit(1)
 
 topoJson = topoRequest.json()
 
-print "@stc " + name + "Id=" + str(topoJson["id"])
-print "@stc " + name + "DeviceCount=" + str(topoJson["deviceCount"])
-print "@stc " + name + "LinkCount=" + str(topoJson["linkCount"])
-print "@stc " + name + "Root=" + topoJson["root"]
+print("@stc " + name + "Id=" + str(topoJson["id"]))
+print("@stc " + name + "DeviceCount=" + str(topoJson["deviceCount"]))
+print("@stc " + name + "LinkCount=" + str(topoJson["linkCount"]))
+print("@stc " + name + "Root=" + topoJson["root"])
 
 sys.exit(0)
 
diff --git a/tools/test/scenarios/bin/query-topo.py b/tools/test/scenarios/bin/query-topo.py
index 9b81b4e..9ce89b0 100755
--- a/tools/test/scenarios/bin/query-topo.py
+++ b/tools/test/scenarios/bin/query-topo.py
@@ -1,13 +1,13 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 3:
-    print "usage: query-topo onos-node name"
+    print("usage: query-topo onos-node name")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -17,15 +17,15 @@
                            auth=HTTPBasicAuth('onos', 'rocks'))
 
 if topoRequest.status_code != 200:
-    print topoRequest.text
+    print(topoRequest.text)
     sys.exit(1)
 
 topoJson = topoRequest.json()
 
-print "@stc " + name + "Time=" + str(topoJson["time"])
-print "@stc " + name + "Devices=" + str(topoJson["devices"])
-print "@stc " + name + "Links=" + str(topoJson["links"])
-print "@stc " + name + "Clusters=" + str(topoJson["clusters"])
+print("@stc " + name + "Time=" + str(topoJson["time"]))
+print("@stc " + name + "Devices=" + str(topoJson["devices"]))
+print("@stc " + name + "Links=" + str(topoJson["links"]))
+print("@stc " + name + "Clusters=" + str(topoJson["clusters"]))
 
 sys.exit(0)
 
diff --git a/tools/test/scenarios/bin/tapiHelper.py b/tools/test/scenarios/bin/tapiHelper.py
index 47fdd65..2f227ef 100755
--- a/tools/test/scenarios/bin/tapiHelper.py
+++ b/tools/test/scenarios/bin/tapiHelper.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import requests
 import json
@@ -143,7 +143,7 @@
                 if service["end-point"][id]["service-interface-point"]["service-interface-point-uuid"] == sip_uuid:
                     return True
     except KeyError:
-        print "There is no line-side service in ONOS now."
+        print("There is no line-side service in ONOS now.")
     return False
 
 
@@ -239,7 +239,7 @@
             used_sip_uuids.add(service["end-point"][0]["service-interface-point"]["service-interface-point-uuid"])
             used_sip_uuids.add(service["end-point"][1]["service-interface-point"]["service-interface-point-uuid"])
     except KeyError:
-        print "There is no existed connectivity service inside ONOS."
+        print("There is no existed connectivity service inside ONOS.")
 
     # select the first available line-side service as bridge. If there is no available line-side service,
     # then only create a client-to-client service for src and dst node.
@@ -256,8 +256,8 @@
             if (client_src_sip_uuid not in used_sip_uuids) and (client_dst_sip_uuid not in used_sip_uuids):
                 # If there is no such client-side connection exists
                 # Create new client-side connection directly
-                print "Create client-side connection between %s and %s." % \
-                      (client_src_name["onos-cp"], client_dst_name["onos-cp"])
+                print("Create client-side connection between %s and %s." % \
+                      (client_src_name["onos-cp"], client_dst_name["onos-cp"]))
                 create_input_json = json.dumps(tapi_client_input((client_src_sip_uuid, client_dst_sip_uuid)))
                 resp = requests.post(url_connectivity, data=create_input_json, headers=headers,
                                      auth=('onos', 'rocks'))
@@ -286,10 +286,10 @@
         # None case means all client-side services exist.
         raise AssertionError("There is no available client-side service could be created.")
     else:
-        print "Create client-side services:"
-        print "\t- from %s to %s." % (empty_client_src_name["onos-cp"], empty_client_dst_name["onos-cp"])
-        print "This service should go through:"
-        print "\t- %s and %s." % (empty_src_name["onos-cp"], empty_dst_name["onos-cp"])
+        print("Create client-side services:")
+        print("\t- from %s to %s." % (empty_client_src_name["onos-cp"], empty_client_dst_name["onos-cp"]))
+        print("This service should go through:")
+        print("\t- %s and %s." % (empty_src_name["onos-cp"], empty_dst_name["onos-cp"]))
         create_input_json = json.dumps(tapi_client_input((empty_client_src_sip_uuid, empty_client_dst_sip_uuid)))
         resp = requests.post(url_connectivity, data=create_input_json, headers=headers,
                              auth=('onos', 'rocks'))
@@ -344,16 +344,16 @@
     # select randomly the src_sip_uuid and dst_sip_uuid with same connection id.
     src_onep, dst_onep, src_sip_uuid, dst_sip_uuid = parse_src_dst(topo)
     while is_port_used(src_sip_uuid, context["tapi-common:context"]["tapi-connectivity:connectivity-context"]):
-        print "Conflict occurs between randomly selected line-side link and existed ones."
+        print("Conflict occurs between randomly selected line-side link and existed ones.")
         src_onep, dst_onep, src_sip_uuid, dst_sip_uuid = parse_src_dst(topo)
 
-    print "\nBuild line-side connectivity:\n|Item|SRC|DST|\n|:--|:--|:--|\n|onos-cp|%s|%s|\n|connection id|%s|%s|\n|sip uuid|%s|%s|" % \
+    print("\nBuild line-side connectivity:\n|Item|SRC|DST|\n|:--|:--|:--|\n|onos-cp|%s|%s|\n|connection id|%s|%s|\n|sip uuid|%s|%s|" % \
           (src_onep["name"][2]["value"], dst_onep["name"][2]["value"],
            src_onep["name"][1]["value"], dst_onep["name"][1]["value"],
-           src_sip_uuid, dst_sip_uuid)
+           src_sip_uuid, dst_sip_uuid))
     create_input_json = json.dumps(tapi_line_input((src_sip_uuid, dst_sip_uuid)))
-    print "\nThe json content of creation operation for line-side connectivity service is \n\t\t%s." % \
-          create_input_json
+    print("\nThe json content of creation operation for line-side connectivity service is \n\t\t%s." % \
+          create_input_json)
     headers = {'Content-type': 'application/json'}
     resp = requests.post(url_connectivity, data=create_input_json, headers=headers, auth=('onos', 'rocks'))
     if resp.status_code != 200:
diff --git a/tools/test/scenarios/bin/verify-topo-devices.py b/tools/test/scenarios/bin/verify-topo-devices.py
index be834b9..fb7f929 100755
--- a/tools/test/scenarios/bin/verify-topo-devices.py
+++ b/tools/test/scenarios/bin/verify-topo-devices.py
@@ -1,13 +1,13 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import requests
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from requests.auth import HTTPBasicAuth
 
 if len(sys.argv) != 5:
-    print "usage: verify-topo-links onos-node cluster-id first-index last-index"
+    print("usage: verify-topo-links onos-node cluster-id first-index last-index")
     sys.exit(1)
 
 node = sys.argv[1]
@@ -23,26 +23,26 @@
                            auth=HTTPBasicAuth('onos', 'rocks'))
 
 if topoRequest.status_code != 200:
-    print topoRequest.text
+    print(topoRequest.text)
     sys.exit(1)
 
 topoJson = topoRequest.json()
 
 for deviceIndex in range(first, last+1):
     lookingFor = "of:" + format(deviceIndex, '016x')
-    print lookingFor
+    print(lookingFor)
     for arrayIndex in range(0, len(topoJson["devices"])):
         device = topoJson["devices"][arrayIndex]
         if device == lookingFor:
             found = found + 1
-            print "Match found for " + device
+            print("Match found for " + device)
             break
 
 
 if found == last - first:
     sys.exit(0)
 
-print "Found " + str(found) + " matches, need " + str(last - first)
+print("Found " + str(found) + " matches, need " + str(last - first))
 sys.exit(2)
 
 
diff --git a/tools/test/scenarios/net-odtn-restconf.xml b/tools/test/scenarios/net-odtn-restconf.xml
index cbfba36..549c9b8 100644
--- a/tools/test/scenarios/net-odtn-restconf.xml
+++ b/tools/test/scenarios/net-odtn-restconf.xml
@@ -23,7 +23,7 @@
     <!-- Push the line-side connectivity service request -->
     <group name="Net-ODTN-Restconf.Line-side-test" requires="Net-ODTN-Restconf.Confirm-conn-empty">
       <step name="Net-ODTN-Restconf.Create-line-side" exec="${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py ${OC1} tapi-connectivity:create-connectivity-service line-side"/>
-      <step name="Net-ODTN-Restconf.Check-line-side" requires="Net-ODTN-Restconf.Create-line-side" exec="${ONOS_SCENARIOS}/odtn/checkUntilSucc.sh 'python ${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py+${OC1}+tapi-connectivity:get-connectivity-service-list+empty+|+grep+'tapi-connectivity:output'+|+grep+connection-uuid+-o+|+wc+-l' 1" />
+      <step name="Net-ODTN-Restconf.Check-line-side" requires="Net-ODTN-Restconf.Create-line-side" exec="${ONOS_SCENARIOS}/odtn/checkUntilSucc.sh 'python3 ${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py+${OC1}+tapi-connectivity:get-connectivity-service-list+empty+|+grep+'tapi-connectivity:output'+|+grep+connection-uuid+-o+|+wc+-l' 1" />
       <step name="Net-ODTN-Restconf.Delete-line-conn" requires="Net-ODTN-Restconf.Check-line-side" exec="${ONOS_SCENARIOS}/bin/execute-tapi-delete-call.py ${OC1} line"/>
       <step name="Net-ODTN-Restconf.Confirm-conn-empty-2" requires="Net-ODTN-Restconf.Delete-line-conn" exec="${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py ${OC1} tapi-connectivity:get-connectivity-service-list empty"/>
       <group name="Net-ODTN-Restconf.Verify-Logs" requires="Net-ODTN-Restconf.Confirm-conn-empty-2">
@@ -35,7 +35,7 @@
     <!-- Push the client-side connectivity service request -->
     <group name="Net-ODTN-Restconf.Client-side-test" requires="Net-ODTN-Restconf.Line-side-test" delay="10" >
       <step name="Net-ODTN-Restconf.Create-client-side" exec="${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py ${OC1} tapi-connectivity:create-connectivity-service client-side"/>
-      <step name="Net-ODTN-Restconf.Check-client-side" requires="Net-ODTN-Restconf.Create-client-side" exec="${ONOS_SCENARIOS}/odtn/checkUntilSucc.sh 'python ${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py+${OC1}+tapi-connectivity:get-connectivity-service-list+empty+|+grep+'tapi-connectivity:output'+|+grep+connection-uuid+-o+|+wc+-l' 1" />
+      <step name="Net-ODTN-Restconf.Check-client-side" requires="Net-ODTN-Restconf.Create-client-side" exec="${ONOS_SCENARIOS}/odtn/checkUntilSucc.sh 'python3 ${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py+${OC1}+tapi-connectivity:get-connectivity-service-list+empty+|+grep+'tapi-connectivity:output'+|+grep+connection-uuid+-o+|+wc+-l' 1" />
       <step name="Net-ODTN-Restconf.Delete-client-conn" requires="Net-ODTN-Restconf.Check-client-side" exec="${ONOS_SCENARIOS}/bin/execute-tapi-delete-call.py ${OC1} both"/>
       <step name="Net-ODTN-Restconf.Confirm-conn-empty-3" requires="Net-ODTN-Restconf.Delete-client-conn" exec="${ONOS_SCENARIOS}/bin/execute-tapi-post-call.py ${OC1} tapi-connectivity:get-connectivity-service-list empty"/>
       <group name="Net-ODTN-Restconf.Verify-Logs-2" requires="Net-ODTN-Restconf.Confirm-conn-empty-3">
diff --git a/tools/test/tests/onos-distributed-manager-test b/tools/test/tests/onos-distributed-manager-test
index 029acbf..ac92f46 100755
--- a/tools/test/tests/onos-distributed-manager-test
+++ b/tools/test/tests/onos-distributed-manager-test
@@ -1,7 +1,7 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
 
 import unittest
-from httplib import OK, BAD_REQUEST
+from http.client import OK, BAD_REQUEST
 
 import requests
 import json
diff --git a/tools/test/topos/attcli.py b/tools/test/topos/attcli.py
index 1945320..80bac6f 100644
--- a/tools/test/topos/attcli.py
+++ b/tools/test/topos/attcli.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 """
 CLI for test with AttMplsTopo
diff --git a/tools/test/topos/attmpls.py b/tools/test/topos/attmpls.py
index fedcb6c..b72e711 100644
--- a/tools/test/topos/attmpls.py
+++ b/tools/test/topos/attmpls.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/bmv2-demo.py b/tools/test/topos/bmv2-demo.py
index 949fe0c..ab0e811 100755
--- a/tools/test/topos/bmv2-demo.py
+++ b/tools/test/topos/bmv2-demo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import os
 import sys
@@ -18,13 +18,13 @@
 JUMBO_MTU=9000
 
 if 'ONOS_ROOT' not in os.environ:
-    print "Environment var $ONOS_ROOT not set"
+    print("Environment var $ONOS_ROOT not set")
     exit()
 else:
     ONOS_ROOT = os.environ["ONOS_ROOT"]
     sys.path.append(ONOS_ROOT + "/tools/dev/mininet")
 if 'RUN_PACK_PATH' not in os.environ:
-    print "Environment var $RUN_PACK_PATH not set"
+    print("Environment var $RUN_PACK_PATH not set")
     exit()
 else:
     RUN_PACK_PATH = os.environ["RUN_PACK_PATH"]
@@ -130,14 +130,14 @@
         self.cmd("killall arping")
 
     def describe(self):
-        print "**********"
-        print self.name
-        print "default interface: %s\t%s\t%s" % (
+        print("**********")
+        print(self.name)
+        print("default interface: %s\t%s\t%s" % (
             self.defaultIntf().name,
             self.defaultIntf().IP(),
             self.defaultIntf().MAC()
-        )
-        print "**********"
+        ))
+        print("**********")
 
     def getInfiniteCmdBg(self, cmd, logfile="/dev/null", delay=1):
         return "(while [ -e {} ]; " \
@@ -227,7 +227,7 @@
             }
         }
 
-    print "Writing network config to %s" % TEMP_NETCFG_FILE
+    print("Writing network config to %s" % TEMP_NETCFG_FILE)
     with open(TEMP_NETCFG_FILE, 'w') as tempFile:
         json.dump(netcfg, tempFile, indent=4)
 
@@ -267,7 +267,7 @@
     net.build()
     net.start()
 
-    print "Network started"
+    print("Network started")
 
     # Always generate background pings.
     sleep(3)
@@ -275,7 +275,7 @@
         h1.startPingBg(h2)
         h2.startPingBg(h1)
 
-    print "Background ping started"
+    print("Background ping started")
 
     # Increase the MTU size for INT operation
     if args.pipeconf_id.endswith("int") or args.pipeconf_id.endswith("full"):
@@ -284,22 +284,22 @@
     for h in net.hosts:
         h.startIperfServer()
 
-    print "Iperf servers started"
+    print("Iperf servers started")
 
     if args.bg_traffic:
         sleep(4)
-        print "Starting iperf clients..."
+        print("Starting iperf clients...")
         net.hosts[0].startIperfClient(net.hosts[-1], flowBw="400k",
                                       numFlows=50, duration=10)
 
     generateNetcfg(onosIp, net, args)
 
     if args.netcfg_sleep > 0:
-        print "Waiting %d seconds before pushing config to ONOS..." \
-              % args.netcfg_sleep
+        print("Waiting %d seconds before pushing config to ONOS..." \
+              % args.netcfg_sleep)
         sleep(args.netcfg_sleep)
 
-    print "Pushing config to ONOS..."
+    print("Pushing config to ONOS...")
     call(("%s/onos-netcfg" % RUN_PACK_PATH, onosIp, TEMP_NETCFG_FILE))
 
     if not args.onos_ip:
diff --git a/tools/test/topos/default.py b/tools/test/topos/default.py
index b58b780..5525c92 100644
--- a/tools/test/topos/default.py
+++ b/tools/test/topos/default.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/dual-onos.py b/tools/test/topos/dual-onos.py
index b0b92ed..a6e424a 100644
--- a/tools/test/topos/dual-onos.py
+++ b/tools/test/topos/dual-onos.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 from onosnet import run
 from dual import DualTopo
diff --git a/tools/test/topos/dual.py b/tools/test/topos/dual.py
index d795a37..3240173 100644
--- a/tools/test/topos/dual.py
+++ b/tools/test/topos/dual.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/ectest.py b/tools/test/topos/ectest.py
index 37acfc5..7115bee 100755
--- a/tools/test/topos/ectest.py
+++ b/tools/test/topos/ectest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import json
 
@@ -54,34 +54,34 @@
         return self.__dId
 
     def getControllers(self, name=None):
-        return self.__cmap.values() if not name else self.__cmap.get(name)
+        return list(self.__cmap.values()) if not name else self.__cmap.get(name)
 
     def getSwitches(self, name=None):
-        return self.__smap.values() if not name else self.__smap.get(name)
+        return list(self.__smap.values()) if not name else self.__smap.get(name)
 
     def getHosts(self, name=None):
-        return self.__hmap.values() if not name else self.__hmap.get(name)
+        return list(self.__hmap.values()) if not name else self.__hmap.get(name)
 
     def injectInto(self, net):
         """ Adds available topology info to a supplied Mininet object. """
         # add switches, hosts, then links to mininet object
-        for sw, args in self.__switches.iteritems():
+        for sw, args in self.__switches.items():
             self.__smap[sw] = net.addSwitch(sw, **args)
-        for h, args in self.__hosts.iteritems():
+        for h, args in self.__hosts.items():
             self.__hmap[h] = net.addHost(h, **args)
-        for l, args in self.__links.iteritems():
+        for l, args in self.__links.items():
             src = self.__smap.get(l[0])
             dst = self.__smap.get(l[1])
             net.addLink(src if src else self.__hmap.get(l[0]),
                          dst if dst else self.__hmap.get(l[1]), **args)
         # then controllers
-        for c, args in self.__ctrls.iteritems():
+        for c, args in self.__ctrls.items():
             self.__cmap[c] = net.addController(c, **args)
 
     def start(self):
         """ starts the switches with the correct controller. """
-        map(lambda c: c.start(), self.__cmap.values())
-        map(lambda s: s.start(self.__cmap.values()), self.__smap.values())
+        list(map(lambda c: c.start(), list(self.__cmap.values())))
+        list(map(lambda s: s.start(list(self.__cmap.values())), list(self.__smap.values())))
 
     def build(self, *args):
         """ override for custom topology, similar to Topo """
@@ -193,7 +193,7 @@
 
     # fire everything up
     net.build()
-    map(lambda x: x.start(), domains)
+    list(map(lambda x: x.start(), domains))
 
     # create a minimal copy of the network for configuring LINC.
     cfgnet = Mininet()
@@ -226,7 +226,7 @@
     setLogLevel('info')
     import sys
     if len(sys.argv) < 4:
-        print ("Usage: sudo -E ./ectest.py ctl-set1 ... ctl-set4\n\n",
-                "Where ctl-set are comma-separated controller IP's")
+        print(("Usage: sudo -E ./ectest.py ctl-set1 ... ctl-set4\n\n",
+                "Where ctl-set are comma-separated controller IP's"))
     else:
         setup(sys.argv)
diff --git a/tools/test/topos/fractal.py b/tools/test/topos/fractal.py
index bc5c689..7590144 100755
--- a/tools/test/topos/fractal.py
+++ b/tools/test/topos/fractal.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from mininet.topo import Topo
 
diff --git a/tools/test/topos/geant.py b/tools/test/topos/geant.py
index 6eedd29..25da34e 100644
--- a/tools/test/topos/geant.py
+++ b/tools/test/topos/geant.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/gratuitousArp.py b/tools/test/topos/gratuitousArp.py
index 27af1e9..0fce183 100755
--- a/tools/test/topos/gratuitousArp.py
+++ b/tools/test/topos/gratuitousArp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 import sys
 import os
 import fcntl
@@ -22,14 +22,14 @@
     try:
         sock.bind((intf, socket.SOCK_RAW))
     except:
-        print 'Device does not exist: %s' % intf
+        print('Device does not exist: %s' % intf)
         return
 
     if not ip:
         try:
             ip = getIPAddress(intf)
         except IOError:
-            print 'No IP for %s' % intf
+            print('No IP for %s' % intf)
             return
     packed_ip = pack('!4B', *[int(x) for x in ip.split('.')])
 
diff --git a/tools/test/topos/metro.py b/tools/test/topos/metro.py
index 76f4ed2..0ba7303 100755
--- a/tools/test/topos/metro.py
+++ b/tools/test/topos/metro.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 import json
 
@@ -53,34 +53,34 @@
         return self.__dId
 
     def getControllers(self, name=None):
-        return self.__cmap.values() if not name else self.__cmap.get(name)
+        return list(self.__cmap.values()) if not name else self.__cmap.get(name)
 
     def getSwitches(self, name=None):
-        return self.__smap.values() if not name else self.__smap.get(name)
+        return list(self.__smap.values()) if not name else self.__smap.get(name)
 
     def getHosts(self, name=None):
-        return self.__hmap.values() if not name else self.__hmap.get(name)
+        return list(self.__hmap.values()) if not name else self.__hmap.get(name)
 
     def injectInto(self, net):
         """ Adds available topology info to a supplied Mininet object. """
         # add switches, hosts, then links to mininet object
-        for sw, args in self.__switches.iteritems():
+        for sw, args in self.__switches.items():
             self.__smap[sw] = net.addSwitch(sw, **args)
-        for h, args in self.__hosts.iteritems():
+        for h, args in self.__hosts.items():
             self.__hmap[h] = net.addHost(h, **args)
-        for l, args in self.__links.iteritems():
+        for l, args in self.__links.items():
             src = self.__smap.get(l[0])
             dst = self.__smap.get(l[1])
             net.addLink(src if src else self.__hmap.get(l[0]),
                          dst if dst else self.__hmap.get(l[1]), **args)
         # then controllers
-        for c, args in self.__ctrls.iteritems():
+        for c, args in self.__ctrls.items():
             self.__cmap[c] = net.addController(c, **args)
 
     def start(self):
         """ starts the switches with the correct controller. """
-        map(lambda c: c.start(), self.__cmap.values())
-        map(lambda s: s.start(self.__cmap.values()), self.__smap.values())
+        list(map(lambda c: c.start(), list(self.__cmap.values())))
+        list(map(lambda s: s.start(list(self.__cmap.values())), list(self.__smap.values())))
 
     def build(self, *args):
         """ override for custom topology, similar to Topo """
@@ -216,7 +216,7 @@
 
     # fire everything up
     net.build()
-    map(lambda x: x.start(), domains)
+    list(map(lambda x: x.start(), domains))
 
     # create a minimal copy of the network for configuring LINC.
     cfgnet = Mininet()
@@ -249,7 +249,7 @@
     setLogLevel('info')
     import sys
     if len(sys.argv) < 5:
-        print ("Usage: sudo -E ./metro.py ctl-set1 ... ctl-set4\n\n",
-                "Where ctl-set are comma-separated controller IP's")
+        print(("Usage: sudo -E ./metro.py ctl-set1 ... ctl-set4\n\n",
+                "Where ctl-set are comma-separated controller IP's"))
     else:
         setup(sys.argv)
diff --git a/tools/test/topos/newFuncTopo.py b/tools/test/topos/newFuncTopo.py
index 5edf7f7..c3c6cbcf 100644
--- a/tools/test/topos/newFuncTopo.py
+++ b/tools/test/topos/newFuncTopo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 """
 Custom topology for Mininet
diff --git a/tools/test/topos/obelisk.py b/tools/test/topos/obelisk.py
index fb6ccdb..3e96ee3 100755
--- a/tools/test/topos/obelisk.py
+++ b/tools/test/topos/obelisk.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from mininet.topo import Topo
 
diff --git a/tools/test/topos/obeliskHostCheck.py b/tools/test/topos/obeliskHostCheck.py
index 988e2e5..92bc166 100755
--- a/tools/test/topos/obeliskHostCheck.py
+++ b/tools/test/topos/obeliskHostCheck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys
 import os
@@ -7,10 +7,10 @@
 # TODO: if none given, use OCI
 try:
     onosIp = sys.argv[1]
-    print "Reading hosts view from ONOS node " + onosIp + ":"
+    print("Reading hosts view from ONOS node " + onosIp + ":")
 except Exception as e:
-    print "Error reading ONOS IP arguement"
-    print e
+    print("Error reading ONOS IP arguement")
+    print(e)
 # Grab the json objects from ONOS
 output = os.popen("onos " + onosIp + " \"hosts -j\"" )
 hosts = json.loads( output.read() )
@@ -49,7 +49,7 @@
 
 if hosts or "Error" not in hosts:
     if hosts == []:
-        print "WARNING: There are no hosts discovered"
+        print("WARNING: There are no hosts discovered")
     else:
         for host in hosts:
             mac = None
@@ -73,19 +73,19 @@
                 # Now check if this matches where they should be
                 if mac and device and port:
                     if device != mappings[ str( mac ) ]:
-                        print "The attachment device is incorrect for host " + str( mac ) +\
-                              ". Expected: " + mappings[ str( mac ) ] + "; Actual: " + device
+                        print("The attachment device is incorrect for host " + str( mac ) +\
+                              ". Expected: " + mappings[ str( mac ) ] + "; Actual: " + device)
                         hostAttachment = False
                     if str( port ) != "1":
-                        print "The attachment port is incorrect for host " + str( mac ) +\
-                              ". Expected: 1; Actual: " + str( port)
+                        print("The attachment port is incorrect for host " + str( mac ) +\
+                              ". Expected: 1; Actual: " + str( port))
                         hostAttachment = False
                 else:
                     hostAttachment = False
             except AssertionError as e:
-                print "ERROR: Json object not as expected:"
-                print e
-                print "host object: " + repr( host )
+                print("ERROR: Json object not as expected:")
+                print(e)
+                print("host object: " + repr( host ))
                 hostAttachment = False
 else:
-    print "No hosts json output or \"Error\" in output. hosts = " + repr( hosts )
+    print("No hosts json output or \"Error\" in output. hosts = " + repr( hosts ))
diff --git a/tools/test/topos/onosnet.py b/tools/test/topos/onosnet.py
index adb4a10..223a585 100644
--- a/tools/test/topos/onosnet.py
+++ b/tools/test/topos/onosnet.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 import itertools
 import os
 import signal
@@ -137,7 +137,7 @@
         t -= 1
         sys.stdout.flush()
         sleep(1)
-    print
+    print()
 
 def formatBw( bw ):
     bw = float(bw)
@@ -221,7 +221,7 @@
 
 def run( topo, controllers=None, link=TCLink, autoSetMacs=True):
     if not topo:
-        print 'Need to provide a topology'
+        print('Need to provide a topology')
         exit(1)
 
     args = parse_args()
@@ -230,14 +230,14 @@
         controllers = args.ipAddrs
 
     if not controllers and args.clusterSize < 1:
-        print 'Need to provide a list of controller IPs, or define a cluster size.'
+        print('Need to provide a list of controller IPs, or define a cluster size.')
         exit( 1 )
 
     setLogLevel( 'info' )
 
     if args.clusterSize > 0:
         if 'ONOS_ROOT' not in os.environ:
-            print "Environment var $ONOS_ROOT not set (needed to import onos.py)"
+            print("Environment var $ONOS_ROOT not set (needed to import onos.py)")
             exit( 1 )
         sys.path.append(os.environ["ONOS_ROOT"] + "/tools/dev/mininet")
         from onos import ONOSCluster, ONOSOVSSwitch, ONOSCLI
diff --git a/tools/test/topos/opticalTest.py b/tools/test/topos/opticalTest.py
index 8e316fa..2f94747 100755
--- a/tools/test/topos/opticalTest.py
+++ b/tools/test/topos/opticalTest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 from opticalUtils import MininetOE, LINCSwitch, LINCLink
 from mininet.topo import Topo
@@ -86,8 +86,8 @@
     if len( sys.argv ) >= 2:
         controllers = sys.argv[1:]
     else:
-        print 'Usage:sudo -E python opticalTest.py (<Controller IP>)+'
-        print 'Using localhost...\n'
+        print('Usage:sudo -E python3 opticalTest.py (<Controller IP>)+')
+        print('Using localhost...\n')
         controllers = [ '127.0.0.1' ]
 
     setLogLevel( 'info' )
diff --git a/tools/test/topos/opticalTestBig.py b/tools/test/topos/opticalTestBig.py
index b730c73..888a52d 100755
--- a/tools/test/topos/opticalTestBig.py
+++ b/tools/test/topos/opticalTestBig.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 from opticalUtils import MininetOE, LINCSwitch, LINCLink
 from mininet.topo import Topo
@@ -379,8 +379,8 @@
     if len( sys.argv ) >= 2:
         controllers = sys.argv[1:]
     else:
-        print 'Usage: sudo -E python opticalTestBig.py (<Controller IP>)+'
-        print 'Using localhost...\n'
+        print('Usage: sudo -E python3 opticalTestBig.py (<Controller IP>)+')
+        print('Using localhost...\n')
         controllers = [ '127.0.0.1' ]
 
     setLogLevel( 'info' )
diff --git a/tools/test/topos/opticalUtils.py b/tools/test/topos/opticalUtils.py
index ca01395..6eaf99d 100644
--- a/tools/test/topos/opticalUtils.py
+++ b/tools/test/topos/opticalUtils.py
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-
+#!/usr/bin/python3
 '''
 Notes:
 
@@ -56,7 +55,7 @@
 import json
 import os
 from time import sleep
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 
 from mininet.node import Switch, OVSSwitch, RemoteController
 from mininet.topo import Topo
@@ -87,7 +86,7 @@
                     switch_id += 1
         return dpids_to_ids
     except:
-        print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info())
+        print("Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info()))
         fd.close()
         return None
 
@@ -114,7 +113,7 @@
     annotations.setdefault('name', switch.name)
     configDict[ 'annotations' ] = annotations
     ports = []
-    for port, intf in switch.intfs.items():
+    for port, intf in list(switch.intfs.items()):
         if intf.name == 'lo':
             continue
         portDict = {}
@@ -330,7 +329,7 @@
         self.configDict[ 'annotations' ].setdefault('name', self.name)
         self.configDict[ 'type' ] = self.switchType
         self.configDict[ 'ports' ] = []
-        for port, intf in self.intfs.items():
+        for port, intf in list(self.intfs.items()):
             if intf.name == 'lo':
                 continue
             else:
@@ -358,7 +357,7 @@
             fd.write(command)
             fd.close()
         except:
-            print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info())
+            print("Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info()))
             if fd:
                 fd.close()
 
@@ -553,26 +552,26 @@
         url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip
         time = 0
         # Set up password authentication
-        pw_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
+        pw_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
         pw_mgr.add_password(None, url, LINCSwitch.restUser, LINCSwitch.restPass)
-        handler = urllib2.HTTPBasicAuthHandler(pw_mgr)
-        opener = urllib2.build_opener(handler)
+        handler = urllib.request.HTTPBasicAuthHandler(pw_mgr)
+        opener = urllib.request.build_opener(handler)
         opener.open(url)
-        urllib2.install_opener(opener)
+        urllib.request.install_opener(opener)
         # focus on just checking the state of devices we're interested in
         # expected devices availability map
-        devMap =  dict.fromkeys(map( lambda x: x['uri'], devices ), False)
+        devMap =  dict.fromkeys([x['uri'] for x in devices], False)
         while True:
-            response = json.load(urllib2.urlopen(url))
+            response = json.load(urllib.request.urlopen(url))
             devs = response.get('devices')
 
             # update availability map
             for d in devs:
-                if devMap.has_key(d['id']):
+                if d['id'] in devMap:
                     devMap[d['id']] = d['available']
 
             # Check if all devices we're interested became available
-            if all(devMap.viewvalues()):
+            if all(devMap.values()):
                 break;
 
             if (time >= TIMEOUT):
@@ -612,7 +611,7 @@
             # Annotations hold switch name and latitude/longitude
             devDict = {}
             devDict[ 'type' ] = switch[ 'type' ]
-            devDict.update({k: v for k, v in switch[ 'annotations' ].iteritems() if k in BasicDevConfigKeys})
+            devDict.update({k: v for k, v in switch[ 'annotations' ].items() if k in BasicDevConfigKeys})
             devSubj = switch[ 'uri' ]
             devices[ devSubj ] = { 'basic': devDict }
 
diff --git a/tools/test/topos/regionabc-onos.py b/tools/test/topos/regionabc-onos.py
index f2c8218..9696b57 100644
--- a/tools/test/topos/regionabc-onos.py
+++ b/tools/test/topos/regionabc-onos.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 from onosnet import run
 from regionabc import RegionABC
diff --git a/tools/test/topos/regionabc.py b/tools/test/topos/regionabc.py
index 14aa9e7..be537f5 100644
--- a/tools/test/topos/regionabc.py
+++ b/tools/test/topos/regionabc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
       [1] ----- [3] ----- [5]
diff --git a/tools/test/topos/rftest.py b/tools/test/topos/rftest.py
index 7aba54f..80807c7 100644
--- a/tools/test/topos/rftest.py
+++ b/tools/test/topos/rftest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys
 
@@ -35,6 +35,6 @@
     if len( sys.argv ) > 1:
         controllers = sys.argv[ 1: ]
     else:
-        print 'Usage: rf-test.py <c0 IP> <c1 IP> ...'
+        print('Usage: rf-test.py <c0 IP> <c1 IP> ...')
         exit( 1 )
     run( controllers )
diff --git a/tools/test/topos/rftesttopo.py b/tools/test/topos/rftesttopo.py
index 9b97578..205811a 100644
--- a/tools/test/topos/rftesttopo.py
+++ b/tools/test/topos/rftesttopo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/routinglib.py b/tools/test/topos/routinglib.py
index 6ac0932..c92e52f 100644
--- a/tools/test/topos/routinglib.py
+++ b/tools/test/topos/routinglib.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 """
 Libraries for creating L3 topologies with routing protocols.
@@ -45,7 +45,7 @@
         self.cmd('sysctl net.ipv4.ip_forward=1')
         self.cmd('sysctl net.ipv4.conf.all.rp_filter=0')
 
-        for intf, configs in self.interfaces.items():
+        for intf, configs in list(self.interfaces.items()):
             self.cmd('ip addr flush dev %s' % intf)
             self.cmd( 'sysctl net.ipv4.conf.%s.rp_filter=0' % intf )
             
@@ -99,9 +99,9 @@
         try:
             original_umask = os.umask(0)
             if (not os.path.isdir(QuaggaRouter.logDir)):
-                os.makedirs(QuaggaRouter.logDir, 0777)
+                os.makedirs(QuaggaRouter.logDir, 0o777)
             if (not os.path.isdir(self.runDir)):
-                os.makedirs(self.runDir, 0777)
+                os.makedirs(self.runDir, 0o777)
         finally:
             os.umask(original_umask)
 
@@ -182,8 +182,8 @@
         conf = ConfigurationWriter(self.configFile)
                     
         def getRouterId(interfaces):
-            intfAttributes = interfaces.itervalues().next()
-            print intfAttributes
+            intfAttributes = next(iter(interfaces.values()))
+            print(intfAttributes)
             if isinstance(intfAttributes, list):
                 # Try use the first set of attributes, but if using vlans they might not have addresses
                 intfAttributes = intfAttributes[1] if not intfAttributes[0]['ipAddrs'] else intfAttributes[0]
@@ -236,8 +236,8 @@
         conf = ConfigurationWriter(self.configFile)
             
         def getRouterId(interfaces):
-            intfAttributes = interfaces.itervalues().next()
-            print intfAttributes
+            intfAttributes = next(iter(interfaces.values()))
+            print(intfAttributes)
             if isinstance(intfAttributes, list):
                 # Try use the first set of attributes, but if using vlans they might not have addresses
                 intfAttributes = intfAttributes[1] if not intfAttributes[0]['ipAddrs'] else intfAttributes[0]
@@ -253,7 +253,7 @@
         conf.writeLine('ospf router-id %s' % getRouterId(self.qr.interfaces))
         conf.writeLine('!')
         
-        for name, intf in self.qr.interfaces.items():
+        for name, intf in list(self.qr.interfaces.items()):
             for ip in intf['ipAddrs']:
                 conf.writeLine('network %s area 0' % ip)
             #if intf['ipAddrs'][0].startswith('192.168'):
@@ -409,7 +409,7 @@
 
     @staticmethod
     def generatePeeringAddresses():
-        network = ip_network(u'10.0.%s.0/24' % AutonomousSystem.psIdx)
+        network = ip_network('10.0.%s.0/24' % AutonomousSystem.psIdx)
         AutonomousSystem.psIdx += 1
         
         return ip_interface('%s/%s' % (network[1], network.prefixlen)), \
@@ -456,7 +456,7 @@
         intfs = {}
         
         router = self.routers[1]
-        for i, router in self.routers.items():
+        for i, router in list(self.routers.items()):
         
             #routerName = 'r%i%i' % (self.num, i)
             routerName = 'r%i' % self.num
@@ -465,12 +465,12 @@
                 
             hostName = 'h%i' % self.num
         
-            for j, interface in router.interfaces.items():
+            for j, interface in list(router.interfaces.items()):
                 nativeAddresses = interface.addressesByVlan.pop(None, [])
                 peeringIntf = [{'mac' : '00:00:%02x:00:%02x:%02x' % (self.num, i, j),
                                'ipAddrs' : nativeAddresses}]
                 
-                for vlan, addresses in interface.addressesByVlan.items():
+                for vlan, addresses in list(interface.addressesByVlan.items()):
                     peeringIntf.append({'vlan':vlan,
                                         'mac':'00:00:%02x:%02x:%02x:%02x' % (self.num, vlan, i, j),
                                         'ipAddrs':addresses})
@@ -486,7 +486,7 @@
                 internalIntf = {'ipAddrs' : internalAddresses}
         
                 # This is the configuration of the next interface after all the peering interfaces
-                intfs.update({'%s-eth%s' % (routerName, len(router.interfaces.keys())) : internalIntf})
+                intfs.update({'%s-eth%s' % (routerName, len(list(router.interfaces.keys()))) : internalIntf})
     
             routerNode = topology.addHost(routerName,  
                                   asNum=self.asNum, neighbors=router.neighbors,
@@ -550,15 +550,15 @@
         self.peerIntfConfig = peerIntfConfig
         self.withFpm = withFpm
         self.externalOnos= externalOnos
-        self.internalPeeringSubnet = ip_network(u'1.1.1.0/24')
+        self.internalPeeringSubnet = ip_network('1.1.1.0/24')
         
-        for router in self.routers.values():
+        for router in list(self.routers.values()):
             # Add iBGP sessions to ONOS nodes
             for onosIp in onosIps:
                 router.neighbors.append({'address':onosIp, 'as':asNum, 'port':2000})
                 
             # Add iBGP sessions to other BGP speakers
-            for i, router2 in self.routers.items():
+            for i, router2 in list(self.routers.items()):
                 if router == router2:
                     continue
                 ip = AutonomousSystem.getIthAddress(self.internalPeeringSubnet, 10+i)
@@ -568,7 +568,7 @@
         
         natIp = AutonomousSystem.getLastAddress(self.internalPeeringSubnet)
         
-        for i, router in self.routers.items():
+        for i, router in list(self.routers.items()):
             name = 'bgp%s' % i
             
             ip = AutonomousSystem.getIthAddress(self.internalPeeringSubnet, 10+i)
@@ -580,7 +580,7 @@
                 eth1 = [{ 'mac':'00:00:00:00:00:%02x' % i, 
                          'ipAddrs' : nativeAddresses }]
                 
-                for vlan, addresses in router.interfaces[1].addressesByVlan.items():
+                for vlan, addresses in list(router.interfaces[1].addressesByVlan.items()):
                     eth1.append({'vlan':vlan,
                                 'mac':'00:00:00:%02x:%02x:00' % (i, vlan),
                                 'ipAddrs':addresses})
diff --git a/tools/test/topos/sdnip.py b/tools/test/topos/sdnip.py
index 7739d58..b561111 100755
--- a/tools/test/topos/sdnip.py
+++ b/tools/test/topos/sdnip.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from mininet.cli import CLI
 from mininet.log import setLogLevel
@@ -65,26 +65,26 @@
         numRoutesPerAs = 32
 
         # Add external ASes
-        as1 = BasicAutonomousSystem(1, generateRoutes(u'192.168.1.0/24', numRoutesPerAs))
+        as1 = BasicAutonomousSystem(1, generateRoutes('192.168.1.0/24', numRoutesPerAs))
         AutonomousSystem.addPeering(as1, sdnAs)
         AutonomousSystem.addPeering(as1, sdnAs, router2=3, intf1=2)
         as1.addLink(s5)
         as1.addLink(s6)
         as1.build(self)
         
-        as2 = BasicAutonomousSystem(2, generateRoutes(u'192.168.2.0/24', numRoutesPerAs))
+        as2 = BasicAutonomousSystem(2, generateRoutes('192.168.2.0/24', numRoutesPerAs))
         AutonomousSystem.addPeering(as2, sdnAs)
         AutonomousSystem.addPeering(as2, sdnAs, router2=2)
         as2.addLink(s7)
         as2.build(self)
         
-        as3 = BasicAutonomousSystem(3, generateRoutes(u'192.168.3.0/24', numRoutesPerAs))
+        as3 = BasicAutonomousSystem(3, generateRoutes('192.168.3.0/24', numRoutesPerAs))
         AutonomousSystem.addPeering(as3, sdnAs, router2=2)
         AutonomousSystem.addPeering(as3, sdnAs, router2=3)
         as3.addLink(s8)
         as3.build(self)
         
-        as4 = BasicAutonomousSystem(4, generateRoutes(u'192.168.4.0/24', numRoutesPerAs), numRouters=2)
+        as4 = BasicAutonomousSystem(4, generateRoutes('192.168.4.0/24', numRoutesPerAs), numRouters=2)
         AutonomousSystem.addPeering(as4, sdnAs)
         AutonomousSystem.addPeering(as4, sdnAs, router1=2, router2=3)
         as4.addLink(s9)
diff --git a/tools/test/topos/sol.py b/tools/test/topos/sol.py
index 68f2d40..823fbe6 100755
--- a/tools/test/topos/sol.py
+++ b/tools/test/topos/sol.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 import sys, solar
 topo = solar.Solar(cips=sys.argv[1:])
 topo.run()
diff --git a/tools/test/topos/solar.py b/tools/test/topos/solar.py
index f316162..be3123a 100644
--- a/tools/test/topos/solar.py
+++ b/tools/test/topos/solar.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 from mininet.cli import CLI
 from mininet.net import Mininet
 from mininet.node import RemoteController, OVSKernelSwitch
diff --git a/tools/test/topos/topo b/tools/test/topos/topo
index 854de50..4ba951f 100755
--- a/tools/test/topos/topo
+++ b/tools/test/topos/topo
@@ -7,4 +7,4 @@
 topo=${1:-att-onos.py}
 
 [ -n "$1" ] && shift
-sudo python $topo "$@"
+sudo python3 $topo "$@"
diff --git a/tools/test/topos/tower.py b/tools/test/topos/tower.py
index 22d515b..02d2721 100755
--- a/tools/test/topos/tower.py
+++ b/tools/test/topos/tower.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/uk-onos.py b/tools/test/topos/uk-onos.py
index 2426b4f..5202ee2 100644
--- a/tools/test/topos/uk-onos.py
+++ b/tools/test/topos/uk-onos.py
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-
+#!/usr/bin/python3
 from onosnet import run
 from uk import UkTopo
 
diff --git a/tools/test/topos/uk-region-onos.py b/tools/test/topos/uk-region-onos.py
index 744844d..214d2e8 100644
--- a/tools/test/topos/uk-region-onos.py
+++ b/tools/test/topos/uk-region-onos.py
@@ -1,5 +1,4 @@
-#!/usr/bin/python
-
+#!/usr/bin/python3
 from onosnet import run
 from ukRegion import UkRegionTopo
 
diff --git a/tools/test/topos/uk.py b/tools/test/topos/uk.py
index aabd0b7..9bb5ec7 100644
--- a/tools/test/topos/uk.py
+++ b/tools/test/topos/uk.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 """
diff --git a/tools/test/topos/ukRegion.py b/tools/test/topos/ukRegion.py
index ecbdf6a..af6c76b 100644
--- a/tools/test/topos/ukRegion.py
+++ b/tools/test/topos/ukRegion.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
   Sample network for demonstrating regions (see uk-region.json)
diff --git a/tools/test/topos/vpls.py b/tools/test/topos/vpls.py
index 0be2e68..8b3adf6 100755
--- a/tools/test/topos/vpls.py
+++ b/tools/test/topos/vpls.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from mininet.cli import CLI
 from mininet.node import Link, Host