improve functional tests 79/88079/9
authorguillaume.lambert <guillaume.lambert@orange.com>
Wed, 26 Feb 2020 15:58:47 +0000 (16:58 +0100)
committerguillaume.lambert <guillaume.lambert@orange.com>
Thu, 27 Feb 2020 13:35:37 +0000 (14:35 +0100)
- make scripts with "sed" compatible with BSD and macOS

- remove illegal reflective access warnings introduced by JDK11
  - create a file tests/reflectwarn.sh with the right JDK_JAVA_OPTIONS
    variable content.
    sourcing this file at build or runtime removes the warnings.
    But instead, it generates a long note in stderr that still pollutes
    nosetests results.
- in functional tests, move sims and controller stderr to a file to
  prevent that note from polluting nosetests results.

https://dev.to/erichelgeson/removing-illegal-reflective-access-warnings-in-grails-4-393o

JIRA: TRNSPRTPCE-192 TRNSPRTPCE-197
Signed-off-by: guillaume.lambert <guillaume.lambert@orange.com>
Change-Id: I04156ab104d7420d1eb2d180579593c67293175b

tests/buildHoneynode.sh
tests/honeynode/1.2.1/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/honeycomb-tpce
tests/honeynode/2.2.1/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/honeycomb-tpce
tests/reflectwarn.sh [new file with mode: 0755]
tests/transportpce_tests/1.2.1/test_utils.py
tests/transportpce_tests/2.2.1/test_utils.py
tox.ini

index a4e28e4333223f817a721edcee167d1f5d0bab78..11633563aa931774407275d250ed4ee7ff22bcdb 100755 (executable)
@@ -3,6 +3,7 @@
 ORDMVERSION=${1:-1.2.1}
 
 set -e
+. reflectwarn.sh
 cd honeynode/$ORDMVERSION
 mvn clean install -DskipTests -Dcheckstyle.skip -Dmaven.javadoc.skip=true -s ../fd_io_honeycomb_settings.xml -q -V
 chmod +x ./honeynode-distribution/target/honeynode-distribution-1.19.04-hc/honeynode-distribution-1.19.04/honeycomb-tpce
