Creating subfolders for test suites

allow teston to look in subfolders
create subfolders for current test suites
move tests into sub folders
create HA suite dependencies folder and moved all common files there
minor driver and test updates
standardize on the name dependencies for the directory
change from admin to sdn users

Conflicts:
	TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.topo

Change-Id: I849e45ab67da8b285c36c5fdf43b34323876e741
diff --git a/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.params b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.params
new file mode 100644
index 0000000..fc296cc
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.params
@@ -0,0 +1,53 @@
+<PARAMS>
+    # CASE - Description
+    # 1 - Variable initialization and optional pull and build ONOS package
+    # 2 - Install ONOS
+    # 100 - Ensure netconf app is running
+    # 200 - Create or modify a configuration file
+    # 300 - Push a configuration file to bring up a device
+    # 400 - Bring down a device (not yet possible)
+
+    <testcases>1,[2,100,200,300]*2</testcases>
+
+    <SCALE>
+        <size>1,3</size>
+    </SCALE>
+
+    <DEPENDENCY>
+        <path> /tests/FUNC/FUNCnetconf/dependencies/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>netconf</wrapper2>
+        <wrapper3>topo</wrapper3>
+        <topology></topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellApps>drivers,openflow,proxyarp,mobility,netconf</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <SLEEP>
+        <startup>20</startup>
+        <upSwitch>10</upSwitch>
+        <topoAttempts>3</topoAttempts>
+    </SLEEP>
+
+    <MININET>
+        <switch>0</switch>
+        <links></links>
+    </MININET>
+
+    <CONFIGURE>
+        <cfgDevicePort>830</cfgDevicePort>
+        <cfgDriver>ovs-netconf</cfgDriver>
+        <cfgApps>org.onosproject.netconf</cfgApps>
+        <cfgName>"sdn"</cfgName>
+        <cfgPass>"rocks"</cfgPass>
+        <cfgAppPort>830</cfgAppPort>
+    </CONFIGURE>
+
+</PARAMS>
diff --git a/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py
new file mode 100644
index 0000000..ddd1cd8
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py
@@ -0,0 +1,361 @@
+# Testing the NETCONF protocol within ONOS
+
+class FUNCnetconf:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import time
+        import imp
+        import re
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        """
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        main.caseExplanation = "This test case is mainly for loading " +\
+                               "from params file, and pull and build the " +\
+                               " latest ONOS package"
+        stepResult = main.FALSE
+
+        # Test variables
+        try:
+            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            gitBranch = main.params[ 'GIT' ][ 'branch' ]
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            # main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+            main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
+            if main.ONOSbench.maxNodes:
+                main.maxNodes = int( main.ONOSbench.maxNodes )
+            else:
+                main.maxNodes = 0
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+            wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.switchSleep = int( main.params[ 'SLEEP' ][ 'upSwitch' ] )
+            main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
+            main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
+
+            # Config file parameters
+            main.configDevicePort = main.params[ 'CONFIGURE' ][ 'cfgDevicePort' ]
+            main.configDriver = main.params[ 'CONFIGURE' ][ 'cfgDriver' ]
+            main.configApps = main.params[ 'CONFIGURE' ][ 'cfgApps' ]
+            main.configName = main.params[ 'CONFIGURE' ][ 'cfgName' ]
+            main.configPass = main.params[ 'CONFIGURE' ][ 'cfgPass' ]
+            main.configPort = main.params[ 'CONFIGURE' ][ 'cfgAppPort' ]
+
+            gitPull = main.params[ 'GIT' ][ 'pull' ]
+            main.cellData = {} # for creating cell file
+            main.hostsData = {}
+            main.CLIs = []
+            main.CLIs2 = []
+            main.ONOSip = []
+            main.assertReturnString = ''  # Assembled assert return string
+
+            main.ONOSip = main.ONOSbench.getOnosIps()
+            print main.ONOSip
+
+            # Assigning ONOS cli handles to a list
+            for i in range( 1,  main.maxNodes + 1 ):
+                main.CLIs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+                main.CLIs2.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+            # -- INIT SECTION, ONLY RUNS ONCE -- #
+            main.startUp = imp.load_source( wrapperFile1,
+                                            main.dependencyPath +
+                                            wrapperFile1 +
+                                            ".py" )
+
+            main.netconfFunction = imp.load_source( wrapperFile2,
+                                            main.dependencyPath +
+                                            wrapperFile2 +
+                                            ".py" )
+
+            main.topo = imp.load_source( wrapperFile3,
+                                         main.dependencyPath +
+                                         wrapperFile3 +
+                                         ".py" )
+
+            # Uncomment out the following if a mininet topology is added
+            # copyResult1 = main.ONOSbench.scp( main.Mininet1,
+            #                                   main.dependencyPath +
+            #                                   main.topology,
+            #                                   main.Mininet1.home + "custom/",
+            #                                   direction="to" )
+
+            if main.CLIs and main.CLIs2:
+                stepResult = main.TRUE
+            else:
+                main.log.error( "Did not properly created list of ONOS CLI handle" )
+                stepResult = main.FALSE
+        except Exception as e:
+            main.log.exception(e)
+            main.cleanup()
+            main.exit()
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        if gitPull == 'True':
+            main.step( "Building ONOS in " + gitBranch + " branch" )
+            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+            stepResult = onosBuildResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully compiled " +
+                                            "latest ONOS",
+                                     onfail="Failed to compile " +
+                                            "latest ONOS" )
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        main.ONOSbench.getVersion( report=True )
+
+    def CASE2( self, main ):
+        """
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.numCtrls = int( main.scale[ 0 ] )
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                   " node(s) ONOS cluster" )
+        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
+                                " node(s) ONOS cluster"
+
+
+
+        #kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+
+
+        time.sleep( main.startUpSleep )
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for ip in main.ONOSip:
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+
+        for i in range( main.maxNodes ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp", main.Mininet1.ip_address,
+                                       main.apps, tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ], options="" )
+        stepResult = onosInstallResult
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        # Start an ONOS cli to provide functionality that is not currently
+        # supported by the Rest API remove this when Leader Checking is supported
+        # by the REST API
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs2[ i ].startOnosCli( main.ONOSip[ i ] )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+        # Remove the first element in main.scale list
+        main.scale.remove( main.scale[ 0 ] )
+
+    def CASE100( self, main ):
+        """
+            Start NETCONF app and OFC-Server or make sure that they are already running
+        """
+        assert main, "There is no main"
+        assert main.CLIs, "There is no main.CLIs"
+        assert main.numCtrls, "Placed the total number of switch topology in \
+                                main.numCtrls"
+
+        testResult = main.FALSE
+        main.testName = "Start up NETCONF app in all nodes"
+        main.case( main.testName + " Test - " + str( main.numCtrls ) +
+                   " NODE(S)" )
+        main.step( "Starting NETCONF app" )
+        main.assertReturnString = "Assertion result for starting NETCONF app"
+        testResult = main.netconfFunction.startApp( main )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+
+        main.step( "Starting OFC-Server" )
+        main.assertReturnString = "Assertion result for starting OFC-Server"
+        testResult = main.netconfFunction.startOFC( main )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+        time.sleep( main.startUpSleep )
+
+    def CASE200( self, main ):
+        """
+            Create or modify a Configuration file
+                -The file is built from information loaded from the .params file
+        """
+        assert main, "There is no main"
+        assert main.CLIs, "There is no main.CLIs"
+        assert main.numCtrls, "Placed the total number of switch topology in \
+                                main.numCtrls"
+
+        main.testName = "Assemble the configuration"
+        main.case( main.testName + " Test - " + str( main.numCtrls ) +
+                   " NODES(S)" )
+        main.step( "Assembling configuration file" )
+        main.assertReturnString = "Assertion result for assembling configuration file"
+        testResult = main.FALSE
+        testResult = main.netconfFunction.createConfig( main )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+        time.sleep( main.startUpSleep )
+
+    def CASE300( self, main ):
+        """
+            Push a configuration and bring up a switch
+        """
+        assert main, "There is no main"
+        assert main.CLIs, "There is no main.CLIs"
+        assert main.numCtrls, "Placed the total number of switch topology in \
+                                main.numCtrls"
+
+        main.testName = "Uploading the configuration"
+        main.case( main.testName + " Test - " + str( main.numCtrls ) +
+                   " NODES(S)" )
+        main.step( "Sending the configuration file")
+        main.assertReturnString = "Assertion result for sending the configuration file"
+        testResult = main.FALSE
+
+        testResult = main.netconfFunction.sendConfig( main )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+
+        time.sleep( main.switchSleep )
+
+        main.step( "Confirming the device was configured" )
+        main.assertReturnString = "Assertion result for confirming a configuration."
+        testResult = main.FALSE
+
+        testResult = main.netconfFunction.devices( main )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+
+    def CASE400( self, main ):
+        """
+            Bring down a switch
+            This test case is not yet possible, but the functionality needed to
+            perform it is planned to be added
+                There is a message that is sent "Device () has closed session"
+                when the device disconnects from onos for some reason.
+                    Because of the triggers for this message are not practical
+                    to activate this will likely not be used to implement the test
+                    case at this time
+            Possible ways to do this may include bringing down mininet then checking
+            ONOS to see if it was recongnized the device being disconnected
+        """
diff --git a/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.topo b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.topo
new file mode 100644
index 0000000..e027146
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.topo
@@ -0,0 +1,87 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <nodes>3</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest1>
+
+        <ONOSrest2>
+            <host>OC2</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest2>
+
+        <ONOSrest3>
+            <host>OC3</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest3>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+         <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <Mininet1>
+            <host>OCN</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS>
+                <home>~/mininet/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/FUNC/FUNCnetconf/README b/TestON/tests/FUNC/FUNCnetconf/README
new file mode 100644
index 0000000..dbf51c0
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/README
@@ -0,0 +1,29 @@
+Summary:
+        This test suite consists of generic NETCONF protocol testing within ONOS
+        using OF-Config to translate NETCONF requests for OVSDB.
+        The following is an overview of how the NETCONF protocol is tested
+        Steps:
+            - Start NETCONF App in all currently running nodes
+            - Start OF-Config server on device to be configured
+            - Create configuration file
+            - Upload the configuration file to the device to be configured
+            - Verify that the device was configured successfully
+
+Required:
+        Make sure that OF-Config, https://github.com/openvswitch/of-config, is
+        installed on the device that is to be configured, the test assumes this
+        device is the machine running TestON.
+        Ensure that <cfgName> and <cfgPass> in the params file are the username
+        and password required to ssh into the desired machine and account that
+        of-config is to be run on.
+        The netconfConfig.json file contains the configuration that was
+        generated by the test.  The test also relies on the existence of this
+        file and will missbehave if it is removed entirely.  The contents of the
+        file are overwritten everytime the test suite runs through Test Case 200
+
+TODO:
+Extend configuration to allow for specification of
+    - Vendor name
+    - Hardware version
+    - Software version
+    - Serial Number
\ No newline at end of file
diff --git a/TestON/tests/FUNC/FUNCnetconf/__init__.py b/TestON/tests/FUNC/FUNCnetconf/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/__init__.py
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py
new file mode 100644
index 0000000..631bd84
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py
@@ -0,0 +1,146 @@
+"""
+    Wrapper functions for FUNCnetconf
+    This functions include Onosclidriver and Mininetclidriver driver functions
+    Author: Jeremy Songster, jeremy@onlab.us
+"""
+import time
+import json
+import os
+
+def __init__( self ):
+    self.default = ''
+
+def startApp( main ):
+    """
+        This function starts the netconf app in all onos nodes and ensures that
+        the OF-Config server is running on the node to be configured
+    """
+
+    startResult = main.FALSE
+    startResult = main.CLIs[ 0 ].activateApp( appName="org.onosproject.netconf" )
+    return startResult
+
+def startOFC( main ):
+    """
+        This function uses pexpect pxssh class to activate the ofc-server daemon on OC2
+    """
+
+    startResult = main.FALSE
+    try:
+        main.ONOSbench.handle.sendline( "" )
+        main.ONOSbench.handle.expect( "\$" )
+        main.ONOSbench.handle.sendline( "ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1 }'" )
+        main.ONOSbench.handle.expect( "\$1 }'" )
+        main.ONOSbench.handle.expect( "\$" )
+        main.configDeviceIp = main.ONOSbench.handle.before
+        main.configDeviceIp = main.configDeviceIp.split()
+        main.configDeviceIp = main.configDeviceIp[ 0 ]
+        main.log.info( "Device to be configured: " + str( main.configDeviceIp ) )
+        main.ONOSbench.handle.sendline( "sudo ofc-server" )
+        main.ONOSbench.handle.expect( "\$" )
+        startResult = main.TRUE
+        return startResult
+    except pexpect.ExceptionPexpect as e:
+        main.log.exception( self.name + ": Pexpect exception found: " )
+        main.log.error( self.name + ":    " + self.handle.before )
+        main.cleanup()
+        main.exit()
+
+def createConfig( main ):
+    """
+        This function writes a configuration file that can later be sent to the
+        REST API to configure a device.
+        The controller device is assumed to be OC1
+        The device to be configured is assumed to be OC2
+    """
+    createCfgResult = main.FALSE
+    # TODO, add ability to set Manufacturer, Hardware and Software versions
+    main.cfgJson = '{ "devices":{ "netconf:'+ main.configDeviceIp + ":" +\
+                    main.configDevicePort + '":' + '{ "basic":{ "driver":"'+\
+                    main.configDriver + '" } } }, "apps": { "' +\
+                    main.configApps + '":{ "devices":[ { "name":' +\
+                    main.configName + ', "password":' + main.configPass +\
+                    ', "ip":"' + main.configDeviceIp + '", "port":' +\
+                    main.configPort + '} ] } } }'
+    try:
+        file = open( os.path.dirname( main.testFile ) + "/dependencies/netconfConfig.json", 'w' )
+        # These lines can cause errors during the configuration process because
+        # they cause the json string to turn into an unordered dictionary before
+        # sorting it alphabetically which can cause the driver type to not be
+        # configured.
+        # main.cfgJson = json.loads( main.cfgJson )
+        # main.cfgJson = json.dumps( main.cfgJson, sort_keys=True,
+        #                        indent=4, separators=(',', ': '))
+        print main.cfgJson
+        file.write( main.cfgJson )
+        if file:
+            createCfgResult = main.TRUE
+            file.close()
+            return createCfgResult
+        else:
+            main.log.error( "There was an error opening the file")
+            return createCfgResult
+    except:
+        main.log.exception( "There was an error opening the file")
+        return createCfgResult
+
+def sendConfig( main ):
+    """
+        This function prepares the command needed to upload the configuration
+        file to the REST API
+    """
+    ip = main.ONOSip[0]
+    port = 8181
+    url = "/network/configuration"
+    method = "POST"
+    data = main.cfgJson
+    configResult = main.FALSE
+    sendResult = main.CLIs[ 0 ].send( ip=ip, port=port, url=url, method=method, data=data )
+    main.log.info( "Device configuration request response code: " + str( sendResult[ 0 ] ) )
+    if ( 200 <= sendResult[ 0 ] <= 299):
+        configResult = main.TRUE
+    else:
+        configResult = main.FALSE
+
+    return configResult
+
+def devices( main ):
+    """
+        This function get the list of devices from the REST API, the ONOS CLI, and
+        the device-controllers command and check to see that each recognizes the
+        device is configured according to the configuration uploaded above.
+    """
+    availResult = main.FALSE
+    typeResult = main.FALSE
+    addressResult = main.FALSE
+    driverResult = main.FALSE
+    try:
+        apiResult = main.CLIs[ 0 ].devices()
+        cliResult = main.CLIs2[ 0 ].devices()
+
+        apiDict = json.loads( apiResult )
+        cliDict = json.loads( cliResult )
+        apiAnnotations = apiDict[ 0 ].get( "annotations" )
+        cliAnnotations = cliDict[ 0 ].get( "annotations" )
+
+        main.log.info( "API device availability result: " + str( apiDict[ 0 ].get( "available" ) ) )
+        main.log.info( "CLI device availability result: " + str( cliDict[ 0 ].get( "available" ) ) )
+        if apiDict[ 0 ].get( "available" ) == True and cliDict[ 0 ].get( "available" ) == True:
+            availResult = main.TRUE
+        main.log.info( "API device type result: " + apiDict[ 0 ].get( "type" ) )
+        main.log.info( "CLI device type result: " + cliDict[ 0 ].get( "type" ) )
+        if apiDict[ 0 ].get( "type" ) == "SWITCH" and cliDict[ 0 ].get( "type" ) == "SWITCH":
+            typeResult = main.TRUE
+        main.log.info( "API device ipaddress: " + apiAnnotations.get( "ipaddress" ) )
+        main.log.info( "CLI device ipaddress: " + apiAnnotations.get( "ipaddress" ) )
+        if str( apiAnnotations.get( "ipaddress" ) ) == main.configDeviceIp and str( cliAnnotations.get( "ipaddress" ) ) == main.configDeviceIp:
+            addressResult = main.TRUE
+        main.log.info( "API device driver: " + apiAnnotations.get( "driver" ) )
+        main.log.info( "CLI device driver: " + cliAnnotations.get( "driver" ) )
+        if apiAnnotations.get( "driver" ) == main.configDriver and cliAnnotations.get( "driver" ) == main.configDriver:
+            driverResult = main.TRUE
+
+        return availResult and typeResult and addressResult and driverResult
+    except TypeError:
+        main.log.error( "Device was not configured correctly" )
+        return main.FALSE
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/netconfConfig.json b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconfConfig.json
new file mode 100644
index 0000000..fc5a231
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconfConfig.json
@@ -0,0 +1,21 @@
+{
+    "apps": {
+        "org.onosproject.netconf": {
+            "devices": [
+                {
+                    "ip": "10.128.50.10",
+                    "name": "sdn",
+                    "password": "rocks",
+                    "port": 830
+                }
+            ]
+        }
+    },
+    "devices": {
+        "netconf:10.128.50.10:830": {
+            "basic": {
+                "driver": "ovs-netconf"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py
new file mode 100644
index 0000000..b44e3fc
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py
@@ -0,0 +1,100 @@
+"""
+    These functions can be used for topology comparisons
+"""
+
+import time
+import os
+import json
+
+def getAllDevices( main ):
+    """
+        Return a list containing the devices output from each ONOS node
+    """
+    devices = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].devices,
+                         name="devices-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        devices.append( t.result )
+    return devices
+
+def getAllHosts( main ):
+    """
+        Return a list containing the hosts output from each ONOS node
+    """
+    hosts = []
+    ipResult = main.TRUE
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].hosts,
+                         name="hosts-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        hosts.append( t.result )
+    return hosts
+
+def getAllPorts( main ):
+    """
+        Return a list containing the ports output from each ONOS node
+    """
+    ports = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].ports,
+                         name="ports-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        ports.append( t.result )
+    return ports
+
+def getAllLinks( main ):
+    """
+        Return a list containing the links output from each ONOS node
+    """
+    links = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].links,
+                         name="links-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        links.append( t.result )
+    return links
+
+def getAllClusters( main ):
+    """
+        Return a list containing the clusters output from each ONOS node
+    """
+    clusters = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].clusters,
+                         name="clusters-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        clusters.append( t.result )
+    return clusters
+
+