Basic Platform test suite using onos docker images; test  activate and deactivate apps

Change-Id: I731f5245883c2ffe6de87b41a613d7159d403b4d
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 3ff43c7..046de84 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -97,6 +97,7 @@
         try:
             path = "http://" + str( ip ) + ":" + str( port ) + base + url
             if self.user_name and self.pwd:
+                main.log.info("users/passwd is: " + self.user_name + "/" + self.pwd)
                 auth = (self.user_name, self.pwd)
             else:
                 auth=None
diff --git a/TestON/drivers/common/api/dockerapidriver.py b/TestON/drivers/common/api/dockerapidriver.py
index 2630f6b..fc96682 100644
--- a/TestON/drivers/common/api/dockerapidriver.py
+++ b/TestON/drivers/common/api/dockerapidriver.py
@@ -5,6 +5,7 @@
 import re
 import subprocess
 from docker import Client
+from docker import errors
 from drivers.common.apidriver import API
 
 class DockerApiDriver( API ):
@@ -39,20 +40,23 @@
         except Exception as e:
             main.log.exception( e )
 
-    def dockerPull( self, image="onosproject/onos", tag="latest" ):
+    def dockerPull( self, onosRepo ="onosproject/onos", onosTag="latest" ):
         """
         Pulls Docker image from repository
         """
         try:
             main.log.info( self.name +
-                           ": Pulling Docker image " + image + ":"+tag )
-            for line in self.dockerClient.pull( repository=image, \
-                    tag=tag, stream=True ):
-                response = json.dumps( json.loads( line ), indent=4 )
-            if( re.search( "Downloaded", response ) ):
+                           ": Pulling Docker image " + onosRepo + ":"+ onosTag )
+            for line in self.dockerClient.pull( repository = onosRepo, \
+                    tag = onosTag, stream = True ):
+                print(json.dumps(json.loads(line), indent =4))
+
+            #response = json.dumps( json.load( pullResult ), indent=4 )
+            if re.search( "for onosproject/onos:latest", line ):
+                main.log.info( "latest onos docker image pulled is: " + line )
                 return main.TRUE
             else:
-                main.log.error( "Failed to download image: " + image +":"+ tag )
+                main.log.error( "Failed to download image from: " + onosRepo +":"+ onosTag )
                 main.log.error( "Error respone: " )
                 main.log.error( response )
                 return main.FALSE
@@ -61,36 +65,39 @@
             main.cleanup()
             main.exit()
 
-    def dockerRun( self, image="onosproject/onos", node="onos1" ):
+    def dockerCreateCT( self, onosImage="onosproject/onos:latest", onosNode="onos1" ):
         """
-            Run specified Docker container
+            Create a Docker container with a specific image
         """
         try:
             main.log.info( self.name +
-                           ": Creating Docker conatiner for node " + node )
-            reponse = self.dockerClient.create_container( image=image, \
-                    tty=True, hostname=node, detach=True )
-            if( reponse['Warnings'] == 'None' ):
-                main.log.info( "Created container for node: " + node )
-                return main.TRUE
+                           ": Creating Docker container for node: " + onosNode )
+            response = self.dockerClient.create_container( image=onosImage, \
+                    tty=True, name=onosNode, detach=True )
+            #print response
+            #print response.get("Id")
+            #print response.get("Warnings")
+            if( str( response.get("Warnings") ) == 'None' ):
+                main.log.info( "Created container for node: " + onosNode + "; container id is: " + response.get("Id") )
+                return ( main.TRUE, response.get("Id") )
             else:
                 main.log.info( "Noticed warnings during create" )
-                return main.FALSE
+                return ( main.FALSE, null)
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def dockerStart( self, node="onos1" ):
+    def dockerStartCT( self, ctID ):
         """
             Start Docker container
         """
         try:
             main.log.info( self.name +
-                           ": Starting Docker conatiner for node " + node )
-            reponse = self.dockerClient.start( node )
-            if( reponse == 'None' ):
-                main.log.info( "Started container for node: " + node )
+                           ": Starting Docker conatiner Id " + ctID )
+            response = self.dockerClient.start( container = ctID )
+            if response is None:
+                main.log.info( "Started container for Id: " + ctID )
                 return main.TRUE
             else:
                 main.log.info( "Noticed warnings during start" )