index f8412be82017ce04b3d8bb5c04c8a71212a6a197..091954c10226060b297c2b499ea83f068f8a1f96 100755 (executable)
@@ -6,16 +6,16 @@ JAVA_VER=$("$JAVA_CMD" -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*
 echo $JAVA_VER
 [ "$JAVA_VER" -ge 110 ] && echo "ok, java is 11 or newer" || { echo "it's too old..."; exit 1; }
 if [ -d  $(dirname $0)/config/yang/common ]; then
-       mv  $(dirname $0)/config/yang/common/*  $(dirname $0)/config/yang/.
-       rm -rf  $(dirname $0)/config/yang/common 
+    mv  $(dirname $0)/config/yang/common/*  $(dirname $0)/config/yang/.
+    rm -rf  $(dirname $0)/config/yang/common
 fi
 if [ -d  $(dirname $0)/config/yang/devices ]; then
-       mv  $(dirname $0)/config/yang/devices/*  $(dirname $0)/config/yang/.
-       rm -rf  $(dirname $0)/config/yang/devices 
+    mv  $(dirname $0)/config/yang/devices/*  $(dirname $0)/config/yang/.
+    rm -rf  $(dirname $0)/config/yang/devices
 fi
 if [ -d  $(dirname $0)/config/yang/openconfig ]; then
-       mv  $(dirname $0)/config/yang/openconfig/*  $(dirname $0)/config/yang/.
-       rm -rf  $(dirname $0)/config/yang/openconfig 
+    mv  $(dirname $0)/config/yang/openconfig/*  $(dirname $0)/config/yang/.
+    rm -rf  $(dirname $0)/config/yang/openconfig
 fi
 
 if [ "$#" -ge 2 ]
@@ -32,20 +32,22 @@ then
         filename=$(basename -- "$CONFIG")
         device=$(basename "$CONFIG" .xml)
         echo "changing netconf port with $PORT in netconf.json file ..."
-        sed -i "/netconf-ssh-binding-port/c\  \"netconf-ssh-binding-port\" : "$PORT"," $(dirname $0)/config/netconf.json
+        sed -i' ' "/netconf-ssh-binding-port/c\  \"netconf-ssh-binding-port\" : "$PORT"," $(dirname $0)/config/netconf.json
         echo "changing restconf http port with $REST_HTTP in restconf.json file ..."
-        sed -i "/restconf-port/c\  \"restconf-port\" : "$REST_HTTP"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-port/c\  \"restconf-port\" : "$REST_HTTP"," $(dirname $0)/config/restconf.json
         echo "changing restconf websocket with $REST_WEBSOCKET in restconf.json file ..."
-        sed -i "/restconf-websocket-port/c\  \"restconf-websocket-port\" : "$REST_WEBSOCKET"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-websocket-port/c\  \"restconf-websocket-port\" : "$REST_WEBSOCKET"," $(dirname $0)/config/restconf.json
         echo "changing restconf-https-enabled to false in restconf.json file ..."
-        sed -i "/restconf-https-enabled/c\  \"restconf-https-enabled\" : \"false\"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-https-enabled/c\  \"restconf-https-enabled\" : \"false\"," $(dirname $0)/config/restconf.json
         echo "changing persist-context and persist-config to false in honeycomb.json file ..."
-        sed -i "/persist-context/c\  \"persist-context\" : \"false\"," $(dirname $0)/config/honeycomb.json
-        sed -i "/persist-config/c\  \"persist-config\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/persist-context/c\  \"persist-context\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/persist-config/c\  \"persist-config\" : \"false\"," $(dirname $0)/config/honeycomb.json
         echo "changing netconf-initial-config-xml location with $CONFIG in honeycomb.json file ..."
-        sed -i "/netconf-initial-config-xml/c\  \"netconf-initial-config-xml\" : \"device/$filename\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/netconf-initial-config-xml/c\  \"netconf-initial-config-xml\" : \"device/$filename\"," $(dirname $0)/config/honeycomb.json
          while [ $STATUS -eq 100 ]
          do
+           . $(dirname $0)/../../../../../../reflectwarn.sh
+           # needed to remove JDK11 reflective access warning
            "$JAVA_CMD" -DDEVICE=${device} -Dlogback.logs.directory=$(dirname $0)/logs -Xms512m -Xmn512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar $(dirname $0)/honeynode-distribution-1.19.04.jar
            STATUS=$?
            echo "Honeycomb exited with status: $STATUS"
@@ -57,7 +59,7 @@ then
     else
         echo "initial config file doesn't exist !"
     fi
-else 
+else
     echo "honeycomb-tpce port initial-config-xml"
     echo "Eg : honeycomb-tpce 17832 sample-config-ROADM.xml (rest-http port will be 81 + netconf-port last two digits : 8132)"
 fi
index 3edbe885240c10433ec36e28960a3387a93308e2..e4e2afc29e3d84093dc9938a599cb2915e9b3833 100755 (executable)
@@ -32,20 +32,22 @@ then
         filename=$(basename -- "$CONFIG")
         device=$(basename "$CONFIG" .xml)
         echo "changing netconf port with $PORT in netconf.json file ..."
-        sed -i "/netconf-ssh-binding-port/c\  \"netconf-ssh-binding-port\" : "$PORT"," $(dirname $0)/config/netconf.json
+        sed -i' ' "/netconf-ssh-binding-port/c\  \"netconf-ssh-binding-port\" : "$PORT"," $(dirname $0)/config/netconf.json
         echo "changing restconf http port with $REST_HTTP in restconf.json file ..."
-        sed -i "/restconf-port/c\  \"restconf-port\" : "$REST_HTTP"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-port/c\  \"restconf-port\" : "$REST_HTTP"," $(dirname $0)/config/restconf.json
         echo "changing restconf websocket with $REST_WEBSOCKET in restconf.json file ..."
-        sed -i "/restconf-websocket-port/c\  \"restconf-websocket-port\" : "$REST_WEBSOCKET"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-websocket-port/c\  \"restconf-websocket-port\" : "$REST_WEBSOCKET"," $(dirname $0)/config/restconf.json
         echo "changing restconf-https-enabled to false in restconf.json file ..."
-        sed -i "/restconf-https-enabled/c\  \"restconf-https-enabled\" : \"false\"," $(dirname $0)/config/restconf.json
+        sed -i' ' "/restconf-https-enabled/c\  \"restconf-https-enabled\" : \"false\"," $(dirname $0)/config/restconf.json
         echo "changing persist-context and persist-config to false in honeycomb.json file ..."
-        sed -i "/persist-context/c\  \"persist-context\" : \"false\"," $(dirname $0)/config/honeycomb.json
-        sed -i "/persist-config/c\  \"persist-config\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/persist-context/c\  \"persist-context\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/persist-config/c\  \"persist-config\" : \"false\"," $(dirname $0)/config/honeycomb.json
         echo "changing netconf-initial-config-xml location with $CONFIG in honeycomb.json file ..."
-        sed -i "/netconf-initial-config-xml/c\  \"netconf-initial-config-xml\" : \"device/$filename\"," $(dirname $0)/config/honeycomb.json
+        sed -i' ' "/netconf-initial-config-xml/c\  \"netconf-initial-config-xml\" : \"device/$filename\"," $(dirname $0)/config/honeycomb.json
          while [ $STATUS -eq 100 ]
          do
+           . $(dirname $0)/../../../../../../reflectwarn.sh
+           # needed to remove JDK11 reflective access warning
            "$JAVA_CMD" -DDEVICE=${device} -Dlogback.logs.directory=$(dirname $0)/logs -Xms512m -Xmn512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar $(dirname $0)/honeynode-distribution-1.19.04.jar
            STATUS=$?
            echo "Honeycomb exited with status: $STATUS"
diff --git a/tests/reflectwarn.sh b/tests/reflectwarn.sh
new file mode 100755 (executable)
index 0000000..fc798e4
--- /dev/null
@@ -0,0 +1,22 @@
+# those options are needed to remove JDK11 reflective access warnings at build and run time
+# GROOVY_TURN_OFF_JAVA_WARNINGS=true cannot be passed directly
+# see https://dev.to/erichelgeson/removing-illegal-reflective-access-warnings-in-grails-4-393o
+
+export JDK_JAVA_OPTIONS="
+ --add-opens=java.base/java.io=ALL-UNNAMED
+ --add-opens=java.base/java.lang=ALL-UNNAMED
+ --add-opens=java.base/java.lang.invoke=ALL-UNNAMED
+ --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+ --add-opens=java.base/java.net=ALL-UNNAMED
+ --add-opens=java.base/java.nio=ALL-UNNAMED
+ --add-opens=java.base/java.nio.charset=ALL-UNNAMED
+ --add-opens=java.base/java.nio.file=ALL-UNNAMED
+ --add-opens=java.base/java.util=ALL-UNNAMED
+ --add-opens=java.base/java.util.jar=ALL-UNNAMED
+ --add-opens=java.base/java.util.stream=ALL-UNNAMED
+ --add-opens=java.base/java.util.zip=ALL-UNNAMED
+ --add-opens java.base/sun.nio.ch=ALL-UNNAMED
+ --add-opens java.base/sun.nio.fs=ALL-UNNAMED
+ -Xlog:disable"
+# --illegal-access=permit #default option, can be set to warn to retrieve all details
+
index 12e6d2f5a1bd58a9f8d051878901bccb9ce555fc..618dfb572623df622cd0ec97f45bb189236105ca 100644 (file)
@@ -8,7 +8,7 @@ def start_xpdra_honeynode():
         with open('honeynode1.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17830", "sample_configs/openroadm/1.2.1/oper-XPDRA.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadma_full_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -17,7 +17,7 @@ def start_roadma_full_honeynode():
         with open('honeynode2.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17821", "sample_configs/openroadm/1.2.1/oper-ROADMA-full.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadma_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -26,7 +26,7 @@ def start_roadma_honeynode():
         with open('honeynode2.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17831", "sample_configs/openroadm/1.2.1/oper-ROADMA.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadmb_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -35,7 +35,7 @@ def start_roadmb_honeynode():
         with open('honeynode3.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17832", "sample_configs/openroadm/1.2.1/oper-ROADMB.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadmc_full_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -44,7 +44,7 @@ def start_roadmc_full_honeynode():
         with open('honeynode3.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17823", "sample_configs/openroadm/1.2.1/oper-ROADMC-full.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadmc_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -53,7 +53,7 @@ def start_roadmc_honeynode():
         with open('honeynode4.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17833", "sample_configs/openroadm/1.2.1/oper-ROADMC.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_xpdrc_honeynode():
     executable = ("./honeynode/1.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -62,7 +62,7 @@ def start_xpdrc_honeynode():
         with open('honeynode4.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17834", "sample_configs/openroadm/1.2.1/oper-XPDRC.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_tpce():
     if "USE_LIGHTY" in os.environ and os.environ['USE_LIGHTY'] == 'True':
@@ -70,12 +70,12 @@ def start_tpce():
         executable = "../lighty/target/lighty-transportpce-12.0.0-SNAPSHOT/clean-start-controller.sh"
         with open('odl.log', 'w') as outfile:
             return subprocess.Popen(
-                ["bash", executable], stdout=outfile,
+                ["bash", executable], stdout=outfile, stderr=outfile,
                 stdin=open(os.devnull))
     else:
         print ("starting KARAF TransportPCE build...")
         executable = "../karaf/target/assembly/bin/karaf"
         with open('odl.log', 'w') as outfile:
             return subprocess.Popen(
-                ["bash", executable, "server"], stdout=outfile,
+                ["bash", executable, "server"], stdout=outfile, stderr=outfile,
                 stdin=open(os.devnull))
index e91353003ed2f4cf1803e3fab142c2687224ed7c..699072b314cb9505b13b9a6f29c7d9f48b48c369 100644 (file)
@@ -8,7 +8,7 @@ def start_xpdra_honeynode():
         with open('honeynode1.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17840", "sample_configs/openroadm/2.2.1/oper-XPDRA.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadma_honeynode():
     executable = ("./honeynode/2.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -17,7 +17,7 @@ def start_roadma_honeynode():
         with open('honeynode2.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17841", "sample_configs/openroadm/2.2.1/oper-ROADMA.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadmb_honeynode():
     executable = ("./honeynode/2.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -26,7 +26,7 @@ def start_roadmb_honeynode():
         with open('honeynode5.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17842", "sample_configs/openroadm/2.2.1/oper-ROADMB.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_roadmc_honeynode():
     executable = ("./honeynode/2.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -35,7 +35,7 @@ def start_roadmc_honeynode():
         with open('honeynode3.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17843", "sample_configs/openroadm/2.2.1/oper-ROADMC.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_xpdrc_honeynode():
     executable = ("./honeynode/2.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -44,7 +44,7 @@ def start_xpdrc_honeynode():
         with open('honeynode4.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17844", "sample_configs/openroadm/2.2.1/oper-XPDRC.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_spdra_honeynode():
     executable = ("./honeynode/2.2.1/honeynode-distribution/target/honeynode-distribution-1.19.04-hc"
@@ -53,7 +53,7 @@ def start_spdra_honeynode():
         with open('honeynode6.log', 'w') as outfile:
             return subprocess.Popen(
                 [executable, "17845", "sample_configs/openroadm/2.2.1/oper-SPDRAv2.xml"],
-                stdout=outfile)
+                stdout=outfile, stderr=outfile)
 
 def start_tpce():
     if "USE_LIGHTY" in os.environ and os.environ['USE_LIGHTY'] == 'True':
@@ -61,12 +61,12 @@ def start_tpce():
         executable = "../lighty/target/lighty-transportpce-12.0.0-SNAPSHOT/clean-start-controller.sh"
         with open('odl.log', 'w') as outfile:
             return subprocess.Popen(
-                ["bash", executable], stdout=outfile,
+                ["bash", executable], stdout=outfile, stderr=outfile,
                 stdin=open(os.devnull))
     else:
         print ("starting KARAF TransportPCE build...")
         executable = "../karaf/target/assembly/bin/karaf"
         with open('odl.log', 'w') as outfile:
             return subprocess.Popen(
-                ["bash", executable, "server"], stdout=outfile,
+                ["bash", executable, "server"], stdout=outfile, stderr=outfile,
                 stdin=open(os.devnull))
diff --git a/tox.ini b/tox.ini
index 6ba7095a6896b6760a9e2f4ef09a03cabd86ea82..da63aad4dafdf6145e8475a97540de38cf8d91aa 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -17,11 +17,19 @@ whitelist_externals = bash
                       sudo
 changedir={toxinidir}/tests
 commands =
+#install maven and JDK11 on the Gate since they are not there by default
   {py3,portmapping,topoPortMapping,rspn,topology,pce,olm,end2end,portmapping221,rspn221,topology221,otntopology,olm221,end2end221,gnpy}: - bash -c "if [ ! `which mvn` ]; then ./installMavenCentOS.sh  ; fi"
+#build 1.2.1 sims
   {py3,portmapping,topoPortMapping,rspn,topology,olm,end2end}: - bash -c "./buildHoneynode.sh"
-  {py3,portmapping,topoPortMapping,rspn,topology,olm,end2end,portmapping221,rspn221,topology221,otn-topology,olm221,end2end221}: - bash -c "sed 's@=.*//#FUNCTESTVAL=@=@g' ../olm/src/main/java/org/opendaylight/transportpce/olm/util/OlmUtils.java >/tmp/pivot; mv /tmp/pivot ../olm/src/main/java/org/opendaylight/transportpce/olm/util/OlmUtils.java"
-  {py3,portmapping,topoPortMapping,rspn,topology,pce,olm,end2end,portmapping221,rspn221,topology221,otntopology,olm221,end2end221,gnpy}: - bash -c "cd .. && mvn clean install -s tests/odl_settings.xml -DskipTests -Dmaven.javadoc.skip=true"
+#patch OLM constant to speed up tests, unnecessary for PCE
+  {py3,portmapping,topoPortMapping,rspn,topology,olm,end2end,portmapping221,rspn221,topology221,otn-topology,olm221,end2end221}: - bash -c "sed -i' ' 's@=.*//#FUNCTESTVAL=@=@g' ../olm/src/main/java/org/opendaylight/transportpce/olm/util/OlmUtils.java"
+#build controller, source JDK_JAVA_OPTIONS to remove illegal reflective acces warnings introduced by Java11
+  {py3,portmapping,topoPortMapping,rspn,topology,pce,olm,end2end,portmapping221,rspn221,topology221,otntopology,olm221,end2end221,gnpy}: - bash -c ". reflectwarn.sh && cd .. && mvn clean install -s tests/odl_settings.xml -DskipTests -Dmaven.javadoc.skip=true"
+#patch Karaf exec for the same reason at runtime
+  {py3,portmapping,topoPortMapping,rspn,topology,pce,olm,end2end,portmapping221,rspn221,topology221,otntopology,olm221,end2end221,gnpy}: - bash -c "sed -i' ' 's@!/bin/sh@!/bin/sh\n. $(dirname $0)/../../../../tests/reflectwarn.sh@' ../karaf/target/assembly/bin/karaf"
+#build Lighty if needed
   {py3,portmapping,topoPortMapping,rspn,topology,pce,olm,end2end,portmapping221,rspn221,topology221,otntopology,olm221,end2end221,gnpy}: - bash -c 'if [ "$USE_LIGHTY" == "True" ]; then (cd ../lighty && ./build.sh); fi'
+#run 1.2.1 functional tests
   {py3,portmapping}: nosetests --with-xunit transportpce_tests/1.2.1/test_portmapping.py
   {py3,topoPortMapping}: nosetests --with-xunit transportpce_tests/1.2.1/test_topoPortMapping.py
   {py3,topology}: nosetests --with-xunit transportpce_tests/1.2.1/test_topology.py
@@ -29,7 +37,9 @@ commands =
   {py3,pce}: nosetests --with-xunit transportpce_tests/1.2.1/test_pce.py
   {py3,olm}: nosetests --with-xunit transportpce_tests/1.2.1/test_olm.py
   {end2end}: nosetests --with-xunit transportpce_tests/1.2.1/test_end2end.py
+#build 2.2.1 sims
   {py3,portmapping221,rspn221,topology221,otntopology,olm221,end2end221}: - bash -c "./buildHoneynode.sh 2.2.1"
+#run 2.2.1 functional tests
   {py3,portmapping221}: nosetests --with-xunit transportpce_tests/2.2.1/test_portmapping.py
   {py3,topology221}: nosetests --with-xunit transportpce_tests/2.2.1/test_topology.py
   {otntopology}: nosetests --with-xunit transportpce_tests/2.2.1/test_otn_topology.py