aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/tools/test/bin
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/tools/test/bin')
-rw-r--r--framework/src/onos/tools/test/bin/find-node.sh32
-rw-r--r--framework/src/onos/tools/test/bin/flow-tester.py45
-rw-r--r--framework/src/onos/tools/test/bin/ogroup-opts58
-rw-r--r--framework/src/onos/tools/test/bin/old.json387
-rwxr-xr-xframework/src/onos/tools/test/bin/onos21
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-archetypes-test21
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-batch17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-apps34
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-bits9
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-components17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-flows15
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-intent24
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-logs60
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-nodes20
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-summary20
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-check-views17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-config57
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-create-intent22
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-die9
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-fetch-logs43
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-fetch-vms11
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-form-cluster32
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-gen-partitions52
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-group90
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-gui9
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-install67
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-intentperf-scrape17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-iterm-cli42
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-iterm-logs42
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-jpenable19
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-kill18
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-list-cells18
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-local7
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-log38
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-log-kill16
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-log-write37
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-mininet69
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-oecfg12
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-patch-vm22
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-bits19
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-bits-through-proxy22
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-keys19
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-test-bits16
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-topos11
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-push-update-bundle27
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-remove-raft-logs14
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-rsdocs9
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-secure-ssh31
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-service55
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-set-controllers17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-show-cell57
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-ssh11
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-stage-apps29
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-start-network17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-topo-cfg14
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-topo-cfg-all15
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-uninstall14
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-untar-and-run24
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-upload-sprites18
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-user-key13
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-verify-cell11
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-wait-for-start28
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-watch17
-rwxr-xr-xframework/src/onos/tools/test/bin/onos-wipe-out9
-rwxr-xr-xframework/src/onos/tools/test/bin/stc23
-rwxr-xr-xframework/src/onos/tools/test/bin/stc-launcher25
-rwxr-xr-xframework/src/onos/tools/test/bin/stl7
67 files changed, 2118 insertions, 0 deletions
diff --git a/framework/src/onos/tools/test/bin/find-node.sh b/framework/src/onos/tools/test/bin/find-node.sh
new file mode 100644
index 00000000..e76a84a6
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/find-node.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+validate_number () {
+ local re="^[0-9]+$"
+ if [[ ! $1 =~ $re ]] ; then
+ return 1
+ fi
+
+ return 0
+}
+
+find_node () {
+ if validate_number $1 ; then
+ # input is a number, try to find if an OC node is defined
+
+ oc_try="OC$1"
+ node=${!oc_try}
+
+ if [ -n "$node" ]; then
+ # node lookup succeeded, return node
+ echo $node
+ else
+ # node lookup failed, return original input
+ echo $1
+ fi
+
+ else
+ echo $1
+ fi
+
+ return 0
+}
diff --git a/framework/src/onos/tools/test/bin/flow-tester.py b/framework/src/onos/tools/test/bin/flow-tester.py
new file mode 100644
index 00000000..d77a861b
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/flow-tester.py
@@ -0,0 +1,45 @@
+import concurrent.futures
+import requests, json
+from optparse import OptionParser
+
+def run(url, request):
+ data = json.dumps(request)
+ r = requests.post(url, data)
+ return r
+
+def runTasks(flowPerDevice, neighbours, url, servers, doJson, remove):
+ # We can use a with statement to ensure threads are cleaned up promptly
+ with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
+ # Start the load operations and mark each future with its URL
+ request = { "flowsPerDevice" : flowPerDevice, "neighbours" : neighbours, "remove" : remove }
+ future_to_url = {executor.submit(run, url % (server), request) for server in servers}
+ for f in concurrent.futures.as_completed(future_to_url):
+ try:
+ response = f.result()
+ server = response.url.split('//')[1].split(':')[0]
+ if (doJson):
+ print (json.dumps({ "server" : server, "elapsed" : response.json()['elapsed'] }))
+ else:
+ print ("%s -> %sms" % (server, response.json()['elapsed']))
+ except Exception as exc:
+ print("Execution failed -> %s" % exc)
+
+if __name__ == "__main__":
+ parser = OptionParser()
+ parser.add_option("-u", "--url", dest="url", help="set the url for the request",
+ default="http://%s:8181/onos/demo/intents/flowTest")
+ parser.add_option("-f", "--flows", dest="flows", help="Number of flows to install per device",
+ default=100, type="int")
+ parser.add_option("-n", "--neighbours", dest="neighs", help="Number of neighbours to communicate to",
+ default=0, type="int")
+ parser.add_option("-s", "--servers", dest="servers", help="List of servers to hit",
+ default=[], action="append")
+ parser.add_option("-r", "--remove", dest="remove", help="Do not remove flows after installation",
+ default=True, action="store_false")
+ parser.add_option("-j", "--json", dest="doJson", help="Print results in json",
+ default=False, action="store_true")
+
+ (options, args) = parser.parse_args()
+ if (len(options.servers) == 0):
+ options.servers.append("localhost")
+ runTasks(options.flows, options.neighs, options.url, options.servers, options.doJson, options.remove)
diff --git a/framework/src/onos/tools/test/bin/ogroup-opts b/framework/src/onos/tools/test/bin/ogroup-opts
new file mode 100644
index 00000000..41842bdd
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/ogroup-opts
@@ -0,0 +1,58 @@
+# Options read by onos-group for help message formatting and sanity checks.
+GOPTS='install kill patch-vm push-keys uninstall'
+
+# Tab completion settings for onos-group.
+function _ogroup-opts () {
+ local cur=${COMP_WORDS[COMP_CWORD]}
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY=( $( compgen -W "${GOPTS} help" -- $cur ) )
+ fi
+}
+
+complete -F _ogroup-opts onos-group
+
+
+# Tab completion settings for stc
+function _stc-opts () {
+ local cur=${COMP_WORDS[COMP_CWORD]}
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY=( $( compgen -W "$(cd $ONOS_ROOT/tools/test/scenarios && ls -1 | sed 's/.xml//g')" -- $cur ) )
+ fi
+}
+
+complete -F _stc-opts stc
+
+
+# Tab completion settings for stl
+function _stl-opts () {
+ local cur=${COMP_WORDS[COMP_CWORD]}
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY=( $( compgen -W "$(cd /tmp/stc && ls -1)" -- $cur ) )
+ elif [ $COMP_CWORD -eq 2 ]; then
+ COMPREPLY=( $( compgen -W "$(cd /tmp/stc/$3 && ls -1)" -- $cur ) )
+ fi
+}
+
+complete -F _stl-opts stl
+
+
+# Tab completion settings for cell
+function _cell-opts () {
+ local cur=${COMP_WORDS[COMP_CWORD]}
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY=( $( compgen -W "$(cd $ONOS_ROOT/tools/test/cells && ls -1)" -- $cur ) )
+ fi
+}
+
+complete -F _cell-opts cell
+
+
+# Tab completion settings for onos-create-app.
+function _ocapp-opts () {
+ local cur=${COMP_WORDS[COMP_CWORD]}
+ if [ $COMP_CWORD -eq 1 ]; then
+ COMPREPLY=( $( compgen -W "bundle ui cli" -- $cur ) )
+ fi
+}
+
+complete -F _ocapp-opts onos-create-app
diff --git a/framework/src/onos/tools/test/bin/old.json b/framework/src/onos/tools/test/bin/old.json
new file mode 100644
index 00000000..713efbf6
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/old.json
@@ -0,0 +1,387 @@
+{
+ "linkConfig": [
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
+ "params": {
+ "nodeName1": "SFO-W10",
+ "nodeName2": "SJC-W10",
+ "numWaves": 80,
+ "port1": 50,
+ "port2": 30
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03",
+ "params": {
+ "nodeName1": "SJC-W10",
+ "nodeName2": "LAX-W10",
+ "numWaves": 80,
+ "port1": 50,
+ "port2": 30
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+ "params": {
+ "nodeName1": "LAX-W10",
+ "nodeName2": "SDG-W10",
+ "numWaves": 80,
+ "port1": 50,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05",
+ "params": {
+ "nodeName1": "SFO-W10",
+ "nodeName2": "MSP-M10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05",
+ "params": {
+ "nodeName1": "SJC-W10",
+ "nodeName2": "MSP-M10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 20
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "nodeName1": "LAX-W10",
+ "nodeName2": "DFW-M10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:04",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "nodeName1": "SDG-W10",
+ "nodeName2": "DFW-M10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 20
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "nodeName1": "MSP-M10",
+ "nodeName2": "DFW-M10",
+ "numWaves": 80,
+ "port1": 30,
+ "port2": 40
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07",
+ "params": {
+ "nodeName1": "MSP-M10",
+ "nodeName2": "CHG-N10",
+ "numWaves": 80,
+ "port1": 40,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08",
+ "params": {
+ "nodeName1": "DFW-M10",
+ "nodeName2": "IAD-M10",
+ "numWaves": 80,
+ "port1": 30,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08",
+ "params": {
+ "nodeName1": "CHG-N10",
+ "nodeName2": "IAD-M10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 30
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09",
+ "params": {
+ "nodeName1": "CHG-N10",
+ "nodeName2": "JFK-M10",
+ "numWaves": 80,
+ "port1": 30,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
+ "params": {
+ "nodeName1": "IAD-M10",
+ "nodeName2": "ATL-S10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 50
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:ff:09",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
+ "params": {
+ "nodeName1": "JFK-M10",
+ "nodeName2": "ATL-S10",
+ "numWaves": 80,
+ "port1": 20,
+ "port2": 20
+ },
+ "type": "wdmLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:01",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": "SFO-R10",
+ "nodeName2": "SFO-W10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:02",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": null,
+ "nodeName2": "SDG-W10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:03",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": "LAX-R10",
+ "nodeName2": "DFW-M10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:04",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": "SDG-R10",
+ "nodeName2": "CHG-N10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:05",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": null,
+ "nodeName2": "JFK-M10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ },
+ {
+ "allowed": true,
+ "nodeDpid1": "00:00:ff:ff:ff:ff:00:06",
+ "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
+ "params": {
+ "bandwidth": 100000,
+ "nodeName1": null,
+ "nodeName2": "ATL-S10",
+ "port1": 2,
+ "port2": 10
+ },
+ "type": "pktOptLink"
+ }
+ ],
+ "switchConfig": [
+ {
+ "allowed": true,
+ "latitude": 37.6,
+ "longitude": 122.3,
+ "name": "SFO-W10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:01",
+ "params": {
+ "numRegen": 0
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 37.3,
+ "longitude": 121.9,
+ "name": "SJC-W10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:02",
+ "params": {
+ "numRegen": 0
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 33.9,
+ "longitude": 118.4,
+ "name": "LAX-W10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:03",
+ "params": {
+ "numRegen": 0
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 32.8,
+ "longitude": 117.1,
+ "name": "SDG-W10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:04",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 44.8,
+ "longitude": 93.1,
+ "name": "MSP-M10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:05",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 32.8,
+ "longitude": 97.1,
+ "name": "DFW-M10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 41.8,
+ "longitude": 120.1,
+ "name": "CHG-N10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:07",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 38.8,
+ "longitude": 77.1,
+ "name": "IAD-M10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:08",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 40.8,
+ "longitude": 73.1,
+ "name": "JFK-M10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:09",
+ "params": {
+ "numRegen": 0
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 33.8,
+ "longitude": 84.1,
+ "name": "ATL-S10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:0A",
+ "params": {
+ "numRegen": 0
+ },
+ "type": "Roadm"
+ },
+ {
+ "allowed": true,
+ "latitude": 32.8,
+ "longitude": 97.1,
+ "name": "DFW-M10",
+ "nodeDpid": "00:00:ff:ff:ff:ff:ff:06",
+ "params": {
+ "numRegen": 3
+ },
+ "type": "Roadm"
+ }
+ ]
+}
diff --git a/framework/src/onos/tools/test/bin/onos b/framework/src/onos/tools/test/bin/onos
new file mode 100755
index 00000000..89197db5
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos
@@ -0,0 +1,21 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS remote command-line client.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+[ "$1" = "-w" ] && shift && onos-wait-for-start $1
+
+[ -n "$1" ] && OCI=$(find_node $1) && shift
+
+if which client 1>/dev/null 2>&1 && [ -z "$ONOS_USE_SSH" ]; then
+ # Use Karaf client only if we can and are allowed to
+ unset KARAF_HOME
+ client -h $OCI -u karaf "$@" 2>/dev/null
+else
+ # Otherwise use raw ssh; strict checking is off for dev environments only
+ ssh -p 8101 -o StrictHostKeyChecking=no $OCI "$@"
+fi
diff --git a/framework/src/onos/tools/test/bin/onos-archetypes-test b/framework/src/onos/tools/test/bin/onos-archetypes-test
new file mode 100755
index 00000000..55f40e76
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-archetypes-test
@@ -0,0 +1,21 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Builds a set of projects using ONOS archetypes.
+# -----------------------------------------------------------------------------
+
+set -e
+
+export AROOT=/tmp/foo
+export ARCHETYPE_OPTS="-DarchetypeGroupId=org.onosproject -DarchetypeVersion=1.3.0-SNAPSHOT"
+
+mkdir -p $AROOT
+for an in api bundle cli ui; do
+ cd $AROOT
+ rm -fr $AROOT/foo-$an
+ mvn archetype:generate $ARCHETYPE_OPTS \
+ -DarchetypeArtifactId=onos-$an-archetype \
+ -DgroupId=org.foo -DartifactId=foo-$an -Dversion=1.0 \
+ -Dpackage=org.foo.$an -DinteractiveMode=false
+ cd $AROOT/foo-$an
+ mvn clean install
+done
diff --git a/framework/src/onos/tools/test/bin/onos-batch b/framework/src/onos/tools/test/bin/onos-batch
new file mode 100755
index 00000000..67864a22
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-batch
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Executes selected set of ONOS commands using the batch mode.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+
+commands="${2:-summary,intents,flows,hosts}"
+
+aux=/tmp/onos-batch.$$
+trap "rm -f $aux" EXIT
+
+echo "$commands" | tr ',' '\n' > $aux
+onos $node -b <$aux
diff --git a/framework/src/onos/tools/test/bin/onos-check-apps b/framework/src/onos/tools/test/bin/onos-check-apps
new file mode 100755
index 00000000..dfd6b4ef
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-apps
@@ -0,0 +1,34 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks whether all and only the ONOS apps configured in ONOS_APPS are active.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux $aux.1 $aux.2 2>/dev/null" EXIT
+
+for attempt in {1..3}; do
+ onos ${1:-$OCI} "onos:apps -s -a" | grep -v /bin/client > $aux
+ cat $aux
+
+ # Normalize the installed apps
+ cut -c7- $aux | grep -v '/bin/client' | cut -d\ -f1 | sort > $aux.1
+
+ # Normalize the expected apps
+ apps=${2:-$ONOS_APPS}
+ apps=${apps:-drivers,openflow}
+ (for app in ${apps//,/ }; do echo org.onosproject.$app; done) | sort > $aux.2
+
+ # Check for differences
+ case ${3:-equals} in
+ equals) diff $aux.1 $aux.2;;
+ includes) [ $(egrep -c -f $aux.2 $aux.1) -eq $(wc -l $aux.2 | sed "s|$aux.2||g") ];;
+ excludes) ! egrep -f $aux.2 $aux.1;;
+ esac
+
+ [ $? -eq 0 ] && exit 0 || sleep 1
+done
+
+exit 1;
diff --git a/framework/src/onos/tools/test/bin/onos-check-bits b/framework/src/onos/tools/test/bin/onos-check-bits
new file mode 100755
index 00000000..0423c342
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-bits
@@ -0,0 +1,9 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks if ONOS bits are available in preparation for install.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+ls -l $ONOS_TAR && cksum $ONOS_TAR
diff --git a/framework/src/onos/tools/test/bin/onos-check-components b/framework/src/onos/tools/test/bin/onos-check-components
new file mode 100755
index 00000000..f4c2df2c
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-components
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks whether all ONOS components are either ACTIVE or DISABLED.
+# -----------------------------------------------------------------------------
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+
+onos ${1:-$OCI} scr:list > $aux
+cat $aux
+grep -q UNSATISFIED $aux && exit 1
+
+if [ -n "$2" ]; then
+ echo "Searching for ACTIVE $2"
+ egrep "ACTIVE.*$2" $aux || exit 1
+fi
+exit 0 \ No newline at end of file
diff --git a/framework/src/onos/tools/test/bin/onos-check-flows b/framework/src/onos/tools/test/bin/onos-check-flows
new file mode 100755
index 00000000..6debebcd
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-flows
@@ -0,0 +1,15 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks ONOS summary data
+# -----------------------------------------------------------------------------
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+
+onos ${1:-$OCI} "onos:flows" > $aux
+cat $aux
+
+let status=0
+grep "PENDING_" $aux && let status=status+1
+
+exit $status \ No newline at end of file
diff --git a/framework/src/onos/tools/test/bin/onos-check-intent b/framework/src/onos/tools/test/bin/onos-check-intent
new file mode 100755
index 00000000..e332dc5b
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-intent
@@ -0,0 +1,24 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks that all intents in the system have a given state.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+target=${1:-$OCI}
+
+echo onos-check-intent: $*
+
+set -x
+for i in {1..10}; do
+ onos $target "onos:intents" | tee $aux
+ ( cat $aux | grep "key=$2" | grep "state=$3" ) && cat $aux && exit 0
+ sleep 1
+done
+
+cat $aux
+exit 1
+
diff --git a/framework/src/onos/tools/test/bin/onos-check-logs b/framework/src/onos/tools/test/bin/onos-check-logs
new file mode 100755
index 00000000..ec1013ab
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-logs
@@ -0,0 +1,60 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks the logs of the remote ONOS instance and makes sure they are clean.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+remote=$ONOS_USER@${1:-$OCI}
+
+LOG=$ONOS_INSTALL_DIR/log/karaf.log*
+
+aux=/tmp/log.$$
+
+if [ "$2" = "old" ]; then
+ ssh $remote "egrep 'ERROR|Exception|Error' $LOG"
+
+else
+ ssh $remote "
+ tac $LOG | awk '
+ BEGIN { off = 0; fail = 0; }
+ / org.apache.karaf.main.lock.SimpleFileLock lock/ {
+ off = 1;
+ exit fail;
+ }
+
+ / ERROR / {
+ if (!off) {
+ print \$0;
+ exc = 0;
+ fail = 1;
+ }
+ }
+ / WARN / {
+ if (!off && exc) {
+ print \$0;
+ exc = 0;
+ }
+ }
+
+ /^[a-zA-Z0-9.]*(Exception|Error)/ {
+ if (!off) {
+ print \$0;
+ exc = 1;
+ fail = 1;
+ }
+ }
+
+ / at / {
+ if (!off) {
+ print \$0;
+ }
+ }
+ END { exit fail; }
+ ' > $aux
+ status=\$?
+ tac $aux && rm $aux
+ exit \$status
+ "
+fi
diff --git a/framework/src/onos/tools/test/bin/onos-check-nodes b/framework/src/onos/tools/test/bin/onos-check-nodes
new file mode 100755
index 00000000..69187b6a
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-nodes
@@ -0,0 +1,20 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks whether all and only the ONOS instances configured active.
+# -----------------------------------------------------------------------------
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux $aux.1 $aux.2 2>/dev/null" EXIT
+
+onos ${1:-$OCI} "onos:nodes" | grep -v /bin/client > $aux
+cat $aux
+
+# Normalize the nodes
+cut -d= -f3 $aux | cut -d: -f1 | sort > $aux.1
+
+# Normalize the expected nodes
+nodes=${2:-$ONOS_INSTANCES}
+(for node in $nodes; do echo $node; done) | sort > $aux.2
+
+# Check for differences
+diff $aux.1 $aux.2
diff --git a/framework/src/onos/tools/test/bin/onos-check-summary b/framework/src/onos/tools/test/bin/onos-check-summary
new file mode 100755
index 00000000..ab7c22dd
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-summary
@@ -0,0 +1,20 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks ONOS summary data
+# -----------------------------------------------------------------------------
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+
+onos ${1:-$OCI} "onos:summary" > $aux
+cat $aux
+
+let status=0
+grep -q "nodes=${2:-.*}" $aux || let status=status+1
+grep -q "devices=${3:-.*}" $aux || let status=status+1
+grep -q "links=${4:-.*}" $aux || let status=status+1
+grep -q "hosts=${5:-.*}" $aux || let status=status+1
+grep -q "flows=${6:-.*}" $aux || let status=status+1
+grep -q "intents=${7:-.*}" $aux || let status=status+1
+
+exit $status \ No newline at end of file
diff --git a/framework/src/onos/tools/test/bin/onos-check-views b/framework/src/onos/tools/test/bin/onos-check-views
new file mode 100755
index 00000000..421de907
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-check-views
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Checks whether all and only the ONOS apps configured in ONOS_APPS are active.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+
+onos ${1:-$OCI} "onos:ui-views" > $aux
+cat $aux
+
+[ $# -gt 0 ] && shift
+
+grep "${@:-topo}" $aux \ No newline at end of file
diff --git a/framework/src/onos/tools/test/bin/onos-config b/framework/src/onos/tools/test/bin/onos-config
new file mode 100755
index 00000000..5c3ab024
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-config
@@ -0,0 +1,57 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely configures & starts ONOS for the first time.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
+
+# ONOS boot features
+export ONOS_BOOT_FEATURES="${ONOS_BOOT_FEATURES:-webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui}"
+
+# ONOS builtin apps and providers ignited by default
+export ONOS_APPS="${ONOS_APPS:-drivers,openflow}"
+
+# Generate a cluster.json from the ON* environment variables
+CDEF_FILE=/tmp/${remote}.cluster.json
+echo "{ \"ipPrefix\": \"$ONOS_NIC\"," > $CDEF_FILE
+echo " \"nodes\":[" >> $CDEF_FILE
+for node in $(env | sort | egrep "OC[2-9]+" | cut -d= -f2); do
+ echo " { \"id\": \"$node\", \"ip\": \"$node\", \"tcpPort\": 9876 }," >> $CDEF_FILE
+done
+echo " { \"id\": \"$OC1\", \"ip\": \"$OC1\", \"tcpPort\": 9876 }" >> $CDEF_FILE
+echo "]}" >> $CDEF_FILE
+scp -q $CDEF_FILE $remote:$ONOS_INSTALL_DIR/config/cluster.json
+
+ssh $remote "
+ echo \"onos.ip = \$(sudo ifconfig | grep $ONOS_NIC | cut -d: -f2 | cut -d\\ -f1)\" \
+ >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/system.properties
+
+ # Drop copycat related log level for the console
+ echo "log4j.logger.net.kuujo.copycat= INFO" \
+ >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.ops4j.pax.logging.cfg
+
+ # Patch the Apache Karaf distribution file to load ONOS boot features
+ perl -pi.old -e \"s|^(featuresBoot=.*,management)(,webconsole,.*)|\1,$ONOS_BOOT_FEATURES|\" \
+ $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.apache.karaf.features.cfg
+
+ # Customize which builtin apps should be ignited
+ for app in $(echo $ONOS_APPS | tr ',' ' '); do
+ touch $ONOS_INSTALL_DIR/apps/org.onosproject.\$app/active
+ done
+"
+
+# Generate a default tablets.json from the ON* environment variables
+TDEF_FILE=/tmp/${remote}.tablets.json
+onos-gen-partitions $TDEF_FILE
+scp -q $TDEF_FILE $remote:$ONOS_INSTALL_DIR/config/tablets.json
+
+# Copy tools/package/config/ to remote
+scp -qr ${ONOS_ROOT}/tools/package/config/ $remote:$ONOS_INSTALL_DIR/
+
+# Copy the desired initial network configuration to remote if needed
+[ -n "$ONOS_CFG" -a -f "$ONOS_CFG" -a "${1:-$OCI}" = "$OC1" ] && \
+ scp $ONOS_CFG $remote:$ONOS_INSTALL_DIR/config/network-cfg.json
diff --git a/framework/src/onos/tools/test/bin/onos-create-intent b/framework/src/onos/tools/test/bin/onos-create-intent
new file mode 100755
index 00000000..d1c0b93d
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-create-intent
@@ -0,0 +1,22 @@
+#!/bin/bash
+#! usage: onos-create-intent target-onos-instance name point deviceId1 deviceId2
+#! onos-create-intent target-onos-instance name host hostId1 hostId2
+# -----------------------------------------------------------------------------
+# Installs a new intent using the ONOS CLI
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+aux=/tmp/stc-$$.log
+trap "rm -f $aux 2>/dev/null" EXIT
+target=$1
+name=$2
+type=$3
+arg1=$4
+arg2=$5
+
+set -x
+
+onos $target "onos:add-${type}-intent" --key $name "${arg1}" "${arg2}"
+
diff --git a/framework/src/onos/tools/test/bin/onos-die b/framework/src/onos/tools/test/bin/onos-die
new file mode 100755
index 00000000..9da768e8
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-die
@@ -0,0 +1,9 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely kills and stops the ONOS service on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+onos-kill "${1:-$OCI}" && onos-service "${1:-$OCI}" stop
diff --git a/framework/src/onos/tools/test/bin/onos-fetch-logs b/framework/src/onos/tools/test/bin/onos-fetch-logs
new file mode 100755
index 00000000..a4d7ffee
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-fetch-logs
@@ -0,0 +1,43 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Collect ONOS logs from a single node or the current ONOS cell.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+function print_usage {
+ command_name=`basename $0`
+ echo "Collect ONOS logs from a single node or the current ONOS cell."
+ echo
+ echo "Usage: $command_name <TARGET> "
+ echo " $command_name [-h | --help]"
+ echo "Options:"
+ echo " TARGET The target of the command"
+ echo " [-h | --help] Print this help"
+ echo ""
+ echo "TARGET: <hostname | --cell>"
+ echo " hostname Execute on the specified host name"
+ echo " --cell Execute on the current ONOS cell"
+ echo ""
+}
+
+# Print usage
+if [ "${1}" = "-h" -o "${1}" = "--help" ]; then
+ print_usage
+ exit 0
+fi
+
+# Select the target
+if [ "${1}" = "--cell" ]; then
+ nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+else
+ nodes=${1:-$OCI}
+fi
+
+# Execute the remote commands
+for node in $nodes; do
+ echo "fetching from ${node}..."
+ mkdir -p ${node}
+ scp -p $ONOS_USER@${node}:$ONOS_INSTALL_DIR/log/karaf.log* ./${node}/
+done
diff --git a/framework/src/onos/tools/test/bin/onos-fetch-vms b/framework/src/onos/tools/test/bin/onos-fetch-vms
new file mode 100755
index 00000000..567f7f5b
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-fetch-vms
@@ -0,0 +1,11 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely fetches the ONOS test VMs from a local share into ~/Downloads.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+mkdir -p /tmp/onos
+mount -t smbfs smb://guest:@10.254.1.15/onos /tmp/onos
+cp /tmp/onos/onos*.ova ~/Downloads
diff --git a/framework/src/onos/tools/test/bin/onos-form-cluster b/framework/src/onos/tools/test/bin/onos-form-cluster
new file mode 100755
index 00000000..daca34cc
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-form-cluster
@@ -0,0 +1,32 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Forms ONOS cluster using REST API.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+# Scan arguments for user/password or other options...
+while getopts u:p: o; do
+ case "$o" in
+ u) user=$OPTARG;;
+ p) password=$OPTARG;;
+ esac
+done
+user=${user:-onos} # user defaults to 'onos'
+password=${password:-$user} # password defaults to user name if not specified
+let OPC=$OPTIND-1
+shift $OPC
+
+node=${1:-$OCI}
+
+if [ $node = "cell" ]; then
+ nodes=${ONOS_INSTANCES}
+ node=${OCI}
+else
+ nodes="$@"
+fi
+
+set -x
+
+ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-form-cluster -u $user -p $password $nodes
diff --git a/framework/src/onos/tools/test/bin/onos-gen-partitions b/framework/src/onos/tools/test/bin/onos-gen-partitions
new file mode 100755
index 00000000..a2558392
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-gen-partitions
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+'''
+ Generate the partitions json file from the $OC* environment variables
+
+ Usage: onos-gen-partitions [output file]
+ If output file is not provided, the json is written to stdout.
+'''
+
+from os import environ
+from collections import deque, OrderedDict
+import re
+import json
+import sys
+
+convert = lambda text: int(text) if text.isdigit() else text.lower()
+alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
+
+def get_OC_vars():
+ vars = []
+ for var in environ:
+ if re.match(r"OC[0-9]+", var):
+ vars.append(var)
+ return sorted(vars, key=alphanum_key)
+
+def get_nodes(vars, port=9876):
+ node = lambda k: { 'id': k, 'ip': k, 'tcpPort': port }
+ return [ node(environ[v]) for v in vars ]
+
+def generate_permutations(nodes, k):
+ l = deque(nodes)
+ perms = {}
+ for i in range(1, len(nodes)+1):
+ perms['p%d' % i] = list(l)[:k]
+ l.rotate(-1)
+ return OrderedDict(sorted(perms.iteritems(), key=lambda (k, v): alphanum_key(k)))
+
+if __name__ == '__main__':
+ vars = get_OC_vars()
+ nodes = get_nodes(vars)
+ partitions = generate_permutations(nodes, 3)
+ data = {
+ 'nodes': nodes,
+ 'partitions': partitions
+ }
+ output = json.dumps(data, indent=4)
+
+ if len(sys.argv) == 2:
+ filename = sys.argv[1]
+ with open(filename, 'w') as f:
+ f.write(output)
+ else:
+ print output
diff --git a/framework/src/onos/tools/test/bin/onos-group b/framework/src/onos/tools/test/bin/onos-group
new file mode 100755
index 00000000..150f9470
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-group
@@ -0,0 +1,90 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Allows a select group of commands to be sent to all ONOS instances in a cell.
+# -----------------------------------------------------------------------------
+
+set -o pipefail
+IFS=$'\n'
+
+source ogroup-opts
+
+function err() {
+ printf '%s: %s: %s\n' "$(basename $0)" "$1" "$2" >&2
+ usage >&2
+ exit 1
+}
+
+function usage() {
+cat << EOF
+
+usage: $(basename $0) <help|[command]>
+
+Sends a command to all ONOS instances in the current cell. Currently supported
+commands are: $GOPTS
+
+options:
+ [command] : A command to send to the instances.
+ help : Displays this message and exits.
+
+notes:
+ Hitting <TAB> will display the options for $(basename $0).
+
+EOF
+}
+
+# gets the utility name
+function getcmd() {
+ # check that utility can be run in "batch-mode"
+ local isgopt=false
+ for c in $(printf '%s' "$GOPTS" | tr ' ' $'\n'); do
+ [ "$c" = "$1" ] && isgopt=true && break
+ done
+ if $isgopt ; then
+ printf 'onos-%s' "$1"
+ else
+ err 'unsupported command' "$1"
+ fi
+}
+
+# early sanity check for instances/arguments
+[ -z "$1" ] && usage && exit 0
+
+OCIS=( $(env | sed -ne 's:OC[0-9]\{1,\}=\(.*\):\1 :g p' | sort -k1) )
+if [ -z "$OCIS" ]; then
+ printf "no controller instances, quitting early" >&2 && exit 0
+fi
+
+CMD_HELP=false
+while [ $# -gt 0 ]; do
+ case "$1" in
+ 'help')
+ usage && exit 0
+ ;;
+ '-'?)
+ err 'invalid flag' "$1" && exit 1
+ ;;
+ *)
+ cmd=$(getcmd $1) || exit 1
+ shift
+ # grab flags aimed at the utility being called.
+ argv=( $@ )
+ args=()
+ for i in "${!argv[@]}"; do
+ # 'help' is a parameter for us; '-h' is for the command
+ [ "${argv[$i]}" = 'help' ] && break
+ [ "${argv[$i]}" = '-h' ] && CMD_HELP=true
+ args[$i]="${argv[$i]}"
+ shift
+ done
+ continue
+ ;;
+ esac
+ shift
+done
+
+( $CMD_HELP ) && $cmd '-h' && exit 0
+
+# TODO: verbose-mode and cleanup
+for i in ${OCIS[@]}; do
+ ${cmd} $(echo ${args[@]}) "$i" 2>/dev/null &
+done
diff --git a/framework/src/onos/tools/test/bin/onos-gui b/framework/src/onos/tools/test/bin/onos-gui
new file mode 100755
index 00000000..517ed11b
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-gui
@@ -0,0 +1,9 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Launches ONOS GUI on the specified node.
+# -----------------------------------------------------------------------------
+
+host=${1:-$OCI}
+host=${host:-localhost}
+
+open http://$host:8181/onos/ui
diff --git a/framework/src/onos/tools/test/bin/onos-install b/framework/src/onos/tools/test/bin/onos-install
new file mode 100755
index 00000000..0f4cc9dd
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-install
@@ -0,0 +1,67 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely pushes bits to a remote node and installs ONOS on it.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+while getopts fnm: o; do
+ case "$o" in
+ f) uninstall=true;;
+ n) nostart=true;;
+ m) mvn_settings=$OPTARG;;
+ esac
+done
+let OPC=$OPTIND-1
+shift $OPC
+
+# If the -f was given, attempt uninstall first.
+[ -n "$uninstall" ] && onos-uninstall ${1:-$OCI}
+
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
+
+$(dirname $0)/onos-push-bits $node
+
+[ ! -z "$mvn_settings" ] && scp -q $mvn_settings $remote:/tmp/settings.xml
+
+ssh $remote "
+ [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1
+
+ # Prepare a landing zone and unroll the bits
+ sudo mkdir -p $ONOS_INSTALL_DIR && sudo chown ${ONOS_USER}:${ONOS_GROUP} $ONOS_INSTALL_DIR
+ tar zxmf /tmp/$ONOS_BITS.tar.gz -C $ONOS_INSTALL_DIR --strip-components=1
+
+ # Make a link to the log file directory and make a home for auxiliaries
+ ln -s $ONOS_INSTALL_DIR/$KARAF_DIST/data/log /opt/onos/log
+ mkdir $ONOS_INSTALL_DIR/var
+ mkdir $ONOS_INSTALL_DIR/config
+
+ # create dir for Raft log
+ # TODO: use $KARAF_DATA
+ mkdir -p -- $ONOS_INSTALL_DIR/$KARAF_DIST/data/raft
+
+ # Install the upstart configuration file and setup options for debugging
+ [ -z "$nostart" ] && sudo cp $ONOS_INSTALL_DIR/debian/onos.conf /etc/init/onos.conf
+ echo 'export ONOS_OPTS=debug' > $ONOS_INSTALL_DIR/options
+
+ # Setup correct user to run onos-service
+ echo 'export ONOS_USER="${ONOS_USER:-sdn}"' >> $ONOS_INSTALL_DIR/options
+
+ # Remove any previous ON.Lab bits from ~/.m2 repo.
+ rm -fr ~/.m2/repository/org/onosproject
+
+ [ ! -z "$mvn_settings" ] && cp /tmp/settings.xml ~/.m2/settings.xml
+
+ # Drop log level for the console
+ echo "log4j.logger.org.apache.sshd = WARN" \
+ >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.ops4j.pax.logging.cfg
+
+"
+
+# Configure the ONOS installation
+onos-config $node
+
+# Unless -n option was given, attempt to ignite the ONOS service.
+[ -z "$nostart" ] && onos-service $node start
diff --git a/framework/src/onos/tools/test/bin/onos-intentperf-scrape b/framework/src/onos/tools/test/bin/onos-intentperf-scrape
new file mode 100755
index 00000000..8d698b1a
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-intentperf-scrape
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Scrapes intent performance numbers from the remote ONOS log file.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+
+for node in $nodes; do
+ echo "fetching from ${node}..."
+ ssh $ONOS_USER@${node} "
+ grep 'Throughput: OVERALL=' $ONOS_INSTALL_DIR/log/karaf.log \
+ | sed 's/ | INFO .*\: OVERALL=/|/;s/\; INSTALL_REQ=.*//;s/\; CURRENT=/|/' | cut -c12-
+ " > ${node}.perf.log
+done
diff --git a/framework/src/onos/tools/test/bin/onos-iterm-cli b/framework/src/onos/tools/test/bin/onos-iterm-cli
new file mode 100755
index 00000000..85cee831
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-iterm-cli
@@ -0,0 +1,42 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Test utility to spawn an iTerm window for testing against current cell.
+#-------------------------------------------------------------------------------
+
+cellName=$ONOS_CELL
+nodeCount=$(env | egrep "OC[0-9]+" | wc -l | tr -d ' ')
+
+osascript -e "
+tell application \"iTerm\"
+
+ set cellName to \"$cellName\"
+ set paneCount to $nodeCount
+
+ set theTerm to (make new terminal)
+
+ tell theTerm
+ set number of columns to 292
+ set number of rows to 24
+ launch session \"Default\"
+ tell the current session
+ set name to \"ONOS Shell 1\"
+ write text \"cell \" & cellName
+ write text \"oi 1 && clear && echo Node \$OCI\"
+ end tell
+ end tell
+
+ tell theTerm
+ repeat with thePane from 2 to paneCount
+ tell the current session
+ tell application \"System Events\" to keystroke \"d\" using command down
+ set name to \"ONOS Shell \" & thePane
+ write text \"cell \" & cellName
+ write text \"oi \" & thePane & \" && clear && echo Node \$OCI\"
+ end tell
+ end repeat
+ end tell
+
+ tell application \"System Events\" to keystroke \"I\" using command down
+
+end tell
+"
diff --git a/framework/src/onos/tools/test/bin/onos-iterm-logs b/framework/src/onos/tools/test/bin/onos-iterm-logs
new file mode 100755
index 00000000..b160c6e0
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-iterm-logs
@@ -0,0 +1,42 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# Test utility to spawn an iTerm window for monitoring logs of current cell.
+#-------------------------------------------------------------------------------
+
+cellName=$ONOS_CELL
+nodeCount=$(env | egrep "OC[0-9]+" | wc -l | tr -d ' ')
+
+osascript -e "
+tell application \"iTerm\"
+
+ set cellName to \"$cellName\"
+ set paneCount to $nodeCount
+
+ set theTerm to (make new terminal)
+
+ tell theTerm
+ set number of columns to 292
+ set number of rows to 64
+ launch session \"Default\"
+ tell the current session
+ set name to \"ONOS Log 1\"
+ write text \"cell \" & cellName
+ write text \"oi 1 && clear && echo Node \$OCI && ol\"
+ end tell
+ end tell
+
+ tell theTerm
+ repeat with thePane from 2 to paneCount
+ tell the current session
+ tell application \"System Events\" to keystroke \"D\" using command down
+ set name to \"ONOS Log \" & thePane
+ write text \"cell \" & cellName
+ write text \"oi \" & thePane & \" && clear && echo Node \$OCI && ol\"
+ end tell
+ end repeat
+ end tell
+
+ tell application \"System Events\" to keystroke \"I\" using command down
+
+end tell
+"
diff --git a/framework/src/onos/tools/test/bin/onos-jpenable b/framework/src/onos/tools/test/bin/onos-jpenable
new file mode 100755
index 00000000..ba3492ae
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-jpenable
@@ -0,0 +1,19 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely instruments the ONOS JVM for profiling with jprofiler.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+export JPROFILER_ROOT=${JPROFILER_ROOT:-/opt/jprofiler8}
+
+ssh $ONOS_USER@${1:-$OCI} "
+ pid=\$(ps -ef | grep karaf.jar | grep -v grep | cut -c10-15 | tr -d ' ')
+ if [ -n \"\$pid\" ]; then
+ echo \"Enabling profiling for ONOS process \$pid on \$(hostname)...\"
+ $JPROFILER_ROOT/bin/jpenable --gui --pid=\$pid --port=8849
+ else
+ echo \"ONOS process is not running...\"
+ exit 1
+ fi
+"
diff --git a/framework/src/onos/tools/test/bin/onos-kill b/framework/src/onos/tools/test/bin/onos-kill
new file mode 100755
index 00000000..47e5360b
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-kill
@@ -0,0 +1,18 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely kills the ONOS service on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+ssh $ONOS_USER@${1:-$OCI} "
+ pid=\$(ps -ef | grep karaf.jar | grep -v grep | cut -c10-15 | tr -d ' ')
+ if [ -n \"\$pid\" ]; then
+ echo \"Killing ONOS process \$pid on \$(hostname)...\"
+ kill -9 \$pid
+ else
+ echo \"ONOS process is not running...\"
+ exit 1
+ fi
+"
diff --git a/framework/src/onos/tools/test/bin/onos-list-cells b/framework/src/onos/tools/test/bin/onos-list-cells
new file mode 100755
index 00000000..39a70ee9
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-list-cells
@@ -0,0 +1,18 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# List available ONOS cells configuration.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+# Lists available cells
+for cell in $(ls -1 $ONOS_ROOT/tools/test/cells); do
+ if [ ${cell} = "${ONOS_CELL}" ]; then
+ cell_id="${cell} *"
+ else
+ cell_id="${cell}"
+ fi
+ cell_descr="$(grep '^#' $ONOS_ROOT/tools/test/cells/$cell | head -n 1)"
+ printf "%-12s %s\n" "${cell_id}" "${cell_descr}"
+done
diff --git a/framework/src/onos/tools/test/bin/onos-local b/framework/src/onos/tools/test/bin/onos-local
new file mode 100755
index 00000000..acf090c8
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-local
@@ -0,0 +1,7 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS local karaf server start.
+# -----------------------------------------------------------------------------
+
+unset KARAF_HOME
+karaf "$@" \ No newline at end of file
diff --git a/framework/src/onos/tools/test/bin/onos-log b/framework/src/onos/tools/test/bin/onos-log
new file mode 100755
index 00000000..fe89f6dd
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-log
@@ -0,0 +1,38 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Monitors remote ONOS log file on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+less=0
+[ "$1" = "-l" ] && shift && less=1
+
+remote=$(find_node $1)
+
+remote=$ONOS_USER@${remote:-$OCI}
+instance=$2
+
+pattern=$3
+
+[ -n "$instance" -a "$instance" != "-" ] && \
+ LOG=$ONOS_INSTALL_DIR/$KARAF_DIST/instances/$instance/data/log/karaf.log || \
+ LOG=$ONOS_INSTALL_DIR/log/karaf.log
+
+
+if [ $less -eq 1 ]; then
+ ssh -t $remote "less $LOG"
+elif [ -n "$pattern" ]; then
+ ssh $remote "grep $LOG -Ee \"$pattern\""
+else
+ ssh -t $remote "
+ while true; do
+ echo ==================================================================
+ [ ! -f $LOG ] && sleep 2 && continue
+ [ \$(uname) = "Darwin" ] && tail -n 512 -f -F $LOG ||
+ tail -n 512 --follow=name $LOG --pid \$$ --sleep-interval 2
+ done
+ "
+fi
diff --git a/framework/src/onos/tools/test/bin/onos-log-kill b/framework/src/onos/tools/test/bin/onos-log-kill
new file mode 100755
index 00000000..c18d9231
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-log-kill
@@ -0,0 +1,16 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Kills all remote ONOS log file monitors on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+less=0
+[ "$1" = "-l" ] && shift && less=1
+
+remote=$(find_node $1)
+remote=$ONOS_USER@${remote:-$OCI}
+
+ssh $remote "ps -ef | grep \"tail -n 512\" | grep -v grep | cut -c10-15 | xargs kill"
diff --git a/framework/src/onos/tools/test/bin/onos-log-write b/framework/src/onos/tools/test/bin/onos-log-write
new file mode 100755
index 00000000..840c43f5
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-log-write
@@ -0,0 +1,37 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Writes block text into the remote ONOS log file on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+remote=$(find_node $1)
+remote=$ONOS_USER@${remote:-$OCI}
+message=$2
+
+if [ -z "$message" ]; then
+ echo "Usage: onos-log-write <instance> <message>"
+ exit
+fi
+if [ -z $(which figlet) ]; then
+ echo "Install figlet; example: brew install figlet"
+ exit
+fi
+
+#text=$(figlet $message)
+#echo "Writing to $remote:"
+#echo $text
+#echo
+
+[ -n "$instance" ] && \
+ LOG=$ONOS_INSTALL_DIR/$KARAF_DIST/instances/$instance/data/log/karaf.log || \
+ LOG=$ONOS_INSTALL_DIR/log/karaf.log
+
+#broken by special chars like `
+#ssh -t $remote "sudo mkdir -p $(dirname $LOG) && echo $text | sudo tee -a $LOG"
+
+figlet $message > /tmp/message.txt
+scp /tmp/message.txt $remote:/tmp
+ssh -t $remote "sudo mkdir -p $(dirname $LOG) && cat /tmp/message.txt | sudo tee -a $LOG; rm /tmp/message.txt"
diff --git a/framework/src/onos/tools/test/bin/onos-mininet b/framework/src/onos/tools/test/bin/onos-mininet
new file mode 100755
index 00000000..ef2c8ea5
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-mininet
@@ -0,0 +1,69 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Starts or interacts with mininet in a remote screen session.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+export MAX_WAIT=60
+
+cmd="$1" && shift
+log="screenlog.0"
+remote="$ONOS_USER@$OCN"
+mininet="ssh -t -t $remote screen -L -S mininet"
+
+case $cmd in
+send)
+ $mininet -X "stuff \"$@\\n\"" 2>/dev/null
+ ;;
+
+sendAndExpect)
+ cmd=""
+ for a in $*; do shift; if [ "$a" = "--expect" ]; then break; fi; cmd="$cmd $a"; done
+ $mininet -X "stuff \"$cmd\\n\"" 2>/dev/null
+ onos-mininet expect "$@"
+ ;;
+
+wait)
+ ssh $remote "
+ let count=0
+ sleep 1 && while test ! -f $log; do if test \$count -ge $MAX_WAIT; then exit 1; fi; sleep 1; let count=count+1; done
+ while ! (tail -n1 $log | egrep -q '^mininet>'); do if [ \$count -ge $MAX_WAIT ]; then exit 1; fi; sleep 1; done
+ sleep ${1-:1}
+ "
+ ;;
+
+expect)
+ aux=/tmp/mininet.$$.log
+ ssh $remote "
+ sleep 1
+ if [ ! -f $log ]; then exit 1; fi;
+ let count=0
+ while ! (tail -n1 $log | egrep -q '^mininet>'); do if test \$count -ge $MAX_WAIT; then exit 1; fi; sleep 1; let count=count+1; done
+ tac $log | awk '{ print \$0; } /^mininet>/ { if (on) { exit 0; } on=1; }' | tac > $aux
+ cat $aux
+ set -x
+ egrep \"$@\" $aux
+ "
+ ;;
+
+attach)
+ $mininet -x
+ ;;
+
+start)
+ ssh $remote "rm -f $log; echo logfile flush 1 > ~/.screenrc"
+ (
+ $mininet "$@"
+ scp $remote:$log /tmp/mininet.log
+ ssh $remote rm -f $log
+ ) &
+ ;;
+
+stop)
+ $mininet -X "stuff \"^C\\n\"" 2>/dev/null && \
+ $mininet -X "stuff \"^C\\n\"" 2>/dev/null && \
+ $mininet -X "stuff \"exit\\n\"" 2>/dev/null
+ ;;
+esac
diff --git a/framework/src/onos/tools/test/bin/onos-oecfg b/framework/src/onos/tools/test/bin/onos-oecfg
new file mode 100755
index 00000000..e709ce31
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-oecfg
@@ -0,0 +1,12 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS OE-Linc config generator.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+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
diff --git a/framework/src/onos/tools/test/bin/onos-patch-vm b/framework/src/onos/tools/test/bin/onos-patch-vm
new file mode 100755
index 00000000..39f1c603
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-patch-vm
@@ -0,0 +1,22 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely patches the ONOS VM to tailor its hostname.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+address=${1:-$OCI}
+remote=$ONOS_USER@$address
+name=${2:-onos-1}
+
+[ -z "$address" ] && echo "Null address not allowed" >&2 && exit 1
+[ -z "$name" ] && echo "Null name not allowed" >&2 && exit 1
+
+ssh $remote "
+ sudo perl -pi.bak -e \"s/127.0.1.1.*/127.0.1.1 $name/g\" /etc/hosts
+ sudo bash -c \"echo $name >/etc/hostname\"
+ sudo hostname $name
+" 2>/dev/null
+
+echo "$address: $(ssh $remote hostname)"
diff --git a/framework/src/onos/tools/test/bin/onos-push-bits b/framework/src/onos/tools/test/bin/onos-push-bits
new file mode 100755
index 00000000..8c9276fc
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-bits
@@ -0,0 +1,19 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely pushes bits to a remote node in preparation for install.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
+
+locHash=$(cksum $ONOS_TAR | cut -d' ' -f1,2)
+remHash=$(ssh $remote cksum $ONOS_TAR 2>/dev/null | cut -d' ' -f1,2)
+
+if [ "$locHash" = "$remHash" ]; then
+ echo "ONOS bits $ONOS_TAR already up-to-date on $node..."
+else
+ scp -q $ONOS_TAR $remote:/tmp
+fi
diff --git a/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy b/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy
new file mode 100755
index 00000000..1ec7107c
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy
@@ -0,0 +1,22 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely pushes bits to all remote nodes in preparation for install.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+OCT=${OCT:-$OCI}
+node=${1:-$OCT}
+remote=$ONOS_USER@$node
+shift
+
+echo "Pushing to proxy $node..."
+onos-push-bits $node
+
+others=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2 | grep -v $OCT)
+
+for other in $others; do
+ echo "Pushing to $other..."
+ ssh $remote "scp $ONOS_TAR $ONOS_USER@$other:$ONOS_TAR"
+done
diff --git a/framework/src/onos/tools/test/bin/onos-push-keys b/framework/src/onos/tools/test/bin/onos-push-keys
new file mode 100755
index 00000000..94da6998
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-keys
@@ -0,0 +1,19 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Pushes the local id_rsa.pub to the authorized_keys on a remote ONOS node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+remote=$ONOS_USER@${1:-$OCI}
+
+cat ~/.ssh/id_rsa.pub | ssh $remote "
+ mkdir -p ~/.ssh
+ chmod 700 ~/.ssh
+ cat >> ~/.ssh/authorized_keys
+ sort -u ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.bak
+ mv ~/.ssh/authorized_keys.bak ~/.ssh/authorized_keys
+ chmod 600 ~/.ssh/authorized_keys
+"
+ssh -n -o PasswordAuthentication=no $remote true
diff --git a/framework/src/onos/tools/test/bin/onos-push-test-bits b/framework/src/onos/tools/test/bin/onos-push-test-bits
new file mode 100755
index 00000000..927d157f
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-test-bits
@@ -0,0 +1,16 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely pushes test bits to a remote test machine and unrolls them in /tmp
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
+
+scp -q $ONOS_TEST_TAR $remote:/tmp
+ssh $remote "
+ rm -f /tmp/onos $ONOS_TEST_BITS
+ cd /tmp && tar zxf $ONOS_TEST_BITS.tar.gz && ln -s $ONOS_TEST_BITS onos
+"
diff --git a/framework/src/onos/tools/test/bin/onos-push-topos b/framework/src/onos/tools/test/bin/onos-push-topos
new file mode 100755
index 00000000..a09d7440
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-topos
@@ -0,0 +1,11 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely pushes test topologies a remote mininet test machine.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCN}
+
+scp -qr $ONOS_ROOT/tools/test/topos $ONOS_USER@$node:
diff --git a/framework/src/onos/tools/test/bin/onos-push-update-bundle b/framework/src/onos/tools/test/bin/onos-push-update-bundle
new file mode 100755
index 00000000..85fa27bc
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-push-update-bundle
@@ -0,0 +1,27 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Pushes the specified bundle to the remote ONOS cell machines and updates it.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+cd ~/.m2/repository
+jar=$(find org/onosproject -type f -name '*.jar' | grep -e $1 | grep -v -e -tests | head -n 1)
+
+[ -z "$jar" ] && echo "No bundle $1 found for" && exit 1
+
+bundle=$(echo $(basename $jar .jar) | sed 's/-[0-9].*//g')
+
+echo "pushing bundle: $bundle"
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+for node in $nodes; do
+ scp -q $jar $ONOS_USER@$node:.m2/repository/$jar
+ scp -q $jar $ONOS_USER@$node:$ONOS_INSTALL_DIR/$KARAF_DIST/system/$jar
+ ssh $ONOS_USER@$node "
+ $ONOS_INSTALL_DIR/bin/onos \"bundle:stop -f $bundle\"
+ $ONOS_INSTALL_DIR/bin/onos \"bundle:update -f $bundle\"
+ $ONOS_INSTALL_DIR/bin/onos \"bundle:start -f $bundle\"
+ " 2>/dev/null
+done
diff --git a/framework/src/onos/tools/test/bin/onos-remove-raft-logs b/framework/src/onos/tools/test/bin/onos-remove-raft-logs
new file mode 100755
index 00000000..1f1e5c68
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-remove-raft-logs
@@ -0,0 +1,14 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Removes Raft logs on all instances
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+
+onos-service --cell stop
+
+# TODO: use $KARAF_DATA
+for node in $nodes; do onos-ssh $node "rm -v -- $ONOS_INSTALL_DIR/$KARAF_DIST/data/raft/onos-copy-cat-log_*"; done
diff --git a/framework/src/onos/tools/test/bin/onos-rsdocs b/framework/src/onos/tools/test/bin/onos-rsdocs
new file mode 100755
index 00000000..bc0127cf
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-rsdocs
@@ -0,0 +1,9 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Launches ONOS REST API docs GUI on the specified node.
+# -----------------------------------------------------------------------------
+
+host=${1:-$OCI}
+host=${host:-localhost}
+
+open http://$host:8181/onos/v1/docs
diff --git a/framework/src/onos/tools/test/bin/onos-secure-ssh b/framework/src/onos/tools/test/bin/onos-secure-ssh
new file mode 100755
index 00000000..3c15fa3c
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-secure-ssh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Secures the ONOS console for all instances in the cell ONOS cluster.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+
+for node in $nodes; do
+ # Setup passwordless login for the remote user on the local bench host
+ onos-user-key $node
+
+ # Prune the node entry from the known hosts file since server key changes
+ ssh-keygen -f "$HOME/.ssh/known_hosts" -R [$node]:8101
+
+ # Setup passwordless login for the local user on the remote node
+ ssh $ONOS_USER@$node "
+ [ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q
+ $ONOS_INSTALL_DIR/bin/onos-user-key \$(id -un) \$(cut -d\\ -f2 ~/.ssh/id_rsa.pub)
+ $ONOS_INSTALL_DIR/bin/onos-secure-ssh "$@"
+
+ # Implicitly accept the new server key in dev/test environments
+ while ! ssh -p 8101 -o StrictHostKeyChecking=no localhost list 2>/dev/null; do
+ echo Waiting for connection...
+ sleep 1
+ done
+ "
+done
+
diff --git a/framework/src/onos/tools/test/bin/onos-service b/framework/src/onos/tools/test/bin/onos-service
new file mode 100755
index 00000000..cc694911
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-service
@@ -0,0 +1,55 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely administers the ONOS service on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+function print_usage {
+ command_name=`basename $0`
+ echo "Remotely administer the ONOS service on a single node or the current ONOS cell."
+ echo
+ echo "Usage: $command_name <TARGET> [COMMAND]"
+ echo " $command_name [-h | --help]"
+ echo "Options:"
+ echo " TARGET The target of the command"
+ echo " COMMAND The command to execute. Default value is 'status'"
+ echo " [-h | --help] Print this help"
+ echo ""
+ echo "TARGET: <hostname | --cell>"
+ echo " hostname Execute on the specified host name"
+ echo " --cell Execute on the current ONOS cell"
+ echo ""
+ echo "COMMAND: [start|stop|restart|status]"
+ echo ""
+}
+
+# Print usage
+if [ "${1}" = "-h" -o "${1}" = "--help" ]; then
+ print_usage
+ exit 0
+fi
+
+case $2 in
+ start|stop|restart|status)
+
+ # Select the target
+ if [ "${1}" = "--cell" ]; then
+ nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+ else
+ nodes=$(find_node ${1:-$OCI})
+ fi
+
+ # Execute the remote commands
+ for node in $nodes; do
+ ssh $ONOS_USER@${node} "sudo ${2:-status} onos"
+ done
+ ;;
+ *)
+ echo "error: $2 is not a valid command"
+ echo ""
+ print_usage
+ ;;
+esac
diff --git a/framework/src/onos/tools/test/bin/onos-set-controllers b/framework/src/onos/tools/test/bin/onos-set-controllers
new file mode 100755
index 00000000..5b3cd6f7
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-set-controllers
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Sets controllers on all OVS bridges on the mininet machine.
+# -----------------------------------------------------------------------------
+
+controllers=""
+
+for node in $ONOS_INSTANCES; do
+ controllers="$controllers tcp:$node:${OF_PORT:-6633}"
+done
+
+ssh ${ONOS_USER:-sdn}@$OCN "
+ sudo ovs-vsctl list-br | while read br; do
+ echo \$br: $controllers
+ sudo ovs-vsctl set-controller \$br $controllers
+ done
+"
diff --git a/framework/src/onos/tools/test/bin/onos-show-cell b/framework/src/onos/tools/test/bin/onos-show-cell
new file mode 100755
index 00000000..f5c75726
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-show-cell
@@ -0,0 +1,57 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Print the configuration of an ONOS cell.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+function print_usage {
+ echo "Print the configuration of an ONOS cell."
+ echo "If no arguments are specified, it will print the configuration for the default"
+ echo "ONOS cell as specified in the 'ONOS_CELL' environmental variable."
+ echo
+ echo "Optional arguments:"
+ echo " [cell-name] Print the configuration of 'cell-name'"
+ echo " [-h | --help] Print this help"
+}
+
+if [ "${1}" = "-h" -o "${1}" = "--help" ]; then
+ print_usage
+ exit 0
+fi
+
+if [ -n "${1}" ]; then
+ cell="${1}"
+else
+ if [ -z "${ONOS_CELL}" ]; then
+ echo "Environmental variable 'ONOS_CELL' is not defined"
+ exit 1
+ else
+ cell="${ONOS_CELL}"
+ fi
+fi
+
+if [ ! -f $ONOS_ROOT/tools/test/cells/${cell} ]; then
+ echo "No such cell: ${cell}"
+ exit 1
+fi
+
+# Load the cell setup
+. $ONOS_ROOT/tools/test/cells/${cell}
+
+echo "ONOS_CELL=${ONOS_CELL}"
+echo "ONOS_NIC=${ONOS_NIC}"
+# get number of OC variables
+max=$( env | egrep 'OC[0-9]+' | wc -l )
+for n in $( seq 0 ${max} ); do
+ ocn="OC${n}"
+ if [ -n "${!ocn}" ]; then
+ echo "$ocn=${!ocn}"
+ fi
+done
+echo "OCN=${OCN}"
+echo "OCT=${OCT}"
+echo "OCI=${OCI}"
+echo "ONOS_APPS=${ONOS_APPS}"
+echo "ONOS_BOOT_FEATURES=${ONOS_BOOT_FEATURES}"
diff --git a/framework/src/onos/tools/test/bin/onos-ssh b/framework/src/onos/tools/test/bin/onos-ssh
new file mode 100755
index 00000000..eb6b88e9
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-ssh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Logs in to the remote ONOS node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+[ -n "$1" ] && OCI=$(find_node $1) && shift
+ssh -Y $ONOS_USER@$OCI "$@"
diff --git a/framework/src/onos/tools/test/bin/onos-stage-apps b/framework/src/onos/tools/test/bin/onos-stage-apps
new file mode 100755
index 00000000..4c2c230e
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-stage-apps
@@ -0,0 +1,29 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Stages builtin ONOS apps into the specified directory for packaging.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+export APPS=${1:-/tmp/apps}
+export KARAF_M2=${2:-/tmp/karaf/system}
+export AUX=$APPS/aux
+
+# Bail on any errors
+set -e
+
+mkdir -p $APPS $KARAF_M2
+rm -fr $AUX
+
+find $M2_REPO/org/onosproject/ -name "*.oar" -path "*/${ONOS_POM_VERSION}/*" | while read line; do
+ mkdir -p $AUX && cd $AUX
+ cp $line $AUX
+ jar -xf $AUX/*.oar
+ name=$(grep "name=" $AUX/app.xml | sed 's/<app name="//g;s/".*//g')
+ mkdir -p $APPS/$name
+ cp $AUX/app.xml $APPS/$name/app.xml
+ cp $AUX/*.oar $APPS/$name/$name.oar
+ cp -rf $AUX/m2/* $KARAF_M2
+ rm -fr $AUX
+done
diff --git a/framework/src/onos/tools/test/bin/onos-start-network b/framework/src/onos/tools/test/bin/onos-start-network
new file mode 100755
index 00000000..1e162fb4
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-start-network
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Verifies connectivity to each node in ONOS cell.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+SSHCMD="ssh -o PasswordAuthentication=no"
+SCPCMD="scp -q -o PasswordAuthentication=no"
+
+echo "Copying topology files to mininet vm."
+$SSHCMD -n $ONOS_USER@$OCN mkdir -p topos
+$SCPCMD $ONOS_ROOT/tools/test/topos/* $ONOS_USER@$OCN:topos/
+
+echo "Starting Network."
+$SSHCMD -t $ONOS_USER@$OCN sudo python topos/sol.py $(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
diff --git a/framework/src/onos/tools/test/bin/onos-topo-cfg b/framework/src/onos/tools/test/bin/onos-topo-cfg
new file mode 100755
index 00000000..5f40d8e7
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-topo-cfg
@@ -0,0 +1,14 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS topology configuration uploader.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node="${1:-$OCI}"
+file="${2:-$ONOS_ROOT/tools/test/topos/oe-linear-3.json}"
+
+curl -sS --fail -L --user $ONOS_WEB_USER:$ONOS_WEB_PASS \
+ -X POST -H 'Content-Type:application/json' \
+ http://$node:8181/onos/v1/config/topology -d@$file
diff --git a/framework/src/onos/tools/test/bin/onos-topo-cfg-all b/framework/src/onos/tools/test/bin/onos-topo-cfg-all
new file mode 100755
index 00000000..adf84c14
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-topo-cfg-all
@@ -0,0 +1,15 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS topology configuration uploader.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2)
+
+for node in $nodes; do
+ printf "$node..."
+ onos-topo-cfg $node $1
+done
+printf "\n"
diff --git a/framework/src/onos/tools/test/bin/onos-uninstall b/framework/src/onos/tools/test/bin/onos-uninstall
new file mode 100755
index 00000000..c04db7ac
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-uninstall
@@ -0,0 +1,14 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Remotely stops & uninstalls ONOS on the specified node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+remote=$ONOS_USER@${1:-$OCI}
+
+ssh $remote "
+ sudo stop onos 1>/dev/null 2>/dev/null
+ sudo rm -fr $ONOS_INSTALL_DIR
+"
diff --git a/framework/src/onos/tools/test/bin/onos-untar-and-run b/framework/src/onos/tools/test/bin/onos-untar-and-run
new file mode 100755
index 00000000..f6e8f9b2
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-untar-and-run
@@ -0,0 +1,24 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Untars ONOS tar.gz on the remote machine and runs ONOS.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+remote=$ONOS_USER@$node
+
+ssh $remote "
+ [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1
+ cd /tmp && rm -fr /tmp/$ONOS_BITS
+ tar zxf /tmp/$ONOS_BITS.tar.gz
+
+ cd /tmp/$ONOS_BITS
+ export ONOS_NIC=$ONOS_NIC
+ bin/onos-service server 1>/tmp/onos.out 2>/tmp/onos.err &
+
+ # Setup a few symlinks to allow other tools to work
+ sudo ln -s /tmp/$ONOS_BITS $ONOS_INSTALL_DIR
+ sudo ln -s /tmp/$ONOS_BITS/$KARAF_DIST/data/log $ONOS_INSTALL_DIR/log
+"
diff --git a/framework/src/onos/tools/test/bin/onos-upload-sprites b/framework/src/onos/tools/test/bin/onos-upload-sprites
new file mode 100755
index 00000000..982d7132
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-upload-sprites
@@ -0,0 +1,18 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Tool to upload GUI sprites definitions using GUI REST API.
+# -----------------------------------------------------------------------------
+
+node=${1}
+sprites=${2}
+
+if [ -z "$node" -o -z "$sprites" ]
+then
+ echo "Usage: onos-upload-sprites <server-ip> <sprites-defn.json>"
+ exit 1
+fi
+
+export URL=http://$node:8181/onos/ui/rs/topology/sprites
+export HDR="-HContent-Type:application/json"
+
+curl --fail -sS -X POST $HDR $URL --data @$sprites
diff --git a/framework/src/onos/tools/test/bin/onos-user-key b/framework/src/onos/tools/test/bin/onos-user-key
new file mode 100755
index 00000000..b324c1a8
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-user-key
@@ -0,0 +1,13 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Adds or removes a user key for managing passwordless loging to ONOS console.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+user=${2:-$(id -un)}
+key=${3:-$(cut -d\ -f2 ~/.ssh/id_rsa.pub)}
+
+ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-user-key $user $key
diff --git a/framework/src/onos/tools/test/bin/onos-verify-cell b/framework/src/onos/tools/test/bin/onos-verify-cell
new file mode 100755
index 00000000..4b3a0ee7
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-verify-cell
@@ -0,0 +1,11 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Verifies connectivity to each node in ONOS cell.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+for node in $(env | sort | egrep "OC[0-9N]+" | cut -d= -f2); do
+ printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date
+done
diff --git a/framework/src/onos/tools/test/bin/onos-wait-for-start b/framework/src/onos/tools/test/bin/onos-wait-for-start
new file mode 100755
index 00000000..e643b5a6
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-wait-for-start
@@ -0,0 +1,28 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Waits for ONOS to reach run-level 100 on the specified remote node.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+. $ONOS_ROOT/tools/test/bin/find-node.sh
+
+node=$(find_node ${1:-$OCI})
+
+remote=$ONOS_USER@$node
+
+ssh -t $remote "
+ # Wait until we reach the run-level 100
+ for i in \$(seq 1 45); do
+ $ONOS_INSTALL_DIR/bin/onos bundle:list 2>/dev/null | \
+ grep -q 'START LEVEL 100' && break || sleep 2
+ done
+
+ # Wait until ApplicationManager is available
+ for i in \$(seq 1 10); do
+ grep -q \" ApplicationManager .* Started\" \
+ $ONOS_INSTALL_DIR/log/karaf.log && break || sleep 1
+ done
+
+ grep -q \" ApplicationManager .* Started\" $ONOS_INSTALL_DIR/log/karaf.log
+"
diff --git a/framework/src/onos/tools/test/bin/onos-watch b/framework/src/onos/tools/test/bin/onos-watch
new file mode 100755
index 00000000..28e88c2f
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-watch
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Monitors selected set of ONOS commands using the system watch command.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node=${1:-$OCI}
+
+commands="${2:-summary,intents,flows,hosts}"
+
+aux=/tmp/onos-watch.$$
+trap "rm -f $aux" EXIT
+
+echo "$commands" | tr ',' '\n' > $aux
+watch $3 "onos $node -b <$aux 2>/dev/null"
diff --git a/framework/src/onos/tools/test/bin/onos-wipe-out b/framework/src/onos/tools/test/bin/onos-wipe-out
new file mode 100755
index 00000000..6e996345
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/onos-wipe-out
@@ -0,0 +1,9 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Wipes out all data from the ONOS cluster. Temporary until wipe-out is fixed.
+# -----------------------------------------------------------------------------
+
+for node in ${ONOS_INSTANCES:-$OCI}; do
+ onos $node wipe-out please
+done
+onos-check-summary $OCI '.*' 0 0 0 0 0
diff --git a/framework/src/onos/tools/test/bin/stc b/framework/src/onos/tools/test/bin/stc
new file mode 100755
index 00000000..fe8a5afe
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/stc
@@ -0,0 +1,23 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# System Test Coordinator
+#-------------------------------------------------------------------------------
+
+VER=1.3.0-SNAPSHOT
+JAR=~/.m2/repository/org/onosproject/onlab-stc/$VER/onlab-stc-$VER.jar
+SCENARIOS=$ONOS_ROOT/tools/test/scenarios
+
+DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=y"
+
+scenario=${1:-smoke}
+
+[ ! -f $scenario ] && scenario=$SCENARIOS/$scenario
+[ ! -f $scenario ] && scenario=$scenario.xml
+[ ! -f $scenario ] && echo "Scenario $scenario file not found" && exit 1
+
+[ $# -ge 1 ] && shift
+
+[ -t 1 ] && stcColor=true || unset stcColor
+
+[ -z "$stcDebug" ] && DEBUG_OPTS=""
+java $DEBUG_OPTS -jar $JAR $scenario "$@"
diff --git a/framework/src/onos/tools/test/bin/stc-launcher b/framework/src/onos/tools/test/bin/stc-launcher
new file mode 100755
index 00000000..6e473cdf
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/stc-launcher
@@ -0,0 +1,25 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# System Test Coordinator process launcher
+#-------------------------------------------------------------------------------
+
+#sleep 5 && exit 0;
+
+env=$1 && shift
+cwd=$1 && shift
+
+if [ $env != "-" -a $env != "~" ]; then
+ [ ! -f $env ] && echo "$env file not found" && exit 1
+ source $env
+fi
+
+if [ $cwd != "-" ]; then
+ [ ! -d $cwd ] && echo "$cwd directory not found" && exit 1
+ cd $cwd
+fi
+
+"$@" 2>&1
+status=$?
+
+[ $env != "~" ] && exit $status
+exit 0
diff --git a/framework/src/onos/tools/test/bin/stl b/framework/src/onos/tools/test/bin/stl
new file mode 100755
index 00000000..1487ab4f
--- /dev/null
+++ b/framework/src/onos/tools/test/bin/stl
@@ -0,0 +1,7 @@
+#!/bin/bash
+#-------------------------------------------------------------------------------
+# System Test Coordinator
+#-------------------------------------------------------------------------------
+
+log=${2:-*}
+less /tmp/stc/$1/${log%.log}.log \ No newline at end of file