@@ -100,35 +107,38 @@
             main.cleanup()
             main.exit()
 
-    def dockerStop( self, node="onos1" ):
+    def dockerStopCT( self, ctName ):
         """
             Stop docker container
         """
         try:
             main.log.info( self.name +
-                           ": Stopping Docker conatiner for node " + node )
-            reponse = self.dockerClient.stop( node )
-            if( reponse == 'None' ):
-                main.log.info( "Stopped container for node: " + node )
+                           ": Stopping Docker conatiner for node " + ctName )
+            response = self.dockerClient.stop( ctName )
+            if response is None:
+                main.log.info( "Stopped container for node: " + ctName )
                 return main.TRUE
             else:
                 main.log.info( "Noticed warnings during stop" )
                 return main.FALSE
+        except errors.NotFound:
+            main.log.info( ctName + " not found! Continue on tests...")
+            return main.TRUE
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            #main.cleanup()
+            #main.exit()
 
-    def dockerRestart( self, node="onos1" ):
+    def dockerRestartCT( self, ctName ):
         """
             Restart Docker container
         """
         try:
             main.log.info( self.name +
-                           ": Restarting Docker conatiner for node " + node )
-            reponse = self.dockerClient.restart( node )
-            if( reponse == 'None' ):
-                main.log.info( "Restarted container for node: " + node )
+                           ": Restarting Docker conatiner for node " + ctName )
+            response = self.dockerClient.restart( ctName )
+            if response is None:
+                main.log.info( "Restarted container for node: " + ctName )
                 return main.TRUE
             else:
                 main.log.info( "Noticed warnings during Restart" )
@@ -138,62 +148,77 @@
             main.cleanup()
             main.exit()
 
-    def dockerStatus( self, node="onos1" ):
+    def dockerCheckCTName( self, ctName):
         """
             Check Docker conatiner status
         """
         try:
             main.log.info( self.name +
-                           ": Checking Docker Status for node " + node )
-            reponse = self.dockerClient.inspect_container( node )
-            if( reponse == 'True' ):
-                main.log.info( "Container " + node + " is running" )
+                           ": Checkeng Docker Status for CT with 'Names'  " + ctName )
+            namelist = [response["Names"] for response in self.dockerClient.containers(all=True) if not []]
+            main.log.info("Name list is: " + str(namelist) )
+            if( [ctName] in namelist):
+                main.log.info( "Container " + ctName + " exists" )
                 return main.TRUE
             else:
-                main.log.info( "Container " + node + " is not running" )
+                main.log.info( "Container " + ctName + " does not exist" )
                 return main.FALSE
+        except errors.NotFound:
+            main.log.warn( ctName + "not found! Continue with the tests...")
+            return main.FALSE
         except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            main.log.exception( self.name + ": Uncaught exception! Continue tests..." )
+            #main.cleanup()
+            #main.exit()
 
-    def dockerRemove( self, node="onos1" ):
+    def dockerRemoveCT( self, ctName ):
         """
             Remove Docker conatiner
         """
         try:
             main.log.info( self.name +
-                           ": Removing Docker container for node " + node )
-            reponse = self.dockerClient.remove_container( node )
-            if( reponse == 'None' ):
-                main.log.info( "Removed container for node: " + node )
+                           ": Removing Docker container for node " + ctName )
+            response = self.dockerClient.remove_container( ctName, force=True )
+            if response is None:
+                main.log.info( "Removed container for node: " + ctName )
                 return main.TRUE
             else:
-                main.log.info( "Noticed warnings during Remove " + node )
+                main.log.info( "Noticed warnings during Remove " + ctName)
                 return main.FALSE
+            main.log.exception(self.name + ": not found, continuing...")
+        except errors.NotFound:
+            main.log.warn( ctName + "not found! Continue with the tests...")
+            return main.TRUE
         except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            main.log.exception( self.name + ": Uncaught exception! Continuing..." )
+            #main.cleanup()
+            #main.exit()
 
-    def dockerImageRemove( self, image="onosproject/onos" ):
+    def dockerRemoveImage( self, image="onosproject/onos:latest" ):
         """
             Remove Docker image
         """
