diff options
Diffstat (limited to 'framework/src/onos/tools/test')
147 files changed, 7642 insertions, 0 deletions
diff --git a/framework/src/onos/tools/test/README b/framework/src/onos/tools/test/README new file mode 100644 index 00000000..3d6b1eb7 --- /dev/null +++ b/framework/src/onos/tools/test/README @@ -0,0 +1 @@ +Artifacts for system testing onos. 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 diff --git a/framework/src/onos/tools/test/cells/beast b/framework/src/onos/tools/test/cells/beast new file mode 100644 index 00000000..6afd61d1 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast @@ -0,0 +1,18 @@ +# Bare metal cluster (7-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 +export OC4=10.254.1.204 +export OC5=10.254.1.205 +export OC6=10.254.1.206 +export OC7=10.254.1.207 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-1 b/framework/src/onos/tools/test/cells/beast-1 new file mode 100644 index 00000000..698eded7 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-1 @@ -0,0 +1,12 @@ +# Bare metal cluster (1-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-3 b/framework/src/onos/tools/test/cells/beast-3 new file mode 100644 index 00000000..6586ddc3 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-3 @@ -0,0 +1,14 @@ +# Bare metal cluster (3-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-5 b/framework/src/onos/tools/test/cells/beast-5 new file mode 100644 index 00000000..e23f0771 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-5 @@ -0,0 +1,18 @@ +# Bare metal cluster (5-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +export OCN=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 +export OC4=10.254.1.204 +export OC5=10.254.1.205 + +export ONOS_APPS="drivers,openflow,proxyarp,fwd" diff --git a/framework/src/onos/tools/test/cells/bramble b/framework/src/onos/tools/test/cells/bramble new file mode 100644 index 00000000..7f17d2f5 --- /dev/null +++ b/framework/src/onos/tools/test/cells/bramble @@ -0,0 +1,8 @@ +export ONOS_NIC=192.168.1.* +export OC1="192.168.1.11" +export OC2="192.168.1.12" +export OC3="192.168.1.13" +export OC4="192.168.1.14" +# export OC5="192.168.1.15" +export OCN="192.168.1.15" +export OCI="${OC1}" diff --git a/framework/src/onos/tools/test/cells/ec2 b/framework/src/onos/tools/test/cells/ec2 new file mode 100644 index 00000000..3d64be27 --- /dev/null +++ b/framework/src/onos/tools/test/cells/ec2 @@ -0,0 +1,18 @@ +# EC2-based cluster (7-node) + +# Use the 10G NIC for cluster communications +export ONOS_NIC="192.168.200.*" + +# ONOS Test proxy +export OCT=192.168.200.101 + +# Use the 1G NICs for external access +export OC1=192.168.200.101 +export OC2=192.168.200.102 +export OC3=192.168.200.103 +export OC4=192.168.200.104 +export OC5=192.168.200.105 +export OC6=192.168.200.106 +export OC7=192.168.200.107 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/local b/framework/src/onos/tools/test/cells/local new file mode 100644 index 00000000..6d8b71cd --- /dev/null +++ b/framework/src/onos/tools/test/cells/local @@ -0,0 +1,8 @@ +# Local VirtualBox-based ONOS instances 1,2 & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OC2="192.168.56.102" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/cells/madan3 b/framework/src/onos/tools/test/cells/madan3 new file mode 100644 index 00000000..857d096e --- /dev/null +++ b/framework/src/onos/tools/test/cells/madan3 @@ -0,0 +1,7 @@ +# Madan's ProxMox ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC="10.128.4.*" +export OC1="10.128.4.2" +export OC2="10.128.4.3" +export OC3="10.128.4.4" +export OCN="10.128.4.5" diff --git a/framework/src/onos/tools/test/cells/office b/framework/src/onos/tools/test/cells/office new file mode 100644 index 00000000..2cd933e2 --- /dev/null +++ b/framework/src/onos/tools/test/cells/office @@ -0,0 +1,7 @@ +# ONLAB_OF Wifi ProxMox-based cell; single node; no mininet-box + +export ONOS_NIC="10.1.10.*" +export OC1="10.1.10.223" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" + diff --git a/framework/src/onos/tools/test/cells/prox b/framework/src/onos/tools/test/cells/prox new file mode 100644 index 00000000..8af41989 --- /dev/null +++ b/framework/src/onos/tools/test/cells/prox @@ -0,0 +1,6 @@ +# ProxMox-based cell of ONOS instances 1,2 & ONOS mininet box + +export ONOS_NIC="10.1.9.*" +export OC1="10.1.9.94" +export OC2="10.1.9.82" +export OCN="10.1.9.93" diff --git a/framework/src/onos/tools/test/cells/sdnip-pmox b/framework/src/onos/tools/test/cells/sdnip-pmox new file mode 100644 index 00000000..e95b7e79 --- /dev/null +++ b/framework/src/onos/tools/test/cells/sdnip-pmox @@ -0,0 +1,8 @@ +# SDN-IP ProxMox cell + +export ONOS_NIC=10.128.4.* +export OC1="10.128.4.65" +export OC2="10.128.4.66" +export OC3="10.128.4.67" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility,config,sdnip" diff --git a/framework/src/onos/tools/test/cells/single b/framework/src/onos/tools/test/cells/single new file mode 100644 index 00000000..dd03e491 --- /dev/null +++ b/framework/src/onos/tools/test/cells/single @@ -0,0 +1,7 @@ +# Local VirtualBox-based single ONOS instance & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/cells/single_optical b/framework/src/onos/tools/test/cells/single_optical new file mode 100644 index 00000000..6bbe176e --- /dev/null +++ b/framework/src/onos/tools/test/cells/single_optical @@ -0,0 +1,7 @@ +# Optical use-case VirtualBox-based single ONOS instance & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility,optical" diff --git a/framework/src/onos/tools/test/cells/tom b/framework/src/onos/tools/test/cells/tom new file mode 100644 index 00000000..28d31729 --- /dev/null +++ b/framework/src/onos/tools/test/cells/tom @@ -0,0 +1,7 @@ +# Thomas' VirtualBox-based 3 ONOS instances & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.11" +export OC2="192.168.56.12" +export OC3="192.168.56.13" +export OCN="192.168.56.7" diff --git a/framework/src/onos/tools/test/cells/tomx b/framework/src/onos/tools/test/cells/tomx new file mode 100644 index 00000000..3e528ee8 --- /dev/null +++ b/framework/src/onos/tools/test/cells/tomx @@ -0,0 +1,10 @@ +# Tom's ProxMox ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC="10.128.11.*" +export OC1="10.128.11.1" +export OC2="10.128.11.2" +export OC3="10.128.11.3" +export OCN="10.128.11.4" + +export OCT=$OC1 +export ONOS_APPS=drivers,openflow,proxyarp
\ No newline at end of file diff --git a/framework/src/onos/tools/test/cells/triple b/framework/src/onos/tools/test/cells/triple new file mode 100644 index 00000000..42471228 --- /dev/null +++ b/framework/src/onos/tools/test/cells/triple @@ -0,0 +1,9 @@ +# Local VirtualBox-based ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OC2="192.168.56.102" +export OC3="192.168.56.104" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/configs/l2-flow.json b/framework/src/onos/tools/test/configs/l2-flow.json new file mode 100644 index 00000000..64bb5297 --- /dev/null +++ b/framework/src/onos/tools/test/configs/l2-flow.json @@ -0,0 +1,28 @@ +{ + "isPermanent": true, + "priority": 100, + "selector": { + "criteria": [ + { + "port": 2, + "type": "IN_PORT" + }, + { + "mac": "00:00:00:00:11:22", + "type": "ETH_SRC" + }, + { + "mac": "00:00:00:00:33:44", + "type": "ETH_DST" + } + ] + }, + "treatment": { + "instructions": [ + { + "port": 1, + "type": "OUTPUT" + } + ] + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/configs/override-basic.json b/framework/src/onos/tools/test/configs/override-basic.json new file mode 100644 index 00000000..c1f23ce6 --- /dev/null +++ b/framework/src/onos/tools/test/configs/override-basic.json @@ -0,0 +1,38 @@ +{ + "devices": { + "of:0000000000000009": { + "basic": { + "allowed": true, + "owner": "Luigi" + } + }, + "of:0000000000000008": { + "basic": { + "name": "NameChangeAgain", + "allowed": true, + "owner": "Mario" + } + }, + "of:0000000000000007": { + "basic": { + "allowed": true, + "owner": "Peach", + "latitude": "25" + } + } + }, + "links": { + "of:0000000000000006/2-of:0000000000000007/2": { + "basic": { + "allowed": true + } + } + }, + "hosts": { + "00:00:00:00:00:03/-1": { + "basic": { + "allowed": true + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/configs/sample-basic.json b/framework/src/onos/tools/test/configs/sample-basic.json new file mode 100644 index 00000000..73cbd305 --- /dev/null +++ b/framework/src/onos/tools/test/configs/sample-basic.json @@ -0,0 +1,54 @@ +{ + "devices": { + "of:0000000000000009": { + "basic": { + "allowed": true, + "owner": "Luigi" + } + }, + "of:0000000000000008": { + "basic": { + "name": "NameChange", + "allowed": true, + "owner": "Mario" + } + }, + "of:0000000000000007": { + "basic": { + "allowed": true, + "owner": "Peach", + "latitude": "25" + } + }, + "of:0000000000000003": { + "basic": { + "allowed": true, + "owner": "Wario" + } + } + }, + "links": { + "of:0000000000000006/2-of:0000000000000007/2": { + "basic": { + "allowed": true + } + } + }, + "hosts": { + "00:00:00:00:00:03/-1": { + "basic": { + "allowed": false + } + }, + "00:00:00:00:00:02/-1": { + "basic": { + "allowed": false + } + }, + "00:00:00:00:00:01/-1": { + "basic": { + "allowed": false + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/archetypes.xml b/framework/src/onos/tools/test/scenarios/archetypes.xml new file mode 100644 index 00000000..8244a32f --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/archetypes.xml @@ -0,0 +1,50 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="archetypes" description="ONOS archetypes test"> + <group name="Archetypes" cwd="${WORKSPACE}/tmp/test-app"> + <step name="Clean-Up" cwd="${WORKSPACE}/tmp" env="~" + exec="rm -r test-app"/> + + <step name="Create-App" cwd="${WORKSPACE}/tmp" requires="^" + exec="onos-create-app app org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App" requires="Create-App" exec="mvn clean install"/> + <step name="Install-App" requires="^" + exec="onos-app ${OCI} install! target/test-app-1.2.3.oar"/> + <step name="Verify-App" requires="^" + exec="onos-check-components ${OCI} org.test.app.AppComponent"/> + + <step name="Create-App-CLI-Overlay" requires="Install-App" + exec="onos-create-app cli org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App-With-CLI" requires="^" + exec="mvn clean install"/> + <step name="Reinstall-App-With-CLI" requires="^,~Verify-App" + exec="onos-app ${OCI} reinstall! target/test-app-1.2.3.oar"/> + <step name="Verify-CLI" requires="^" + exec="onos ${OCI} sample"/> + + <step name="Create-App-UI-Overlay" requires="Reinstall-App-With-CLI" + exec="onos-create-app ui org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App-With-UI" requires="^" + exec="mvn clean install"/> + <step name="Reinstall-App-With-UI" requires="^,~Verify-CLI" + exec="onos-app ${OCI} reinstall! target/test-app-1.2.3.oar"/> + <step name="Verify-UI" requires="^" + exec="onos-check-views ${OCI} id=sample"/> + + <step name="Uninstall-App" requires="^" + exec="onos-app ${OCI} uninstall org.foo.app"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/bin/create-flow.py b/framework/src/onos/tools/test/scenarios/bin/create-flow.py new file mode 100755 index 00000000..4e9b452b --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/create-flow.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python + +import requests + +from requests.auth import HTTPBasicAuth +import sys + + + +if len(sys.argv) != 6: + print "usage: create-flow onos-node name device in-port out-port" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +device = sys.argv[3] +inPort = sys.argv[4] +outPort = sys.argv[5] + +flowJsonTemplate = \ + '{{' + \ + '"priority": 1,' + \ + '"isPermanent": true,' + \ + '"treatment": {{' + \ + '"instructions": [' + \ + '{{' + \ + '"type": "OUTPUT",' + \ + '"port": {}' + \ + '}}' + \ + ']' + \ + '}},' + \ + '"selector": {{' + \ + '"criteria": [' + \ + '{{' + \ + '"type": "IN_PORT",' + \ + '"port": {}' + \ + '}}' + \ + ']' + \ + '}}' + \ + '}}' + +flowJson = flowJsonTemplate.format(inPort, outPort) +intentRequest = requests.post('http://' + node + ':8181/onos/v1/flows/' + device, + auth=HTTPBasicAuth('onos', 'rocks'), + data=flowJson) + +if intentRequest.status_code != 201: + print intentRequest.text + sys.exit(1) + +location = intentRequest.headers["location"] +print "@stc " + name + "Location=" + location +sys.exit(0) + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/create-intent.py b/framework/src/onos/tools/test/scenarios/bin/create-intent.py new file mode 100755 index 00000000..4e5d4f62 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/create-intent.py @@ -0,0 +1,49 @@ +#! /usr/bin/env python + +import requests + +from requests.auth import HTTPBasicAuth +import sys + + + +if len(sys.argv) != 7: + print "usage: create-intent onos-node name ingressDevice ingressPort egressDevice egressPort" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +ingress = sys.argv[3] +ingressPort = sys.argv[4] +egress = sys.argv[5] +egressPort = sys.argv[6] + +intentJsonTemplate = \ + '{{' + \ + '"type": "PointToPointIntent",' + \ + '"appId": "org.onosproject.cli",' + \ + '"ingressPoint": {{' + \ + ' "device": "{}",' + \ + ' "port": "{}"' + \ + '}},' + \ + '"egressPoint": {{' + \ + ' "device": "{}",' + \ + ' "port": "{}"' + \ + '}}' + \ + '}}' + +intentJson = intentJsonTemplate.format(ingress, ingressPort, egress, egressPort) +intentRequest = requests.post('http://' + node + ':8181/onos/v1/intents/', + auth=HTTPBasicAuth('onos', 'rocks'), + data=intentJson) + +if intentRequest.status_code != 201: + print intentRequest.text + sys.exit(1) + +location = intentRequest.headers["location"] +print "@stc " + name + "Location=" + location +sys.exit(0) + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-device.py b/framework/src/onos/tools/test/scenarios/bin/find-device.py new file mode 100755 index 00000000..430e18ad --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-device.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python + +import requests +import sys +import urllib + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-device onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +id = sys.argv[3] + +deviceRequest = requests.get('http://' + node + ':8181/onos/v1/devices/' + + urllib.quote_plus(id), + auth=HTTPBasicAuth('onos', 'rocks')) + +if deviceRequest.status_code != 200: + 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"]) +channelId = deviceJson["annotations"]["channelId"] +channelIdWords = channelId.split(':') +print "@stc " + name + "IpAddress=" + channelIdWords[0] + +sys.exit(0) + + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-flow.py b/framework/src/onos/tools/test/scenarios/bin/find-flow.py new file mode 100755 index 00000000..a2f2e4d1 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-flow.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python + +import requests +import sys + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-flow onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +deviceId = sys.argv[3] + +flowsRequest = requests.get('http://' + node + ':8181/onos/v1/flows/' + deviceId, + auth=HTTPBasicAuth('onos', 'rocks')) + +if flowsRequest.status_code != 200: + print flowsRequest.text + sys.exit(1) + +flowsJson = flowsRequest.json() + +for flow in flowsJson["flows"]: + if deviceId == flow["deviceId"]: + for criterion in flow["selector"]["criteria"]: + 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"]) + sys.exit(0) + +sys.exit(1) + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-host.py b/framework/src/onos/tools/test/scenarios/bin/find-host.py new file mode 100755 index 00000000..e87a4090 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-host.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python + +import requests +import sys +import urllib + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-host onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +id = sys.argv[3] + +hostRequest = requests.get('http://' + node + ':8181/onos/v1/hosts/' + + urllib.quote_plus(id), + auth=HTTPBasicAuth('onos', 'rocks')) + +if hostRequest.status_code != 200: + 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] + +sys.exit(0) + + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-link.py b/framework/src/onos/tools/test/scenarios/bin/find-link.py new file mode 100755 index 00000000..9ac6e358 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-link.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python + +import requests +import sys + +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" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +srcDeviceId = sys.argv[3] +srcPort = sys.argv[4] +dstDeviceId = sys.argv[5] +dstPort = sys.argv[6] + + +linksRequest = requests.get('http://' + node + ':8181/onos/v1/links?device=' + + srcDeviceId + '&port=' + srcPort, + auth=HTTPBasicAuth('onos', 'rocks')) + +if linksRequest.status_code != 200: + print linksRequest.text + sys.exit(1) + +linksJson = linksRequest.json() + +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"] + sys.exit(0) + +sys.exit(1) + + + + diff --git a/framework/src/onos/tools/test/scenarios/example.xml b/framework/src/onos/tools/test/scenarios/example.xml new file mode 100644 index 00000000..65803141 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/example.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="example" description="Example"> + <step name="One" exec="echo @stc foo=bar"/> + <step name="Two" requires="One" exec="echo ${foo}"/> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-create-flows.xml b/framework/src/onos/tools/test/scenarios/net-create-flows.xml new file mode 100644 index 00000000..6a6a80b0 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-create-flows.xml @@ -0,0 +1,93 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-create-flows" + description="Network Flow Creation Test Using REST API"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Create-Flows"> + + <!-- Make sure that reactive forwarding is off --> + <step name="Net-Create-Flows.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Net-Create-Flows.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <!-- Force discovery of hosts --> + <step name="Net-Create-Flows.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect 100% packet loss"/> + <step name="Net-Create-Flows.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect 100% packet loss"/> + + + <!-- Use REST API to create a point to point intent in each direction --> + <step name="Net-Create-Flows.1-to-Host" requires="Net-Create-Flows.Find-Host-2" + exec="create-flow.py ${OC1} f1 of:0000000000000001 5 1"/> + <step name="Net-Create-Flows.1-to-19" requires="^" + exec="create-flow.py ${OC1} f2 of:0000000000000001 1 2"/> + <step name="Net-Create-Flows.19-to-7" requires="^" + exec="create-flow.py ${OC1} f3 of:0000000000000019 2 8"/> + <step name="Net-Create-Flows.7-to-4" requires="^" + exec="create-flow.py ${OC1} f4 of:0000000000000007 2 3"/> + <step name="Net-Create-Flows.4-to-Host" requires="^" + exec="create-flow.py ${OC1} f5 of:0000000000000004 1 3"/> + + <step name="Net-Create-Flows.Host-to-1" requires="^" + exec="create-flow.py ${OC1} f6 of:0000000000000001 1 5"/> + <step name="Net-Create-Flows.19-to-1" requires="^" + exec="create-flow.py ${OC1} f7 of:0000000000000001 2 1"/> + <step name="Net-Create-Flows.7-to-19" requires="^" + exec="create-flow.py ${OC1} f8 of:0000000000000019 8 2"/> + <step name="Net-Create-Flows.4-to-7" requires="^" + exec="create-flow.py ${OC1} f9 of:0000000000000007 3 2"/> + <step name="Net-Create-Flows.Host-to-4" requires="^" + exec="create-flow.py ${OC1} f10 of:0000000000000004 3 1"/> + + <!-- Check that connectivity was established --> + <step name="Net-Create-Flows.Ping-XY" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Net-Create-Flows.Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 0% packet loss"/> + + <!-- Use REST API to remove the flows. --> + <step name="Net-Create-Flows.Delete-f1" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f1Location}"/> + <step name="Net-Create-Flows.Delete-f2" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f2Location}"/> + <step name="Net-Create-Flows.Delete-f3" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f3Location}"/> + <step name="Net-Create-Flows.Delete-f4" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f4Location}"/> + <step name="Net-Create-Flows.Delete-f5" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f5Location}"/> + <step name="Net-Create-Flows.Delete-f6" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f6Location}"/> + <step name="Net-Create-Flows.Delete-f7" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f7Location}"/> + <step name="Net-Create-Flows.Delete-f8" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f8Location}"/> + <step name="Net-Create-Flows.Delete-f9" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f9Location}"/> + <step name="Net-Create-Flows.Delete-f10" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f10Location}"/> + + <!-- Ping again to be sure the path was removed. --> + <step name="Net-Create-Flows.Fail-Ping-XY" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 100% packet loss"/> + <step name="Net-Create-Flows.Fail-Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 100% packet loss"/> + + + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-host-intent.xml b/framework/src/onos/tools/test/scenarios/net-host-intent.xml new file mode 100644 index 00000000..fbf8c4ab --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-host-intent.xml @@ -0,0 +1,59 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-host-intent" description="Network host intent connectivity test"> + <!-- TODO: parametrize this via recipes --> + <group name="Host-Intent-Connectivity"> + <step name="Host-Intent.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Host-Intent.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <step name="Host-Intent.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="Host-Intent.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <step name="Host-Intent.Create-Intent" requires="^" + exec="onos-create-intent ${OC1} h2h host 00:00:00:00:00:01/-1 00:00:00:00:00:04/-1"/> + <step name="Host-Intent.Validate-Intent-Installed" requires="Host-Intent.Create-Intent" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Host-Intent"/> + <dependency name="Host-Intent.Net-Link-Down-Up" + requires="Host-Intent.Validate-Intent-Installed"/> + + <step name="Host-Intent.Validate-Intent-Installed-Still" requires="Host-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <dependency name="Host-Intent.Link-2-Down" + requires="~Host-Intent.Validate-Intent-Installed-Still" /> + + <step name="Host-Intent.Validate-Intent-Failed" requires="Host-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} h2h FAILED"/> + + <dependency name="Host-Intent.Link-1-Up" + requires="~Host-Intent.Validate-Intent-Failed" /> + + <step name="Host-Intent.Validate-Intent-Installed-Again" requires="Host-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <dependency name="Host-Intent.Ping-4" + requires="~Host-Intent.Validate-Intent-Installed-Again" /> + + <step name="Host-Intent.Remove-Intent" requires="~Host-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli h2h"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-link-down-up.xml b/framework/src/onos/tools/test/scenarios/net-link-down-up.xml new file mode 100644 index 00000000..8bcbfa7f --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-link-down-up.xml @@ -0,0 +1,38 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-link-down-up" description="Network link up-down test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Link-Down-Up"> + <step name="Ping-1" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-1-Down" requires="~Ping-1" + exec="onos-mininet sendAndExpect link s4 s7 down --expect ."/> + <step name="Ping-2" requires="~Link-1-Down" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-2-Down" requires="~Ping-2" + exec="onos-mininet sendAndExpect link s4 s5 down --expect ."/> + <step name="Ping-3" requires="~Link-2-Down" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect 100% packet loss"/> + <step name="Link-1-Up" requires="~Ping-3" + exec="onos-mininet sendAndExpect link s4 s7 up --expect ."/> + <step name="Ping-4" requires="~Link-1-Up" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-2-Up" requires="~Ping-4" + exec="onos-mininet sendAndExpect link s4 s5 up --expect ."/> + <step name="Ping-5" requires="~Link-2-Up" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-pingall.xml b/framework/src/onos/tools/test/scenarios/net-pingall.xml new file mode 100644 index 00000000..8968e0dc --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-pingall.xml @@ -0,0 +1,37 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-pingall" description="Network pingall test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Pingall"> + <step name="Install-Apps" + exec="onos ${OC1} app activate org.onosproject.openflow org.onosproject.proxyarp org.onosproject.fwd"/> + <step name="Check-Apps" requires="^" + exec="onos-check-apps ${OC1} drivers,openflow,proxyarp,fwd includes"/> + + <!-- TODO: take this out when initial pingall sweep is 100% --> + <step name="Initial-Ping-All" requires="Check-Apps" + exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600 received"/> + + <step name="Ping-All-And-Verify" requires="Check-Apps,Initial-Ping-All" + exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600/600 received"/> + + <step name="Check-Summary-For-Hosts" requires="~Ping-All-And-Verify" + exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/> + + <step name="Config-Topo" requires="~Check-Summary-For-Hosts" + exec="onos-topo-cfg ${OC1} ${ONOS_ROOT}/tools/test/topos/attmpls.json"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-point-intent.xml b/framework/src/onos/tools/test/scenarios/net-point-intent.xml new file mode 100644 index 00000000..acb8212b --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-point-intent.xml @@ -0,0 +1,77 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-point-intent" + description="Network point to point intent connectivity test"> + <!-- TODO: parametrize this via recipes --> + <group name="P2P-Intent-Connectivity"> + <step name="P2P-Intent.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="P2P-Intent.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <step name="P2P-Intent.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="P2P-Intent.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <step name="P2P-Intent.Create-Intent-XY" requires="^" + exec="onos-create-intent ${OC1} xy point of:0000000000000001/1 of:0000000000000004/1"/> + <step name="P2P-Intent.Create-Intent-YX" requires="^" + exec="onos-create-intent ${OC1} yx point of:0000000000000004/1 of:0000000000000001/1"/> + + <step name="P2P-Intent.Validate-Intent-XY-Installed" requires="^" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed" requires="^" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="P2P-Intent"/> + <dependency name="P2P-Intent.Net-Link-Down-Up" + requires="P2P-Intent.Validate-Intent-XY-Installed, + P2P-Intent.Validate-Intent-YX-Installed"/> + + <step name="P2P-Intent.Validate-Intent-XY-Installed-Still" requires="P2P-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed-Still" requires="P2P-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + + <dependency name="P2P-Intent.Link-2-Down" + requires="~P2P-Intent.Validate-Intent-XY-Installed-Still, + ~P2P-Intent.Validate-Intent-YX-Installed-Still"/> + + <step name="P2P-Intent.Validate-Intent-XY-Failed" requires="P2P-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} xy FAILED"/> + <step name="P2P-Intent.Validate-Intent-YX-Failed" requires="P2P-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} yx FAILED"/> + + <dependency name="P2P-Intent.Link-1-Up" + requires="~P2P-Intent.Validate-Intent-XY-Failed, + ~P2P-Intent.Validate-Intent-YX-Failed" /> + + <step name="P2P-Intent.Validate-Intent-XY-Installed-Again" requires="P2P-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed-Again" requires="P2P-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + + <dependency name="P2P-Intent.Ping-4" + requires="~P2P-Intent.Validate-Intent-XY-Installed-Again, + ~P2P-Intent.Validate-Intent-YX-Installed-Again"/> + + <step name="P2P-Intent.Remove-Intent-XY" requires="~P2P-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli xy"/> + <step name="P2P-Intent.Remove-Intent-YX" requires="~P2P-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli yx"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-rest.xml b/framework/src/onos/tools/test/scenarios/net-rest.xml new file mode 100644 index 00000000..fc7b1d08 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-rest.xml @@ -0,0 +1,160 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-rest" + description="Network REST API test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-REST"> + + <!-- Make sure that reactive forwarding is off --> + <step name="Net-REST.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Net-REST.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <!-- Force discovery of hosts --> + <step name="Net-REST.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="Net-REST.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <!-- Verify some links using the REST API --> + <step name="Net-REST.Query-Link-1" requires="Net-REST.Find-Host-2" + exec="find-link.py ${OC1} link1 of:0000000000000001 5 of:0000000000000006 4"/> + <step name="Net-REST.Validate-Link-1-State" requires="^" + exec="test '${link1State}' == 'ACTIVE'"/> + <step name="Net-REST.Validate-Link-1-Type" requires="^" + exec="test '${link1Type}' == 'DIRECT'"/> + <step name="Net-REST.Validate-Link-1-Src-Device" requires="^" + exec="test '${link1SrcDevice}' == 'of:0000000000000001'"/> + <step name="Net-REST.Validate-Link-1-Dst-Device" requires="^" + exec="test '${link1DstDevice}' == 'of:0000000000000006'"/> + <step name="Net-REST.Validate-Link-1-Src-Port" requires="^" + exec="test '${link1SrcPort}' == '5'"/> + <step name="Net-REST.Validate-Link-1-Dst-Port" requires="^" + exec="test '${link1DstPort}' == '4'"/> + + <step name="Net-REST.Query-Link-2" requires="Net-REST.Find-Host-2" + exec="find-link.py ${OC1} link2 of:0000000000000019 7 of:0000000000000006 3"/> + <step name="Net-REST.Validate-Link-2-State" requires="^" + exec="test '${link2State}' == 'ACTIVE'"/> + <step name="Net-REST.Validate-Link-2-Type" requires="^" + exec="test '${link2Type}' == 'DIRECT'"/> + <step name="Net-REST.Validate-Link-2-Src-Device" requires="^" + exec="test '${link2SrcDevice}' == 'of:0000000000000019'"/> + <step name="Net-REST.Validate-Link-2-Dst-Device" requires="^" + exec="test '${link2DstDevice}' == 'of:0000000000000006'"/> + <step name="Net-REST.Validate-Link-2-Src-Port" requires="^" + exec="test '${link2SrcPort}' == '7'"/> + <step name="Net-REST.Validate-Link-2-Dst-Port" requires="^" + exec="test '${link2DstPort}' == '3'"/> + + <!-- Verify the hosts using the REST API --> + <step name="Net-REST.Query-Host-1" requires="Net-REST.Find-Host-2" + exec="find-host.py ${OC1} host1 00:00:00:00:00:01/-1"/> + <step name="Net-REST.Validate-Host-1-Id" requires="^" + exec="test '${host1Id}' == '00:00:00:00:00:01/-1'"/> + <step name="Net-REST.Validate-Host-1-Mac" requires="^" + exec="test '${host1Mac}' == '00:00:00:00:00:01'"/> + <step name="Net-REST.Validate-Host-1-Ip" requires="^" + exec="test '${host1IpAddress}' == '10.0.0.1'"/> + + <step name="Net-REST.Query-Host-2" requires="Net-REST.Find-Host-2" + exec="find-host.py ${OC1} host2 00:00:00:00:00:04/-1"/> + <step name="Net-REST.Validate-Host-2-Id" requires="^" + exec="test '${host2Id}' == '00:00:00:00:00:04/-1'"/> + <step name="Net-REST.Validate-Host-2-Mac" requires="^" + exec="test '${host2Mac}' == '00:00:00:00:00:04'"/> + <step name="Net-REST.Validate-Host-2-Ip" requires="^" + exec="test '${host2IpAddress}' == '10.0.0.4'"/> + + <!-- Verify a switch using the REST API --> + <step name="Net-REST.Query-Dev-1" requires="Net-REST.Find-Host-2" + exec="find-device.py ${OC1} dev1 of:0000000000000014"/> + <step name="Net-REST.Validate-Dev1-Id" requires="^" + exec="test '${dev1Id}' == 'of:0000000000000014'"/> + <step name="Net-REST.Validate-Dev1-Type" requires="^" + exec="test '${dev1Type}' == 'SWITCH'"/> + <step name="Net-REST.Validate-Dev1-Available" requires="^" + exec="test '${dev1Available}' == 'True'"/> + <step name="Net-REST.Validate-Dev1-ChannelId" requires="^" + exec="test '${dev1IpAddress}' == '${OCN}'"/> + + <!-- Use REST API to create a point to point intent in each direction --> + <step name="Net-REST.Create-Intent-XY" requires="Net-REST.Find-Host-2" + exec="create-intent.py ${OC1} xy of:0000000000000001 1 of:0000000000000004 1"/> + <step name="Net-REST.Create-Intent-YX" requires="^" + exec="create-intent.py ${OC1} yx of:0000000000000004 1 of:0000000000000001 1"/> + + <!-- Check that the intents can be fetched via the REST API --> + <step name="Net-REST.Validate-Intent-XY-Installed" + requires="Net-REST.Create-Intent-YX" + exec="curl -f -uonos:rocks ${xyLocation}"/> + <step name="Net-REST.Validate-Intent-YX-Installed" + requires="^" + exec="curl -f -uonos:rocks ${yxLocation}"/> + + <!-- Use REST API to query flows created by the intents --> + <step name="Net-REST.Validate-Intent-XY-Flow-Installed" + requires="Net-REST.Create-Intent-YX" + exec="find-flow.py ${OC1} dev1out of:0000000000000001"/> + <step name="Net-REST.Validate-XY-Flow-State" requires="^" + exec="test '${dev1outFlowState}' == 'ADDED' -o '${dev1outFlowState}' == 'PENDING_ADD'"/> + <step name="Net-REST.Validate-XY-Flow-Port" requires="^" + exec="test ${dev1outFlowPort} -ge 1 -a ${dev1outFlowPort} -le 5"/> + + <step name="Net-REST.Validate-Intent-YX-Flow-Installed" requires="Net-REST.Create-Intent-YX" + exec="find-flow.py ${OC1} dev4out of:0000000000000004"/> + <step name="Net-REST.Validate-YX-Flow-State" requires="^" + exec="test '${dev4outFlowState}' == 'ADDED' -o '${dev4outFlowState}' == 'PENDING_ADD'"/> + <step name="Net-REST.Validate-YX-Flow-Port" requires="^" + exec="test '${dev4outFlowPort}' == '3'"/> + + <!-- Check that connectivity was established --> + <step name="Net-REST.Ping-XY" requires="Net-REST.Create-Intent-XY,Net-REST.Create-Intent-YX" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Net-REST.Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 0% packet loss"/> + + <!-- Remove the intents via the REST API --> + <step name="Net-REST.Delete-Intent-XY" + requires="Net-REST.Validate-Intent-XY-Installed, + Net-REST.Validate-Intent-YX-Installed, + Net-REST.Validate-Intent-XY-Flow-Installed, + Net-REST.Validate-Intent-YX-Flow-Installed, + Net-REST.Ping-XY, + Net-REST.Ping-YX" + exec="curl -f -X DELETE -uonos:rocks ${xyLocation}"/> + <step name="Net-REST.Delete-Intent-YX" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${yxLocation}"/> + + <!-- Use REST API to be sure that flows are no longer installed --> + <step name="Net-REST.Validate-XY-Flows-Removed" requires="Net-REST.Delete-Intent-XY" + exec="find-flow.py ${OC1} dev1out of:0000000000000001" + env="!"/> + <step name="Net-REST.Validate-YX-Flows-Removed" requires="Net-REST.Delete-Intent-YX" + exec="find-flow.py ${OC1} dev4out of:0000000000000004" + env="!"/> + + <!-- Check that the deleted intents no longer appear in the REST API --> + <step name="Net-REST.Allow-Intents-To-Purge" requires="Net-REST.Delete-Intent-XY" + exec="sleep 1"/> + <step name="Net-REST.Validate-Intent-XY-Removed" requires="Net-REST.Allow-Intents-To-Purge" + exec="curl -f -uonos:rocks ${xyLocation}" env="!"/> + <step name="Net-REST.Validate-Intent-YX-Removed" requires="Net-REST.Allow-Intents-To-Purge" + exec="curl -f -uonos:rocks ${yxLocation}" env="!"/> + + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-setup.xml b/framework/src/onos/tools/test/scenarios/net-setup.xml new file mode 100644 index 00000000..e179ec5a --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-setup.xml @@ -0,0 +1,46 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-setup" description="Network setup steps"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Setup"> + <step name="Push-Topos" exec="onos-push-topos ${OCN}"/> + <step name="Stop-Mininet-If-Needed" env="~" exec="onos-mininet stop"/> + + <step name="Wipe-Out-Data-Before" exec="onos-wipe-out"/> + + <step name="Initial-Summary-Check" requires="~Wipe-Out-Data-Before" + exec="onos-check-summary ${OC1} [0-9]* 0 0 0"/> + + <step name="Start-Mininet" + requires="Install-Apps,Initial-Summary-Check,Push-Topos,Stop-Mininet-If-Needed" + exec="onos-mininet start topos/topo att-onos.py ${ONOS_INSTANCES}"/> + + <step name="Wait-For-Mininet" requires="Start-Mininet" + exec="onos-mininet wait 10"/> + + <step name="Check-Summary" requires="Wait-For-Mininet" + exec="onos-check-summary ${OC1} [0-9]* 25 140 0"/> + + <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}" + exec="onos ${OC1} balance-masters"/> + + <step name="Pause-For-Masters" requires="Balance-Masters" if="${OC2}" + exec="sleep 10"/> + + <step name="Check-Flows" requires="~Pause-For-Masters,~Check-Summary" + exec="onos-check-flows ${OC1}"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-smoke.xml b/framework/src/onos/tools/test/scenarios/net-smoke.xml new file mode 100644 index 00000000..53a5729c --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-smoke.xml @@ -0,0 +1,44 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-smoke" description="Basic network functionality smoke test"> + <group name="Net-Smoke"> + <import file="${ONOS_SCENARIOS}/net-setup.xml"/> + + <import file="${ONOS_SCENARIOS}/net-pingall.xml" namespace="Reactive-Forwarding"/> + <dependency name="Reactive-Forwarding.Net-Pingall" requires="Net-Setup"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Reactive-Forwarding"/> + <dependency name="Reactive-Forwarding.Net-Link-Down-Up" requires="Net-Setup,~Reactive-Forwarding.Net-Pingall"/> + + <import file="${ONOS_SCENARIOS}/net-host-intent.xml"/> + <dependency name="Host-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up"/> + + <import file="${ONOS_SCENARIOS}/net-point-intent.xml"/> + <dependency name="P2P-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up,Host-Intent-Connectivity"/> + + <import file="${ONOS_SCENARIOS}/net-rest.xml"/> + <dependency name="Net-REST" requires="Net-Setup,P2P-Intent-Connectivity"/> + + <import file="${ONOS_SCENARIOS}/net-create-flows.xml"/> + <dependency name="Net-Create-Flows" requires="Net-Setup,P2P-Intent-Connectivity,Net-REST"/> + + <import file="${ONOS_SCENARIOS}/net-teardown.xml"/> + <dependency name="Net-Teardown" requires="~Host-Intent-Connectivity, + ~P2P-Intent-Connectivity, + ~Net-REST, + ~Net-Create-Flows"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-teardown.xml b/framework/src/onos/tools/test/scenarios/net-teardown.xml new file mode 100644 index 00000000..a5d93ee2 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-teardown.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="net-setup" description="Network teardown steps"> + <group name="Net-Teardown"> + <step name="Stop-Mininet" exec="onos-mininet stop"/> + <XXXstep name="Wipe-Out-Data-After" requires="~Stop-Mininet" exec="onos-wipe-out"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/prerequisites.xml b/framework/src/onos/tools/test/scenarios/prerequisites.xml new file mode 100644 index 00000000..650aa411 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/prerequisites.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="prerequisites" description="ONOS test pre-requisites"> + <group name="Prerequisites"> + <step name="Check-Environment" exec="test -n ${ONOS_ROOT} -a -n ${ONOS_NIC} -a -n ${OC1}"/> + <step name="Check-ONOS-Bits" exec="onos-check-bits"/> + + <parallel var="${OC#}"> + <step name="Check-Passwordless-Login-${#}" + exec="ssh -n -o ConnectTimeout=3 -o PasswordAuthentication=no sdn@${OC#} date"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/setup.xml b/framework/src/onos/tools/test/scenarios/setup.xml new file mode 100644 index 00000000..c26c0dea --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/setup.xml @@ -0,0 +1,47 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="setup" description="ONOS cluster setup"> + <group name="Setup"> + <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/> + <step name="Secure-SSH" exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS}" if="${ONOS_USE_SSH}"/> + + <parallel var="${OC#}"> + <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" + unless="${OCT}"/> + <step name="Uninstall-${#}" exec="onos-uninstall ${OC#}"/> + <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}" + requires="Uninstall-${#}"/> + + <step name="Install-${#}" exec="onos-install ${OC#}" + requires="Kill-${#},Push-Bits-${#},Push-Bits"/> + + <dependency name="Secure-SSH" requires="Install-${#}"/> + + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Install-${#},~Secure-SSH"/> + + <step name="Check-Nodes-${#}" exec="onos-check-nodes ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Components-${#}" + exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-${#},"/> + <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/shutdown.xml b/framework/src/onos/tools/test/scenarios/shutdown.xml new file mode 100644 index 00000000..0be21647 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/shutdown.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="shutdown" description="ONOS cluster shutdown"> + <group name="Shutdown"> + <parallel var="${OC#}"> + <step name="Stop-Service-${#}" exec="onos-service ${OC#} stop"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Stop-Service-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/smoke.xml b/framework/src/onos/tools/test/scenarios/smoke.xml new file mode 100644 index 00000000..ce8140ad --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/smoke.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="smoke" description="ONOS smoke test"> + <import file="${ONOS_SCENARIOS}/prerequisites.xml"/> + + <import file="${ONOS_SCENARIOS}/setup.xml"/> + <dependency name="Setup" requires="Prerequisites"/> + + <import file="${ONOS_SCENARIOS}/net-smoke.xml"/> + <dependency name="Net-Smoke" requires="Setup"/> + + <import file="${ONOS_SCENARIOS}/archetypes.xml"/> + <dependency name="Archetypes" requires="Setup"/> + + <import file="${ONOS_SCENARIOS}/wrapup.xml"/> + <dependency name="Wrapup" requires="~Archetypes,~Setup,~Net-Smoke"/> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/startup.xml b/framework/src/onos/tools/test/scenarios/startup.xml new file mode 100644 index 00000000..430d51c3 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/startup.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="startup" description="ONOS cluster startup"> + <group name="Startup"> + <parallel var="${OC#}"> + <step name="Start-Service-${#}" exec="onos-service ${OC#} start"/> + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Start-Service-${#}"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/tar-setup.xml b/framework/src/onos/tools/test/scenarios/tar-setup.xml new file mode 100644 index 00000000..e330b2df --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/tar-setup.xml @@ -0,0 +1,64 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="tar-setup" description="ONOS cluster setup via onos.tar.gz"> + <group name="Setup-Instances"> + <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/> + <step name="Secure-SSH" exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS}" if="${ONOS_USE_SSH}"/> + + <parallel var="${OC#}"> + <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" unless="${OCT}"/> + <step name="Uninstall-${#}" exec="onos-uninstall ${OC#}"/> + <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}" requires="Uninstall-${#}"/> + + <step name="Untar-And-Run-${#}" exec="onos-untar-and-run ${OC#}" + requires="Kill-${#},Push-Bits-${#},Push-Bits"/> + + <dependency name="Secure-SSH" requires="Untar-And-Run-${#}"/> + + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Untar-And-Run-${#},~Secure-SSH"/> + + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Components-${#}" exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#} drivers" + requires="~Wait-for-Start-${#}"/> + + <step name="Check-Nodes-${#}" exec="onos-check-nodes ${OC#} ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> + + <group name="Setup-Cluster" requires="Setup-Instances" unless="${NO_CLUSTER}"> + <step name="Form-Cluster" exec="onos-form-cluster -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} cell"/> + <parallel var="${OC#}"> + <step name="Wait-for-Start-Again-${#}" exec="onos-wait-for-start ${OC#}" + requires="Form-Cluster"/> + + <step name="Check-Logs-Again-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + <step name="Check-Components-Again-${#}" exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + <step name="Check-Apps-Again-${#}" exec="onos-check-apps ${OC#} drivers" + requires="~Wait-for-Start-Again-${#}"/> + + <step name="Check-Nodes-Again-${#}" exec="onos-check-nodes ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + </parallel> + </group> + +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/wrapup.xml b/framework/src/onos/tools/test/scenarios/wrapup.xml new file mode 100644 index 00000000..e46441d6 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/wrapup.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<scenario name="wrapup" description="ONOS test wrapup"> + <group name="Wrapup"> + <parallel var="${OC#}"> + <step name="Final-Check-Logs-${#}" exec="onos-check-logs ${OC#}"/> + <step name="Fetch-Logs-${#}" exec="onos-fetch-logs ${OC#}" + cwd="${WORKSPACE}/tmp/stc" requires="~^"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/topos/att-onos b/framework/src/onos/tools/test/topos/att-onos new file mode 100755 index 00000000..9ad918a9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos @@ -0,0 +1,10 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts ATT ONOS topology in mininet. +# ----------------------------------------------------------------------------- +cd $(dirname $0) +if [ -n "$1" ]; then + sudo python att-onos.py "$@" +else + sudo python att-onos.py 10.128.11.1 10.128.11.2 10.128.11.3 +fi diff --git a/framework/src/onos/tools/test/topos/att-onos-ext.py b/framework/src/onos/tools/test/topos/att-onos-ext.py new file mode 100644 index 00000000..a058b648 --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos-ext.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.link import TCLink + +from attmplsext import AttMplsTopoExt + +setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + net = Mininet( topo=AttMplsTopoExt(), link=TCLink, build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: att-onos-ext.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/att-onos.py b/framework/src/onos/tools/test/topos/att-onos.py new file mode 100644 index 00000000..109d335d --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.link import TCLink + +from attmpls import AttMplsTopo + +setLogLevel( 'info' ) + +def pingloop( net ): + setLogLevel( 'error' ) + try: + while True: + net.ping() + finally: + setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + Mininet.pingloop = pingloop + net = Mininet( topo=AttMplsTopo(), link=TCLink, build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + ctrl_count = ctrl_count + 1 + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: att-onos.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/attcli.py b/framework/src/onos/tools/test/topos/attcli.py new file mode 100644 index 00000000..19453204 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attcli.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +""" +CLI for test with AttMplsTopo +""" + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.util import quietRun +from mininet.log import setLogLevel, info, output, error +from mininet.node import RemoteController + +from attmplsfast import AttMplsTopo + +from subprocess import PIPE, STDOUT +from time import time +import random + +class IperfCLI( CLI ): + "CLI with iperf UDP traffic generation" + + def __init__( self, net, *args, **kwargs ): + self.iperfs = {} + self.bw = '12k' + self.mn = net + self.lastbw = {} # last bandwidth reports + self.start() + quietRun( 'rm /tmp/*.iperf /tmp/*.client' ) + CLI.__init__( self, net, *args, **kwargs ) + + def __del__( self ): + "Destructor: kill *all* iperf servers and clients!" + quietRun( 'pkill -9 iperf' ) + + def start( self ): + "Start iperf servers" + for h in sorted( self.mn.hosts ): + with open( '/tmp/%s.iperf' % h, 'w' ) as f: + cmd = 'iperf -f k -i 1 -s -u' + popen = h.popen( cmd, stdin=PIPE, stdout=f, stderr=STDOUT ) + self.iperfs[ h ] = popen + + def udpstart( self, h1, h2, bw): + "Start up a udp iperf from h1 to h2 with bandwidth bw" + # For udp we don't have to wait for startup + self.udpstop( h1 ) + h1.cmdPrint( 'iperf -c', h2.IP(), + '-t 36000 -u -b', bw, + '1>/tmp/%s.client 2>&1 &' % h1 ) + + def udpstop( self, h ): + "udpstop h: Stop udp client on host h" + h.cmdPrint( 'kill %iperf && wait %iperf' ) + h.cmdPrint( 'rm /tmp/%s.client' % h ) + + def do_udp( self, line ): + """udp h1 h2 [rate]: start a udp iperf session from h1 to h2 + rate: udp transmit rate [12k]""" + args = line.split() + if len( args ) not in ( 2, 3 ): + error( 'usage: udp h1 h2 [rate]\n' ) + return + h1, h2 = self.mn.get( *args[ :2 ] ) + bw = self.bw if len( args ) == 2 else args[ 2 ] + self.udpstart( h1, h2, bw ) + + def do_stop( self, line ): + "stop [host | all]: Stop iperf client on host" + if not line or line == 'all': + hosts = self.mn.hosts + else: + hosts = [ self.mn.get( line ) ] + for h in hosts: + self.udpstop( h ) + + def do_bw( self, line ): + "bw: show last reported iperf server ingress bandwidth" + output( "Last reported iperf UDP server input bandwidth:\n" ) + for h in self.mn.hosts: + lastout, lasttime = self.lastbw.get( h, ( '', 0 ) ) + out = h.cmd( 'tail -1 /tmp/%s.iperf' % h ) + if '---' in out or ( out == lastout and + time() - lasttime > 1.5 ): + # Stale update - don't display + out = '\n' + else: + self.lastbw[ h ] = ( out, time() ) + output( '%s:' % h, out ) + + def do_rand( self, line ): + """rand [N [bw]]: Start N random flows (default: 10) + at the given bandwidth (default: 12k) + Note: this may replace existing flows""" + args = line.split() + N = 10 + if args: + try: + N = int( args[ 0 ] ) + except: + error( 'please specify an integer' ) + return + output( 'Starting/restarting', N, 'random flows...\n' ) + bw = self.bw if len( args ) < 2 else args[ 1 ] + servers = random.sample( self.mn.hosts, N ) + clients = [] + for server in servers: + allclients = [ h for h in self.mn.hosts + if h not in clients ] + client = random.choice( allclients ) + clients.append( client ) + self.udpstart( client, server, bw ) + + def do_jobs( self, line ): + "jobs: List iperf jobs" + output( "Currently running jobs:\n" ) + for h in self.mn.hosts: + output( '%s:' % h, h.cmd( 'jobs' ).strip(), '\n' ) + + +def run( Topo=AttMplsTopo ): + "Create network and run CLI" + topo = Topo() + net = Mininet( topo=topo, controller=RemoteController ) + net.start() + info( '\n### Welcome to the custom iperf udp CLI!\n' + '###\n' + '### udp h1 h2 [bw] start iperf udp from h1 to h2\n' + '### stop h1 h2 stop iperf udp from h1 to h2\n' + '### rand [N] start/restart N random udp iperfs\n' + '### bw show last reported udp ingress bandwidth\n' + '### jobs list iperf jobs\n\n' ) + IperfCLI( net ) + net.stop() + + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() diff --git a/framework/src/onos/tools/test/topos/attmpls-intents b/framework/src/onos/tools/test/topos/attmpls-intents new file mode 100755 index 00000000..f4624595 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls-intents @@ -0,0 +1,8 @@ +#!/bin/bash +# Creates some sample intents +onos $OCI add-host-intent 00:00:00:00:00:15/-1 00:00:00:00:00:0b/-1 +onos $OCI add-host-intent 00:00:00:00:00:15/-1 00:00:00:00:00:0e/-1 +onos $OCI add-host-intent 00:00:00:00:00:10/-1 00:00:00:00:00:0a/-1 +onos $OCI add-host-intent 00:00:00:00:00:09/-1 00:00:00:00:00:0c/-1 +onos $OCI add-host-intent 00:00:00:00:00:02/-1 00:00:00:00:00:0e/-1 +onos $OCI add-host-intent 00:00:00:00:00:11/-1 00:00:00:00:00:05/-1 diff --git a/framework/src/onos/tools/test/topos/attmpls.json b/framework/src/onos/tools/test/topos/attmpls.json new file mode 100644 index 00000000..096a78fa --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls.json @@ -0,0 +1,58 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "mac": "000000000001", "annotations": { "name": "CMBR", "latitude": 42.373730, "longitude": -71.109734 }, "type": "SWITCH" }, + { "alias": "s2", "uri": "of:0000000000000002", "mac": "000000000002", "annotations": { "name": "CHCG", "latitude": 41.877461, "longitude": -87.642892 }, "type": "SWITCH" }, + { "alias": "s3", "uri": "of:0000000000000003", "mac": "000000000003", "annotations": { "name": "CLEV", "latitude": 41.498928, "longitude": -81.695217 }, "type": "SWITCH" }, + { "alias": "s4", "uri": "of:0000000000000004", "mac": "000000000004", "annotations": { "name": "RLGH", "latitude": 35.780150, "longitude": -78.644026 }, "type": "SWITCH" }, + { "alias": "s5", "uri": "of:0000000000000005", "mac": "000000000005", "annotations": { "name": "ATLN", "latitude": 33.749017, "longitude": -84.394168 }, "type": "SWITCH" }, + { "alias": "s6", "uri": "of:0000000000000006", "mac": "000000000006", "annotations": { "name": "PHLA", "latitude": 39.952906, "longitude": -75.172278 }, "type": "SWITCH" }, + { "alias": "s7", "uri": "of:0000000000000007", "mac": "000000000007", "annotations": { "name": "WASH", "latitude": 38.906696, "longitude": -77.035509 }, "type": "SWITCH" }, + { "alias": "s8", "uri": "of:0000000000000008", "mac": "000000000008", "annotations": { "name": "NSVL", "latitude": 36.166410, "longitude": -86.787305 }, "type": "SWITCH" }, + { "alias": "s9", "uri": "of:0000000000000009", "mac": "000000000009", "annotations": { "name": "STLS", "latitude": 38.626418, "longitude": -90.198143 }, "type": "SWITCH" }, + { "alias": "s10", "uri": "of:000000000000000a", "mac": "00000000000a", "annotations": { "name": "NWOR", "latitude": 29.951475, "longitude": -90.078434 }, "type": "SWITCH" }, + { "alias": "s11", "uri": "of:000000000000000b", "mac": "00000000000b", "annotations": { "name": "HSTN", "latitude": 29.763249, "longitude": -95.368332 }, "type": "SWITCH" }, + { "alias": "s12", "uri": "of:000000000000000c", "mac": "00000000000c", "annotations": { "name": "SNAN", "latitude": 29.424331, "longitude": -98.491745 }, "type": "SWITCH" }, + { "alias": "s13", "uri": "of:000000000000000d", "mac": "00000000000d", "annotations": { "name": "DLLS", "latitude": 32.777665, "longitude": -96.802064 }, "type": "SWITCH" }, + { "alias": "s14", "uri": "of:000000000000000e", "mac": "00000000000e", "annotations": { "name": "ORLD", "latitude": 28.538641, "longitude": -81.381110 }, "type": "SWITCH" }, + { "alias": "s15", "uri": "of:000000000000000f", "mac": "00000000000f", "annotations": { "name": "DNVR", "latitude": 39.736623, "longitude": -104.984887 }, "type": "SWITCH" }, + { "alias": "s16", "uri": "of:0000000000000010", "mac": "000000000010", "annotations": { "name": "KSCY", "latitude": 39.100725, "longitude": -94.581228 }, "type": "SWITCH" }, + { "alias": "s17", "uri": "of:0000000000000011", "mac": "000000000011", "annotations": { "name": "SNFN", "latitude": 37.779751, "longitude": -122.409791 }, "type": "SWITCH" }, + { "alias": "s18", "uri": "of:0000000000000012", "mac": "000000000012", "annotations": { "name": "SCRM", "latitude": 38.581001, "longitude": -121.497844 }, "type": "SWITCH" }, + { "alias": "s19", "uri": "of:0000000000000013", "mac": "000000000013", "annotations": { "name": "PTLD", "latitude": 45.523317, "longitude": -122.677768 }, "type": "SWITCH" }, + { "alias": "s20", "uri": "of:0000000000000014", "mac": "000000000014", "annotations": { "name": "STTL", "latitude": 47.607326, "longitude": -122.331786 }, "type": "SWITCH" }, + { "alias": "s21", "uri": "of:0000000000000015", "mac": "000000000015", "annotations": { "name": "SLKC", "latitude": 40.759577, "longitude": -111.895079 }, "type": "SWITCH" }, + { "alias": "s22", "uri": "of:0000000000000016", "mac": "000000000016", "annotations": { "name": "LA03", "latitude": 34.056346, "longitude": -118.235951 }, "type": "SWITCH" }, + { "alias": "s23", "uri": "of:0000000000000017", "mac": "000000000017", "annotations": { "name": "SNDG", "latitude": 32.714564, "longitude": -117.153528 }, "type": "SWITCH" }, + { "alias": "s24", "uri": "of:0000000000000018", "mac": "000000000018", "annotations": { "name": "PHNX", "latitude": 33.448289, "longitude": -112.076299 }, "type": "SWITCH" }, + { "alias": "s25", "uri": "of:0000000000000019", "mac": "000000000019", "annotations": { "name": "NY54", "latitude": 40.728270, "longitude": -73.994483 }, "type": "SWITCH" } + ], + + "hosts": [ + { "alias": "h1", "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000000000000001/1", "ip": "10.0.0.1", "annotations": { "name": "CMBR", "latitude": 43.355715, "longitude": -69.528243 } }, + { "alias": "h2", "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000000000000002/1", "ip": "10.0.0.2", "annotations": { "name": "CHCG", "latitude": 43.632679, "longitude": -88.772526 } }, + { "alias": "h3", "mac": "00:00:00:00:00:03", "vlan": -1, "location": "of:0000000000000003/1", "ip": "10.0.0.3", "annotations": { "name": "CLEV", "latitude": 42.756945, "longitude": -79.831317 } }, + { "alias": "h4", "mac": "00:00:00:00:00:04", "vlan": -1, "location": "of:0000000000000004/1", "ip": "10.0.0.4", "annotations": { "name": "RLGH", "latitude": 36.972249, "longitude": -76.667163 } }, + { "alias": "h5", "mac": "00:00:00:00:00:05", "vlan": -1, "location": "of:0000000000000005/1", "ip": "10.0.0.5", "annotations": { "name": "ATLN", "latitude": 35.427493, "longitude": -83.885831 } }, + { "alias": "h6", "mac": "00:00:00:00:00:06", "vlan": -1, "location": "of:0000000000000006/1", "ip": "10.0.0.6", "annotations": { "name": "PHLA", "latitude": 39.208113, "longitude": -73.421341 } }, + { "alias": "h7", "mac": "00:00:00:00:00:07", "vlan": -1, "location": "of:0000000000000007/1", "ip": "10.0.0.7", "annotations": { "name": "WASH", "latitude": 40.133860, "longitude": -79.238299 } }, + { "alias": "h8", "mac": "00:00:00:00:00:08", "vlan": -1, "location": "of:0000000000000008/1", "ip": "10.0.0.8", "annotations": { "name": "NSVL", "latitude": 37.407589, "longitude": -84.415068 } }, + { "alias": "h9", "mac": "00:00:00:00:00:09", "vlan": -1, "location": "of:0000000000000009/1", "ip": "10.0.0.9", "annotations": { "name": "STLS", "latitude": 40.066810, "longitude": -90.932405 } }, + { "alias": "h10", "mac": "00:00:00:00:00:0a", "vlan": -1, "location": "of:000000000000000a/1", "ip": "10.0.0.10", "annotations": { "name": "NWOR", "latitude": 31.470982, "longitude": -88.779353 } }, + { "alias": "h11", "mac": "00:00:00:00:00:0b", "vlan": -1, "location": "of:000000000000000b/1", "ip": "10.0.0.11", "annotations": { "name": "HSTN", "latitude": 31.136858, "longitude": -94.351656 } }, + { "alias": "h12", "mac": "00:00:00:00:00:0c", "vlan": -1, "location": "of:000000000000000c/1", "ip": "10.0.0.12", "annotations": { "name": "SNAN", "latitude": 28.040975, "longitude": -99.169527 } }, + { "alias": "h13", "mac": "00:00:00:00:00:0d", "vlan": -1, "location": "of:000000000000000d/1", "ip": "10.0.0.13", "annotations": { "name": "DLLS", "latitude": 31.899825, "longitude": -99.287263 } }, + { "alias": "h14", "mac": "00:00:00:00:00:0e", "vlan": -1, "location": "of:000000000000000e/1", "ip": "10.0.0.14", "annotations": { "name": "ORLD", "latitude": 26.670509, "longitude": -81.291920 } }, + { "alias": "h15", "mac": "00:00:00:00:00:0f", "vlan": -1, "location": "of:000000000000000f/1", "ip": "10.0.0.15", "annotations": { "name": "DNVR", "latitude": 40.888148, "longitude": -103.459878 } }, + { "alias": "h16", "mac": "00:00:00:00:00:10", "vlan": -1, "location": "of:0000000000000010/1", "ip": "10.0.0.16", "annotations": { "name": "KSCY", "latitude": 40.545088, "longitude": -93.734002 } }, + { "alias": "h17", "mac": "00:00:00:00:00:11", "vlan": -1, "location": "of:0000000000000011/1", "ip": "10.0.0.17", "annotations": { "name": "SNFN", "latitude": 39.081743, "longitude": -124.330172 } }, + { "alias": "h18", "mac": "00:00:00:00:00:12", "vlan": -1, "location": "of:0000000000000012/1", "ip": "10.0.0.18", "annotations": { "name": "SCRM", "latitude": 40.107468, "longitude": -120.424689 } }, + { "alias": "h19", "mac": "00:00:00:00:00:13", "vlan": -1, "location": "of:0000000000000013/1", "ip": "10.0.0.19", "annotations": { "name": "PTLD", "latitude": 44.383051, "longitude": -124.767594 } }, + { "alias": "h20", "mac": "00:00:00:00:00:14", "vlan": -1, "location": "of:0000000000000014/1", "ip": "10.0.0.20", "annotations": { "name": "STTL", "latitude": 48.832627, "longitude": -120.298441 } }, + { "alias": "h21", "mac": "00:00:00:00:00:15", "vlan": -1, "location": "of:0000000000000015/1", "ip": "10.0.0.21", "annotations": { "name": "SLKC", "latitude": 42.301734, "longitude": -111.217297 } }, + { "alias": "h22", "mac": "00:00:00:00:00:16", "vlan": -1, "location": "of:0000000000000016/1", "ip": "10.0.0.22", "annotations": { "name": "LA03", "latitude": 33.224634, "longitude": -121.532943 } }, + { "alias": "h23", "mac": "00:00:00:00:00:17", "vlan": -1, "location": "of:0000000000000017/1", "ip": "10.0.0.23", "annotations": { "name": "SNDG", "latitude": 31.834607, "longitude": -118.847982 } }, + { "alias": "h24", "mac": "00:00:00:00:00:18", "vlan": -1, "location": "of:0000000000000018/1", "ip": "10.0.0.24", "annotations": { "name": "PHNX", "latitude": 34.662290, "longitude": -110.946662 } }, + { "alias": "h25", "mac": "00:00:00:00:00:19", "vlan": -1, "location": "of:0000000000000019/1", "ip": "10.0.0.25", "annotations": { "name": "NY54", "latitude": 42.395459, "longitude": -75.293563 } } + ] + +} diff --git a/framework/src/onos/tools/test/topos/attmpls.py b/framework/src/onos/tools/test/topos/attmpls.py new file mode 100644 index 00000000..4fe71154 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class AttMplsTopo( Topo ): + "Internet Topology Zoo Specimen." + + def __init__( self ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self ) + + # add nodes, switches first... + NY54 = self.addSwitch( 's25' ) # 40.728270, -73.994483 + CMBR = self.addSwitch( 's1' ) # 42.373730, -71.109734 + CHCG = self.addSwitch( 's2', protocols='OpenFlow13' ) # 41.877461, -87.642892 + CLEV = self.addSwitch( 's3' ) # 41.498928, -81.695217 + RLGH = self.addSwitch( 's4' ) # 35.780150, -78.644026 + ATLN = self.addSwitch( 's5' ) # 33.749017, -84.394168 + PHLA = self.addSwitch( 's6' ) # 39.952906, -75.172278 + WASH = self.addSwitch( 's7' ) # 38.906696, -77.035509 + NSVL = self.addSwitch( 's8' ) # 36.166410, -86.787305 + STLS = self.addSwitch( 's9', protocols='OpenFlow13' ) # 38.626418, -90.198143 + NWOR = self.addSwitch( 's10' ) # 29.951475, -90.078434 + HSTN = self.addSwitch( 's11' ) # 29.763249, -95.368332 + SNAN = self.addSwitch( 's12' ) # 29.424331, -98.491745 + DLLS = self.addSwitch( 's13' ) # 32.777665, -96.802064 + ORLD = self.addSwitch( 's14' ) # 28.538641, -81.381110 + DNVR = self.addSwitch( 's15' ) # 39.736623, -104.984887 + KSCY = self.addSwitch( 's16' ) # 39.100725, -94.581228 + SNFN = self.addSwitch( 's17' ) # 37.779751, -122.409791 + SCRM = self.addSwitch( 's18' ) # 38.581001, -121.497844 + PTLD = self.addSwitch( 's19' ) # 45.523317, -122.677768 + STTL = self.addSwitch( 's20' ) # 47.607326, -122.331786 + SLKC = self.addSwitch( 's21' ) # 40.759577, -111.895079 + LA03 = self.addSwitch( 's22', protocols='OpenFlow13' ) # 34.056346, -118.235951 + SNDG = self.addSwitch( 's23' ) # 32.714564, -117.153528 + PHNX = self.addSwitch( 's24' ) # 33.448289, -112.076299 + + # ... and now hosts + NY54_host = self.addHost( 'h25' ) + CMBR_host = self.addHost( 'h1' ) + CHCG_host = self.addHost( 'h2' ) + CLEV_host = self.addHost( 'h3' ) + RLGH_host = self.addHost( 'h4' ) + ATLN_host = self.addHost( 'h5' ) + PHLA_host = self.addHost( 'h6' ) + WASH_host = self.addHost( 'h7' ) + NSVL_host = self.addHost( 'h8' ) + STLS_host = self.addHost( 'h9' ) + NWOR_host = self.addHost( 'h10' ) + HSTN_host = self.addHost( 'h11' ) + SNAN_host = self.addHost( 'h12' ) + DLLS_host = self.addHost( 'h13' ) + ORLD_host = self.addHost( 'h14' ) + DNVR_host = self.addHost( 'h15' ) + KSCY_host = self.addHost( 'h16' ) + SNFN_host = self.addHost( 'h17' ) + SCRM_host = self.addHost( 'h18' ) + PTLD_host = self.addHost( 'h19' ) + STTL_host = self.addHost( 'h20' ) + SLKC_host = self.addHost( 'h21' ) + LA03_host = self.addHost( 'h22' ) + SNDG_host = self.addHost( 'h23' ) + PHNX_host = self.addHost( 'h24' ) + + # add edges between switch and corresponding host + self.addLink( NY54 , NY54_host ) + self.addLink( CMBR , CMBR_host ) + self.addLink( CHCG , CHCG_host ) + self.addLink( CLEV , CLEV_host ) + self.addLink( RLGH , RLGH_host ) + self.addLink( ATLN , ATLN_host ) + self.addLink( PHLA , PHLA_host ) + self.addLink( WASH , WASH_host ) + self.addLink( NSVL , NSVL_host ) + self.addLink( STLS , STLS_host ) + self.addLink( NWOR , NWOR_host ) + self.addLink( HSTN , HSTN_host ) + self.addLink( SNAN , SNAN_host ) + self.addLink( DLLS , DLLS_host ) + self.addLink( ORLD , ORLD_host ) + self.addLink( DNVR , DNVR_host ) + self.addLink( KSCY , KSCY_host ) + self.addLink( SNFN , SNFN_host ) + self.addLink( SCRM , SCRM_host ) + self.addLink( PTLD , PTLD_host ) + self.addLink( STTL , STTL_host ) + self.addLink( SLKC , SLKC_host ) + self.addLink( LA03 , LA03_host ) + self.addLink( SNDG , SNDG_host ) + self.addLink( PHNX , PHNX_host ) + + # add edges between switches + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CHCG, bw=10, delay='0.806374975652ms') + self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms') + self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms') + self.addLink( NY54 , WASH, bw=10, delay='0.605826192092ms') + self.addLink( CMBR , PHLA, bw=10, delay='1.4018238197ms') + self.addLink( CHCG , CLEV, bw=10, delay='0.232315346482ms') + self.addLink( CHCG , PHLA, bw=10, delay='1.07297714274ms') + self.addLink( CHCG , STLS, bw=10, delay='1.12827896944ms') + self.addLink( CHCG , DNVR, bw=10, delay='1.35964770335ms') + self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms') + self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms') + self.addLink( CHCG , SNFN, bw=10, delay='0.620743405435ms') + self.addLink( CHCG , STTL, bw=10, delay='0.93027212534ms') + self.addLink( CHCG , SLKC, bw=10, delay='0.735621751348ms') + self.addLink( CLEV , NSVL, bw=10, delay='0.523419372248ms') + self.addLink( CLEV , STLS, bw=10, delay='1.00360290845ms') + self.addLink( CLEV , PHLA, bw=10, delay='0.882912133249ms') + self.addLink( RLGH , ATLN, bw=10, delay='1.1644489729ms') + self.addLink( RLGH , WASH, bw=10, delay='1.48176810502ms') + self.addLink( ATLN , WASH, bw=10, delay='0.557636936322ms') + self.addLink( ATLN , NSVL, bw=10, delay='1.32869749865ms') + self.addLink( ATLN , STLS, bw=10, delay='0.767705554748ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , ORLD, bw=10, delay='1.46119152532ms') + self.addLink( PHLA , WASH, bw=10, delay='0.372209320106ms') + self.addLink( NSVL , STLS, bw=10, delay='1.43250491305ms') + self.addLink( NSVL , DLLS, bw=10, delay='1.67698215288ms') + self.addLink( STLS , DLLS, bw=10, delay='0.256389964194ms') + self.addLink( STLS , KSCY, bw=10, delay='0.395511571791ms') + self.addLink( STLS , LA03, bw=10, delay='0.257085227363ms') + self.addLink( NWOR , HSTN, bw=10, delay='0.0952906633914ms') + self.addLink( NWOR , DLLS, bw=10, delay='1.60231329739ms') + self.addLink( NWOR , ORLD, bw=10, delay='0.692731063896ms') + self.addLink( HSTN , SNAN, bw=10, delay='0.284150653798ms') + self.addLink( HSTN , DLLS, bw=10, delay='1.65690128332ms') + self.addLink( HSTN , ORLD, bw=10, delay='0.731886304782ms') + self.addLink( SNAN , PHNX, bw=10, delay='1.34258627257ms') + self.addLink( SNAN , DLLS, bw=10, delay='1.50063532341ms') + self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms') + self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms') + self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms') + self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms') + self.addLink( DLLS , SNFN, bw=10, delay='0.74304274592ms') + self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms') + self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms') + self.addLink( DNVR , KSCY, bw=10, delay='0.223328790403ms') + self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms') + self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms') + self.addLink( DNVR , SLKC, bw=10, delay='0.631898982721ms') + self.addLink( KSCY , SNFN, bw=10, delay='0.922778522233ms') + self.addLink( SNFN , SCRM, bw=10, delay='0.630352278097ms') + self.addLink( SNFN , PTLD, bw=10, delay='0.828572513655ms') + self.addLink( SNFN , STTL, bw=10, delay='1.54076081649ms') + self.addLink( SNFN , SLKC, bw=10, delay='0.621507502625ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SCRM , SLKC, bw=10, delay='0.461350343644ms') + self.addLink( PTLD , STTL, bw=10, delay='1.17591515181ms') + self.addLink( SLKC , LA03, bw=10, delay='0.243225267023ms') + self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms') + self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms') + self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms') + self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms') + self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') + +topos = { 'att': ( lambda: AttMplsTopo() ) } diff --git a/framework/src/onos/tools/test/topos/attmplsfast.py b/framework/src/onos/tools/test/topos/attmplsfast.py new file mode 100644 index 00000000..7f904462 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmplsfast.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class AttMplsTopo( Topo ): + "Internet Topology Zoo Specimen." + + def build( self ): + "Create a topology." + + # add nodes, switches first... + CMBR = self.addSwitch( 's1' ) # 42.373730, -71.109734 + CHCG = self.addSwitch( 's2' ) # 41.877461, -87.642892 + CLEV = self.addSwitch( 's3' ) # 41.498928, -81.695217 + RLGH = self.addSwitch( 's4' ) # 35.780150, -78.644026 + ATLN = self.addSwitch( 's5' ) # 33.749017, -84.394168 + PHLA = self.addSwitch( 's6' ) # 39.952906, -75.172278 + WASH = self.addSwitch( 's7' ) # 38.906696, -77.035509 + NSVL = self.addSwitch( 's8' ) # 36.166410, -86.787305 + STLS = self.addSwitch( 's9' ) # 38.626418, -90.198143 + NWOR = self.addSwitch( 's10' ) # 29.951475, -90.078434 + HSTN = self.addSwitch( 's11' ) # 29.763249, -95.368332 + SNAN = self.addSwitch( 's12' ) # 29.424331, -98.491745 + DLLS = self.addSwitch( 's13' ) # 32.777665, -96.802064 + ORLD = self.addSwitch( 's14' ) # 28.538641, -81.381110 + DNVR = self.addSwitch( 's15' ) # 39.736623, -104.984887 + KSCY = self.addSwitch( 's16' ) # 39.100725, -94.581228 + SNFN = self.addSwitch( 's17' ) # 37.779751, -122.409791 + SCRM = self.addSwitch( 's18' ) # 38.581001, -121.497844 + PTLD = self.addSwitch( 's19' ) # 45.523317, -122.677768 + STTL = self.addSwitch( 's20' ) # 47.607326, -122.331786 + SLKC = self.addSwitch( 's21' ) # 40.759577, -111.895079 + LA03 = self.addSwitch( 's22' ) # 34.056346, -118.235951 + SNDG = self.addSwitch( 's23' ) # 32.714564, -117.153528 + PHNX = self.addSwitch( 's24' ) # 33.448289, -112.076299 + NY54 = self.addSwitch( 's25' ) # 40.728270, -73.994483 + + # ... and now hosts + CMBR_host = self.addHost( 'h1' ) + CHCG_host = self.addHost( 'h2' ) + CLEV_host = self.addHost( 'h3' ) + RLGH_host = self.addHost( 'h4' ) + ATLN_host = self.addHost( 'h5' ) + PHLA_host = self.addHost( 'h6' ) + WASH_host = self.addHost( 'h7' ) + NSVL_host = self.addHost( 'h8' ) + STLS_host = self.addHost( 'h9' ) + NWOR_host = self.addHost( 'h10' ) + HSTN_host = self.addHost( 'h11' ) + SNAN_host = self.addHost( 'h12' ) + DLLS_host = self.addHost( 'h13' ) + ORLD_host = self.addHost( 'h14' ) + DNVR_host = self.addHost( 'h15' ) + KSCY_host = self.addHost( 'h16' ) + SNFN_host = self.addHost( 'h17' ) + SCRM_host = self.addHost( 'h18' ) + PTLD_host = self.addHost( 'h19' ) + STTL_host = self.addHost( 'h20' ) + SLKC_host = self.addHost( 'h21' ) + LA03_host = self.addHost( 'h22' ) + SNDG_host = self.addHost( 'h23' ) + PHNX_host = self.addHost( 'h24' ) + NY54_host = self.addHost( 'h25' ) + + # add edges between switch and corresponding host + self.addLink( NY54 , NY54_host ) + self.addLink( CMBR , CMBR_host ) + self.addLink( CHCG , CHCG_host ) + self.addLink( CLEV , CLEV_host ) + self.addLink( RLGH , RLGH_host ) + self.addLink( ATLN , ATLN_host ) + self.addLink( PHLA , PHLA_host ) + self.addLink( WASH , WASH_host ) + self.addLink( NSVL , NSVL_host ) + self.addLink( STLS , STLS_host ) + self.addLink( NWOR , NWOR_host ) + self.addLink( HSTN , HSTN_host ) + self.addLink( SNAN , SNAN_host ) + self.addLink( DLLS , DLLS_host ) + self.addLink( ORLD , ORLD_host ) + self.addLink( DNVR , DNVR_host ) + self.addLink( KSCY , KSCY_host ) + self.addLink( SNFN , SNFN_host ) + self.addLink( SCRM , SCRM_host ) + self.addLink( PTLD , PTLD_host ) + self.addLink( STTL , STTL_host ) + self.addLink( SLKC , SLKC_host ) + self.addLink( LA03 , LA03_host ) + self.addLink( SNDG , SNDG_host ) + self.addLink( PHNX , PHNX_host ) + + # add edges between switches + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CHCG) + self.addLink( NY54 , PHLA) + self.addLink( NY54 , PHLA) + self.addLink( NY54 , WASH) + self.addLink( CMBR , PHLA) + self.addLink( CHCG , CLEV) + self.addLink( CHCG , PHLA) + self.addLink( CHCG , STLS) + self.addLink( CHCG , DNVR) + self.addLink( CHCG , KSCY) + self.addLink( CHCG , KSCY) + self.addLink( CHCG , SNFN) + self.addLink( CHCG , STTL) + self.addLink( CHCG , SLKC) + self.addLink( CLEV , NSVL) + self.addLink( CLEV , STLS) + self.addLink( CLEV , PHLA) + self.addLink( RLGH , ATLN) + self.addLink( RLGH , WASH) + self.addLink( ATLN , WASH) + self.addLink( ATLN , NSVL) + self.addLink( ATLN , STLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , ORLD) + self.addLink( PHLA , WASH) + self.addLink( NSVL , STLS) + self.addLink( NSVL , DLLS) + self.addLink( STLS , DLLS) + self.addLink( STLS , KSCY) + self.addLink( STLS , LA03) + self.addLink( NWOR , HSTN) + self.addLink( NWOR , DLLS) + self.addLink( NWOR , ORLD) + self.addLink( HSTN , SNAN) + self.addLink( HSTN , DLLS) + self.addLink( HSTN , ORLD) + self.addLink( SNAN , PHNX) + self.addLink( SNAN , DLLS) + self.addLink( DLLS , DNVR) + self.addLink( DLLS , DNVR) + self.addLink( DLLS , KSCY) + self.addLink( DLLS , KSCY) + self.addLink( DLLS , SNFN) + self.addLink( DLLS , LA03) + self.addLink( DLLS , LA03) + self.addLink( DNVR , KSCY) + self.addLink( DNVR , SNFN) + self.addLink( DNVR , SNFN) + self.addLink( DNVR , SLKC) + self.addLink( KSCY , SNFN) + self.addLink( SNFN , SCRM) + self.addLink( SNFN , PTLD) + self.addLink( SNFN , STTL) + self.addLink( SNFN , SLKC) + self.addLink( SNFN , LA03) + self.addLink( SNFN , LA03) + self.addLink( SNFN , LA03) + self.addLink( SCRM , SLKC) + self.addLink( PTLD , STTL) + self.addLink( SLKC , LA03) + self.addLink( LA03 , SNDG) + self.addLink( LA03 , SNDG) + self.addLink( LA03 , PHNX) + self.addLink( LA03 , PHNX) + self.addLink( SNDG , PHNX) + +topos = { 'att': ( lambda: AttMplsTopo() ) } diff --git a/framework/src/onos/tools/test/topos/chordal.py b/framework/src/onos/tools/test/topos/chordal.py new file mode 100644 index 00000000..22f9ca19 --- /dev/null +++ b/framework/src/onos/tools/test/topos/chordal.py @@ -0,0 +1,402 @@ +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class chordalTopo( Topo ): + + def __init__( self, **opts ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self, **opts ) + + # add nodes, switches first... + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + s8 = self.addSwitch( 's8' ) + s9 = self.addSwitch( 's9' ) + s10 = self.addSwitch( 's10' ) + s11 = self.addSwitch( 's11' ) + s12 = self.addSwitch( 's12' ) + s13 = self.addSwitch( 's13' ) + s14 = self.addSwitch( 's14' ) + s15 = self.addSwitch( 's15' ) + s16 = self.addSwitch( 's16' ) + s17 = self.addSwitch( 's17' ) + s18 = self.addSwitch( 's18' ) + s19 = self.addSwitch( 's19' ) + s20 = self.addSwitch( 's20' ) + s21 = self.addSwitch( 's21' ) + s22 = self.addSwitch( 's22' ) + s23 = self.addSwitch( 's23' ) + s24 = self.addSwitch( 's24' ) + s25 = self.addSwitch( 's25' ) + + # ... and now hosts + s1_host = self.addHost( 'h1' ) + s2_host = self.addHost( 'h2' ) + s3_host = self.addHost( 'h3' ) + s4_host = self.addHost( 'h4' ) + s5_host = self.addHost( 'h5' ) + s6_host = self.addHost( 'h6' ) + s7_host = self.addHost( 'h7' ) + s8_host = self.addHost( 'h8' ) + s9_host = self.addHost( 'h9' ) + s10_host = self.addHost( 'h10' ) + s11_host = self.addHost( 'h11' ) + s12_host = self.addHost( 'h12' ) + s13_host = self.addHost( 'h13' ) + s14_host = self.addHost( 'h14' ) + s15_host = self.addHost( 'h15' ) + s16_host = self.addHost( 'h16' ) + s17_host = self.addHost( 'h17' ) + s18_host = self.addHost( 'h18' ) + s19_host = self.addHost( 'h19' ) + s20_host = self.addHost( 'h20' ) + s21_host = self.addHost( 'h21' ) + s22_host = self.addHost( 'h22' ) + s23_host = self.addHost( 'h23' ) + s24_host = self.addHost( 'h24' ) + s25_host = self.addHost( 'h25' ) + + # add edges between switch and corresponding host + self.addLink( s1 , s1_host ) + self.addLink( s2 , s2_host ) + self.addLink( s3 , s3_host ) + self.addLink( s4 , s4_host ) + self.addLink( s5 , s5_host ) + self.addLink( s6 , s6_host ) + self.addLink( s7 , s7_host ) + self.addLink( s8 , s8_host ) + self.addLink( s9 , s9_host ) + self.addLink( s10 , s10_host ) + self.addLink( s11 , s11_host ) + self.addLink( s12 , s12_host ) + self.addLink( s13 , s13_host ) + self.addLink( s14 , s14_host ) + self.addLink( s15 , s15_host ) + self.addLink( s16 , s16_host ) + self.addLink( s17 , s17_host ) + self.addLink( s18 , s18_host ) + self.addLink( s19 , s19_host ) + self.addLink( s20 , s20_host ) + self.addLink( s21 , s21_host ) + self.addLink( s22 , s22_host ) + self.addLink( s23 , s23_host ) + self.addLink( s24 , s24_host ) + self.addLink( s25 , s25_host ) + self.addLink(s1, s2) + self.addLink(s1, s3) + self.addLink(s1, s4) + self.addLink(s1, s5) + self.addLink(s1, s6) + self.addLink(s1, s7) + self.addLink(s1, s8) + self.addLink(s1, s9) + self.addLink(s1, s10) + self.addLink(s1, s11) + self.addLink(s1, s12) + self.addLink(s1, s13) + self.addLink(s1, s14) + self.addLink(s1, s15) + self.addLink(s1, s16) + self.addLink(s1, s17) + self.addLink(s1, s18) + self.addLink(s1, s19) + self.addLink(s1, s20) + self.addLink(s1, s21) + self.addLink(s1, s22) + self.addLink(s1, s23) + self.addLink(s1, s24) + self.addLink(s1, s25) + self.addLink(s2, s3) + self.addLink(s2, s4) + self.addLink(s2, s5) + self.addLink(s2, s6) + self.addLink(s2, s7) + self.addLink(s2, s8) + self.addLink(s2, s9) + self.addLink(s2, s10) + self.addLink(s2, s11) + self.addLink(s2, s12) + self.addLink(s2, s13) + self.addLink(s2, s14) + self.addLink(s2, s15) + self.addLink(s2, s16) + self.addLink(s2, s17) + self.addLink(s2, s18) + self.addLink(s2, s19) + self.addLink(s2, s20) + self.addLink(s2, s21) + self.addLink(s2, s22) + self.addLink(s2, s23) + self.addLink(s2, s24) + self.addLink(s2, s25) + self.addLink(s3, s4) + self.addLink(s3, s5) + self.addLink(s3, s6) + self.addLink(s3, s7) + self.addLink(s3, s8) + self.addLink(s3, s9) + self.addLink(s3, s10) + self.addLink(s3, s11) + self.addLink(s3, s12) + self.addLink(s3, s13) + self.addLink(s3, s14) + self.addLink(s3, s15) + self.addLink(s3, s16) + self.addLink(s3, s17) + self.addLink(s3, s18) + self.addLink(s3, s19) + self.addLink(s3, s20) + self.addLink(s3, s21) + self.addLink(s3, s22) + self.addLink(s3, s23) + self.addLink(s3, s24) + self.addLink(s3, s25) + self.addLink(s4, s5) + self.addLink(s4, s6) + self.addLink(s4, s7) + self.addLink(s4, s8) + self.addLink(s4, s9) + self.addLink(s4, s10) + self.addLink(s4, s11) + self.addLink(s4, s12) + self.addLink(s4, s13) + self.addLink(s4, s14) + self.addLink(s4, s15) + self.addLink(s4, s16) + self.addLink(s4, s17) + self.addLink(s4, s18) + self.addLink(s4, s19) + self.addLink(s4, s20) + self.addLink(s4, s21) + self.addLink(s4, s22) + self.addLink(s4, s23) + self.addLink(s4, s24) + self.addLink(s4, s25) + self.addLink(s5, s6) + self.addLink(s5, s7) + self.addLink(s5, s8) + self.addLink(s5, s9) + self.addLink(s5, s10) + self.addLink(s5, s11) + self.addLink(s5, s12) + self.addLink(s5, s13) + self.addLink(s5, s14) + self.addLink(s5, s15) + self.addLink(s5, s16) + self.addLink(s5, s17) + self.addLink(s5, s18) + self.addLink(s5, s19) + self.addLink(s5, s20) + self.addLink(s5, s21) + self.addLink(s5, s22) + self.addLink(s5, s23) + self.addLink(s5, s24) + self.addLink(s5, s25) + self.addLink(s6, s7) + self.addLink(s6, s8) + self.addLink(s6, s9) + self.addLink(s6, s10) + self.addLink(s6, s11) + self.addLink(s6, s12) + self.addLink(s6, s13) + self.addLink(s6, s14) + self.addLink(s6, s15) + self.addLink(s6, s16) + self.addLink(s6, s17) + self.addLink(s6, s18) + self.addLink(s6, s19) + self.addLink(s6, s20) + self.addLink(s6, s21) + self.addLink(s6, s22) + self.addLink(s6, s23) + self.addLink(s6, s24) + self.addLink(s6, s25) + self.addLink(s7, s8) + self.addLink(s7, s9) + self.addLink(s7, s10) + self.addLink(s7, s11) + self.addLink(s7, s12) + self.addLink(s7, s13) + self.addLink(s7, s14) + self.addLink(s7, s15) + self.addLink(s7, s16) + self.addLink(s7, s17) + self.addLink(s7, s18) + self.addLink(s7, s19) + self.addLink(s7, s20) + self.addLink(s7, s21) + self.addLink(s7, s22) + self.addLink(s7, s23) + self.addLink(s7, s24) + self.addLink(s7, s25) + self.addLink(s8, s9) + self.addLink(s8, s10) + self.addLink(s8, s11) + self.addLink(s8, s12) + self.addLink(s8, s13) + self.addLink(s8, s14) + self.addLink(s8, s15) + self.addLink(s8, s16) + self.addLink(s8, s17) + self.addLink(s8, s18) + self.addLink(s8, s19) + self.addLink(s8, s20) + self.addLink(s8, s21) + self.addLink(s8, s22) + self.addLink(s8, s23) + self.addLink(s8, s24) + self.addLink(s8, s25) + self.addLink(s9, s10) + self.addLink(s9, s11) + self.addLink(s9, s12) + self.addLink(s9, s13) + self.addLink(s9, s14) + self.addLink(s9, s15) + self.addLink(s9, s16) + self.addLink(s9, s17) + self.addLink(s9, s18) + self.addLink(s9, s19) + self.addLink(s9, s20) + self.addLink(s9, s21) + self.addLink(s9, s22) + self.addLink(s9, s23) + self.addLink(s9, s24) + self.addLink(s9, s25) + self.addLink(s10, s11) + self.addLink(s10, s12) + self.addLink(s10, s13) + self.addLink(s10, s14) + self.addLink(s10, s15) + self.addLink(s10, s16) + self.addLink(s10, s17) + self.addLink(s10, s18) + self.addLink(s10, s19) + self.addLink(s10, s20) + self.addLink(s10, s21) + self.addLink(s10, s22) + self.addLink(s10, s23) + self.addLink(s10, s24) + self.addLink(s10, s25) + self.addLink(s11, s12) + self.addLink(s11, s13) + self.addLink(s11, s14) + self.addLink(s11, s15) + self.addLink(s11, s16) + self.addLink(s11, s17) + self.addLink(s11, s18) + self.addLink(s11, s19) + self.addLink(s11, s20) + self.addLink(s11, s21) + self.addLink(s11, s22) + self.addLink(s11, s23) + self.addLink(s11, s24) + self.addLink(s11, s25) + self.addLink(s12, s13) + self.addLink(s12, s14) + self.addLink(s12, s15) + self.addLink(s12, s16) + self.addLink(s12, s17) + self.addLink(s12, s18) + self.addLink(s12, s19) + self.addLink(s12, s20) + self.addLink(s12, s21) + self.addLink(s12, s22) + self.addLink(s12, s23) + self.addLink(s12, s24) + self.addLink(s12, s25) + self.addLink(s13, s14) + self.addLink(s13, s15) + self.addLink(s13, s16) + self.addLink(s13, s17) + self.addLink(s13, s18) + self.addLink(s13, s19) + self.addLink(s13, s20) + self.addLink(s13, s21) + self.addLink(s13, s22) + self.addLink(s13, s23) + self.addLink(s13, s24) + self.addLink(s13, s25) + self.addLink(s14, s15) + self.addLink(s14, s16) + self.addLink(s14, s17) + self.addLink(s14, s18) + self.addLink(s14, s19) + self.addLink(s14, s20) + self.addLink(s14, s21) + self.addLink(s14, s22) + self.addLink(s14, s23) + self.addLink(s14, s24) + self.addLink(s14, s25) + self.addLink(s15, s16) + self.addLink(s15, s17) + self.addLink(s15, s18) + self.addLink(s15, s19) + self.addLink(s15, s20) + self.addLink(s15, s21) + self.addLink(s15, s22) + self.addLink(s15, s23) + self.addLink(s15, s24) + self.addLink(s15, s25) + self.addLink(s16, s17) + self.addLink(s16, s18) + self.addLink(s16, s19) + self.addLink(s16, s20) + self.addLink(s16, s21) + self.addLink(s16, s22) + self.addLink(s16, s23) + self.addLink(s16, s24) + self.addLink(s16, s25) + self.addLink(s17, s18) + self.addLink(s17, s19) + self.addLink(s17, s20) + self.addLink(s17, s21) + self.addLink(s17, s22) + self.addLink(s17, s23) + self.addLink(s17, s24) + self.addLink(s17, s25) + self.addLink(s18, s19) + self.addLink(s18, s20) + self.addLink(s18, s21) + self.addLink(s18, s22) + self.addLink(s18, s23) + self.addLink(s18, s24) + self.addLink(s18, s25) + self.addLink(s19, s20) + self.addLink(s19, s21) + self.addLink(s19, s22) + self.addLink(s19, s23) + self.addLink(s19, s24) + self.addLink(s19, s25) + self.addLink(s20, s21) + self.addLink(s20, s22) + self.addLink(s20, s23) + self.addLink(s20, s24) + self.addLink(s20, s25) + self.addLink(s21, s22) + self.addLink(s21, s23) + self.addLink(s21, s24) + self.addLink(s21, s25) + self.addLink(s22, s23) + self.addLink(s22, s24) + self.addLink(s22, s25) + self.addLink(s23, s24) + self.addLink(s23, s25) + self.addLink(s24, s25) + +topos = { 'chordal': ( lambda: chordalTopo() ) } diff --git a/framework/src/onos/tools/test/topos/cord.json b/framework/src/onos/tools/test/topos/cord.json new file mode 100644 index 00000000..418a6b4b --- /dev/null +++ b/framework/src/onos/tools/test/topos/cord.json @@ -0,0 +1,24 @@ +{ + "devices": [ + { "uri": "of:00010001e88b9368", "mac": "0001e88b9368", "annotations": { "name": "s101", "latitude": 37.710742, "longitude": -103.975010 }}, + { "uri": "of:00010001e88b939b", "mac": "0001e88b939b", "annotations": { "name": "s102", "latitude": 37.756072, "longitude": -97.547678 }}, + { "uri": "of:00010001e88b938c", "mac": "0001e88b938c", "annotations": { "name": "s103", "latitude": 37.657851, "longitude": -90.778101 }}, + { "uri": "of:00010001e88b93ad", "mac": "0001e88b93ad", "annotations": { "name": "s104", "latitude": 37.634692, "longitude": -84.215821 }}, + { "uri": "of:00010001e88b93bc", "mac": "0001e88b93bc", "annotations": { "name": "s105", "latitude": 41.951018, "longitude": -103.853350 }}, + { "uri": "of:00010001e88b93c2", "mac": "0001e88b93c2", "annotations": { "name": "s106", "latitude": 41.945684, "longitude": -97.526174 }}, + { "uri": "of:00010001e88b9398", "mac": "0001e88b9398", "annotations": { "name": "s107", "latitude": 41.952876, "longitude": -90.696484 }}, + { "uri": "of:00010001e88b27e3", "mac": "0001e88b27e3", "annotations": { "name": "s108", "latitude": 41.996877, "longitude": -84.169273 }} + ], + "hosts": [ + { "id": "00:1f:29:e1:2c:36/-1", "mac": "00:1f:29:e1:2c:36", "vlan": -1, "location": "of:00010001e88b9368/46", "ip": "10.200.1.11", "annotations": { "name": "h11", "latitude": 34.384830, "longitude": -104.019262 }}, + { "id": "00:1e:0b:cb:9d:64/-1", "mac": "00:1e:0b:cb:9d:64", "vlan": -1, "location": "of:00010001e88b9368/45", "ip": "10.200.1.12", "annotations": { "name": "h12", "latitude": 34.384830, "longitude": -104.019262 }}, + { "id": "00:1c:c4:6b:d8:12/-1", "mac": "00:1c:c4:6b:d8:12", "vlan": -1, "location": "of:00010001e88b939b/46", "ip": "10.200.2.21", "annotations": { "name": "h21", "latitude": 34.133376, "longitude": -89.442032 }}, + { "id": "00:1e:0b:ca:90:44/-1", "mac": "00:1e:0b:ca:90:44", "vlan": -1, "location": "of:00010001e88b939b/45", "ip": "10.200.2.22", "annotations": { "name": "h22", "latitude": 34.133376, "longitude": -89.442032 }}, + { "id": "00:1e:0b:ca:e5:1a/-1", "mac": "00:1e:0b:ca:e5:1a", "vlan": -1, "location": "of:00010001e88b938c/46", "ip": "10.200.3.31", "annotations": { "name": "h31", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "2c:44:fd:e0:90:40/-1", "mac": "2c:44:fd:e0:90:40", "vlan": -1, "location": "of:00010001e88b938c/45", "ip": "10.200.3.32", "annotations": { "name": "h32", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "2c:44:fd:e0:90:44/-1", "mac": "2c:44:fd:e0:90:44", "vlan": -1, "location": "of:00010001e88b938c/47", "ip": "10.200.3.33", "annotations": { "name": "h33", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "00:1e:0b:cb:3f:ac/-1", "mac": "00:1e:0b:cb:3f:ac", "vlan": -1, "location": "of:00010001e88b93ad/46", "ip": "10.200.4.41", "annotations": { "name": "h41", "latitude": 34.225065, "longitude": -97.492882 }}, + { "id": "c8:1f:66:e2:9b:d0/-1", "mac": "c8:1f:66:e2:9b:d0", "vlan": -1, "location": "of:00010001e88b93ad/45", "ip": "10.200.4.42", "annotations": { "name": "h42", "latitude": 34.249236, "longitude": -84.253025 }}, + { "id": "c8:1f:66:e2:9b:d2/-1", "mac": "c8:1f:66:e2:9b:d2", "vlan": -1, "location": "of:00010001e88b93ad/47", "ip": "10.200.4.43", "annotations": { "name": "h43", "latitude": 34.249236, "longitude": -84.253025 }} + ] +} diff --git a/framework/src/onos/tools/test/topos/fractal.py b/framework/src/onos/tools/test/topos/fractal.py new file mode 100755 index 00000000..bc5c6899 --- /dev/null +++ b/framework/src/onos/tools/test/topos/fractal.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +from mininet.topo import Topo + +class FractalTopo( Topo ): + def build( self, n=3, h=2 ): + + clusters = [] + for i in range( 1, n+1 ): + clusterSws = [] + # create switches in cluster + for j in range( 1, n+1 ): + id = i * 1000 + j + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + [ self.addLink(s, sw) for s in clusterSws ] + clusterSws.append(sw) + clusters.append(clusterSws) + + for i in range( 1, n+1 ): + # create the edge switch + id = i * 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + for j in range( 1, h+1 ): + id = i * 1000 + j + host = self.addHost( 'h%d' % id ) + self.addLink( host, sw ) + + for i in range( 1, n+1 ): + # connect the clusters + if i == n: + id = n * 1000000 + 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + self.addLink(clusters[0].pop(0), sw) + + else: + id = (i+1) * 1000000 + i * 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + self.addLink(clusters[i].pop(0), sw) + + +topos = { 'fractal': FractalTopo } + +def run(): + topo = FractalTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() + diff --git a/framework/src/onos/tools/test/topos/linear-2.json b/framework/src/onos/tools/test/topos/linear-2.json new file mode 100644 index 00000000..c248a236 --- /dev/null +++ b/framework/src/onos/tools/test/topos/linear-2.json @@ -0,0 +1,6 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "annotations": { "driver": "ovs-corsa" } }, + { "alias": "s2", "uri": "of:0000000000000002", "annotations": { "driver": "ovs-corsa" } } + ] +} diff --git a/framework/src/onos/tools/test/topos/newFuncTopo.py b/framework/src/onos/tools/test/topos/newFuncTopo.py new file mode 100644 index 00000000..5edf7f78 --- /dev/null +++ b/framework/src/onos/tools/test/topos/newFuncTopo.py @@ -0,0 +1,148 @@ +#!/usr/bin/python + +""" +Custom topology for Mininet +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import Host, RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections +from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch ) + +class VLANHost( Host ): + def config( self, vlan=100, **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ifconfig %s inet 0' % intf ) + self.cmd( 'vconfig add %s %d' % ( intf, vlan ) ) + self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) ) + newName = '%s.%d' % ( intf, vlan ) + intf.name = newName + self.nameToIntf[ newName ] = intf + return r + +class IPv6Host( Host ): + def config( self, v6Addr='1000:1/64', **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ifconfig %s inet 0' % intf ) + self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) ) + return r + +class dualStackHost( Host ): + def config( self, v6Addr='2000:1/64', **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) ) + return r + +class MyTopo( Topo ): + + def __init__( self ): + # Initialize topology + Topo.__init__( self ) + # Switch S5 Hosts + host1=self.addHost( 'h1', ip='10.1.0.2/24' ) + host2=self.addHost( 'h2', cls=IPv6Host, v6Addr='1000::2/64' ) + host3=self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='2000::2/64' ) + #VLAN hosts + host4=self.addHost( 'h4', ip='100.1.0.2/24', cls=VLANHost, vlan=100 ) + host5=self.addHost( 'h5', ip='200.1.0.2/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host6=self.addHost( 'h6', ip='11.1.0.2/24' ) + host7=self.addHost( 'h7', ip='12.1.0.2/24' ) + #Multicast Sender + host8=self.addHost( 'h8', ip='10.1.0.4/24' ) + + # Switch S6 Hosts + host9=self.addHost( 'h9', ip='10.1.0.5/24' ) + host10=self.addHost( 'h10', cls=IPv6Host, v6Addr='1000::3/64' ) + host11=self.addHost( 'h11', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='2000::3/64' ) + #VLAN hosts + host12=self.addHost( 'h12', ip='100.1.0.3/24', cls=VLANHost, vlan=100 ) + host13=self.addHost( 'h13', ip='200.1.0.3/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host14=self.addHost( 'h14', ip='11.1.0.3/24' ) + host15=self.addHost( 'h15', ip='12.1.0.3/24' ) + #Multicast Receiver + host16=self.addHost( 'h16', ip='10.1.0.7/24' ) + + # Switch S7 Hosts + host17=self.addHost( 'h17', ip='10.1.0.8/24' ) + host18=self.addHost( 'h18', cls=IPv6Host, v6Addr='1000::4/64' ) + host19=self.addHost( 'h19', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='2000::4/64' ) + #VLAN hosts + host20=self.addHost( 'h20', ip='100.1.0.4/24', cls=VLANHost, vlan=100 ) + host21=self.addHost( 'h21', ip='200.1.0.4/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host22=self.addHost( 'h22', ip='11.1.0.4/24' ) + host23=self.addHost( 'h23', ip='12.1.0.4/24' ) + #Multicast Receiver + host24=self.addHost( 'h24', ip='10.1.0.10/24' ) + + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + + self.addLink(s5,host1) + self.addLink(s5,host2) + self.addLink(s5,host3) + self.addLink(s5,host4) + self.addLink(s5,host5) + self.addLink(s5,host6) + self.addLink(s5,host7) + self.addLink(s5,host8) + + self.addLink(s6,host9) + self.addLink(s6,host10) + self.addLink(s6,host11) + self.addLink(s6,host12) + self.addLink(s6,host13) + self.addLink(s6,host14) + self.addLink(s6,host15) + self.addLink(s6,host16) + + self.addLink(s7,host17) + self.addLink(s7,host18) + self.addLink(s7,host19) + self.addLink(s7,host20) + self.addLink(s7,host21) + self.addLink(s7,host22) + self.addLink(s7,host23) + self.addLink(s7,host24) + + self.addLink(s1,s2) + self.addLink(s1,s3) + self.addLink(s1,s4) + self.addLink(s1,s5) + self.addLink(s2,s3) + self.addLink(s2,s5) + self.addLink(s2,s6) + self.addLink(s3,s4) + self.addLink(s3,s6) + self.addLink(s4,s7) + topos = { 'mytopo': ( lambda: MyTopo() ) } + +# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS + +def setupNetwork(): + "Create network" + topo = MyTopo() + network = Mininet(topo=topo, autoSetMacs=True, controller=None) + network.start() + CLI( network ) + network.stop() + +if __name__ == '__main__': + setLogLevel('info') + #setLogLevel('debug') + setupNetwork() diff --git a/framework/src/onos/tools/test/topos/obelisk.py b/framework/src/onos/tools/test/topos/obelisk.py new file mode 100755 index 00000000..fb6ccdbe --- /dev/null +++ b/framework/src/onos/tools/test/topos/obelisk.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +from mininet.topo import Topo + +class ObeliskTopo( Topo ): + def __init__( self ): + Topo.__init__( self ) + topSwitch = self.addSwitch('s1',dpid='1000'.zfill(16)) + leftTopSwitch = self.addSwitch('s2',dpid='2000'.zfill(16)) + rightTopSwitch = self.addSwitch('s5',dpid='5000'.zfill(16)) + leftBotSwitch = self.addSwitch('s3',dpid='3000'.zfill(16)) + rightBotSwitch = self.addSwitch('s6',dpid='6000'.zfill(16)) + midBotSwitch = self.addSwitch('s28',dpid='2800'.zfill(16)) + + topHost = self.addHost( 'h1' ) + leftTopHost = self.addHost('h2') + rightTopHost = self.addHost('h5') + leftBotHost = self.addHost('h3') + rightBotHost = self.addHost('h6') + midBotHost = self.addHost('h28') + self.addLink(topSwitch,topHost) + self.addLink(leftTopSwitch,leftTopHost) + self.addLink(rightTopSwitch,rightTopHost) + self.addLink(leftBotSwitch,leftBotHost) + self.addLink(rightBotSwitch,rightBotHost) + self.addLink(midBotSwitch,midBotHost) + self.addLink(leftTopSwitch,rightTopSwitch) + self.addLink(topSwitch,leftTopSwitch) + self.addLink(topSwitch,rightTopSwitch) + self.addLink(leftTopSwitch,leftBotSwitch) + self.addLink(rightTopSwitch,rightBotSwitch) + self.addLink(leftBotSwitch,midBotSwitch) + self.addLink(midBotSwitch,rightBotSwitch) + + agg1Switch = self.addSwitch('s4',dpid = '3004'.zfill(16)) + agg2Switch = self.addSwitch('s7',dpid = '6007'.zfill(16)) + agg1Host = self.addHost('h4') + agg2Host = self.addHost('h7') + self.addLink(agg1Switch,agg1Host) + self.addLink(agg2Switch,agg2Host) + self.addLink(agg1Switch, leftBotSwitch) + self.addLink(agg2Switch, rightBotSwitch) + + for i in range(10): + num = str(i+8) + switch = self.addSwitch('s'+num,dpid = ('30'+num.zfill(2)).zfill(16)) + host = self.addHost('h'+num) + self.addLink(switch, host) + self.addLink(switch, agg1Switch) + + for i in range(10): + num = str(i+18) + switch = self.addSwitch('s'+num,dpid = ('60'+num.zfill(2)).zfill(16)) + host = self.addHost('h'+num) + self.addLink(switch, host) + self.addLink(switch, agg2Switch) + +topos = { 'obelisk': (lambda: ObeliskTopo() ) } + +def run(): + topo = ObeliskTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() + diff --git a/framework/src/onos/tools/test/topos/obeliskHostCheck.py b/framework/src/onos/tools/test/topos/obeliskHostCheck.py new file mode 100755 index 00000000..e928f89f --- /dev/null +++ b/framework/src/onos/tools/test/topos/obeliskHostCheck.py @@ -0,0 +1,91 @@ +#!/usr/bin/python + +import sys +import os +import json + +# TODO: if none given, use OCI +try: + onosIp = sys.argv[1] + print "Reading hosts view from ONOS node " + onosIp + ":" +except Exception as 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() ) +#hosts = json.loads( output.split( 'Logging in as karaf\n' )[1] ) + +hostAttachment = True +# FIXME: topo-HA/obelisk specific mappings: +# key is mac and value is dpid +mappings = {} +for i in range( 1, 29 ): # hosts 1 through 28 + # set up correct variables: + macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2) + if i == 1: + deviceId = "1000".zfill(16) + elif i == 2: + deviceId = "2000".zfill(16) + elif i == 3: + deviceId = "3000".zfill(16) + elif i == 4: + deviceId = "3004".zfill(16) + elif i == 5: + deviceId = "5000".zfill(16) + elif i == 6: + deviceId = "6000".zfill(16) + elif i == 7: + deviceId = "6007".zfill(16) + elif i >= 8 and i <= 17: + dpid = '3' + str( i ).zfill( 3 ) + deviceId = dpid.zfill(16) + elif i >= 18 and i <= 27: + dpid = '6' + str( i ).zfill( 3 ) + deviceId = dpid.zfill(16) + elif i == 28: + deviceId = "2800".zfill(16) + mappings[ macId ] = deviceId + +if hosts or "Error" not in hosts: + if hosts == []: + print "WARNING: There are no hosts discovered" + else: + for host in hosts: + mac = None + location = None + device = None + port = None + try: + mac = host.get( 'mac' ) + assert mac, "mac field could not be found for this host object" + + location = host.get( 'location' ) + assert location, "location field could not be found for this host object" + + # Trim the protocol identifier off deviceId + device = str( location.get( 'elementId' ) ).split(':')[1] + assert device, "elementId field could not be found for this host location object" + + port = location.get( 'port' ) + assert port, "port field could not be found for this host location object" + + # 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 + hostAttachment = False + if str( port ) != "1": + 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 ) + hostAttachment = False +else: + print "No hosts json output or \"Error\" in output. hosts = " + repr( hosts ) diff --git a/framework/src/onos/tools/test/topos/oe-linear-3.json b/framework/src/onos/tools/test/topos/oe-linear-3.json new file mode 100644 index 00000000..44fccd99 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-linear-3.json @@ -0,0 +1,48 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM1", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, { "port": 20, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM2", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 11, "speed": 100000, "type": "FIBER" }, { "port": 21, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM3", "latitude": 33.9, "longitude": -118.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER1", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER2", "latitude": 37.3, "longitude": -121.9 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + ], + + "links" : [ + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff03/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff02/21", "dst": "of:0000ffffffffff03/31", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } } + ], + + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000ffffffff0001/1", "ip": "10.0.0.1" }, + { "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000ffffffff0002/1", "ip": "10.0.0.2" } + ] +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/topos/oe-nonlinear-10.json b/framework/src/onos/tools/test/topos/oe-nonlinear-10.json new file mode 100644 index 00000000..9bf291e8 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-nonlinear-10.json @@ -0,0 +1,149 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SFO-W10", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed":100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SJC-W10", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 20, "speed": 100000, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "LAX-W10", "latitude": 33.9, "longitude": -118.4, "optical.regens": 0 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff04", "mac": "ffffffffffff04", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SDG-W10", "latitude": 32.8, "longitude": -117.1, "optical.regens": 3 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, + { "port":50, "speed": 0, "type": "FIBER" }, + { "port":20, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff05", "mac": "ffffffffffff05", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "MSP-M10", "latitude": 44.8, "longitude": -93.1, "optical.regens": 3 }, + "ports": [ { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 40, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff06", "mac": "ffffffffffff06", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "DFW-M10", "latitude": 32.8, "longitude": -97.1, "optical.regens": 3 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 40, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff07", "mac": "ffffffffffff07", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "CHG-N10", "latitude": 41.8, "longitude": -87.6, "optical.regens": 3 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff08", "mac": "ffffffffffff08", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "IAD-M10", "latitude": 38.8, "longitude": -77.1, "optical.regens": 3 }, + "ports": [ { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff09", "mac": "ffffffffffff09", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "JFK-M10", "latitude": 40.8, "longitude": -73.1, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff0A", "mac": "ffffffffffff0A", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ATL-S10", "latitude": 33.8, "longitude": -84.1, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "SFO-R10", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0003", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "LAX-R10", "latitude": 33.9, "longitude": -118.4 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0003", "mac": "ffffffffff0004", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "SDG-R10", "latitude": 32.8, "longitude": -117.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0004", "mac": "ffffffffff0007", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "CHG-R10", "latitude": 41.8, "longitude": -87.6 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0005", "mac": "ffffffffff0009", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "JFK-R10", "latitude": 40.8, "longitude": -73.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0006", "mac": "ffffffffff000A", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ATL-R10", "latitude": 33.8, "longitude": -84.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + + ], + + "links" : [ + { "src": "of:0000ffffffffff01/50", "dst": "of:0000ffffffffff02/30","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 48, "durable": "true" } }, + { "src": "of:0000ffffffffff02/50", "dst": "of:0000ffffffffff03/30","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 493, "durable": "true" } }, + { "src": "of:0000ffffffffff03/50", "dst": "of:0000ffffffffff04/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 171, "durable": "true" } }, + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff05/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2555, "durable": "true" } }, + { "src": "of:0000ffffffffff02/20", "dst": "of:0000ffffffffff05/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2539, "durable": "true" } }, + { "src": "of:0000ffffffffff03/20", "dst": "of:0000ffffffffff06/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1979, "durable": "true" } }, + { "src": "of:0000ffffffffff04/20", "dst": "of:0000ffffffffff06/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1867, "durable": "true" } }, + { "src": "of:0000ffffffffff05/30", "dst": "of:0000ffffffffff06/40","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1378, "durable": "true" } }, + { "src": "of:0000ffffffffff05/40", "dst": "of:0000ffffffffff07/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2200, "durable": "true" } }, + { "src": "of:0000ffffffffff06/30", "dst": "of:0000ffffffffff08/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1918, "durable": "true" } }, + { "src": "of:0000ffffffffff07/20", "dst": "of:0000ffffffffff08/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 3625, "durable": "true" } }, + { "src": "of:0000ffffffffff07/30", "dst": "of:0000ffffffffff09/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 3880, "durable": "true" } }, + { "src": "of:0000ffffffffff08/20", "dst": "of:0000ffffffffff0A/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 838, "durable": "true" } }, + { "src": "of:0000ffffffffff09/20", "dst": "of:0000ffffffffff0A/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1245, "durable": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff04/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0003/2", "dst": "of:0000ffffffffff06/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0004/2", "dst": "of:0000ffffffffff07/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0005/2", "dst": "of:0000ffffffffff09/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0006/2", "dst": "of:0000ffffffffff0A/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } } + ] +} diff --git a/framework/src/onos/tools/test/topos/oe-nonlinear-4.json b/framework/src/onos/tools/test/topos/oe-nonlinear-4.json new file mode 100644 index 00000000..47782a86 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-nonlinear-4.json @@ -0,0 +1,52 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM1", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, { "port": 20, "speed": 0, "type": "FIBER" }, { "port": 22, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM2", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 11, "speed": 100000, "type": "FIBER" }, { "port": 21, "speed": 0, "type": "FIBER" }, { "port": 22, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM3", "latitude": 33.9, "longitude": -118.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff04", "mac": "ffffffffffff04", "type":"ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM4", "latitude": 39.9, "longitude": -119.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER1", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER2", "latitude": 37.3, "longitude": -121.9 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + ], + + "links" : [ + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff03/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff02/21", "dst": "of:0000ffffffffff03/31", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff01/22", "dst": "of:0000ffffffffff04/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff04/31", "dst": "of:0000ffffffffff02/22", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } } + ] + +} + diff --git a/framework/src/onos/tools/test/topos/onos.py b/framework/src/onos/tools/test/topos/onos.py new file mode 100755 index 00000000..3e5bff7c --- /dev/null +++ b/framework/src/onos/tools/test/topos/onos.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python + +# TODO add onos-app-fwd to features +# TODO check if service is running... i think this might already be done by mn + +from mininet.node import Controller, OVSSwitch, CPULimitedHost, RemoteController +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.topo import LinearTopo, Topo +from mininet.log import setLogLevel, info, warn +from mininet.util import quietRun, numCores + +from shutil import copyfile +from os import environ, path +from functools import partial +import time +from sys import argv +from time import sleep +from sets import Set + +class ONOS( Controller ): + "TODO" + + onosDir = '/opt/onos/' + + def __init__( self, name, onosDir=onosDir, + reactive=True, features=[ 'onos-app-tvue' ], + **kwargs ): + '''TODO''' + + Controller.__init__( self, name, **kwargs ) + # the following have been done for us: + #self.ip = ip ('127.0.0.1') + #self.port = port (6633) + #self.protocol = protocol ('tcp') + #self.checkListening() + + self.onosDir = onosDir + self.karafDir = onosDir + 'apache-karaf-3.0.3/' + self.instanceDir = self.karafDir + + # add default modules + # TODO: consider an ordered set + self.features = Set([ 'webconsole', + 'onos-rest', + 'onos-api', + 'onos-cli', + 'onos-openflow' ]) + self.features.update( features ) + # add reactive forwarding modules + if reactive: + self.features.update( ['onos-app-fwd', + 'onos-app-proxyarp', + 'onos-app-mobility' ] ) + # add the distributed core if we are in a namespace with no trivial core + if self.inNamespace and 'onos-core-trivial' not in self.features: + self.features.add( 'onos-core' ) + # if there is no core, add the trivial one + if 'onos-core' not in self.features: + self.features.add( 'onos-core-trivial' ) + print self.features + + def start( self ): + if self.inNamespace: + instanceOpts = ( '-furl mvn:org.onosproject/onos-features/1.3.0-SNAPSHOT/xml/features ' + '-s 8101' ) + if self.ip is not None: + instanceOpts += (' -a %s' % self.IP() ) + self.userCmd( self.karafDir + 'bin/instance create %s %s' % ( instanceOpts, self.name ) ) + self.instanceDir = self.karafDir + 'instances/%s/' % self.name + else: + # we are running in the root namespace, so let's use the root instance + # clean up the data directory + #self.userCmd( 'rm -rf '+ self.karafDir + 'data/' ) + pass + + self.userCmd( 'rm -rf '+ self.instanceDir + 'data/' ) + + # Update etc/org.apache.karaf.features.cfg + self.updateFeatures() + + # TODO 2. Update etc/hazelcast.xml : interface lines + #cp etc/hazelcast.xml instances/c1/etc/ + self.updateHazelcast() + + # TODO 3. Update etc/system.properties : onos.ip + # TODO 4. Update config/cluster.json : with all nodes + + # start onos + self.userCmd( '%sbin/instance start -d %s' % ( self.karafDir, self.name ) ) + #TODO we should wait for startup... + + def stop( self ): + self.userCmd( self.instanceDir + 'bin/stop' ) + #if self.inNamespace: + # self.userCmd( self.karafDir + 'bin/instance destroy %s' % self.name ) + self.terminate() + + def updateHazelcast( self ): + hz = '192.168.123.*' + if self.ip is not None: + hz = '.'.join(self.ip.split('.')[:-1]) + '.*' + + readfile = self.karafDir + 'etc/hazelcast.xml' + writefile = self.instanceDir + 'etc/hazelcast.xml' + with open( readfile, 'r' ) as r: + with open( writefile, 'w' ) as w: + for line in r.readlines(): + if '<interface>' in line: + line = '<interface>' + hz + '</interface>\n' + w.write( line ) + + def updateFeatures( self ): + filename = self.instanceDir + 'etc/org.apache.karaf.features.cfg' + with open( filename, 'r+' ) as f: + lines = f.readlines() + f.seek(0) + f.truncate() + for line in lines: + #print '?', line, + if 'featuresBoot=' in line: + # parse the features from the line + features = line.rstrip().split('=')[1].split(',') + # add the features to our features set + self.features.update( features ) + # generate the new features line + line = 'featuresBoot=' + ','.join( self.features ) + '\n' + #print '!', line, + f.write( line ) + + + @classmethod + def isAvailable( self ): + return quietRun( 'ls %s' % self.onosDir ) + + def userCmd( self, cmd ): + # switch to the non-root user because karaf gets upset otherwise + # because the .m2repo is not stored with root + cmd = 'sudo -u %s %s' % ( self.findUser(), cmd ) + return self.cmd( cmd ) + + @staticmethod + def findUser(): + "Try to return logged-in (usually non-root) user" + try: + # If we're running sudo + return os.environ[ 'SUDO_USER' ] + except: + try: + # Logged-in user (if we have a tty) + return quietRun( 'who am i' ).split()[ 0 ] + except: + # Give up and return effective user + return quietRun( 'whoami' ) + + +class ControlNetwork( Topo ): + "Control Network Topology" + def __init__( self, n, dataController=ONOS, **kwargs ): + """n: number of data network controller nodes + dataController: class for data network controllers""" + Topo.__init__( self, **kwargs ) + # Connect everything to a single switch + cs0 = self.addSwitch( 'cs0' ) + # Add hosts which will serve as data network controllers + for i in range( 1, n+1 ): + c = self.addHost( 'c%s' % i, cls=dataController, + inNamespace=True ) + self.addLink( c, cs0 ) + # Connect switch to root namespace so that data network + # switches will be able to talk to us + root = self.addHost( 'root', inNamespace=False ) + self.addLink( root, cs0 ) + +class ONOSCluster( Controller ): + # TODO + n = 3 + + def start( self ): + ctopo = ControlNetwork( n=self.n, dataController=ONOS ) + self.cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None ) + self.cnet.addController( 'cc0', controller=Controller ) + self.cnet.start() + + self.ctrls = [] + for host in self.cnet.hosts: + if isinstance( host, Controller ): + self.ctrls.append( host ) + host.start() + + def stop( self ): + for host in self.cnet.hosts: + if isinstance( host, Controller ): + host.stop() + self.cnet.stop() + + def clist( self ): + "Return list of Controller proxies for this ONOS cluster" + print 'controllers:', self.ctrls + return self.ctrls + +class OVSSwitchONOS( OVSSwitch ): + "OVS switch which connects to multiple controllers" + def start( self, controllers ): + assert len( controllers ) == 1 + c0 = controllers[ 0 ] + assert type( c0 ) == ONOSCluster + controllers = c0.clist() + OVSSwitch.start( self, controllers ) + +controllers = { 'onos': ONOS } +switches = { 'ovso': OVSSwitchONOS } + +if __name__ == '__main__': + # Simple test for ONOS() controller class + setLogLevel( 'info' ) #TODO info + size = 2 if len( argv ) != 2 else int( argv[ 1 ] ) + net = Mininet( topo=LinearTopo( size ), + #controller=ONOS, + controller=partial( ONOSCluster, n=3 ), #TODO + switch=OVSSwitchONOS ) + net.start() + #waitConnected( net.switches ) + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/optical.py b/framework/src/onos/tools/test/topos/optical.py new file mode 100755 index 00000000..300332aa --- /dev/null +++ b/framework/src/onos/tools/test/topos/optical.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +''' file: optical.py ''' + +from mininet.topo import Topo +from mininet.node import RemoteController +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info +from mininet.link import Intf, Link +from mininet.util import irange + +class NullIntf( Intf ): + "A dummy interface with a blank name that doesn't do any configuration" + def __init__( self, name, **params ): + self.name = '' + +class NullLink( Link ): + "A dummy link that doesn't touch either interface" + def makeIntfPair( cls, intf1, intf2, addr1=None, addr2=None ): + pass + def delete( self ): + pass + +class OpticalTopo( Topo ): + + def addIntf( self, switch, intfName ): + "Add intf intfName to switch" + self.addLink( switch, switch, cls=NullLink, + intfName1=intfName, cls2=NullIntf, intfName2=intfName ) + + def build( self, n=2, tapStart=3 ): + + # Add hosts and switches + hosts = [] + switches = [] + for i in irange( 1, n ): + h = self.addHost( 'h%d' % i ) + s = self.addSwitch( 's%d' % i, dpid="0000ffffffff%04d" % i ) + self.addLink( h, s ) + hosts.append( h ) + switches.append( s ) + + # Add optical tap interfaces + tapNum = tapStart + for sw in switches: + self.addIntf( sw, 'tap%d' % tapNum ) + tapNum += 1 + +# if you use, sudo mn --custom custom/optical.py, then register the topo: +#sudo mn --custom optical.py --topo optical,5 +topos = { 'optical': OpticalTopo } + +def installStaticFlows( net ): + for sw in net.switches: + info( 'Adding flows to %s...' % sw.name ) + sw.dpctl( 'add-flow', 'in_port=1,actions=output=2' ) + sw.dpctl( 'add-flow', 'in_port=2,actions=output=1' ) + info( sw.dpctl( 'dump-flows' ) ) + +def run( n ): + topo = OpticalTopo( n ) + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + #installStaticFlows( net ) + CLI( net ) + net.stop() + +# if the script is run directly (sudo custom/optical.py): +if __name__ == '__main__': + import sys + try: + n = int( sys.argv[1] ) + except: + print ( 'Usage: ./optical.py n # n is number of switches\n' + 'Starting with default of 2 switches...\n' ) + n = 2 + setLogLevel( 'info' ) + run( n ) diff --git a/framework/src/onos/tools/test/topos/optical2.py b/framework/src/onos/tools/test/topos/optical2.py new file mode 100644 index 00000000..36cdbadd --- /dev/null +++ b/framework/src/onos/tools/test/topos/optical2.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +''' file: custom/optical.py ''' + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info +from mininet.link import Intf, Link +from mininet.node import RemoteController + +class NullIntf( Intf ): + "A dummy interface with a blank name that doesn't do any configuration" + def __init__( self, name, **params ): + self.name = '' + +class NullLink( Link ): + "A dummy link that doesn't touch either interface" + def makeIntfPair( cls, intf1, intf2, *args, **kwargs ): + pass + def delete( self ): + pass + +class OpticalTopo(Topo): + def addIntf( self, switch, intfName ): + "Add intf intfName to switch" + self.addLink( switch, switch, cls=NullLink, + intfName1=intfName, cls2=NullIntf ) + def __init__(self): + + # Initialize topology + Topo.__init__(self) + + # Add hosts and switches + h1 = self.addHost('h1') + h2 = self.addHost('h2') + h3 = self.addHost('h3') + h4 = self.addHost('h4') + h5 = self.addHost('h5') + h6 = self.addHost('h6') + + s1 = self.addSwitch('s1', dpid="0000ffffffff0001") + s2 = self.addSwitch('s2', dpid="0000ffffffff0002") + s3 = self.addSwitch('s3', dpid="0000ffffffff0003") + s4 = self.addSwitch('s4', dpid="0000ffffffff0004") + s5 = self.addSwitch('s5', dpid="0000ffffffff0005") + s6 = self.addSwitch('s6', dpid="0000ffffffff0006") + + + # Add links from hosts to OVS + self.addLink(s1, h1) + self.addLink(s2, h2) + self.addLink(s3, h3) + self.addLink(s4, h4) + self.addLink(s5, h5) + self.addLink(s6, h6) + + # add links from ovs to linc-oe + # sorry about the syntax :( + self.addIntf(s1,'tap29') + self.addIntf(s2,'tap30') + self.addIntf(s3,'tap31') + self.addIntf(s4,'tap32') + self.addIntf(s5,'tap33') + self.addIntf(s6,'tap34') + + # if you use, sudo mn --custom custom/optical.py, then register the topo: +topos = {'optical': ( lambda: OpticalTopo() )} + + +def run(): + c = RemoteController('c','127.0.0.1',6633) + net = Mininet( topo=OpticalTopo(),controller=None,autoSetMacs=True) + net.addController(c) + net.start() + + #installStaticFlows( net ) + CLI( net ) + net.stop() + +# if the script is run directly (sudo custom/optical.py): +if __name__ == '__main__': + setLogLevel('info') + run() diff --git a/framework/src/onos/tools/test/topos/opticalTest.py b/framework/src/onos/tools/test/topos/opticalTest.py new file mode 100644 index 00000000..b34f08da --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalTest.py @@ -0,0 +1,98 @@ +#!/usr/bin/python + +from opticalUtils import MininetOE, LINCSwitch, LINCLink +from mininet.topo import Topo +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.cli import CLI + +class SmallOpticalTopo( Topo ): + + def build( self ): + o1ann = { "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 } + O1 = self.addSwitch( 'SFO-W10', dpid='0000ffffffffff01', annotations=o1ann, cls=LINCSwitch ) + o2ann = { "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 } + O2 = self.addSwitch( 'SJC-W10', dpid='0000ffffffffff02', annotations=o2ann, cls=LINCSwitch ) + o3ann = { "latitude": 33.9, "longitude": -118.4, "optical.regens": 0 } + O3 = self.addSwitch( 'LAX-W10', dpid='0000ffffffffff03', annotations=o3ann, cls=LINCSwitch ) + o4ann = { "latitude": 32.8, "longitude": -117.1, "optical.regens": 3 } + O4 = self.addSwitch( 'SDG-W10', dpid='0000ffffffffff04', annotations=o4ann, cls=LINCSwitch ) + o5ann = { "latitude": 44.8, "longitude": -93.1, "optical.regens": 3 } + O5 = self.addSwitch( 'MSP-M10', dpid='0000ffffffffff05', annotations=o5ann, cls=LINCSwitch ) + o6ann = { "latitude": 32.8, "longitude": -97.1, "optical.regens": 3 } + O6 = self.addSwitch( 'DFW-M10', dpid='0000ffffffffff06', annotations=o6ann, cls=LINCSwitch ) + o7ann = { "latitude": 41.8, "longitude": -87.6, "optical.regens": 3 } + O7 = self.addSwitch( 'CHG-N10', dpid='0000ffffffffff07', annotations=o7ann, cls=LINCSwitch ) + o8ann = { "latitude": 38.8, "longitude": -77.1, "optical.regens": 3 } + O8 = self.addSwitch( 'IAD-M10', dpid='0000ffffffffff08', annotations=o8ann, cls=LINCSwitch ) + o9ann = { "latitude": 40.8, "longitude": -73.1, "optical.regens": 0 } + O9 = self.addSwitch( 'JFK-M10', dpid='0000ffffffffff09', annotations=o9ann, cls=LINCSwitch ) + o10ann = { "latitude": 33.8, "longitude": -84.1, "optical.regens": 0 } + O10 = self.addSwitch( 'ATL-S10', dpid='0000ffffffffff0a', annotations=o10ann, cls=LINCSwitch ) + + + SFOR10 = self.addSwitch( 'SFO-R10', dpid='0000ffffffff0001', annotations={"latitude": 37.6, "longitude": -122.3} ) + LAXR10 = self.addSwitch( 'LAX-R10', dpid='0000ffffffff0002', annotations={ "latitude": 33.9, "longitude": -118.4 } ) + SDGR10 = self.addSwitch( 'SDG-R10', dpid='0000ffffffff0003', annotations={ "latitude": 32.8, "longitude": -117.1 } ) + CHGR10 = self.addSwitch( 'CHG-R10', dpid='0000ffffffff0004', annotations={ "latitude": 41.8, "longitude": -87.6 } ) + JFKR10 = self.addSwitch( 'JFK-R10', dpid='0000ffffffff0005', annotations={ "latitude": 40.8, "longitude": -73.1 } ) + ATLR10 = self.addSwitch( 'ATL-R10', dpid='0000ffffffff0006', annotations={ "latitude": 33.8, "longitude": -84.1 } ) + + self.addLink( O1, O2, port1=50, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O2, O3, port1=50, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O3, O4, port1=50, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O1, O5, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O2, O5, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O3, O6, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O4, O6, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O5, O6, port1=30, port2=40, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O5, O7, port1=40, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O6, O8, port1=30, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O7, O8, port1=20, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O7, O9, port1=30, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O8, O10, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O9, O10, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + + self.addLink( SFOR10, O1, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SFOR10, O1, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( LAXR10, O3, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + # added second tap + self.addLink( LAXR10, O3, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SDGR10, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( CHGR10, O7, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( JFKR10, O9, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( JFKR10, O9, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( ATLR10, O10, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + h1 = self.addHost( 'h1' ) + h2 = self.addHost( 'h2' ) + h3 = self.addHost( 'h3' ) + h4 = self.addHost( 'h4' ) + h5 = self.addHost( 'h5' ) + h6 = self.addHost( 'h6' ) + + self.addLink( SFOR10, h1, port1=1 ) + self.addLink( LAXR10, h2, port1=1 ) + self.addLink( SDGR10, h3, port1=1 ) + self.addLink( CHGR10, h4, port1=1 ) + self.addLink( JFKR10, h5, port1=1 ) + self.addLink( ATLR10, h6, port1=1 ) + +if __name__ == '__main__': + import sys + if len( sys.argv ) >= 2: + controllers = sys.argv[1:] + else: + print 'Usage:sudo -E python opticalTest.py (<Controller IP>)+' + print 'Using localhost...\n' + controllers = [ '127.0.0.1' ] + + setLogLevel( 'info' ) + net = MininetOE( topo=SmallOpticalTopo(), controller=None, autoSetMacs=True ) + net.addControllers( controllers ) + net.start() + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/opticalTestBig.py b/framework/src/onos/tools/test/topos/opticalTestBig.py new file mode 100644 index 00000000..943699b0 --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalTestBig.py @@ -0,0 +1,391 @@ +#!/usr/bin/python + +from opticalUtils import MininetOE, LINCSwitch, LINCLink +from mininet.topo import Topo +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.cli import CLI + +class BigOpticalTopo( Topo ): + + def build( self ): + # Optical layer ROADMs + o1ann = { "latitude": 32.508086, "longitude": -99.741564, "optical.regens": 0 } + O1 = self.addSwitch( 'ABLNTXRO', dpid='0000ffffffffff01', annotations=o1ann, cls=LINCSwitch ) + o2ann = { "latitude": 35.084446, "longitude": -106.649719, "optical.regens": 0 } + O2 = self.addSwitch( 'ALBQNMMA', dpid='0000ffffffffff02', annotations=o2ann, cls=LINCSwitch ) + o3ann = { "latitude": 42.652222, "longitude": -73.758333, "optical.regens": 0 } + O3 = self.addSwitch( 'ALBYNYSS', dpid='0000ffffffffff03', annotations=o3ann, cls=LINCSwitch ) + o4ann = { "latitude": 33.755833, "longitude": -97.743057, "optical.regens": 5 } + O4 = self.addSwitch( 'ATLNGATL', dpid='0000ffffffffff04', annotations=o4ann, cls=LINCSwitch ) # ATLNGATL Connected to packet node + o5ann = { "latitude": 42.882778, "longitude": -78.877778, "optical.regens": 0 } + O5 = self.addSwitch( 'BFLONYFR', dpid='0000ffffffffff05', annotations=o5ann, cls=LINCSwitch ) + o6ann = { "latitude": 45.781667, "longitude": -108.509167, "optical.regens": 0 } + O6 = self.addSwitch( 'BLNGMTMA', dpid='0000ffffffffff06', annotations=o6ann, cls=LINCSwitch ) + o7ann = { "latitude": 39.293781, "longitude": -76.614127, "optical.regens": 0 } + O7 = self.addSwitch( 'BLTMMDCH', dpid='0000ffffffffff07', annotations=o7ann, cls=LINCSwitch ) + o8ann = { "latitude": 33.517223, "longitude": -86.812225, "optical.regens": 0 } + O8 = self.addSwitch( 'BRHMALMT', dpid='0000ffffffffff08', annotations=o8ann, cls=LINCSwitch ) + o9ann = { "latitude": 46.836379, "longitude": -100.796917, "optical.regens": 0 } + O9 = self.addSwitch( 'BSMRNDJC', dpid='0000ffffffffff09', annotations=o9ann, cls=LINCSwitch ) + o10ann = { "latitude": 30.449722, "longitude": -91.184167, "optical.regens": 0 } + O10 = self.addSwitch( 'BTRGLAMA', dpid='0000ffffffffff0a', annotations=o10ann, cls=LINCSwitch ) + o11ann = { "latitude": 41.881484, "longitude": -87.640432, "optical.regens": 4 } + O11 = self.addSwitch( 'CHCGILCL', dpid='0000ffffffffff0b', annotations=o11ann, cls=LINCSwitch ) + o12ann = { "latitude": 35.224924, "longitude": -80.837502, "optical.regens": 0 } + O12 = self.addSwitch( 'CHRLNCCA', dpid='0000ffffffffff0c', annotations=o12ann, cls=LINCSwitch ) + o13ann = { "latitude": 32.785278, "longitude": -79.938056, "optical.regens": 0 } + O13 = self.addSwitch( 'CHTNSCDT', dpid='0000ffffffffff0d', annotations=o13ann, cls=LINCSwitch ) + o14ann = { "latitude": 41.498333, "longitude": -81.686943, "optical.regens": 0 } + O14 = self.addSwitch( 'CLEVOH02', dpid='0000ffffffffff0e', annotations=o14ann, cls=LINCSwitch ) + o15ann = { "latitude": 39.965279, "longitude": -82.996666, "optical.regens": 0 } + O15 = self.addSwitch( 'CLMBOH11', dpid='0000ffffffffff0f', annotations=o15ann, cls=LINCSwitch ) + o16ann = { "latitude": 42.36745, "longitude": -71.084918, "optical.regens": 0 } + O16 = self.addSwitch( 'CMBRMA01', dpid='0000ffffffffff10', annotations=o16ann, cls=LINCSwitch ) + o17ann = { "latitude": 39.102778, "longitude": -84.516944, "optical.regens": 0 } + O17 = self.addSwitch( 'CNCNOHWS', dpid='0000ffffffffff11', annotations=o17ann, cls=LINCSwitch ) + o18ann = { "latitude": 32.797524, "longitude": -96.780431, "optical.regens": 0 } + O18 = self.addSwitch( 'DLLSTXTL', dpid='0000ffffffffff12', annotations=o18ann, cls=LINCSwitch ) # DLLSTXTL Connected to packet node + o19ann = { "latitude": 39.744999, "longitude": -104.996391, "optical.regens": 0 } + O19 = self.addSwitch( 'DNVRCOMA', dpid='0000ffffffffff13', annotations=o19ann, cls=LINCSwitch ) + o20ann = { "latitude": 42.332779, "longitude": -83.054169, "optical.regens": 5 } + O20 = self.addSwitch( 'DTRTMIBA', dpid='0000ffffffffff14', annotations=o20ann, cls=LINCSwitch ) + o21ann = { "latitude": 31.756389, "longitude": -106.483611, "optical.regens": 0 } + O21 = self.addSwitch( 'ELPSTXMA', dpid='0000ffffffffff15', annotations=o21ann, cls=LINCSwitch ) + o22ann = { "latitude": 36.73923, "longitude": -119.79423, "optical.regens": 0 } + O22 = self.addSwitch( 'FRSNCA01', dpid='0000ffffffffff16', annotations=o22ann, cls=LINCSwitch ) + o23ann = { "latitude": 36.072222, "longitude": -79.793889, "optical.regens": 0 } + O23 = self.addSwitch( 'GNBONCEU', dpid='0000ffffffffff17', annotations=o23ann, cls=LINCSwitch ) + o24ann = { "latitude": 41.765833, "longitude": -72.676389, "optical.regens": 0 } + O24 = self.addSwitch( 'HRFRCT03', dpid='0000ffffffffff18', annotations=o24ann, cls=LINCSwitch ) + o25ann = { "latitude": 29.748333, "longitude": -95.36528, "optical.regens": 0 } + O25 = self.addSwitch( 'HSTNTX01', dpid='0000ffffffffff19', annotations=o25ann, cls=LINCSwitch ) + o26ann = { "latitude": 30.33071, "longitude": -81.43, "optical.regens": 0 } + O26 = self.addSwitch( 'JCVLFLCL', dpid='0000ffffffffff1a', annotations=o26ann, cls=LINCSwitch ) + o27ann = { "latitude": 39.096649, "longitude": -94.578716, "optical.regens": 0 } + O27 = self.addSwitch( 'KSCYMO09', dpid='0000ffffffffff1b', annotations=o27ann, cls=LINCSwitch ) + o28ann = { "latitude": 40.5899999,"longitude": -73.6699993, "optical.regens": 0 } + O28 = self.addSwitch( 'LGISLAND', dpid='0000ffffffffff1c', annotations=o28ann, cls=LINCSwitch ) + o29ann = { "latitude": 34.051227, "longitude": -118.252958, "optical.regens": 0 } + O29 = self.addSwitch( 'LSANCA03', dpid='0000ffffffffff1d', annotations=o29ann, cls=LINCSwitch ) # LSANCA03 Connected to packet node + o30ann = { "latitude": 36.168056, "longitude": -115.138889, "optical.regens": 0 } + O30 = self.addSwitch( 'LSVGNV02', dpid='0000ffffffffff1e', annotations=o30ann, cls=LINCSwitch ) + o31ann = { "latitude":38.249167, "longitude": -85.760833, "optical.regens": 0 } + O31 = self.addSwitch( 'LSVLKYCS', dpid='0000ffffffffff1f', annotations=o31ann, cls=LINCSwitch ) + o32ann = { "latitude": 34.740833, "longitude": -92.271942, "optical.regens": 2 } + O32 = self.addSwitch( 'LTRKARFR', dpid='0000ffffffffff20', annotations=o32ann, cls=LINCSwitch ) + o33ann = { "latitude": 25.779167, "longitude": -80.195, "optical.regens": 0 } + O33 = self.addSwitch( 'MIAMFLAC', dpid='0000ffffffffff21', annotations=o33ann, cls=LINCSwitch ) + o34ann = { "latitude": 43.037224, "longitude": -87.922501, "optical.regens": 0 } + O34 = self.addSwitch( 'MILWWIHE', dpid='0000ffffffffff22', annotations=o34ann, cls=LINCSwitch ) + o35ann = { "latitude": 35.145158, "longitude": -90.048058, "optical.regens": 0 } + O35 = self.addSwitch( 'MMPHTNMA', dpid='0000ffffffffff23', annotations=o35ann, cls=LINCSwitch ) + o36ann = { "latitude": 44.977365, "longitude": -93.26718, "optical.regens": 0 } + O36 = self.addSwitch( 'MPLSMNDT', dpid='0000ffffffffff24', annotations=o36ann, cls=LINCSwitch ) # MPLSMNDT Connected to packet node + o37ann = { "latitude": 36.853333, "longitude": -76.29, "optical.regens": 0 } + O37 = self.addSwitch( 'NRFLVABS', dpid='0000ffffffffff25', annotations=o37ann, cls=LINCSwitch ) + o38ann = { "latitude": 36.163955, "longitude": -86.775558, "optical.regens": 0 } + O38 = self.addSwitch( 'NSVLTNMT', dpid='0000ffffffffff26', annotations=o38ann, cls=LINCSwitch ) + o39ann = { "latitude": 29.949806, "longitude": -90.07222, "optical.regens": 0 } + O39 = self.addSwitch( 'NWORLAMA', dpid='0000ffffffffff27', annotations=o39ann, cls=LINCSwitch ) + o40ann = { "latitude": 40.734408, "longitude": -74.177978, "optical.regens": 0 } + O40 = self.addSwitch( 'NWRKNJ02', dpid='0000ffffffffff28', annotations=o40ann, cls=LINCSwitch ) # NWRKNJ02 Connected to packet node + o41ann = { "latitude": 40.767497, "longitude": -73.989713, "optical.regens": 0 } + O41 = self.addSwitch( 'NYCMNY54', dpid='0000ffffffffff29', annotations=o41ann, cls=LINCSwitch ) + o42ann = { "latitude": 35.470833, "longitude": -97.515274, "optical.regens": 0 } + O42 = self.addSwitch( 'OKCYOKCE', dpid='0000ffffffffff2a', annotations=o42ann, cls=LINCSwitch ) + o43ann = { "latitude": 37.805556, "longitude": -122.268889, "optical.regens": 2 } + O43 = self.addSwitch( 'OKLDCA03', dpid='0000ffffffffff2b', annotations=o43ann, cls=LINCSwitch ) + o44ann = { "latitude": 41.259167, "longitude":-95.940277, "optical.regens": 0 } + O44 = self.addSwitch( 'OMAHNENW', dpid='0000ffffffffff2c', annotations=o44ann, cls=LINCSwitch ) + o45ann = { "latitude": 28.543279, "longitude": -81.377502, "optical.regens": 0 } + O45 = self.addSwitch( 'ORLDFLMA', dpid='0000ffffffffff2d', annotations=o45ann, cls=LINCSwitch ) # ORLDFLMA Connected to packet node + o46ann = { "latitude": 39.946446, "longitude": -75.184139, "optical.regens": 0 } + O46 = self.addSwitch( 'PHLAPASL', dpid='0000ffffffffff2e', annotations=o46ann, cls=LINCSwitch ) + o47ann = { "latitude": 33.450361, "longitude": -112.07709, "optical.regens": 0 } + O47 = self.addSwitch( 'PHNXAZMA', dpid='0000ffffffffff2f', annotations=o47ann, cls=LINCSwitch ) # PHNXAZMA Connected to packet node + o48ann = { "latitude":40.441387, "longitude": -79.995552, "optical.regens": 0 } + O48 = self.addSwitch( 'PITBPADG', dpid='0000ffffffffff30', annotations=o48ann, cls=LINCSwitch ) + o49ann = { "latitude":41.818889, "longitude": -71.415278, "optical.regens": 0 } + O49 = self.addSwitch( 'PRVDRIGR', dpid='0000ffffffffff31', annotations=o49ann, cls=LINCSwitch ) + o50ann = { "latitude": 45.522499, "longitude": -122.678055, "optical.regens": 2 } + O50 = self.addSwitch( 'PTLDOR62', dpid='0000ffffffffff32', annotations=o50ann, cls=LINCSwitch ) + o51ann = { "latitude": 37.540752, "longitude": -77.436096, "optical.regens": 0 } + O51 = self.addSwitch( 'RCMDVAGR', dpid='0000ffffffffff33', annotations=o51ann, cls=LINCSwitch ) + o52ann = { "latitude": 35.779656, "longitude": -78.640831, "optical.regens": 0 } + O52 = self.addSwitch( 'RLGHNCMO', dpid='0000ffffffffff34', annotations=o52ann, cls=LINCSwitch ) + o53ann = { "latitude": 43.157222, "longitude": -77.616389, "optical.regens": 0 } + O53 = self.addSwitch( 'ROCHNYXA', dpid='0000ffffffffff35', annotations=o53ann, cls=LINCSwitch ) # ROCHNYXA Connected to packet node + o54ann = { "latitude": 38.578609, "longitude": -121.487221, "optical.regens": 0 } + O54 = self.addSwitch( 'SCRMCA01', dpid='0000ffffffffff36', annotations=o54ann, cls=LINCSwitch ) + o55ann = { "latitude": 41.415278, "longitude": -75.649167, "optical.regens": 0 } + O55 = self.addSwitch( 'SCTNPA01', dpid='0000ffffffffff37', annotations=o55ann, cls=LINCSwitch ) + o56ann = { "latitude": 40.767776, "longitude": -111.888336, "optical.regens": 0 } + O56 = self.addSwitch( 'SLKCUTMA', dpid='0000ffffffffff38', annotations=o56ann, cls=LINCSwitch ) + o57ann = { "latitude": 29.429445, "longitude": -98.488892, "optical.regens": 0 } + O57 = self.addSwitch( 'SNANTXCA', dpid='0000ffffffffff39', annotations=o57ann, cls=LINCSwitch ) # SNANTXCA Connected to packet node + o58ann = { "latitude": 34.418889, "longitude": -119.7, "optical.regens": 0 } + O58 = self.addSwitch( 'SNBBCA01', dpid='0000ffffffffff3a', annotations=o58ann, cls=LINCSwitch ) + o59ann = { "latitude":32.746944, "longitude": -117.158611, "optical.regens": 0 } + O59 = self.addSwitch( 'SNDGCA02', dpid='0000ffffffffff3b', annotations=o59ann, cls=LINCSwitch ) + o60ann = { "latitude":37.785143, "longitude": -122.397263, "optical.regens": 0 } + O60 = self.addSwitch( 'SNFCCA21', dpid='0000ffffffffff3c', annotations=o60ann, cls=LINCSwitch ) + o61ann = { "latitude": 37.333333, "longitude": -121.892778, "optical.regens": 0 } + O61 = self.addSwitch( 'SNJSCA02', dpid='0000ffffffffff3d', annotations=o61ann, cls=LINCSwitch ) # SNJSCA02 Connected to packet node + o62ann = { "latitude": 39.795278, "longitude": -89.649444, "optical.regens": 0 } + O62 = self.addSwitch( 'SPFDILSD', dpid='0000ffffffffff3e', annotations=o62ann, cls=LINCSwitch ) + o63ann = { "latitude": 47.654724, "longitude": -117.419167, "optical.regens": 0 } + O63 = self.addSwitch( 'SPKNWA01', dpid='0000ffffffffff3f', annotations=o63ann, cls=LINCSwitch ) + o64ann = { "latitude": 38.633335, "longitude": -90.215279, "optical.regens": 0 } + O64 = self.addSwitch( 'STLSMO09', dpid='0000ffffffffff40', annotations=o64ann, cls=LINCSwitch ) + o65ann = { "latitude": 47.606945, "longitude": -122.333336, "optical.regens": 0 } + O65 = self.addSwitch( 'STTLWA06', dpid='0000ffffffffff41', annotations=o65ann, cls=LINCSwitch ) + o66ann = { "latitude": 43.049444, "longitude": -76.1475, "optical.regens": 3 } + O66 = self.addSwitch( 'SYRCNYSU', dpid='0000ffffffffff42', annotations=o66ann, cls=LINCSwitch ) + o67ann = { "latitude": 28.0225, "longitude": -82.522778, "optical.regens": 0 } + O67 = self.addSwitch( 'TAMQFLFN', dpid='0000ffffffffff43', annotations=o67ann, cls=LINCSwitch ) + o68ann = { "latitude": 32.224444, "longitude": -110.968333, "optical.regens": 0 } + O68 = self.addSwitch( 'TCSNAZMA', dpid='0000ffffffffff44', annotations=o68ann, cls=LINCSwitch ) + o69ann = { "latitude": 30.456389, "longitude": -84.290833, "optical.regens": 0 } + O69 = self.addSwitch( 'TLHSFLAT', dpid='0000ffffffffff45', annotations=o69ann, cls=LINCSwitch ) + o70ann = { "latitude": 41.65, "longitude": -83.538056, "optical.regens": 2 } + O70 = self.addSwitch( 'TOLDOH21', dpid='0000ffffffffff46', annotations=o70ann, cls=LINCSwitch ) + o71ann = { "latitude": 36.151669, "longitude": -95.985832, "optical.regens": 0 } + O71 = self.addSwitch( 'TULSOKTB', dpid='0000ffffffffff47', annotations=o71ann, cls=LINCSwitch ) + o72ann = { "latitude": 38.88306 , "longitude": -77.01028, "optical.regens": 0 } + O72 = self.addSwitch( 'WASHDCSW', dpid='0000ffffffffff48', annotations=o72ann, cls=LINCSwitch ) # WASHDCSW Connected to packet node + o73ann = { "latitude": 39.739167, "longitude": -75.553889, "optical.regens": 0 } + O73 = self.addSwitch( 'WLMGDE01', dpid='0000ffffffffff49', annotations=o73ann, cls=LINCSwitch ) + o74ann = { "latitude": 26.709391, "longitude": -80.05278, "optical.regens": 0 } + O74 = self.addSwitch( 'WPBHFLAN', dpid='0000ffffffffff4a', annotations=o74ann, cls=LINCSwitch ) + o75ann = { "latitude": 29.57, "longitude": -96.7, "optical.regens": 0 } + O75 = self.addSwitch( 'AUSTTXGR', dpid='0000ffffffffff4b', annotations=o75ann, cls=LINCSwitch ) + #o25ann = { "latitude": 29.748333, "longitude": -95.36528, "optical.regens": 0 } + #o57ann = { "latitude": 29.429445, "longitude": -98.488892, "optical.regens": 0 } + + + # Packet Layer switches + ''' # from opticalTest.py + SFOR10 = self.addSwitch( 'SFO-R10', dpid='0000ffffffff0001', annotations={"latitude": 37.6, "longitude": -122.3} ) + LAXR10 = self.addSwitch( 'LAX-R10', dpid='0000ffffffff0002', annotations={ "latitude": 33.9, "longitude": -118.4 } ) + SDGR10 = self.addSwitch( 'SDG-R10', dpid='0000ffffffff0003', annotations={ "latitude": 32.8, "longitude": -117.1 } ) + CHGR10 = self.addSwitch( 'CHG-R10', dpid='0000ffffffff0004', annotations={ "latitude": 41.8, "longitude": -87.6 } ) + JFKR10 = self.addSwitch( 'JFK-R10', dpid='0000ffffffff0005', annotations={ "latitude": 40.8, "longitude": -73.1 } ) + ATLR10 = self.addSwitch( 'ATL-R10', dpid='0000ffffffff0006', annotations={ "latitude": 33.8, "longitude": -84.1 } ) + ''' + WASHDCSWR = self.addSwitch( 'WASHDCSW-R', dpid='0000ffffff000001', annotations={ "latitude": 38.8, "longitude": -77.0 } ) # this switch is O72 + SNJSCA02R = self.addSwitch( 'SNJSCA02-R', dpid='0000ffffff000002', annotations={ "latitude": 37.3, "longitude": -121.8 } ) # O61 + SNANTXCAR = self.addSwitch( 'SNANTXCA-R', dpid='0000ffffff000003', annotations={ "latitude": 29.4, "longitude": -98.4 } ) # O57 + ROCHNYXAR = self.addSwitch( 'ROCHNYXA-R', dpid='0000ffffff000004', annotations={ "latitude": 43.1, "longitude": -77.6 } ) # O53 + PHNXAZMAR = self.addSwitch( 'PHNXAZMA-R', dpid='0000ffffff000005', annotations={ "latitude": 33.4, "longitude": -112.0 } ) # O47 + ORLDFLMAR = self.addSwitch( 'ORLDFLMA-R', dpid='0000ffffff000006', annotations={ "latitude": 28.5, "longitude": -81.3 } ) # O45 + NWRKNJ02R = self.addSwitch( 'NWRKNJ02-R', dpid='0000ffffff000007', annotations={ "latitude": 40.7, "longitude": -74.1 } ) # O40 + MPLSMNDTR = self.addSwitch( 'MPLSMNDT-R', dpid='0000ffffff000008', annotations={ "latitude": 44.9, "longitude": -93.2 } ) # O36 + LSANCA03R = self.addSwitch( 'LSANCA03-R', dpid='0000ffffff000009', annotations={ "latitude": 34.1, "longitude": -118.3 } ) # O29 + DLLSTXTLR = self.addSwitch( 'DLLSTXTL-R', dpid='0000ffffff00000a', annotations={ "latitude": 32.7, "longitude": -96.7 } ) # O18 + ATLNGATLR = self.addSwitch( 'ATLNGATL-R', dpid='0000ffffff00000b', annotations={ "latitude": 33.7, "longitude": -97.7 } ) # O4 + + + + # Optical Links between the ROADMs (although Distance is not used; we should keep these for future reference) + self.addLink( O1, O18, port1=100, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 334, "durable": "true" }, cls=LINCLink ) # ABLNTXRO DLLSTXTL + self.addLink( O1, O21, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 768, "durable": "true" }, cls=LINCLink ) # ABLNTXRO ELPSTXMA + self.addLink( O3, O16, port1=100, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 265, "durable": "true" }, cls=LINCLink ) # ALBYNYSS CMBRMA01 + self.addLink( O3, O66, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 239, "durable": "true" }, cls=LINCLink ) # ALBYNYSS SYRCNYSU + self.addLink( O2, O18, port1=100, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1134, "durable": "true" }, cls=LINCLink ) # ALBQNMMA DLLSTXTL + self.addLink( O2, O19, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 646, "durable": "true" }, cls=LINCLink ) # ALBQNMMA DNVRCOMA + self.addLink( O2, O21, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 444, "durable": "true" }, cls=LINCLink ) # ALBQNMMA ELPSTXMA + self.addLink( O2, O30, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 931, "durable": "true" }, cls=LINCLink ) # ALBQNMMA LSVGNV02 + self.addLink( O4, O8, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 271, "durable": "true" }, cls=LINCLink ) # ATLNGATL BRHMALMT + self.addLink( O4, O12, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 436, "durable": "true" }, cls=LINCLink ) # ATLNGATL CHRLNCCA + self.addLink( O4, O26, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 566, "durable": "true" }, cls=LINCLink ) # ATLNGATL JCVLFLCL + self.addLink( O75, O25, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 283, "durable": "true" }, cls=LINCLink ) # AUSTTXGR HSTNTX01 + self.addLink( O75, O57, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 141, "durable": "true" }, cls=LINCLink ) # AUSTTXGR SNANTXCA + self.addLink( O7, O46, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 170, "durable": "true" }, cls=LINCLink ) # BLTMMDCH PHLAPASL + self.addLink( O7, O48, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 378, "durable": "true" }, cls=LINCLink ) # BLTMMDCH PITBPADG + self.addLink( O7, O70, port1=103, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 68, "durable": "true" }, cls=LINCLink ) # BLTMMDCH WASHDCSW + self.addLink( O10, O25, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 491, "durable": "true" }, cls=LINCLink ) # BTRGLAMA HSTNTX01 + self.addLink( O10, O39, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 144, "durable": "true" }, cls=LINCLink ) # BTRGLAMA NWORLAMA + self.addLink( O6, O9, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 724, "durable": "true" }, cls=LINCLink ) # BLNGMTMA BSMRNDJC + self.addLink( O6, O19, port1=102, port2=107, annotations={ "optical.wves": 80, "optical.type": "WDM", "optical.kms": 875, "durable": "true" }, cls=LINCLink ) # BLNGMTMA DNVRCOMA + self.addLink( O6, O63, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 852, "durable": "true" }, cls=LINCLink ) # BLNGMTMA SPKNWA01 + self.addLink( O8, O38, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 353, "durable": "true" }, cls=LINCLink ) # BRHMALMT NSVLTNMT + self.addLink( O8, O39, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 602, "durable": "true" }, cls=LINCLink ) # BRHMALMT NWORLAMA + self.addLink( O9, O36, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 741, "durable": "true" }, cls=LINCLink ) # BSMRNDJC MPLSMNDT + self.addLink( O16, O49, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 80, "durable": "true" }, cls=LINCLink ) # CMBRMA01 PRVDRIGR + self.addLink( O5, O14, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 333, "durable": "true" }, cls=LINCLink ) # BFLONYFR CLEVOH02 + self.addLink( O5, O53, port1=104, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 128, "durable": "true" }, cls=LINCLink ) # BFLONYFR ROCHNYXA + self.addLink( O13, O26, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 368, "durable": "true" }, cls=LINCLink ) # CHTNSCDT JCVLFLCL + self.addLink( O13, O52, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 424, "durable": "true" }, cls=LINCLink ) # CHTNSCDT RLGHNCMO + self.addLink( O12, O23, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 160, "durable": "true" }, cls=LINCLink ) # CHRLNCCA GNBONCEU + self.addLink( O11, O20, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 458, "durable": "true" }, cls=LINCLink ) # CHCGILCL DTRTMIBA + self.addLink( O11, O34, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 156, "durable": "true" }, cls=LINCLink ) # CHCGILCL MILWWIHE + self.addLink( O11, O62, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 344, "durable": "true" }, cls=LINCLink ) # CHCGILCL SPFDILSD + self.addLink( O17, O15, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 194, "durable": "true" }, cls=LINCLink ) # CNCNOHWS CLMBOH11 + self.addLink( O17, O31, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 172, "durable": "true" }, cls=LINCLink ) # CNCNOHWS LSVLKYCS + self.addLink( O17, O72, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 779, "durable": "true" }, cls=LINCLink ) # CNCNOHWS WASHDCSW + self.addLink( O14, O15, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 243, "durable": "true" }, cls=LINCLink ) # CLEVOH02 CLMBOH11 + self.addLink( O14, O70, port1=102, port2=101, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 185, "durable": "true" }, cls=LINCLink ) # CLEVOH02 TOLDOH21 + self.addLink( O15, O48, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 312, "durable": "true" }, cls=LINCLink ) # CLMBOH11 PITBPADG + self.addLink( O18, O25, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 437, "durable": "true" }, cls=LINCLink ) # DLLSTXTL HSTNTX01 + self.addLink( O18, O32, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 563, "durable": "true" }, cls=LINCLink ) # DLLSTXTL LTRKARFR + self.addLink( O18, O42, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 365, "durable": "true" }, cls=LINCLink ) # DLLSTXTL OKCYOKCE + self.addLink( O19, O44, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 940, "durable": "true" }, cls=LINCLink ) # DNVRCOMA OMAHNENW + self.addLink( O19, O56, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 714, "durable": "true" }, cls=LINCLink ) # DNVRCOMA SLKCUTMA + self.addLink( O20, O70, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 103, "durable": "true" }, cls=LINCLink ) # DTRTMIBA TOLDOH21 + self.addLink( O21, O57, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 969, "durable": "true" }, cls=LINCLink ) # ELPSTXMA SNANTXCA + self.addLink( O21, O68, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 511, "durable": "true" }, cls=LINCLink ) # ELPSTXMA TCSNAZMA + self.addLink( O22, O31, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 505, "durable": "true" }, cls=LINCLink ) # FRSNCA01 LSVGNV02 + self.addLink( O22, O29, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 396, "durable": "true" }, cls=LINCLink ) # FRSNCA01 LSANCA03 + self.addLink( O22, O42, port1=103, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 298, "durable": "true" }, cls=LINCLink ) # FRSNCA01 OKLDCA03 + self.addLink( O23, O31, port1=101, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 697, "durable": "true" }, cls=LINCLink ) # GNBONCEU LSVLKYCS + self.addLink( O23, O52, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 130, "durable": "true" }, cls=LINCLink ) # GNBONCEU RLGHNCMO + self.addLink( O23, O51, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 319, "durable": "true" }, cls=LINCLink ) # GNBONCEU RCMDVAGR + self.addLink( O24, O28, port1=101, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 185, "durable": "true" }, cls=LINCLink ) # HRFRCT03 L_Island + self.addLink( O24, O49, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 125, "durable": "true" }, cls=LINCLink ) # HRFRCT03 PRVDRIGR + self.addLink( O26, O45, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 238, "durable": "true" }, cls=LINCLink ) # JCVLFLCL ORLDFLMA + self.addLink( O27, O44, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 320, "durable": "true" }, cls=LINCLink ) # KSCYMO09 OMAHNENW + self.addLink( O27, O64, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 457, "durable": "true" }, cls=LINCLink ) # KSCYMO09 STLSMO09 + self.addLink( O27, O71, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 420, "durable": "true" }, cls=LINCLink ) # KSCYMO09 TULSOKTB + self.addLink( O30, O47, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 494, "durable": "true" }, cls=LINCLink ) # LSVGNV02 PHNXAZMA + self.addLink( O30, O56, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 701, "durable": "true" }, cls=LINCLink ) # LSVGNV02 SLKCUTMA + self.addLink( O32, O35, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 249, "durable": "true" }, cls=LINCLink ) # LTRKARFR MMPHTNMA + self.addLink( O28, O41, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 40, "durable": "true" }, cls=LINCLink ) # L_Island NYCMNY54 + self.addLink( O29, O59, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 212, "durable": "true" }, cls=LINCLink ) # LSANCA03 SNDGCA02 + self.addLink( O29, O58, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 167, "durable": "true" }, cls=LINCLink ) # LSANCA03 SNBBCA01 + self.addLink( O31, O38, port1=104, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 298, "durable": "true" }, cls=LINCLink ) # LSVLKYCS NSVLTNMT + self.addLink( O31, O64, port1=102, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 468, "durable": "true" }, cls=LINCLink ) # LSVLKYCS STLSMO09 + self.addLink( O35, O38, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 380, "durable": "true" }, cls=LINCLink ) # MMPHTNMA NSVLTNMT + self.addLink( O33, O67, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 407, "durable": "true" }, cls=LINCLink ) # MIAMFLAC TAMQFLFN + self.addLink( O33, O74, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 125, "durable": "true" }, cls=LINCLink ) # MIAMFLAC WPBHFLAN + self.addLink( O34, O36, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 574, "durable": "true" }, cls=LINCLink ) # MILWWIHE MPLSMNDT + self.addLink( O36, O44, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 560, "durable": "true" }, cls=LINCLink ) # MPLSMNDT OMAHNENW + self.addLink( O39, O69, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 670, "durable": "true" }, cls=LINCLink ) # NWORLAMA TLHSFLAT + self.addLink( O41, O40, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 19, "durable": "true" }, cls=LINCLink ) # NYCMNY54 NWRKNJ02 + self.addLink( O41, O55, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 187, "durable": "true" }, cls=LINCLink ) # NYCMNY54 SCTNPA01 + self.addLink( O41, O73, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 210, "durable": "true" }, cls=LINCLink ) # NYCMNY54 WLMGDE01 + self.addLink( O40, O46, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 146, "durable": "true" }, cls=LINCLink ) # NWRKNJ02 PHLAPASL + self.addLink( O37, O52, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 290, "durable": "true" }, cls=LINCLink ) # NRFLVABS RLGHNCMO + self.addLink( O37, O73, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 392, "durable": "true" }, cls=LINCLink ) # NRFLVABS WLMGDE01 + self.addLink( O43, O54, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 131, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SCRMCA01 + self.addLink( O43, O56, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1142, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SLKCUTMA + self.addLink( O43, O60, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 13, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SNFCCA21 + self.addLink( O42, O71, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 188, "durable": "true" }, cls=LINCLink ) # OKCYOKCE TULSOKTB + self.addLink( O45, O74, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 290, "durable": "true" }, cls=LINCLink ) # ORLDFLMA WPBHFLAN + self.addLink( O46, O55, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 201, "durable": "true" }, cls=LINCLink ) # PHLAPASL SCTNPA01 + self.addLink( O47, O59, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 575, "durable": "true" }, cls=LINCLink ) # PHNXAZMA SNDGCA02 + self.addLink( O47, O68, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 205, "durable": "true" }, cls=LINCLink ) # PHNXAZMA TCSNAZMA + self.addLink( O48, O55, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 457, "durable": "true" }, cls=LINCLink ) # PITBPADG SCTNPA01 + self.addLink( O50, O54, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 934, "durable": "true" }, cls=LINCLink ) # PTLDOR62 SCRMCA01 + self.addLink( O50, O56, port1=102, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1225, "durable": "true" }, cls=LINCLink ) # PTLDOR62 SLKCUTMA + self.addLink( O50, O65, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 280, "durable": "true" }, cls=LINCLink ) # PTLDOR62 STTLWA06 + self.addLink( O51, O72, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 184, "durable": "true" }, cls=LINCLink ) # RCMDVAGR WASHDCSW + self.addLink( O53, O66, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 143, "durable": "true" }, cls=LINCLink ) # ROCHNYXA SYRCNYSU + self.addLink( O60, O61, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 80., "durable": "true" }, cls=LINCLink ) # SNFCCA21 SNJSCA02 + self.addLink( O61, O58, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 455, "durable": "true" }, cls=LINCLink ) # SNJSCA02 SNBBCA01 + self.addLink( O55, O66, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 223, "durable": "true" }, cls=LINCLink ) # SCTNPA01 SYRCNYSU + self.addLink( O65, O63, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 442, "durable": "true" }, cls=LINCLink ) # STTLWA06 SPKNWA01 + self.addLink( O62, O64, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 165, "durable": "true" }, cls=LINCLink ) # SPFDILSD STLSMO09 + self.addLink( O69, O67, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 384, "durable": "true" }, cls=LINCLink ) # TLHSFLAT TAMQFLFN + + # Packet/Optical cross connect links (this will be the tap interfaces) + self.addLink( WASHDCSWR, O72, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + + # Attach hosts to the packet layer switches + for i in range( 1, 4 ): #don't make this more than 4!!!!! + # Create Hosts 1..11 + h1 = self.addHost( 'h1d%d' % i, ip='10.0.1.%d/16' % i ) + h2 = self.addHost( 'h2d%d' % i, ip='10.0.2.%d/16' % i ) + h3 = self.addHost( 'h3d%d' % i, ip='10.0.3.%d/16' % i ) + h4 = self.addHost( 'h4d%d' % i, ip='10.0.4.%d/16' % i ) + h5 = self.addHost( 'h5d%d' % i, ip='10.0.5.%d/16' % i ) + h6 = self.addHost( 'h6d%d' % i, ip='10.0.6.%d/16' % i ) + h7 = self.addHost( 'h7d%d' % i, ip='10.0.7.%d/16' % i ) + h8 = self.addHost( 'h8d%d' % i, ip='10.0.8.%d/16' % i ) + h9 = self.addHost( 'h9d%d' % i, ip='10.0.9.%d/16' % i ) + h10 = self.addHost( 'h10d%d' % i, ip='10.0.10.%d/16' % i ) + h11 = self.addHost( 'h11d%d' % i, ip='10.0.11.%d/16' % i ) + + port = i + 6 + self.addLink( SNJSCA02R, h1, port1=port ) + self.addLink( SNANTXCAR, h2, port1=port ) + self.addLink( ROCHNYXAR, h3, port1=port ) + self.addLink( PHNXAZMAR, h4, port1=port ) + self.addLink( ORLDFLMAR, h5, port1=port ) + self.addLink( NWRKNJ02R, h6, port1=port ) + self.addLink( MPLSMNDTR, h7, port1=port ) + self.addLink( LSANCA03R, h8, port1=port ) + self.addLink( DLLSTXTLR, h9, port1=port ) + self.addLink( ATLNGATLR, h10, port1=port ) + self.addLink( WASHDCSWR, h11, port1=port ) + +if __name__ == '__main__': + import sys + if len( sys.argv ) >= 2: + controllers = sys.argv[1:] + else: + print 'Usage: sudo -E python opticalTestBig.py (<Controller IP>)+' + print 'Using localhost...\n' + controllers = [ '127.0.0.1' ] + + setLogLevel( 'info' ) + net = MininetOE( topo=BigOpticalTopo(), controller=None, autoSetMacs=True ) + net.addControllers( controllers ) + net.start() + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/opticalUtils.py b/framework/src/onos/tools/test/topos/opticalUtils.py new file mode 100644 index 00000000..bef9deca --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalUtils.py @@ -0,0 +1,771 @@ +#!/usr/bin/python + +''' +Notes: + +This file contains classes and methods useful for integrating LincOE with Mininet, +such as startOE, stopOE, LINCLink, and OpticalSwitch + +- $ONOS_ROOT ust be set +- Need to run with sudo -E to preserve ONOS_ROOT env var +- We assume LINC-Config-Generator is named LINC-Config-Generator +- We also assume linc-oe is named linc-oe +- LINC-config-generator and linc-oe must be subdirectories of the user's + home directory + + TODO + ----------- + - clean up files after runtime + - maybe save the old files in a separate directory? + - modify script to allow startOE to run before net.start() + - add ONOS as a controller in script + + Usage: + ------------ + - import LINCLink and OpticalSwitch from this module + - import startOE and stopOE from this module + - create topology as you would a normal topology. when + to an optical switch with topo.addLink, always specify cls=LINCLink + - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch + - for annotations on links and switches, a dictionary must be passed in as + the annotations argument + - startOE must be run AFTER net.start() with net as an argument. + - stopOE can be run at any time + +I created a separate function to start lincOE to avoid subclassing Mininet. +In case anyone wants to write something that DOES subclass Mininet, I +thought I would outline how: + +If we want an object that starts lincOE within the mininet class itself, +we need to add another object to Mininet that contains all of the json object +information for each switch. We would still subclass switch and link, but these +classes would basically be dummy classes that store their own json information +in the Mininet class object. We may also change the default switch class to add +it's tap interfaces from lincOE during startup. The start() method for mininet would +grab all of the information from these switches and links, write configuration files +for lincOE using the json module, start lincOE, then run the start methodfor each +switch. The new start() method for each switch would parse through the sys.config +file that was created and find the tap interface it needs to connect to, similar +to the findTap function that I currently use. After all of the controllers and +switches have been started, the new Mininet start() method should also push the +Topology configuration file to ONOS. + +''' +import sys +import re +import json +import os +from time import sleep +import urllib2 + +from mininet.node import Switch, RemoteController +from mininet.topo import Topo +from mininet.util import quietRun +from mininet.net import Mininet +from mininet.log import setLogLevel, info, error, warn +from mininet.link import Link, Intf +from mininet.cli import CLI + +# Sleep time and timeout values in seconds +SLEEP_TIME = 2 +TIMEOUT = 60 + +REST_USER = 'onos' +REST_PW = 'rocks' + +class OpticalSwitch(Switch): + """ + For now, same as Switch class. + """ + pass + +class OpticalIntf(Intf): + """ + For now,same as Intf class. + """ + pass + +class OpticalLink(Link): + """ + For now, same as Link. + """ + pass + +class LINCSwitch(OpticalSwitch): + """ + LINCSwitch class + """ + # FIXME:Sometimes LINC doesn't remove pipes and on restart increase the pipe + # number from erlang.pipe.1.* to erlang.pipe.2.*, so should read and write + # from latest pipe files. For now we are removing all the pipes before + # starting LINC. + ### User Name ### + user = os.getlogin() + ### pipes ### + readPipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.r".format(user) + writePipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.w".format(user) + ### sys.config path ### + sysConfig = "/home/{}/linc-oe/rel/linc/releases/1.0/sys.config".format(user) + ### method, mapping dpid to LINC switchId ### + @staticmethod + def dpids_to_ids(sysConfig): + ''' + return the dict containing switch dpids as key and LINC switch id as values + ''' + dpids_to_ids = {} + fd = None + try: + with open(sysConfig, 'r', 0) as fd: + switch_id = 1 + for line in fd: + dpid = re.search(r'([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})+', line, re.I) + if dpid: + dpids_to_ids[dpid.group().replace(':', '')] = switch_id + switch_id += 1 + return dpids_to_ids + except: + print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info()) + fd.close() + return None + ### dict of containing dpids as key and corresponding LINC switchId as values ### + dpidsToLINCSwitchId = dpids_to_ids.__func__(sysConfig) + @staticmethod + def findDir(directory, userName): + "finds and returns the path of any directory in the user's home directory" + homeDir = '/home/' + userName + Dir = quietRun('find %s -maxdepth 1 -name %s -type d' % (homeDir, directory)).strip('\n') + DirList = Dir.split('\n') + if not Dir: + return None + elif len(DirList) > 1 : + warn('***WARNING: Found multiple instances of %s; using %s\n' + % (directory, DirList[ 0 ])) + return DirList[ 0 ] + else: + return Dir + ### ONOS Directory ### + try: + onosDir = os.environ[ 'ONOS_ROOT' ] + except: + onosDir = findDir('onos', user) + if not onosDir: + error('Please set ONOS_ROOT environment variable!\n') + else: + os.environ[ 'ONOS_ROOT' ] = onosDir + ### LINC-directory + lincDir = findDir.__func__('linc-oe', user) + if not lincDir: + error("***ERROR: Could not find linc-oe in user's home directory\n") + ### LINC config generator directory### + configGen = findDir.__func__('LINC-config-generator', user) + if not configGen: + error("***ERROR: Could not find LINC-config-generator in user's home directory\n") + # list of all the controllers + controllers = None + def __init__(self, name, dpid=None, allowed=True, + switchType='ROADM', topo=None, annotations={}, controller=None, **params): + params[ 'inNamespace' ] = False + Switch.__init__(self, name, dpid=dpid, **params) + self.name = name + self.annotations = annotations + self.allowed = allowed + self.switchType = switchType + self.configDict = {} # dictionary that holds all of the JSON configuration data + self.crossConnects = [] + self.deletedCrossConnects = [] + self.controller = controller + self.lincId = self._get_linc_id() # use to communicate with LINC + self.lincStarted = False + + def start(self, *opts, **params): + '''Instead of starting a virtual switch, we build the JSON + dictionary for the emulated optical switch''' + # TODO:Once LINC has the ability to spawn network element dynamically + # we need to use this method to spawn new logical LINC switch rather then + # bulding JSON. + # if LINC is started then we can start and stop logical switches else create JSON + if self.lincStarted: + return self.start_oe() + self.configDict[ 'uri' ] = 'of:' + self.dpid + self.configDict[ 'annotations' ] = self.annotations + self.configDict[ 'annotations' ].setdefault('name', self.name) + self.configDict[ 'hw' ] = 'LINC-OE' + self.configDict[ 'mfr' ] = 'Linc' + self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1] + self.configDict[ 'type' ] = self.switchType + self.configDict[ 'ports' ] = [] + for port, intf in self.intfs.items(): + if intf.name == 'lo': + continue + else: + self.configDict[ 'ports' ].append(intf.json()) + self.lincStarted = True + + def stop(self, deleteIntfs=False): + ''' + stop the existing switch + ''' + # TODO:Add support for deleteIntf + self.stop_oe() + + def dpctl( self, *args ): + "Run dpctl command: ignore for now" + pass + + def write_to_cli(self, command): + ''' + send command to LINC + ''' + fd = None + try: + fd = open(self.writePipe, 'w', 0) + fd.write(command) + fd.close() + except: + print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info()) + if fd: + fd.close() + + def read_from_cli(self): + ''' + read the output from the LINC CLI + ''' + response = None + fd = None + try: + fd = open(self.readPipe, 'r', 0) + fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) # for non-blocking read + # FIXME:Due to non-blocking read most for the time we read nothing + response = fd.read() + fd.close() + except : + # print "Error working with {}\nError: {}\n".format(self.readPipe, sys.exc_info()) + if fd: + fd.close() + return response + + def _get_linc_id(self): + ''' + return the corresponding LINC switchId. + ''' + return LINCSwitch.dpidsToLINCSwitchId.get(self.dpid) + #-------------------------------------------------------------------------- + # LINC CLI commands + #-------------------------------------------------------------------------- + def start_oe(self): + ''' + existing LINC switch + ''' + #starting Switch + cmd = "linc:start_switch({}).\r\n".format(self.lincId) + self.write_to_cli(cmd) + #hanlding taps interfaces related to the switch + crossConnectJSON = {} + linkConfig = [] + for i in range(0,len(self.deletedCrossConnects)): + crossConnect = self.deletedCrossConnects.pop() + tap = None + if isinstance(crossConnect.intf1.node, LINCSwitch): + intf = crossConnect.intf2 + tapPort = crossConnect.intf1.port + else: + intf = crossConnect.intf1 + tapPort = crossConnect.intf2.port + tap = LINCSwitch.findTap(self, tapPort) + if tap: + LINCSwitch.setupInts([tap]) + intf.node.attach(tap) + self.crossConnects.append(crossConnect) + linkConfig.append(crossConnect.json()) + #Sending crossConnect info to the ONOS. + crossConnectJSON['links'] = linkConfig + with open("crossConnect.json", 'w') as fd: + json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': ')) + info('*** Pushing crossConnect.json to ONOS\n') + output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\ + Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True) + + def stop_oe(self): + ''' + stop the existing LINC switch + ''' + cmd = "linc:stop_switch({}).\r\n".format(self.lincId) + self.write_to_cli(cmd) + #handling taps if any + for i in range(0, len(self.crossConnects)): + crossConnect = self.crossConnects.pop() + if isinstance(crossConnect.intf1.node, LINCSwitch): + intf = crossConnect.intf2 + tapPort = crossConnect.intf1.port + else: + intf = crossConnect.intf1 + tapPort = crossConnect.intf2.port + intf.node.detach(LINCSwitch.findTap(self, tapPort)) + self.deletedCrossConnects.append(crossConnect) + + def w_port_up(self, port): + ''' + port_up + ''' + cmd = "linc:port_up({},{}).\r\n".format(self.lincId, port) + self.write_to_cli(cmd) + + def w_port_down(self, port): + ''' + port_down + ''' + cmd = "linc:port_down({},{}).\r\n".format(self.lincId, port) + self.write_to_cli(cmd) + + # helper functions + @staticmethod + def switchJSON(switch): + "Returns the json configuration for a packet switch" + configDict = {} + configDict[ 'uri' ] = 'of:' + switch.dpid + configDict[ 'mac' ] = quietRun('cat /sys/class/net/%s/address' % switch.name).strip('\n').translate(None, ':') + configDict[ 'hw' ] = 'PK' # FIXME what about OVS? + configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS? + configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS? + annotations = switch.params.get('annotations', {}) + annotations.setdefault('name', switch.name) + configDict[ 'annotations' ] = annotations + ports = [] + for port, intf in switch.intfs.items(): + if intf.name == 'lo': + continue + portDict = {} + portDict[ 'port' ] = port + portDict[ 'type' ] = 'FIBER' if isinstance(intf.link, LINCLink) else 'COPPER' + intfList = [ intf.link.intf1, intf.link.intf2 ] + intfList.remove(intf) + portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0 + ports.append(portDict) + configDict[ 'ports' ] = ports + return configDict + + @staticmethod + def bootOE(net): + "Start the LINC optical emulator within a mininet instance" + LINCSwitch.opticalJSON = {} + linkConfig = [] + devices = [] + #setting up the controllers for LINCSwitch class + LINCSwitch.controllers = net.controllers + + for switch in net.switches: + if isinstance(switch, OpticalSwitch): + devices.append(switch.json()) + else: + devices.append(LINCSwitch.switchJSON(switch)) + LINCSwitch.opticalJSON[ 'devices' ] = devices + + for link in net.links: + if isinstance(link, LINCLink) : + linkConfig.append(link.json()) + LINCSwitch.opticalJSON[ 'links' ] = linkConfig + + info('*** Writing Topology.json file\n') + with open('Topology.json', 'w') as outfile: + json.dump(LINCSwitch.opticalJSON, outfile, indent=4, separators=(',', ': ')) + + info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file (no oecfg) \n') + + topoConfigJson = {}; + dpIdToName = {}; + + topoConfigJson["switchConfig"] = LINCSwitch.getSwitchConfig(dpIdToName); + topoConfigJson["linkConfig"] = LINCSwitch.getLinkConfig(dpIdToName); + + #Writing to TopoConfig.json + with open( 'TopoConfig.json', 'w' ) as outfile: + json.dump( topoConfigJson, outfile, indent=4, separators=(',', ': ') ) + + info('*** Creating sys.config...\n') + output = quietRun('%s/config_generator TopoConfig.json %s/sys.config.template %s %s' + % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[ 0 ].ip, LINCSwitch.controllers[ 0 ].port), shell=True) + if output: + error('***ERROR: Error creating sys.config file: %s\n' % output) + return False + + info ('*** Setting multiple controllers in sys.config...\n') + searchStr = '\[{"Switch.*$' + ctrlStr = '' + for index in range(len(LINCSwitch.controllers)): + ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port) + replaceStr = '[%s]},' % ctrlStr[:-1] # Cut off last comma + sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr) + output = quietRun(sedCmd, shell=True) + + info('*** Copying sys.config to linc-oe directory: ', output + '\n') + output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n') + info(output + '\n') + + info('*** Adding taps and bringing them up...\n') + LINCSwitch.setupInts(LINCSwitch.getTaps()) + + info('*** removing pipes if any \n') + quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True) + + info('*** Starting linc OE...\n') + output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True) + if output: + error('***ERROR: LINC-OE: %s' % output + '\n') + quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) + return False + + info('*** Waiting for linc-oe to start...\n') + LINCSwitch.waitStarted(net) + + info('*** Adding cross-connect (tap) interfaces to packet switches...\n') + for link in net.links: + if isinstance(link, LINCLink): + if link.annotations[ 'optical.type' ] == 'cross-connect': + for intf in [ link.intf1, link.intf2 ]: + if not isinstance(intf, LINCIntf): + intfList = [ intf.link.intf1, intf.link.intf2 ] + intfList.remove(intf) + intf2 = intfList[ 0 ] + intf.node.attach(LINCSwitch.findTap(intf2.node, intf2.node.ports[ intf2 ])) + + info('*** Waiting for all devices to be available in ONOS...\n') + url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip + time = 0 + # Set up password authentication + pw_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() + pw_mgr.add_password(None, url, REST_USER, REST_PW) + handler = urllib2.HTTPBasicAuthHandler(pw_mgr) + opener = urllib2.build_opener(handler) + opener.open(url) + urllib2.install_opener(opener) + while True: + response = json.load(urllib2.urlopen(url)) + devs = response.get('devices') + + # Wait for all devices to be registered + if (len(devices) != len(devs)): + continue + + # Wait for all devices to available + available = True + for d in devs: + available &= d['available'] + if available: + break + + if (time >= TIMEOUT): + error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT) + break + + time += SLEEP_TIME + sleep(SLEEP_TIME) + + info('*** Pushing Topology.json to ONOS\n') + for index in range(len(LINCSwitch.controllers)): + output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json &' % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True) + # successful output contains the two characters '{}' + # if there is more output than this, there is an issue + if output.strip('{}'): + warn('***WARNING: Could not push topology file to ONOS: %s\n' % output) + + #converts node ids to linc-oe format, with colons every two chars + @staticmethod + def dpId(id): + nodeDpid = "" + id = id.split("/", 1)[0] + for i in range(3, len(id) - 1, 2): + nodeDpid += (id[i:(i + 2):]) + ":" + return nodeDpid[0:-1]; + + @staticmethod + def getSwitchConfig (dpIdToName): + switchConfig = []; + #Iterate through all switches and convert the ROADM switches to linc-oe format + for switch in LINCSwitch.opticalJSON["devices"]: + if switch.get("type", "none") == "ROADM": + builtSwitch = {} + + #set basic switch params based on annotations + builtSwitch["allowed"] = True; + builtSwitch["latitude"] = switch["annotations"].get("latitude", 0.0); + builtSwitch["longitude"] = switch["annotations"].get("longitude", 0.0); + + #assumed that all switches have this entry + nodeId = switch["uri"] + + #convert the nodeId to linc-oe format + nodeDpid = LINCSwitch.dpId(nodeId); + + builtSwitch["name"] = switch.get("name", "none"); + + #keep track of the name corresponding to each switch dpid + dpIdToName[nodeDpid] = builtSwitch["name"]; + + builtSwitch["nodeDpid"] = nodeDpid + + #set switch params and type + builtSwitch["params"] = {}; + builtSwitch["params"]["numregens"] = switch["annotations"].get("optical.regens", 0); + builtSwitch["type"] = "Roadm" + + #append to list of switches + switchConfig.append(builtSwitch); + return switchConfig + + @staticmethod + def getLinkConfig (dpIdToName): + newLinkConfig = []; + #Iterate through all optical links and convert them to linc-oe format + for link in LINCSwitch.opticalJSON["links"]: + if link.get("type", "none") == "OPTICAL": + builtLink = {} + + #set basic link params for src and dst + builtLink["allowed"] = True; + builtLink["nodeDpid1"] = LINCSwitch.dpId(link["src"]) + builtLink["nodeDpid2"] = LINCSwitch.dpId(link["dst"]) + + #set more params such as name/bandwidth/port/waves if they exist + params = {} + params["nodeName1"] = dpIdToName.get(builtLink["nodeDpid1"], "none") + params["nodeName2"] = dpIdToName.get(builtLink["nodeDpid2"], "none") + + params["port1"] = int(link["src"].split("/")[1]) + params["port2"] = int(link["dst"].split("/")[1]) + + if "bandwidth" in link["annotations"]: + params["bandwidth"] = link["annotations"]["bandwidth"] + + if "optical.waves" in link["annotations"]: + params["numWaves"] = link["annotations"]["optical.waves"] + + builtLink["params"] = params + + #set type of link (WDM or pktOpt) + if link["annotations"].get("optical.type", "cross-connect") == "WDM": + builtLink["type"] = "wdmLink" + else: + builtLink["type"] = "pktOptLink" + + newLinkConfig.append(builtLink); + return newLinkConfig + + + @staticmethod + def waitStarted(net, timeout=TIMEOUT): + "wait until all tap interfaces are available" + tapCount = 0 + time = 0 + for link in net.links: + if isinstance(link, LINCLink): + if link.annotations[ 'optical.type' ] == 'cross-connect': + tapCount += 1 + + while True: + if str(tapCount) == quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'): + return True + if timeout: + if time >= TIMEOUT: + error('***ERROR: LINC OE did not start within %s seconds\n' % TIMEOUT) + return False + time += SLEEP_TIME + sleep(SLEEP_TIME) + + @staticmethod + def shutdownOE(): + "stop the optical emulator" + info('*** Stopping linc OE...\n') + quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) + + @staticmethod + def setupInts(intfs): + ''' + add taps and bring them up. + ''' + for i in intfs: + quietRun('ip tuntap add dev %s mode tap' % i) + quietRun('ip link set dev %s up' % i) + info('*** Intf %s set\n' % i) + + @staticmethod + def getTaps(path=None): + ''' + return list of all the tops in sys.config + ''' + if path is None: + path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir + fd = open(path, 'r', 0) + sys_data = fd.read() + taps = re.findall('tap\d+', sys_data) + fd.close() + return taps + + @staticmethod + def findUser(): + "Try to return logged-in (usually non-root) user" + try: + # If we're running sudo + return os.environ[ 'SUDO_USER' ] + except: + try: + # Logged-in user (if we have a tty) + return quietRun('who am i').split()[ 0 ] + except: + # Give up and return effective user + return quietRun('whoami') + + + @staticmethod + def findTap(node, port, path=None): + '''utility function to parse through a sys.config + file to find tap interfaces for a switch''' + switch = False + portLine = '' + intfLines = [] + + if path is None: + path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir + + with open(path) as f: + for line in f: + if 'tap' in line: + intfLines.append(line) + if node.dpid in line.translate(None, ':'): + switch = True + continue + if switch: + if 'switch' in line: + switch = False + if 'port_no,%s}' % port in line: + portLine = line + break + + if portLine: + m = re.search('port,\d+', portLine) + port = m.group(0).split(',')[ 1 ] + else: + error('***ERROR: Could not find any ports in sys.config\n') + return + + for intfLine in intfLines: + if 'port,%s' % port in intfLine: + return re.findall('tap\d+', intfLine)[ 0 ] + + def json(self): + "return json configuration dictionary for switch" + return self.configDict + + def terminate(self): + pass + + + +class LINCLink(Link): + """ + LINC link class + """ + def __init__(self, node1, node2, port1=None, port2=None, allowed=True, + intfName1=None, intfName2=None, linkType='OPTICAL', + annotations={}, speed1=0, speed2=0, **params): + "Creates a dummy link without a virtual ethernet pair." + self.allowed = allowed + self.annotations = annotations + self.linkType = linkType + self.port1 = port1 + self.port2 = port2 + params1 = { 'speed': speed1 } + params2 = { 'speed': speed2 } + # self.isCrossConnect = True if self.annotations.get('optical.type') == 'cross-connect' else False + if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch): + self.isCrossConnect = False + else: + self.isCrossConnect = True + if isinstance(node1, LINCSwitch): + cls1 = LINCIntf + if self.isCrossConnect: + node1.crossConnects.append(self) + else: + cls1 = Intf + # bad hack to stop error message from appearing when we try to set up intf in a packet switch, + # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up + intfName1 = 'lo' + if isinstance(node2, LINCSwitch): + cls2 = LINCIntf + if self.isCrossConnect: + node2.crossConnects.append(self) + else: + cls2 = Intf + intfName2 = 'lo' + Link.__init__(self, node1, node2, port1=port1, port2=port2, + intfName1=intfName1, intfName2=intfName2, cls1=cls1, + cls2=cls2, params1=params1, params2=params2) + + @classmethod + def makeIntfPair(_cls, intfName1, intfName2, *args, **kwargs): + pass + + def json(self): + "build and return the json configuration dictionary for this link" + configData = {} + configData[ 'src' ] = ('of:' + self.intf1.node.dpid + + '/%s' % self.intf1.node.ports[ self.intf1 ]) + configData[ 'dst' ] = ('of:' + self.intf2.node.dpid + + '/%s' % self.intf2.node.ports[ self.intf2 ]) + configData[ 'type' ] = self.linkType + configData[ 'annotations' ] = self.annotations + return configData + +class LINCIntf(OpticalIntf): + """ + LINC interface class + """ + def __init__(self, name=None, node=None, speed=0, + port=None, link=None, **params): + self.node = node + self.speed = speed + self.port = port + self.link = link + self.name = name + node.addIntf(self, port=port) + self.params = params + self.ip = None + + def json(self): + "build and return the JSON information for this interface( not used right now )" + configDict = {} + configDict[ 'port' ] = self.port + configDict[ 'speed' ] = self.speed + configDict[ 'type' ] = 'FIBER' + return configDict + + def config(self, *args, **kwargs): + "dont configure a dummy interface" + pass + + def ifconfig(self, status): + "configure the status" + if status == "up": + return self.node.w_port_up(self.port) + elif status == "down": + return self.node.w_port_down(self.port) + + +class MininetOE(Mininet): + "Mininet with Linc-OE support (starts and stops linc-oe)" + + def start(self): + Mininet.start(self) + LINCSwitch.bootOE(self) + + def stop(self): + Mininet.stop(self) + LINCSwitch.shutdownOE() + + def addControllers(self, controllers): + i = 0 + for ctrl in controllers: + self.addController(RemoteController('c%d' % i, ip=ctrl)) + i += 1 + +if __name__ == '__main__': + pass diff --git a/framework/src/onos/tools/test/topos/rftest.py b/framework/src/onos/tools/test/topos/rftest.py new file mode 100644 index 00000000..7aba54f9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/rftest.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController + +from rftesttopo import ReactiveForwardingTestTopo + +setLogLevel( 'info' ) + +def pingloop( net ): + setLogLevel( 'error' ) + try: + while True: + net.ping() + finally: + setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + Mininet.pingloop = pingloop + net = Mininet( topo=ReactiveForwardingTestTopo(), build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + ctrl_count = ctrl_count + 1 + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: rf-test.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/rftesttopo.py b/framework/src/onos/tools/test/topos/rftesttopo.py new file mode 100644 index 00000000..9b975785 --- /dev/null +++ b/framework/src/onos/tools/test/topos/rftesttopo.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class ReactiveForwardingTestTopo( Topo ): + "Internet Topology Zoo Specimen." + + def __init__( self ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self ) + + # add nodes, switches first... + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + s8 = self.addSwitch( 's8' ) + s9 = self.addSwitch( 's9' ) + + # ... and now hosts + h1 = self.addHost( 'h1' ) + h2 = self.addHost( 'h2' ) + h3 = self.addHost( 'h3' ) + h4 = self.addHost( 'h4' ) + + # add edges between switch and corresponding host + self.addLink( s1 , h1 ) + self.addLink( s2 , h2 ) + self.addLink( s3 , h3 ) + self.addLink( s4 , h4 ) + + # add edges between switches + self.addLink( s1 , s5 ) + self.addLink( s2 , s5 ) + self.addLink( s2 , s8 ) + self.addLink( s3 , s4 ) + self.addLink( s3 , s7 ) + self.addLink( s4 , s5 ) + self.addLink( s6 , s8 ) + self.addLink( s6 , s7 ) + self.addLink( s5 , s9 ) + self.addLink( s6 , s9 ) + +topos = { 'att': ( lambda: ReactiveForwardingTestTopo() ) } diff --git a/framework/src/onos/tools/test/topos/sdn-ip.json b/framework/src/onos/tools/test/topos/sdn-ip.json new file mode 100644 index 00000000..153d9959 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sdn-ip.json @@ -0,0 +1,26 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "mac": "000000000001", "annotations": { "name": "DEN", "latitude": 39.739317, "longitude": -104.983791 }, "type": "SWITCH" }, + { "alias": "s2", "uri": "of:0000000000000002", "mac": "000000000002", "annotations": { "name": "IND", "latitude": 39.769089, "longitude": -86.158039 }, "type": "SWITCH" }, + { "alias": "s3", "uri": "of:0000000000000003", "mac": "000000000003", "annotations": { "name": "ABQ", "latitude": 35.116541, "longitude": -106.604146 }, "type": "SWITCH" }, + { "alias": "s4", "uri": "of:0000000000000004", "mac": "000000000004", "annotations": { "name": "DFW", "latitude": 32.779501, "longitude": -96.801104 }, "type": "SWITCH" }, + { "alias": "s5", "uri": "of:0000000000000005", "mac": "000000000005", "annotations": { "name": "PDX", "latitude": 45.522585, "longitude": -122.677890 }, "type": "SWITCH" }, + { "alias": "s6", "uri": "of:0000000000000006", "mac": "000000000006", "annotations": { "name": "SFO", "latitude": 37.785286, "longitude": -122.406509 }, "type": "SWITCH" }, + { "alias": "s7", "uri": "of:0000000000000007", "mac": "000000000007", "annotations": { "name": "LAX", "latitude": 34.055604, "longitude": -118.248567 }, "type": "SWITCH" }, + { "alias": "s8", "uri": "of:0000000000000008", "mac": "000000000008", "annotations": { "name": "JFK", "latitude": 40.769487, "longitude": -73.972520 }, "type": "SWITCH" }, + { "alias": "s9", "uri": "of:0000000000000009", "mac": "000000000009", "annotations": { "name": "IAD", "latitude": 38.897676, "longitude": -77.036525 }, "type": "SWITCH" }, + { "alias": "s10", "uri": "of:0000000000000010", "mac": "000000000010", "annotations": { "name": "ATL", "latitude": 33.756298, "longitude": -84.388507 }, "type": "SWITCH" } + ], + + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000000000000001/10", "ip": "10.0.1.2, 10.0.2.2", "annotations": { "type": "bgpSpeaker", "latitude": 42.292306, "longitude": -104.084378 } }, + { "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000000000000002/10", "ip": "10.0.11.2, 10.0.22.2, 10.0.3.2, 10.0.4.2", "annotations": { "type": "bgpSpeaker", "latitude": 41.019068, "longitude": -91.079570 } }, + { "mac": "00:00:00:00:00:03", "vlan": -1, "location": "of:0000000000000003/10", "ip": "10.0.33.2, 10.0.44.2", "annotations": { "type": "bgpSpeaker", "latitude": 32.043892, "longitude": -105.644437 } }, + { "mac": "00:00:00:00:01:01", "vlan": -1, "location": "of:0000000000000005/10", "ip": "10.0.1.1", "annotations": { "type": "router", "latitude": 42.985256, "longitude": -127.074018 } }, + { "mac": "00:00:00:00:01:02", "vlan": -1, "location": "of:0000000000000006/10", "ip": "10.0.11.1", "annotations": { "type": "router", "latitude": 40.593824, "longitude": -127.074018 } }, + { "mac": "00:00:00:00:02:01", "vlan": -1, "location": "of:0000000000000007/10", "ip": "10.0.2.1, 10.0.22.1", "annotations": { "type": "router", "latitude": 31.277098, "longitude": -121.35488 } }, + { "mac": "00:00:00:00:03:01", "vlan": -1, "location": "of:0000000000000008/10", "ip": "10.0.3.1, 10.0.33.1", "annotations": { "type": "router", "latitude": 39.368502, "longitude": -69.976271 } }, + { "mac": "00:00:00:00:04:01", "vlan": -1, "location": "of:0000000000000009/10", "ip": "10.0.4.1", "annotations": { "type": "router", "latitude": 34.936264, "longitude": -75.526168 } }, + { "mac": "00:00:00:00:44:01", "vlan": -1, "location": "of:0000000000000010/10", "ip": "10.0.44.1", "annotations": { "type": "router", "latitude": 32.863420, "longitude": -77.505795 } } + ] +} diff --git a/framework/src/onos/tools/test/topos/sol.py b/framework/src/onos/tools/test/topos/sol.py new file mode 100755 index 00000000..68f2d406 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sol.py @@ -0,0 +1,4 @@ +#!/usr/bin/python +import sys, solar +topo = solar.Solar(cips=sys.argv[1:]) +topo.run() diff --git a/framework/src/onos/tools/test/topos/solar.py b/framework/src/onos/tools/test/topos/solar.py new file mode 100644 index 00000000..ea11b664 --- /dev/null +++ b/framework/src/onos/tools/test/topos/solar.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +from mininet.cli import CLI +from mininet.net import Mininet +from mininet.node import RemoteController, OVSKernelSwitch + +MAC = 12 +DPID = 16 + +class CustomCLI(CLI): + """Custom CLI to allow us to add our own commands.""" + + def __init__ (self, net): + """Init method for our custom CLI.""" + self.net = net + CLI.__init__(self, net) + +class Solar(object): + """ Create a tiered topology from semi-scratch in Mininet """ + + def __init__(self, cname='onos', cips=['192.168.56.1'], islands=3, edges=2, hosts=2): + """Create tower topology for mininet""" + + # We are creating the controller with local-loopback on purpose to avoid + # having the switches connect immediately. Instead, we'll set controller + # explicitly for each switch after configuring it as we want. + self.ctrls = [ RemoteController(cname, cip, 6633) for cip in cips ] + self.net = Mininet(controller=RemoteController, switch = OVSKernelSwitch, + build=False) + + self.cips = cips + self.spines = [] + self.leaves = [] + self.hosts = [] + for ctrl in self.ctrls: + self.net.addController(ctrl) + + # Create the two core switches and links between them + c1 = self.net.addSwitch('c1',dpid='1111000000000000') + c2 = self.net.addSwitch('c2',dpid='2222000000000000') + self.spines.append(c1) + self.spines.append(c2) + + self.net.addLink(c1, c2) + self.net.addLink(c2, c1) + + for i in range(1, islands + 1): + sc = self.createSpineClump(i, edges, hosts) + self.net.addLink(c1, sc[0]) + self.net.addLink(c2, sc[0]) + self.net.addLink(c1, sc[1]) + self.net.addLink(c2, sc[1]) + + def createSpineClump(self, island, edges, hosts): + """ Creates a clump of spine and edge switches with hosts""" + s1 = self.net.addSwitch('s%1d1' % island,dpid='00000%1d0100000000' % island) + s2 = self.net.addSwitch('s%1d2' % island,dpid='00000%1d0200000000' % island) + self.net.addLink(s1, s2) + self.net.addLink(s2, s1) + + for i in range(1, edges + 1): + es = self.createEdgeSwitch(island, i, hosts) + self.net.addLink(es, s1) + self.net.addLink(es, s2) + + self.spines.append(s1) + self.spines.append(s2) + + clump = [] + clump.append(s1) + clump.append(s2) + return clump + + def createEdgeSwitch(self, island, index, hosts): + """ Creates an edge switch in an island and ads hosts to it""" + sw = self.net.addSwitch('e%1d%1d' % (island, index),dpid='0000000%1d0000000%1d' % (island, index)) + self.leaves.append(sw) + + for j in range(1, hosts + 1): + host = self.net.addHost('h%d%d%d' % (island, index, j),ip='10.%d.%d.%d' % (island, index, j)) + self.net.addLink(host, sw) + self.hosts.append(host) + return sw + + def run(self): + """ Runs the created network topology and launches mininet cli""" + self.net.build() + self.net.start() + CustomCLI(self.net) + self.net.stop() + + def pingAll(self): + """ PingAll to create flows - for unit testing """ + self.net.pingAll() + + def stop(self): + "Stops the topology. You should call this after run_silent" + self.net.stop() diff --git a/framework/src/onos/tools/test/topos/sys-nonlinear-10.config b/framework/src/onos/tools/test/topos/sys-nonlinear-10.config new file mode 100644 index 00000000..2b999d39 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys-nonlinear-10.config @@ -0,0 +1,183 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"dummy"},{type,optical}]}, + {port,4,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,11,[{interface,"dummy"},{type,optical}]}, + {port,12,[{interface,"dummy"},{type,optical}]}, + {port,13,[{interface,"dummy"},{type,optical}]}, + {port,14,[{interface,"dummy"},{type,optical}]}, + {port,15,[{interface,"dummy"},{type,optical}]}, + {port,16,[{interface,"dummy"},{type,optical}]}, + {port,17,[{interface,"dummy"},{type,optical}]}, + {port,18,[{interface,"dummy"},{type,optical}]}, + {port,19,[{interface,"dummy"},{type,optical}]}, + {port,20,[{interface,"dummy"},{type,optical}]}, + {port,21,[{interface,"dummy"},{type,optical}]}, + {port,22,[{interface,"dummy"},{type,optical}]}, + {port,23,[{interface,"dummy"},{type,optical}]}, + {port,24,[{interface,"dummy"},{type,optical}]}, + {port,25,[{interface,"dummy"},{type,optical}]}, + {port,26,[{interface,"dummy"},{type,optical}]}, + {port,27,[{interface,"dummy"},{type,optical}]}, + {port,28,[{interface,"dummy"},{type,optical}]}, + {port,29,[{interface,"tap29"}]}, + {port,30,[{interface,"tap30"}]}, + {port,31,[{interface,"tap31"}]}, + {port,32,[{interface,"tap32"}]}, + {port,33,[{interface,"tap33"}]}, + {port,34,[{interface,"tap34"}]}]}, + {capable_switch_queues,[]}, + {optical_links, + [{{1,50},{2,30}}, + {{2,50},{3,30}}, + {{3,50},{4,50}}, + {{1,20},{5,50}}, + {{2,20},{5,20}}, + {{3,20},{6,50}}, + {{4,20},{6,20}}, + {{5,30},{6,40}}, + {{5,40},{7,50}}, + {{6,30},{8,50}}, + {{7,20},{8,30}}, + {{7,30},{9,50}}, + {{8,20},{10,50}}, + {{9,20},{10,20}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,50}]}, + {port,7,[{queues,[]},{port_no,20}]}, + {port,29,[{queues,[]},{port_no,10}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,30}]}, + {port,3,[{queues,[]},{port_no,50}]}, + {port,9,[{queues,[]},{port_no,20}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,4,[{queues,[]},{port_no,30}]}, + {port,5,[{queues,[]},{port_no,50}]}, + {port,11,[{queues,[]},{port_no,20}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,6,[{queues,[]},{port_no,50}]}, + {port,13,[{queues,[]},{port_no,20}]}, + {port,30,[{queues,[]},{port_no,10}]}]}]}, + {switch,5, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:05"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,8,[{queues,[]},{port_no,50}]}, + {port,10,[{queues,[]},{port_no,20}]}, + {port,15,[{queues,[]},{port_no,30}]}, + {port,17,[{queues,[]},{port_no,40}]}]}]}, + {switch,7, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:07"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,18,[{queues,[]},{port_no,50}]}, + {port,21,[{queues,[]},{port_no,20}]}, + {port,23,[{queues,[]},{port_no,30}]}, + {port,32,[{queues,[]},{port_no,10}]}]}]}, + {switch,8, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:08"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,20,[{queues,[]},{port_no,50}]}, + {port,22,[{queues,[]},{port_no,30}]}, + {port,25,[{queues,[]},{port_no,20}]}]}]}, + {switch,9, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:09"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,24,[{queues,[]},{port_no,50}]}, + {port,27,[{queues,[]},{port_no,20}]}, + {port,33,[{queues,[]},{port_no,10}]}]}]}, + {switch,10, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:0A"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,26,[{queues,[]},{port_no,50}]}, + {port,28,[{queues,[]},{port_no,20}]}, + {port,34,[{queues,[]},{port_no,10}]}]}]}, + {switch,6, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:06"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,12,[{queues,[]},{port_no,50}]}, + {port,14,[{queues,[]},{port_no,20}]}, + {port,16,[{queues,[]},{port_no,40}]}, + {port,19,[{queues,[]},{port_no,30}]}, + {port,31,[{queues,[]},{port_no,10}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,info}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/sys-nonlinear-4.config b/framework/src/onos/tools/test/topos/sys-nonlinear-4.config new file mode 100644 index 00000000..b843146a --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys-nonlinear-4.config @@ -0,0 +1,79 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"tap3"}]}, + {port,4,[{interface,"tap4"}]}]}, + {capable_switch_queues,[]}, + {optical_links,[{{1,20},{3,30}},{{3,31},{2,21}},{{1,22},{4,30}},{{4,31},{2,22}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,20}]}, + {port,7,[{queues,[]},{port_no,22}]}, + {port,3,[{queues,[]},{port_no,10}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,5,[{queues,[]},{port_no,30}]}, + {port,6,[{queues,[]},{port_no,31}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,21}]}, + {port,8,[{queues,[]},{port_no,22}]}, + {port,4,[{queues,[]},{port_no,11}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,9,[{queues,[]},{port_no,30}]}, + {port,10,[{queues,[]},{port_no,31}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,debug}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/sys.config b/framework/src/onos/tools/test/topos/sys.config new file mode 100644 index 00000000..2b999d39 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys.config @@ -0,0 +1,183 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"dummy"},{type,optical}]}, + {port,4,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,11,[{interface,"dummy"},{type,optical}]}, + {port,12,[{interface,"dummy"},{type,optical}]}, + {port,13,[{interface,"dummy"},{type,optical}]}, + {port,14,[{interface,"dummy"},{type,optical}]}, + {port,15,[{interface,"dummy"},{type,optical}]}, + {port,16,[{interface,"dummy"},{type,optical}]}, + {port,17,[{interface,"dummy"},{type,optical}]}, + {port,18,[{interface,"dummy"},{type,optical}]}, + {port,19,[{interface,"dummy"},{type,optical}]}, + {port,20,[{interface,"dummy"},{type,optical}]}, + {port,21,[{interface,"dummy"},{type,optical}]}, + {port,22,[{interface,"dummy"},{type,optical}]}, + {port,23,[{interface,"dummy"},{type,optical}]}, + {port,24,[{interface,"dummy"},{type,optical}]}, + {port,25,[{interface,"dummy"},{type,optical}]}, + {port,26,[{interface,"dummy"},{type,optical}]}, + {port,27,[{interface,"dummy"},{type,optical}]}, + {port,28,[{interface,"dummy"},{type,optical}]}, + {port,29,[{interface,"tap29"}]}, + {port,30,[{interface,"tap30"}]}, + {port,31,[{interface,"tap31"}]}, + {port,32,[{interface,"tap32"}]}, + {port,33,[{interface,"tap33"}]}, + {port,34,[{interface,"tap34"}]}]}, + {capable_switch_queues,[]}, + {optical_links, + [{{1,50},{2,30}}, + {{2,50},{3,30}}, + {{3,50},{4,50}}, + {{1,20},{5,50}}, + {{2,20},{5,20}}, + {{3,20},{6,50}}, + {{4,20},{6,20}}, + {{5,30},{6,40}}, + {{5,40},{7,50}}, + {{6,30},{8,50}}, + {{7,20},{8,30}}, + {{7,30},{9,50}}, + {{8,20},{10,50}}, + {{9,20},{10,20}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,50}]}, + {port,7,[{queues,[]},{port_no,20}]}, + {port,29,[{queues,[]},{port_no,10}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,30}]}, + {port,3,[{queues,[]},{port_no,50}]}, + {port,9,[{queues,[]},{port_no,20}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,4,[{queues,[]},{port_no,30}]}, + {port,5,[{queues,[]},{port_no,50}]}, + {port,11,[{queues,[]},{port_no,20}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,6,[{queues,[]},{port_no,50}]}, + {port,13,[{queues,[]},{port_no,20}]}, + {port,30,[{queues,[]},{port_no,10}]}]}]}, + {switch,5, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:05"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,8,[{queues,[]},{port_no,50}]}, + {port,10,[{queues,[]},{port_no,20}]}, + {port,15,[{queues,[]},{port_no,30}]}, + {port,17,[{queues,[]},{port_no,40}]}]}]}, + {switch,7, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:07"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,18,[{queues,[]},{port_no,50}]}, + {port,21,[{queues,[]},{port_no,20}]}, + {port,23,[{queues,[]},{port_no,30}]}, + {port,32,[{queues,[]},{port_no,10}]}]}]}, + {switch,8, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:08"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,20,[{queues,[]},{port_no,50}]}, + {port,22,[{queues,[]},{port_no,30}]}, + {port,25,[{queues,[]},{port_no,20}]}]}]}, + {switch,9, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:09"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,24,[{queues,[]},{port_no,50}]}, + {port,27,[{queues,[]},{port_no,20}]}, + {port,33,[{queues,[]},{port_no,10}]}]}]}, + {switch,10, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:0A"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,26,[{queues,[]},{port_no,50}]}, + {port,28,[{queues,[]},{port_no,20}]}, + {port,34,[{queues,[]},{port_no,10}]}]}]}, + {switch,6, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:06"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,12,[{queues,[]},{port_no,50}]}, + {port,14,[{queues,[]},{port_no,20}]}, + {port,16,[{queues,[]},{port_no,40}]}, + {port,19,[{queues,[]},{port_no,30}]}, + {port,31,[{queues,[]},{port_no,10}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,info}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/topo b/framework/src/onos/tools/test/topos/topo new file mode 100755 index 00000000..854de504 --- /dev/null +++ b/framework/src/onos/tools/test/topos/topo @@ -0,0 +1,10 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts the specified mininet topology. +# ----------------------------------------------------------------------------- +cd $(dirname $0) + +topo=${1:-att-onos.py} + +[ -n "$1" ] && shift +sudo python $topo "$@" diff --git a/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py b/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py new file mode 100644 index 00000000..bb964e2b --- /dev/null +++ b/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py @@ -0,0 +1,20 @@ + +from mininet.topo import Topo + +class MyTopo( Topo ): + "10 'floating' switch topology" + + def __init__( self ): + # Initialize topology + Topo.__init__( self ) + + sw_list = [] + swC = self.addSwitch('sc', dpid = 'ffffffff00000001') + + for i in range(1, 201): + switch=self.addSwitch('s'+str(i), dpid = str(i).zfill(16)) + self.addLink(switch,swC) + + sw_list.append(switch) + +topos = { 'mytopo': ( lambda: MyTopo() ) } diff --git a/framework/src/onos/tools/test/topos/tower b/framework/src/onos/tools/test/topos/tower new file mode 100755 index 00000000..8244bae9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/tower @@ -0,0 +1,2 @@ +#!/bin/bash +cd ~/topos && sudo mn --custom tower.py --topo tower --controller remote,${1:-192.168.56.101} --mac diff --git a/framework/src/onos/tools/test/topos/tower.py b/framework/src/onos/tools/test/topos/tower.py new file mode 100755 index 00000000..b75bfe40 --- /dev/null +++ b/framework/src/onos/tools/test/topos/tower.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +from mininet.topo import Topo +from mininet.cli import CLI +from mininet.net import Mininet +from mininet.node import RemoteController, OVSKernelSwitch +from mininet.log import setLogLevel + + +class TowerTopo( Topo ): + """Create a tower topology""" + + def build( self, k=4, h=6 ): + spines = [] + leaves = [] + hosts = [] + + # Create the two spine switches + spines.append(self.addSwitch('s1')) + spines.append(self.addSwitch('s2')) + + # Create two links between the spine switches + self.addLink(spines[0], spines[1]) + #TODO add second link between spines when multi-link topos are supported + #self.addLink(spines[0], spines[1]) + + # Now create the leaf switches, their hosts and connect them together + i = 1 + c = 0 + while i <= k: + leaves.append(self.addSwitch('s1%d' % i)) + for spine in spines: + self.addLink(leaves[i-1], spine) + + j = 1 + while j <= h: + hosts.append(self.addHost('h%d%d' % (i, j))) + self.addLink(hosts[c], leaves[i-1]) + j+=1 + c+=1 + + i+=1 + +topos = { 'tower': TowerTopo } + +def run(): + topo = TowerTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() |