-        try:
-            main.log.info( self.name +
-                           ": Removing Docker container for node " + node )
-            reponse = self.dockerClient.remove_image( image )
-            if( reponse == 'None' ):
-                main.log.info( "Removed Docker image: " + image )
+        if self.dockerClient.images() is []: 
+            main.log.info( "no image found with RepoTags: " + image )
+            return main.TRUE
+        else:
+            try:
+                main.log.info( self.name +
+                           ": Removing Docker image " + image )
+                response = self.dockerClient.remove_image( image, force = True)
+                if response is None:
+                    main.log.info( "Removed Docker image: " + image )
+                    return main.TRUE
+                else:
+                    main.log.info( "Noticed warnings during Remove " + image )
+                    return main.FALSE
+            except errors.NotFound:
+                main.log.warn( image + "not found! Continue with the tests...")
                 return main.TRUE
-            else:
-                main.log.info( "Noticed warnings during Remove " + image )
-                return main.FALSE
-        except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            except Exception:
+                main.log.exception( self.name + ": Uncaught exception! Continuing..." )
+                #main.cleanup()
+                #main.exit()
 
     def fetchLatestClusterFile( self, branch="master" ):
         """
@@ -211,32 +236,37 @@
             main.cleanup()
             main.exit()
 
-    def onosFormCluster( self, onosIPs, user="onos", passwd="rocks" ):
+    def onosFormCluster( self, onosIPs, cmdPath="~/OnosSystemTest/TestON/tests/PLATdockertest/Dependency", user="karaf", passwd="karaf" ):
         """
             From ONOS cluster for IP addresses in onosIPs list
         """
         try:
             onosIPs = " ".join(onosIPs)
-            command = "./onos-form-cluster -u " + user + " -p " + passwd + \
-                    " `" + onosIPs + "`"
-            subprocess.call( command ) # output checks are missing for now
-            return main.TRUE # FALSE condition will be verified from output
+            command = cmdPath + "/onos-form-cluster -u " + user + " -p " + passwd + \
+                    " " + onosIPs
+            result = subprocess.call( command, shell=True )
+            if result == 0:
+                return main.TRUE
+            else:
+                main.log.info("Something is not right in forming cluster>")
+                return main.FALSE
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def dockerIP( self, node='onos1' ):
+    def dockerIP( self, ctName ):
         """
             Fetch IP address assigned to specified node/container
         """
         try:
-            output = self.dockerClient.inspect_container(node)
+            output = self.dockerClient.inspect_container( ctName )
             nodeIP = output['NetworkSettings']['IPAddress']
-            #main.log.info( " Docker IP " + str(nodeIP) )
+            main.log.info( " Docker IP " + str(nodeIP) )
             return str(nodeIP)
 
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
diff --git a/TestON/tests/PLATdockertest/Dependency/onos-form-cluster b/TestON/tests/PLATdockertest/Dependency/onos-form-cluster
new file mode 100755
index 0000000..3ccf2a5
--- /dev/null
+++ b/TestON/tests/PLATdockertest/Dependency/onos-form-cluster
@@ -0,0 +1,39 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Forms ONOS cluster using REST API of each separate instance.
+# -----------------------------------------------------------------------------
+
+[ $# -lt 2 ] && echo "usage: $(basename $0) ip1 ip2..." && exit 1
+
+# 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
+
+ip=$1
+shift
+nodes=$*
+
+ipPrefix=${ip%.*}
+
+aux=/tmp/${ipPrefix}.cluster.json
+trap "rm -f $aux" EXIT
+
+echo "{ \"nodes\": [ { \"ip\": \"$ip\" }" > $aux
+for node in $nodes; do
+    echo ", { \"ip\": \"$node\" }" >> $aux
+done
+echo "], \"ipPrefix\": \"$ipPrefix.*\" }" >> $aux
+
+for node in $ip $nodes; do
+    echo "Forming cluster on $node..."
+    curl --user $user:$password -X POST \
+        http://$node:8181/onos/v1/cluster/configuration -d @$aux
+done
diff --git a/TestON/tests/PLATdockertest/PLATdockertest.params b/TestON/tests/PLATdockertest/PLATdockertest.params
new file mode 100755
index 0000000..f09cb52
--- /dev/null
+++ b/TestON/tests/PLATdockertest/PLATdockertest.params
@@ -0,0 +1,45 @@
+<PARAMS>
+
+    <testcases>1,5,1000,10,110,1000</testcases>
+
+    <DOCKER>
+        <repo>onosproject/onos</repo>
+        <tag>latest</tag>
+        <user>karaf</user>
+        <password>karaf</password>
+    </DOCKER>
+
+    <SCALE>
+        <nodelist>onos1,onos2,onos3</nodelist>
+    </SCALE>
+
+    <CASE110>
+        <clustercmdpath>~/OnosSystemTest/TestON/tests/PLATdockertest/Dependency</clustercmdpath>
+        <apps>org.onosproject.proxyarp,org.onosproject.fwd</apps>
+    </CASE110>
+
+    <DEPENDENCY>
+        <path>/tests/SAMPstartTemplate/Dependency/</path>
+        <wrapper1>startUp</wrapper1>
+        <topology>newFuncTopo.py</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers,openflow,proxyarp,mobility</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>120</startup>
+    </SLEEP>
+
+</PARAMS>
diff --git a/TestON/tests/PLATdockertest/PLATdockertest.py b/TestON/tests/PLATdockertest/PLATdockertest.py
new file mode 100644
index 0000000..f753834
--- /dev/null
+++ b/TestON/tests/PLATdockertest/PLATdockertest.py
@@ -0,0 +1,238 @@
+
+# This is a sample template that starts up ONOS cluster, this template
+# is used as a starting script for creating functionality and performance test
+
+class PLATdockertest:
+    """
+    This testsuite performs the following tests:
+    1) checkout onos docker image;
+    2) test image start up in single and clustered mode;
+    3) test onos app activation and deactivation;
+
+    Prerequisites:
+    1) docker-engine installed on test station (localhost);
+    2) python docker client (docker-py) installed on test station
+    """
+
+    def __init__( self ):
+        self.default = ''
+        global DOCKERREPO, DOCKERTAG
+        global IPlist
+        global CTIDlist
+        global NODElist
+
+        DOCKERREPO = "onosproject/onos"
+        DOCKERTAG = "latest"
+
+    def CASE1( self, main ):
+        """
+        1) set up test params;
+        """
+        import re
+
+        main.case("Set case test params")
+        main.step("Initialize test params")
+        NODElist = main.params["SCALE"]["nodelist"].split(',')
+        main.log.info("onos container names are: " + ",".join(NODElist) )
+        IPlist = list()
+        main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
+        DOCKERREPO = main.params[ 'DOCKER' ][ 'repo' ]
+        DOCKERTAG = main.params[ 'DOCKER' ][ 'tag' ]
+        CTIDlist = list()
+        utilities.assert_equals( expect = main.TRUE, actual = main.TRUE,
+                                    onpass = "Params set",
+                                    onfail = "Failed to set params")
+
+    def CASE5(self, main):
+        """
+        Pull (default) "onosproject/onos:latest" image
+        """
+
+        main.case( "Pull latest onos docker image from onosproject/onos - \
+                    it may take sometime if this is a first time pulling." )
+        stepResult = main.FALSE
+        main.step( "pull latest image from onosproject/onos")
+        stepResult = main.ONOSbenchDocker.dockerPull( onosRepo = DOCKERREPO, onosTag = DOCKERTAG )
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Succeeded in pulling " + DOCKERREPO + ":" + DOCKERTAG,
+                                    onfail = "Failed to pull " + DOCKERREPO + ":" + DOCKERTAG )
+
+    def CASE10( self, main ):
+        """
+        Start docker containers for list of onos nodes, only if not already existed
+        """
+        import re
+
+        main.case( "Start onos container(s)")
+        image = DOCKERREPO + ":" + DOCKERTAG
+
+        main.step( "Create and (re)start docker container(s) if not already exist")
+        #stepResult = main.FALSE
+
+        for ct in xrange(0, len(NODElist)):
+            if not main.ONOSbenchDocker.dockerCheckCTName( ctName = NODElist[ct] ):
+                main.log.info( "Create new container for onos" + str(ct + 1) )
+                createResult, ctid = main.ONOSbenchDocker.dockerCreateCT( onosImage = image, onosNode = NODElist[ct])
+                CTIDlist.append(ctid)
+                startResult = main.ONOSbenchDocker.dockerStartCT( ctID = ctid )
+            else:
+                main.log.info("Container exists for node onos" + str(ct + 1) + "; restart container with latest image" )
+                startResult = main.ONOSbenchDocker.dockerRestartCT( ctName = NODElist[ct ] )
+
+        utilities.assert_equals( expect = main.TRUE, actual = createResult and startResult,
+                                    onpass = "Container successfully created",
+                                    onfail = "Failed to create the container" )
+
+        main.step( "Get IP address on onos containers" )
+        stepResult = main.FALSE
+
+        for ct in xrange(0,len(NODElist)):
+            IPlist.append(main.ONOSbenchDocker.dockerIP( ctName = NODElist[ct] ))
+        main.log.info("Container IPs are: " +  ', '.join( IPlist ))
+
+        if IPlist is not []:stepResult = main.TRUE
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Container successfully started",
+                                    onfail = "Failed to start the container" )
+
+    def CASE110(self,main):
+        """
+        Steps:
+        1) check default startup standalone onos applications status;
+        2) form onos cluster with all nodes;
+        3) check onos applications status;
+        4) activate apps per params and check app status;
+        5) deactivate apps and check app status
+
+        """
+        import time
+        import json
+
+        startupSleep = int(main.params["SLEEP"]["startup"])
+
+        appToAct = main.params["CASE110"]["apps"]
+        stepResult = main.FALSE
+
+        main.log.info( "Wait for startup, sleep (sec): " + str(startupSleep))
+        time.sleep(startupSleep)
+
+        main.step( "Check initial app states from onos1")
+        stepResult = main.TRUE
+        response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
+        main.log.debug("Rest call response is: " + response)
+        if response is not main.FALSE:
+            for item in json.loads(response):
+                if item["state"] not in ["ACTIVE", "INSTALLED"]:
+                    main.log.info("Some bundles are not in correct state. ")
+                    main.log.info("App states are: " + response)
+                    stepResult = main.FALSE
+                    break;
+                if (item["description"] == "Builtin device drivers") and (item["state"] !=  "ACTIVE"):
+                    main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
+                    stepResult = main.FALSE
+                    break;
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "ONOS successfully started",
+                                    onfail = "Failed to start ONOS correctly" )
+        if stepResult is main.FALSE: main.skipCase
+
+        main.step( "Form onos cluster using 'Dependency/onos-form-cluster' util")
+        stepResult = main.FALSE
+        clcmdpath = main.params["CASE110"]["clustercmdpath"]
+        main.log.info("onos-form-cluster cmd path is: " + clcmdpath)
+        dkruser = main.params["DOCKER"]["user"]
+        dkrpasswd = main.params["DOCKER"]["password"]
+        main.ONOSbenchDocker.onosFormCluster(cmdPath = clcmdpath, onosIPs=IPlist, user=dkruser, passwd = dkrpasswd)
+        main.log.info("Wait for cluster to form with sleep time of " + str(startupSleep))
+        time.sleep(startupSleep)
+        status, response = main.ONOSbenchRest.send(ip=IPlist[0],port=8181, url="/cluster")
+        main.log.debug("Rest call response: " + str(status) + " - " + response)
+        if status == 200:
+            jrsp = json.loads(response)
+            clusterIP = [item["ip"]for item in jrsp["nodes"] if item["status"]== "ACTIVE"]
+            if set(IPlist) == set(clusterIP): stepResult = main.TRUE
+
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "ONOS successfully started",
+                                    onfail = "Failed to start ONOS correctly" )
+        if stepResult is main.FALSE: main.skipCase
+
+        main.step( "Check cluster app status")
+        stepResult = main.TRUE
+        response = main.ONOSbenchRest.apps( ip=IPlist[0], port = 8181 )
+        if response is not main.FALSE:
+            for item in json.loads(response):
+                if item["state"] not in ["ACTIVE", "INSTALLED"]:
+                    main.log.info("Some bundles are not in correct state. ")
+                    main.log.info("App states are: " + response)
+                    stepResult = main.FALSE
+                    break;
+                if (item["description"] == "Builtin device drivers") and (item["state"] != "ACTIVE"):
+                    main.log.info("Driver app is not in 'ACTIVE' state, but in: " + item["state"])
+                    stepResult = main.FALSE
+                    break;
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "ONOS successfully started",
+                                    onfail = "Failed to start ONOS correctly" )
+        if stepResult is main.FALSE: main.skipCase
+
+        main.step(" Activate an APP from REST and check APP status")
+        appResults = list()
+        stepResult = main.TRUE
+        applist = main.params["CASE110"]["apps"].split(",")
+        main.log.info("List of apps to activate: " + str(applist) )
+        for app in applist:
+            time.sleep(5)
+            appRslt = main.ONOSbenchRest.activateApp(appName=app, ip=IPlist[0], port=8181, check=True)
+            appResults.append(appRslt)
+            stepResult = stepResult and appRslt
+        main.log.debug("Apps activation result for " + ",".join(applist) + ": " + str(appResults) ) 
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Successfully activate apps",
+                                    onfail = "Failed to activate apps correctly" )
+        if stepResult is main.FALSE: main.skipCase
+
+        main.step(" Deactivate an APP from REST and check APP status")
+        appResults = list()
+        stepResult = main.TRUE
+        applist = main.params["CASE110"]["apps"].split(",")
+        main.log.info("Apps to activae: " + str(applist) )
+        for app in applist:
+            time.sleep(5)
+            appRslt = main.ONOSbenchRest.deactivateApp(appName=app, ip=IPlist[0], port=8181, check=True)
+            appResults.append(appRslt)
+            stepResult = stepResult and appRslt
+        main.log.debug("Apps deactivation result for " + ",".join(applist) + ": " + str(appResults) )
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Successfully deactivate apps",
+                                    onfail = "Failed to deactivate apps correctly" )
+        if stepResult is main.FALSE: main.skipCase
+
+    def CASE1000( self, main ):
+
+        """
+        Cleanup after tests - stop and delete the containers created; delete "onosproject/onos:latest image
+        """
+        import time
+
+        main.step("Stop onos containers")
+        stepResult = main.TRUE
+        for ctname in NODElist:
+            if main.ONOSbenchDocker.dockerCheckCTName(ctName = "/" + ctname):
+                main.log.info( "stopping docker container: /" + ctname)
+                stopResult = main.ONOSbenchDocker.dockerStopCT( ctName = "/" + ctname )
+                time.sleep(10)
+                rmResult = main.ONOSbenchDocker.dockerRemoveCT( ctName = "/" + ctname)
+                stepResult = stepResult and stopResult and rmResult
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Container successfully stopped",
+                                    onfail = "Failed to stopped the container" )
+
+        #main.step( "remove exiting onosproject/onos images")
+        #stepResult = main.ONOSbenchDocker.dockerRemoveImage( image = DOCKERREPO + ":" + DOCKERTAG )
+        main.step( "remove exiting '<none>:<none>' images")
+        stepResult = main.ONOSbenchDocker.dockerRemoveImage( image = "<none>:<none>" )
+        utilities.assert_equals( expect = main.TRUE, actual = stepResult,
+                                    onpass = "Succeeded in deleting image " + "<none>:<none>",
+                                    onfail = "Failed to delete image " + "<none>:<none>" )
+
diff --git a/TestON/tests/PLATdockertest/PLATdockertest.topo b/TestON/tests/PLATdockertest/PLATdockertest.topo
new file mode 100755
index 0000000..8fd6ed9
--- /dev/null
+++ b/TestON/tests/PLATdockertest/PLATdockertest.topo
@@ -0,0 +1,46 @@
+<TOPOLOGY>
+    <COMPONENT>
+        <ONOSbenchCli>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbenchCli>
+
+        <ONOSbenchRest>
+            <host>localhost</host>
+            <port>8181</port>
+            <user>karaf</user>
+            <password>karaf</password>
+            <type>OnosRestDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbenchRest>
+
+        <ONOSbenchDocker>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>DockerApiDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbenchDocker>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+                <home>~/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/PLATdockertest/__init__.py b/TestON/tests/PLATdockertest/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/PLATdockertest/__init__.py