Update initialization test case to have scaling functionality
diff --git a/TestON/core/logger.py b/TestON/core/logger.py
index 1dfe6bf..e77d440 100644
--- a/TestON/core/logger.py
+++ b/TestON/core/logger.py
@@ -1,7 +1,7 @@
 #/usr/bin/env python
 '''
 Created on 07-Jan-2013
-       
+
 @author: Raghav Kashyap(raghavkashyap@paxterrasolutions.com)
 
     TestON is free software: you can redistribute it and/or modify
@@ -15,7 +15,7 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with TestON.  If not, see <http://www.gnu.org/licenses/>.		
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
 
 
 '''
@@ -27,7 +27,7 @@
 class Logger:
     '''
         Add continuous logs and reports of the test.
-        
+
         @author: Raghav Kashyap(raghavkashyap@paxterrasolutions.com)
     '''
     def _printHeader(self,main) :
@@ -39,7 +39,7 @@
         logmsg = logmsg + "\n\tReport Log File : " + main.ReportFileName + ""
         for component in main.componentDictionary.keys():
             logmsg = logmsg + "\n\t"+component+" Session Log : " + main.logdir+"/"+component+".session" + ""
-            
+
         logmsg = logmsg + "\n\tTest Script :" + path + "Tests/" + main.TEST + ".py"+ ""
         logmsg = logmsg + "\n\tTest Params : " + path + "Tests/" + main.TEST + ".params" + ""
         logmsg = logmsg + "\n\tTopology : " + path + "Tests/" +main.TEST + ".topo" + ""
@@ -49,11 +49,10 @@
         values = re.sub("{", "\n\t", values)
         values = re.sub("}", "\n\t", values)
         logmsg = logmsg + values
-        
         logmsg = logmsg + "\n\n"+" " * 31+"+---------------+\n" +"-" * 29+" { Components Used }  " +"-" * 29+"\n"+" " * 31+"+---------------+\n"
         component_list = []
         component_list.append(None)
-        
+
         # Listing the components in the order of test_target component should be first.
         if type(main.componentDictionary) == dict:
             for key in main.componentDictionary.keys():
@@ -61,64 +60,74 @@
                     component_list[0] = key+"-Test Target"
                 else :
                     component_list.append(key)
-                        
+
         for index in range(len(component_list)) :
             if index==0:
                 if component_list[index]:
                     logmsg+="\t"+component_list[index]+"\n"
             elif index > 0 :
                 logmsg+="\t"+str(component_list[index])+"\n"
-                
-            
-            
+
         logmsg = logmsg + "\n\n"+" " * 30+"+--------+\n" +"-" * 28+" { Topology }  "+"-" * 28 +"\n" +" " * 30+"+--------+\n"
         values = "\n\t" + str(main.topology['COMPONENT'])
         values = re.sub(",", "\n\t", values)
         values = re.sub("{", "\n\t", values)
         values = re.sub("}", "\n\t", values)
         logmsg = logmsg + values
-        
         logmsg = logmsg + "\n"+"-" * 60+"\n"
-        
+
         # enter into log file all headers
         logfile = open(main.LogFileName,"w+")
         logfile.write (logmsg)
         print logmsg
         main.logHeader = logmsg
-
         logfile.close()
-        
+
         #enter into report file all headers
         main.reportFile = open(main.ReportFileName,"w+")
         main.reportFile.write(logmsg)
         main.reportFile.close()
-        
+
+        #Sumamry file header
+        currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
+        main.summaryFile = open( main.SummaryFileName, "w+" )
+        main.summaryFile.write( main.TEST + " at " + currentTime + "\n" )
+        main.summaryFile.close()
+
+        #wiki file header
+        currentTime = str( main.STARTTIME.strftime("%d %b %Y %H:%M:%S") )
+        main.wikiFile = open( main.WikiFileName, "w+" )
+        main.wikiFile.write( main.TEST + " at " + currentTime + "<p></p>\n" )
+        main.wikiFile.close()
+
     def initlog(self,main):
         '''
             Initialise all the log handles.
         '''
         main._getTest()
-        main.STARTTIME = datetime.datetime.now() 
+        main.STARTTIME = datetime.datetime.now()
 
         currentTime = re.sub("-|\s|:|\.", "_", str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S")))
         if main.logdir:
             main.logdir = main.logdir+ "/"+main.TEST + "_" + currentTime
         else:
             main.logdir = main.logs_path + main.TEST + "_" + currentTime
-            
+
         os.mkdir(main.logdir)
-           
+
         main.LogFileName = main.logdir + "/" + main.TEST + "_" +str(currentTime) + ".log"
         main.ReportFileName = main.logdir + "/" + main.TEST + "_" + str(currentTime) + ".rpt"
+        main.WikiFileName = main.logdir + "/" + main.TEST + "Wiki.txt"
+        main.SummaryFileName = main.logdir + "/" + main.TEST + "Summary.txt"
         main.JenkinsCSV = main.logdir + "/" + main.TEST + ".csv"
- 
+
         #### Add log-level - Report
         logging.addLevelName(9, "REPORT")
         logging.addLevelName(7, "EXACT")
         logging.addLevelName(11, "CASE")
         logging.addLevelName(12, "STEP")
         main.log = logging.getLogger(main.TEST)
-        def report (msg):
+        def report(msg):
             '''
                 Will append the report message to the logs.
             '''
@@ -130,11 +139,32 @@
             main.reportFile = open(main.ReportFileName,"a+")
             main.reportFile.write(newmsg)
             main.reportFile.close()
-            
-            
-        main.log.report = report 
-        
-        def exact (exmsg):
+
+        main.log.report = report
+
+        def summary( msg ):
+            '''
+                Will append the message to the txt file for the summary.
+            '''
+            main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
+            main.summaryFile = open(main.SummaryFileName,"a+")
+            main.summaryFile.write(msg+"\n")
+            main.summaryFile.close()
+
+        main.log.summary = summary
+
+        def wiki( msg ):
+            '''
+                Will append the message to the txt file for the wiki.
+            '''
+            main.log._log(6,msg,"OpenFlowAutoMattion","OFAutoMation")
+            main.wikiFile = open(main.WikiFileName,"a+")
+            main.wikiFile.write(msg+"\n")
+            main.wikiFile.close()
+
+        main.log.wiki = wiki
+
+        def exact(exmsg):
             '''
                Will append the raw formatted message to the logs
             '''
@@ -146,10 +176,9 @@
             logfile.write("\n"+ str(exmsg) +"\n")
             logfile.close()
             print exmsg
-            
-        main.log.exact = exact 
-       
-        
+
+        main.log.exact = exact
+
         def case(msg):
             '''
                Format of the case type log defined here.
@@ -161,10 +190,10 @@
             logfile.write("\n"+ str(newmsg) +"\n")
             logfile.close()
             print newmsg
-                        
+
         main.log.case = case 
-        
-        def step (msg):
+
+        def step(msg):
             '''
                 Format of the step type log defined here.
             '''
@@ -175,9 +204,9 @@
             logfile.write("\n"+ str(newmsg) +"\n")
             logfile.close()
             print newmsg
-                        
-        main.log.step = step 
-        
+
+        main.log.step = step
+
         main.LogFileHandler = logging.FileHandler(main.LogFileName)
         self._printHeader(main)
 
@@ -185,7 +214,7 @@
         main.log.setLevel(logging.INFO)
         main.log.setLevel(logging.DEBUG) # Temporary
         main.LogFileHandler.setLevel(logging.INFO)
-       
+
         # create console handler with a higher log level
         main.ConsoleHandler = logging.StreamHandler()
         main.ConsoleHandler.setLevel(logging.INFO)
@@ -225,7 +254,7 @@
         # add the handlers to logger
         main.log.addHandler(main.ConsoleHandler)
         main.log.addHandler(main.LogFileHandler)
-        
+
     def testSummary(self,main):
         '''
             testSummary will take care about the Summary of test.
@@ -237,12 +266,10 @@
             main.TOTAL_TC_SUCCESS = 0
         else:
             main.TOTAL_TC_SUCCESS = str((main.TOTAL_TC_PASS*100)/main.TOTAL_TC_RUN)
-            
         if (main.TOTAL_TC_RUN == 0) :
             main.TOTAL_TC_EXECPERCENT = 0
         else :
             main.TOTAL_TC_EXECPERCENT = str((main.TOTAL_TC_RUN*100)/main.TOTAL_TC_PLANNED)
-        
         testResult = "\n\n"+"*" * 37+"\n" + "\tTest Execution Summary\n" + "\n"+"*" * 37+" \n"
         testResult =  testResult + "\n Test Start           : " + str(main.STARTTIME.strftime("%d %b %Y %H:%M:%S"))
         testResult =  testResult + "\n Test End             : " + str(main.ENDTIME.strftime("%d %b %Y %H:%M:%S"))
@@ -254,7 +281,7 @@
         testResult =  testResult + "\n Total No Result      : " + str(main.TOTAL_TC_NORESULT)
         testResult =  testResult + "\n Success Percentage   : " + str(main.TOTAL_TC_SUCCESS) + "%"
         testResult =  testResult + "\n Execution Result     : " + str(main.TOTAL_TC_EXECPERCENT) + "%"
-        
+
         #main.log.report(testResult)
         main.testResult = testResult
         main.log.exact(testResult)
@@ -266,24 +293,32 @@
         logfile.write(",".join( [str(int(main.TOTAL_TC_FAIL)), str(int(main.TOTAL_TC_PASS)), str(int(main.TOTAL_TC_PLANNED))] ))
         logfile.close()
 
-
-
-
     def updateCaseResults(self,main):
         '''
             Update the case result based on the steps execution and asserting each step in the test-case
         '''
         case = str(main.CurrentTestCaseNumber)
-        
-        if main.testCaseResult[case] == 2:
+        currentResult = main.testCaseResult.get(case, 2)
+
+        if currentResult == 2:
             main.TOTAL_TC_RUN  = main.TOTAL_TC_RUN + 1
             main.TOTAL_TC_NORESULT = main.TOTAL_TC_NORESULT + 1
             main.log.exact("\n "+"*" * 29+"\n" + "\n Result: No Assertion Called \n"+"*" * 29+"\n")
-        elif main.testCaseResult[case] == 1:
+            line = "Case "+case+": "+main.CurrentTestCase+" - No Result"
+        elif currentResult == 1:
             main.TOTAL_TC_RUN  = main.TOTAL_TC_RUN  + 1
             main.TOTAL_TC_PASS =  main.TOTAL_TC_PASS + 1
             main.log.exact("\n"+"*" * 29+"\n Result: Pass \n"+"*" * 29+"\n")
-        elif main.testCaseResult[case] == 0:
+            line = "Case "+case+": "+main.CurrentTestCase+" - PASS"
+        elif currentResult == 0:
             main.TOTAL_TC_RUN  = main.TOTAL_TC_RUN  + 1
             main.TOTAL_TC_FAIL = main.TOTAL_TC_FAIL + 1
             main.log.exact("\n"+"*" * 29+"\n Result: Failed \n"+"*" * 29+"\n")
+            line = "Case "+case+": "+main.CurrentTestCase+" - FAIL"
+        else:
+            main.log.error( " Unknown result of case " + case +
+                            ". Result was: " + currentResult )
+            line = "Case "+case+": "+main.CurrentTestCase+" - ERROR"
+        main.log.wiki( "<h3>" + line + "</h3>" )
+        main.log.summary( line )
+
diff --git a/TestON/core/teston.py b/TestON/core/teston.py
index 961e824..7199280 100644
--- a/TestON/core/teston.py
+++ b/TestON/core/teston.py
@@ -52,32 +52,34 @@
 
 class TestON:
     '''
-    
-    TestON will initiate the specified test. 
-    The main tasks are : 
-    * Initiate the required Component handles for the test. 
+    TestON will initiate the specified test.
+    The main tasks are :
+    * Initiate the required Component handles for the test.
     * Create Log file  Handles.
-    
     '''
     def __init__(self,options):
         '''
            Initialise the component handles specified in the topology file of the specified test.
-          
         '''
         # Initialization of the variables.
         __builtin__.main = self
-        
         __builtin__.path = path
         __builtin__.utilities = Utilities()
         self.TRUE = 1
         self.FALSE = 0
         self.ERROR = -1
+        self.NORESULT = 2
         self.FAIL = False
         self.PASS = True
-        self.CASERESULT = self.TRUE
+        self.CASERESULT = self.ERROR
+        self.STEPRESULT = self.NORESULT
+        self.stepResults = []
         self.init_result = self.TRUE
         self.testResult = "Summary"
-        self.stepName =""
+        self.stepName = ""
+        self.stepCache = ""
+        # make this into two lists? one for step names, one for results?
+        # this way, the case result could be a true AND of these results
         self.EXPERIMENTAL_MODE = False
         self.test_target = None
         self.lastcommand = None
@@ -127,7 +129,6 @@
             #Ordering components based on the connect order.
             ordered_component_list =sorted(components_connect_order, key=lambda key: components_connect_order[key])
             print ordered_component_list
-            
             for component in ordered_component_list:
                 self.componentInit(component)
 
@@ -143,7 +144,7 @@
                 return self.configDict
             except Exception:
                 print "There is no such file to parse " + self.configFile
-                        
+
     def componentInit(self,component):
         '''
         This method will initialize specified component
@@ -157,12 +158,12 @@
         driver_options['name']=component
         driverName = self.componentDictionary[component]['type']
         driver_options ['type'] = driverName
-        
+
         classPath = self.getDriverPath(driverName.lower())
         driverModule = importlib.import_module(classPath)
         driverClass = getattr(driverModule, driverName)
         driverObject = driverClass()
-         
+
         connect_result = driverObject.connect(user_name = self.componentDictionary[component]['user'] if ('user' in self.componentDictionary[component].keys()) else getpass.getuser(),
                                               ip_address= self.componentDictionary[component]['host'] if ('host' in self.componentDictionary[component].keys()) else 'localhost',
                                               pwd = self.componentDictionary[component]['password'] if ('password' in self.componentDictionary[component].keys()) else 'changeme',
@@ -171,17 +172,16 @@
         if not connect_result:
             self.log.error("Exiting form the test execution because the connecting to the "+component+" component failed.")
             self.exit()
-            
+
         vars(self)[component] = driverObject
-                        
+
     def run(self):
         '''
-           The Execution of the test script's cases listed in the Test params file will be done here. 
-           And Update each test case result. 
-           This method will return TRUE if it executed all the test cases successfully, 
+           The Execution of the test script's cases listed in the Test params file will be done here.
+           And Update each test case result.
+           This method will return TRUE if it executed all the test cases successfully,
            else will retun FALSE
         '''
-        
         self.testCaseResult = {}
         self.TOTAL_TC = 0
         self.TOTAL_TC_RUN = 0
@@ -191,8 +191,8 @@
         self.TOTAL_TC_PASS = 0
         self.TEST_ITERATION = 0
         self.stepCount = 0
-        self.CASERESULT = self.TRUE
-        
+        self.CASERESULT = self.NORESULT
+
         import testparser
         testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
         test = testparser.TestParser(testFile)
@@ -200,16 +200,20 @@
         self.code = test.getStepCode()
         repeat= int(self.params['repeat']) if ('repeat' in self.params) else 1
         self.TOTAL_TC_PLANNED = len(self.testcases_list)*repeat
-        
+
         result = self.TRUE
         while(repeat):
             for self.CurrentTestCaseNumber in self.testcases_list:
                 result = self.runCase(self.CurrentTestCaseNumber)
             repeat-=1
         return result
-    
+
     def runCase(self,testCaseNumber):
         self.CurrentTestCaseNumber = testCaseNumber
+        self.CurrentTestCase = ""
+        self.stepResults = []
+        self.stepName = ""
+        self.caseExplaination = ""
         result = self.TRUE
         self.stepCount = 0
         self.EXPERIMENTAL_MODE = self.FALSE
@@ -221,7 +225,7 @@
         except KeyError:
             self.log.error("There is no Test-Case "+ self.testCaseNumber)
             return self.FALSE
-        
+
         self.stepCount = 0
         while self.stepCount < len(self.code[self.testCaseNumber].keys()):
             result = self.runStep(self.stepList,self.code,self.testCaseNumber)
@@ -229,28 +233,78 @@
                 break
             elif result == self.TRUE:
                 continue
-            
         if not stopped :
+            if all( self.TRUE == i for i in self.stepResults ):
+                # ALL PASSED
+                self.CASERESULT = self.TRUE
+            elif self.FALSE in self.stepResults:
+                # AT LEAST ONE FAILED
+                self.CASERESULT = self.FALSE
+            elif self.TRUE in self.stepResults:
+                # AT LEAST ONE PASSED
+                self.CASERESULT = self.TRUE
+            else:
+                self.CASERESULT = self.NORESULT
             self.testCaseResult[str(self.CurrentTestCaseNumber)] = self.CASERESULT
             self.logger.updateCaseResults(self)
+            self.log.wiki( "<p>" + self.caseExplaination + "</p>" )
+            self.log.summary( self.caseExplaination )
+            self.log.wiki( "<ul>" )
+            for line in self.stepCache.splitlines():
+                if re.search( " - PASS$", line ):
+                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"tick\" /></li>\n" )
+                elif re.search( " - FAIL$", line ):
+                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"cross\" /></li>\n" )
+                elif re.search( " - No Result$", line ):
+                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"warning\" /></li>\n" )
+            self.log.wiki( "</ul>" )
+            self.log.summary( self.stepCache )
+            self.stepCache = ""
         return result
-    
+
     def runStep(self,stepList,code,testCaseNumber):
         if not cli.pause:
             try :
                 step = stepList[self.stepCount]
+                self.STEPRESULT = self.NORESULT
                 exec code[testCaseNumber][step] in module.__dict__
                 self.stepCount = self.stepCount + 1
+                if step > 0:
+                    self.stepCache += "\t"+str(testCaseNumber)+"."+str(step)+" "+self.stepName+" - "
+                    if self.STEPRESULT == self.TRUE:
+                        self.stepCache += "PASS\n"
+                        #self.stepCache += "PASS  <ac:emoticon ac:name=\"tick\" /></li>\n"
+                    elif self.STEPRESULT == self.FALSE:
+                        self.stepCache += "FAIL\n"
+                        #self.stepCache += "FAIL  <ac:emoticon ac:name=\"cross\" /></li>\n"
+                    else:
+                        self.stepCache += "No Result\n"
+                        #self.stepCache += "No Result  <ac:emoticon ac:name=\"warning\" /></li>\n"
+                    self.stepResults.append(self.STEPRESULT)
             except TypeError,e:
-                print "Exception in the following section of code: Test Step " +\
-                      str(testCaseNumber) + "." + str(step) + " ):"
+                print "\nException in the following section of code: " +\
+                      str(testCaseNumber) + "." + str(step) + ": " +\
+                      self.stepName
                 #print code[testCaseNumber][step]
                 self.stepCount = self.stepCount + 1
                 self.log.exception(e)
+                self.logger.updateCaseResults(self)
+                #WIKI results
+                self.log.wiki( "<ul>" )
+                for line in self.stepCache.splitlines():
+                    if re.search( " - PASS$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"tick\" /></li>\n" )
+                    elif re.search( " - FAIL$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"cross\" /></li>\n" )
+                    elif re.search( " - No Result$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"warning\" /></li>\n" )
+                self.log.wiki( "</ul>" )
+                #summary results
+                self.log.summary( self.stepCache )
+                self.stepCache = ""
                 self.cleanup()
                 self.exit()
             return main.TRUE
-        
         if cli.stop:
             cli.stop = False
             stopped = True
@@ -259,21 +313,21 @@
             self.logger.updateCaseResults(self)
             result = self.cleanup()
             return main.FALSE
-        
+
     def addCaseHeader(self):
         caseHeader = "\n"+"*" * 30+"\n Result summary for Testcase"+str(self.CurrentTestCaseNumber)+"\n"+"*" * 30+"\n"
         self.log.exact(caseHeader)
         caseHeader = "\n"+"*" * 40 +"\nStart of Test Case"+str(self.CurrentTestCaseNumber)+" : "
         for driver in self.componentDictionary.keys():
             vars(self)[driver+'log'].info(caseHeader)
-    
+
     def addCaseFooter(self):
         if self.stepCount-1 > 0 :
             previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
             stepHeader = "\n"+"*" * 40+"\nEnd of Step "+previousStep+"\n"+"*" * 40+"\n"
-            
+
         caseFooter = "\n"+"*" * 40+"\nEnd of Test case "+str(self.CurrentTestCaseNumber)+"\n"+"*" * 40+"\n"
-            
+
         for driver in self.driversList:
             vars(self)[driver].write(stepHeader+"\n"+caseFooter)
 
@@ -289,7 +343,6 @@
 
         #self.reportFile.close()
 
-
         #utilities.send_mail()
         for component in self.componentDictionary.keys():
             try :
@@ -314,12 +367,11 @@
         This function will pause the test's execution, and will continue after user provide 'resume' command.
         '''
         __builtin__.testthread.pause()
-    
+
     def onfail(self,*components):
         '''
-        When test step failed, calling all the components onfail. 
+        When test step failed, calling all the components onfail.
         '''
-         
         if not components:
             try :
                 for component in self.componentDictionary.keys():
@@ -328,7 +380,6 @@
             except(Exception),e:
                 print str(e)
                 result = self.FALSE
-                
         else:
             try :
                 for component in components:
@@ -337,8 +388,7 @@
             except(Exception),e:
                 print str(e)
                 result = self.FALSE
-    
-    
+
     def getDriverPath(self,driverName):
         '''
            Based on the component 'type' specified in the params , this method will find the absolute path ,
@@ -348,23 +398,22 @@
 
         cmd = "find "+drivers_path+" -name "+driverName+".py"
         result = commands.getoutput(cmd)
-        
+
         result_array = str(result).split('\n')
         result_count = 0
-        
+
         for drivers_list in result_array:
             result_count = result_count+1
         if result_count > 1 :
             print "found "+driverName+" "+ str(result_count) + "  times"+str(result_array)
             self.exit()
-            
+
         result = re.sub("(.*)drivers","",result)
         result = re.sub("\.py","",result)
         result = re.sub("\.pyc","",result)
         result = re.sub("\/",".",result)
         result = "drivers"+result
         return result
-    
 
     def step(self,stepDesc):
         '''
@@ -379,16 +428,16 @@
                 stepName = " INIT : Initializing the test case :"+self.CurrentTestCase
         except AttributeError:
                 stepName = " INIT : Initializing the test case :"+str(self.CurrentTestCaseNumber)
-            
+
         self.log.step(stepName)
         stepHeader = ""
         if self.stepCount > 1 :
             stepHeader = "\n"+"-"*45+"\nEnd of Step "+previousStep+"\n"+"-"*45+"\n"
-        
+
         stepHeader += "\n"+"-"*45+"\nStart of Step"+stepName+"\n"+"-"*45+"\n"
         for driver in self.componentDictionary.keys():
             vars(self)[driver+'log'].info(stepHeader)
-            
+
     def case(self,testCaseName):
         '''
            Test's each test-case information will append to the logs.
@@ -399,14 +448,14 @@
         caseHeader = testCaseName+"\n"+"*" * 40+"\n"
         for driver in self.componentDictionary.keys():
             vars(self)[driver+'log'].info(caseHeader)
-        
+
     def testDesc(self,description):
         '''
            Test description will append to the logs.
         '''
         description = "Test Description : " + str (description) + ""
         self.log.info(description)
-        
+
     def _getTest(self):
         '''
            This method will parse the test script to find required test information.
@@ -422,17 +471,15 @@
             if lineMatch:
                 counter  = counter + 1
                 self.TC_PLANNED = len(self.testcases_list)
-        
-                
+
     def response_parser(self,response, return_format):
         ''' It will load the default response parser '''
         response_dict = {}
         response_dict = self.response_to_dict(response, return_format)
         return_format_string = self.dict_to_return_format(response,return_format,response_dict)
         return return_format_string
-    
+
     def response_to_dict(self,response,return_format):
-        
         response_dict = {}
         json_match = re.search('^\s*{', response)
         xml_match = re.search('^\s*\<', response)
@@ -440,12 +487,10 @@
         if json_match :
             self.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
             # Formatting the json string
-            
             response = re.sub(r"{\s*'?(\w)", r'{"\1', response)
             response = re.sub(r",\s*'?(\w)", r',"\1', response)
             response = re.sub(r"(\w)'?\s*:", r'\1":', response)
             response = re.sub(r":\s*'(\w)'\s*([,}])", r':"\1"\2', response)
-            
             try :
                 import json
                 response_dict = json.loads(response)
@@ -453,7 +498,6 @@
                 self.log.exception( e )
                 self.log.error("Json Parser is unable to parse the string")
             return response_dict
-        
         elif ini_match :
             self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
             from configobj import ConfigObj
@@ -462,7 +506,6 @@
             response_file.close()
             response_dict = ConfigObj("respnse_file.temp")
             return response_dict
-            
         elif xml_match :
             self.log.info(" Response is in 'XML' format and Converting to '"+return_format+"' format")
             try :
@@ -470,16 +513,15 @@
             except Exception, e:
                 self.log.exception( e )
             return response_dict
-        
+
     def dict_to_return_format(self,response,return_format,response_dict):
-        
         if return_format =='table' :
             ''' Will return in table format'''
             to_do = "Call the table output formatter"
             global response_table
             response_table = '\n'
             response_table = response_table +'\t'.join(response_dict)+"\n"
-            
+
             def get_table(value_to_convert):
                 ''' This will parse the dictionary recusrsively and print as table format'''
                 table_data = ""
@@ -490,16 +532,12 @@
                 else :
                     table_data = table_data + str(value_to_convert) +"\t"
                 return table_data
-            
+
             for value in response_dict.values() :
                 response_table =  response_table + get_table(value)
-                
-
-                
             # response_table = response_table + '\t'.join(response_dict.values())
-                
             return response_table
-        
+
         elif return_format =='config':
             ''' Will return in config format'''
             to_do = 'Call dict to config coverter'
@@ -511,24 +549,22 @@
             response_config = re.sub("}", "\n", response_config)
             response_config = re.sub(":", " =", response_config)
             return "[response]\n\t "+response_config
-            
         elif return_format == 'xml':
             ''' Will return in xml format'''
             response_xml = xmldict.dict_to_xml(response_dict)
             response_xml = re.sub(">\s*<", ">\n<", response_xml)
             return "\n"+response_xml
-        
         elif return_format == 'json':
             ''' Will return in json format'''
             to_do = 'Call dict to xml coverter'
             import json
             response_json = json.dumps(response_dict)
             return response_json
-    
+
     def get_random(self):
         self.random_order = self.random_order + 1
         return self.random_order
-        
+
     def exit(self):
         __builtin__.testthread = None
         sys.exit()
@@ -567,14 +603,14 @@
         main.testDir = path+'/examples/'
         main.tests_path = path+"/examples/"
         main.classPath = "examples."+main.TEST+"."+main.TEST
-               
+
 def verifyLogdir(options):
     # Verifying Log directory option
     if options.logdir:
         main.logdir = options.logdir
     else :
         main.logdir = main.FALSE
-        
+
 def verifyMail(options):
     # Checking the mailing list
     if options.mail:
@@ -611,7 +647,7 @@
         else :
             print "testcases not specifed in params, please provide in params file or 'testcases' commandline argument"
             sys.exit()
-                  
+
 def verifyTestScript(options):
     '''
     Verifyies test script.
@@ -627,7 +663,6 @@
         print "\nThere is no :\""+main.TEST+"\" test, Please Provide OpenSpeak Script/ test script"
         __builtin__.testthread = None
         main.exit()
-              
     try :
         testModule = __import__(main.classPath, globals(), locals(), [main.TEST], -1)
     except(ImportError):
@@ -639,20 +674,19 @@
     load_parser()
     main.params = main.parser.parseParams(main.classPath)
     main.topology = main.parser.parseTopology(main.classPath)
-    
+
 def verifyParams():
     try :
         main.params = main.params['PARAMS']
     except(KeyError):
         print "Error with the params file: Either the file not specified or the format is not correct"
         main.exit()
-    
     try :
         main.topology = main.topology['TOPOLOGY']
     except(KeyError):
         print "Error with the Topology file: Either the file not specified or the format is not correct"
         main.exit()
-        
+
 def load_parser() :
     '''
     It facilitates the loading customised parser for topology and params file.
@@ -674,11 +708,9 @@
                     main.parser = parsingClass()
                     #hashobj = main.parser.parseParams(main.classPath)
                     if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
-                        
                         pass
                     else:
                         main.exit()
-
                 except ImportError:
                     print sys.exc_info()[1]
                     main.exit()
@@ -709,7 +741,6 @@
     except ImportError:
         print sys.exc_info()[1]
 
-
 def load_logger() :
     '''
     It facilitates the loading customised parser for topology and params file.
@@ -773,8 +804,5 @@
         print sys.exc_info()[1]
         main.exit()
 
-
-
-
 def _echo(self):
     print "THIS IS ECHO"
diff --git a/TestON/core/utilities.py b/TestON/core/utilities.py
index 671dba5..dda43bf 100644
--- a/TestON/core/utilities.py
+++ b/TestON/core/utilities.py
@@ -68,28 +68,22 @@
                         operators = matchVar.group(2)
                     elif matchVar.group(1) == "_" and matchVar.group(2):
                         operators = matchVar.group(2)
-                        
                 except AttributeError:
                     if matchVar==None and nameVar:
                         operators ='equals'
-                        
-                result = self._assert(NOT=notVar,operator=operators,**kwargs) 
+                result = self._assert(NOT=notVar,operator=operators,**kwargs)
                 if result == main.TRUE:
                     main.log.info("Assertion Passed")
-                    main.CASERESULT = main.TRUE
+                    main.STEPRESULT = main.TRUE
                 elif result == main.FALSE:
                     main.log.warn("Assertion Failed")
-                    main.CASERESULT = main.FALSE
-                    
-                else :
+                    main.STEPRESULT = main.FALSE
+                else:
                     main.log.error("There is an Error in Assertion")
-                    main.CASERESULT = main.ERROR
-                    
+                    main.STEPRESULT = main.ERROR
                 return result
-            
             return assertHandling
-        
-    
+
     def _assert (self,**assertParam):  
         '''
         It will take the arguments :
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 7a74ab3..4502971 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -562,6 +562,8 @@
         # on here.
         appString = "export ONOS_APPS=" + appString
         mnString = "export OCN="
+        if mnIpAddrs == "":
+            mnString = ""
         onosString = "export OC"
         tempCount = 1
 
diff --git a/TestON/tests/SingleFunc/SingleFunc.params b/TestON/tests/SingleFunc/SingleFunc.params
index 553b15b..9db302f 100755
--- a/TestON/tests/SingleFunc/SingleFunc.params
+++ b/TestON/tests/SingleFunc/SingleFunc.params
@@ -1,17 +1,30 @@
 <PARAMS>
 
-    <testcases>10,11,1000</testcases>
+    <testcases>10,11</testcases>
+    
+    <SCALE>1,3</SCALE>
+    <availableNodes>3</availableNodes>
     <ENV>
         <cellName>single_func</cellName>
+        <cellApps>drivers,openflow,proxyarp,mobility,fwd</cellApps>
     </ENV>
     <GIT>
         <pull>False</pull>
         <branch>master</branch>
     </GIT>
     <CTRL>
+        <num>3</num>
         <ip1>10.128.10.21</ip1>
         <port1>6633</port1>
+        <ip2>10.128.10.22</ip2>
+        <port2>6633</port2>
+        <ip3>10.128.10.23</ip3>
+        <port3>6633</port3>
     </CTRL>
+    <BENCH>
+        <user>admin</user>
+        <ip1>10.128.10.20</ip1>
+    </BENCH>
     <MININET>
         <switch>7</switch>
         <links>20</links>
diff --git a/TestON/tests/SingleFunc/SingleFunc.py b/TestON/tests/SingleFunc/SingleFunc.py
index 93fd0a3..9a69d8d 100644
--- a/TestON/tests/SingleFunc/SingleFunc.py
+++ b/TestON/tests/SingleFunc/SingleFunc.py
@@ -26,18 +26,100 @@
         onos-install -f
         onos-wait-for-start
         """
+        global init
+        try:
+            if type(init) is not bool:
+                init = False
+        except NameError:
+            init = False
         #Local variables
         cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.ONOS1ip = os.environ[ 'OC1' ]
+        apps = main.params[ 'ENV' ][ 'cellApps' ]
+        main.ONOS1ip = main.params[ 'CTRL' ][ 'ip1' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
         main.ONOS1port = main.params[ 'CTRL' ][ 'port1' ]
+        benchIp = main.params[ 'BENCH' ][ 'ip1' ]
+        benchUser = main.params[ 'BENCH' ][ 'user' ]
         main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
         main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        main.numCtrls = main.params[ 'CTRL' ][ 'num' ]
         topology = main.params[ 'MININET' ][ 'topo' ]
+        maxNodes = int( main.params[ 'availableNodes' ] )
         PULLCODE = False
         if main.params[ 'GIT' ][ 'pull' ] == 'True':
             PULLCODE = True
         main.case( "Setting up test environment" )
+        main.CLIs = []
+        for i in range( 1, int( main.numCtrls ) + 1 ):
+            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- #
+        if init == False:
+            init = True
+            global nodeCount             #number of nodes running
+            global ONOSIp                   #list of ONOS IP addresses
+            global scale
+
+            ONOSIp = [ ]
+            scale = ( main.params[ 'SCALE' ] ).split( "," )
+            nodeCount = int( scale[ 0 ] )
+
+            if PULLCODE:
+                main.step( "Git checkout and pull " + gitBranch )
+                main.ONOSbench.gitCheckout( gitBranch )
+                gitPullResult = main.ONOSbench.gitPull()
+                if gitPullResult == main.ERROR:
+                    main.log.error( "Error pulling git branch" )
+                main.step( "Using mvn clean & install" )
+                cleanInstallResult = main.ONOSbench.cleanInstall()
+                stepResult = cleanInstallResult
+                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" )
+            # Populate ONOSIp with ips from params
+            for i in range( 1, maxNodes + 1):
+                ONOSIp.append( main.params[ 'CTRL' ][ 'ip' + str( i ) ] )
+
+        nodeCount = int( scale[ 0 ] )
+        scale.remove( scale[ 0 ] )
+        #kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating enviornment setup" )
+        for i in range( maxNodes ):
+            main.ONOSbench.onosDie( ONOSIp[ i ] )
+        """
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( cellName )
+        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( "Removing raft logs" )
+        removeRaftResult = main.ONOSbench.onosRemoveRaftLogs()
+        stepResult = removeRaftResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully removed raft logs",
+                                 onfail="Failed to remove raft logs" )
+        """
+        print "NODE COUNT = ", nodeCount
+        main.log.info( "Creating cell file" )
+        cellIp = []
+        for i in range( nodeCount ):
+            cellIp.append( str( ONOSIp[ i ] ) )
+        print cellIp
+        main.ONOSbench.createCellFile( benchIp, cellName, "",
+                                       str( apps ), *cellIp )
 
         main.step( "Apply cell to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
@@ -48,30 +130,6 @@
                                  onpass="Successfully applied cell to " + \
                                         "environment",
                                  onfail="Failed to apply cell to environment " )
-        """main.step( "Removing raft logs" )
-        removeRaftResult = main.ONOSbench.onosRemoveRaftLogs()
-        stepResult = removeRaftResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully removed raft logs",
-                                 onfail="Failed to remove raft logs" )
-        """
-        if PULLCODE:
-            main.step( "Git checkout and pull " + gitBranch )
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            if gitPullResult == main.ERROR:
-                main.log.error( "Error pulling git branch" )
-            main.step( "Using mvn clean & install" )
-            cleanInstallResult = main.ONOSbench.cleanInstall()
-            stepResult = cleanInstallResult
-            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.step( "Creating ONOS package" )
         packageResult = main.ONOSbench.onosPackage()
@@ -82,8 +140,10 @@
                                  onfail="Failed to create ONOS package" )
 
         main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.ONOSbench.onosUninstall(
-                                                          nodeIp=main.ONOS1ip )
+        onosUninstallResult = main.TRUE
+        for i in range( nodeCount):
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=ONOSIp[ i ] )
         stepResult = onosUninstallResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -91,44 +151,44 @@
                                  onfail="Failed to uninstall ONOS package" )
         time.sleep( 5 )
         main.step( "Installing ONOS package" )
-        onosInstallResult = main.ONOSbench.onosInstall( node=main.ONOS1ip )
+        onosInstallResult = main.TRUE
+        for i in range( nodeCount):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=ONOSIp[ i ] )
         stepResult = onosInstallResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully installed ONOS package",
                                  onfail="Failed to install ONOS package" )
 
+        time.sleep( 5 )
         main.step( "Starting ONOS service" )
         stopResult = main.TRUE
         startResult = main.TRUE
-        onosIsUp = main.ONOSbench.isup()
+        onosIsUp = main.TRUE
+        for i in range( nodeCount ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( 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 " )
-            stopResult = main.ONOSbench.onosStop( main.ONOS1ip )
-            startResult = main.ONOSbench.onosStart( main.ONOS1ip )
+            for i in range( nodeCount ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( ONOSIp[ i ] )
+            for i in range( nodeCount ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( 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" )
-
-        main.step( "Starting Mininet Topology" )
-        topoResult = main.Mininet1.startNet( topoFile=topology )
-        stepResult = topoResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully loaded topology",
-                                 onfail="Failed to load topology" )
-        # Exit if topology did not load properly
-        if not topoResult:
-            main.cleanup()
-            main.exit()
-
+        
         main.step( "Start ONOS cli" )
-        cliResult =  main.ONOScli1.startOnosCli( ONOSIp=main.ONOS1ip )
+        cliResult = main.TRUE
+        for i in range( nodeCount ):
+            cliResult = cliResult and main.CLIs[i].startOnosCli( ONOSIp[ i ] )
         stepResult = cliResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -143,6 +203,18 @@
         main.log.report( "Assigning switches to controllers" )
         main.log.case( "Assigning swithes to controllers" )
 
+        main.step( "Starting Mininet Topology" )
+        topoResult = main.Mininet1.startNet( topoFile=topology )
+        stepResult = topoResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully loaded topology",
+                                 onfail="Failed to load topology" )
+        # Exit if topology did not load properly
+        if not topoResult:
+            main.cleanup()
+            main.exit()
+
         main.step( "Assigning switches to controllers" )
         assignResult = main.TRUE
         for i in range( 1, ( main.numSwitch + 1 ) ):
@@ -166,7 +238,7 @@
                                         "controller" )
 
 
-    def CASE1000( self, main ):
+    def CASE1001( self, main ):
         """
             Add host intents between 2 host:
                 - Discover hosts
@@ -204,13 +276,14 @@
         dualStack1 = { 'name': 'DUALSTACK1', 'host1':
                  { 'name': 'h3', 'MAC': '00:00:00:00:00:03',
                    'id':'00:00:00:00:00:03/-1' } , 'host2':
-                 { 'name': '', 'MAC': '00:00:00:00:00:0B',
+                 { 'name': 'h11', 'MAC': '00:00:00:00:00:0B',
                    'id':'00:00:00:00:00:0B/-1'}, 'link': { 'switch1': 's5',
                    'switch2': 's2', 'num':'18' } }
         items.append( ipv4 )
+        items.append( dualStack1 )
         # Global variables
         
-        main.case( "Add host intents between 2 host" )
+        main.log.case( "Add host intents between 2 host" )
         
         for item in items:
             stepResult = main.TRUE
@@ -358,7 +431,7 @@
                                             " host intent successful",
                                      onfail=item[ 'name' ] +
                                             "Add host intent failed" )
-    def CASE2000( self, main ):
+    def CASE1002( self, main ):
         """
             Add point intents between 2 hosts:
                 - Get device ids
@@ -374,7 +447,7 @@
                 - Remove intents
         """
 
-    def CASE3000( self, main ):
+    def CASE1003( self, main ):
         """
             Add single point to multi point intents
                 - Get device ids
@@ -390,7 +463,7 @@
                 - Remove intents
         """
 
-    def CASE4000( self, main ):
+    def CASE1004( self, main ):
         """
             Add multi point to single point intents
                 - Get device ids
diff --git a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py b/TestON/tests/SingleFunc/SingleFunc2.py
similarity index 85%
rename from TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py
rename to TestON/tests/SingleFunc/SingleFunc2.py
index 4400262..e991dee 100644
--- a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py
+++ b/TestON/tests/SingleFunc/SingleFunc2.py
@@ -8,15 +8,14 @@
 import os.path
 
 
-class ScaleOutTemplate:
+class SingleFunc:
 
     def __init__( self ):
         self.default = ''
 
-    def CASE1( self, main ):           
-                                        
-        import time                     
-        global init       
+    def CASE1( self, main ):
+        import time
+        global init
         try: 
             if type(init) is not bool: 
                 init = False  
@@ -24,15 +23,14 @@
             init = False 
        
         #Load values from params file
-        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
-        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        checkoutBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
         cellName = main.params[ 'ENV' ][ 'cellName' ]
         Apps = main.params[ 'ENV' ][ 'cellApps' ]
         BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
         BENCHUser = main.params[ 'BENCH' ][ 'user' ]
-        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
         maxNodes = int(main.params[ 'availableNodes' ])
-        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        skipMvn = main.params[ 'skipCleanInstall' ]
         cellName = main.params[ 'ENV' ][ 'cellName' ]        
 
         # -- INIT SECTION, ONLY RUNS ONCE -- # 
@@ -58,7 +56,7 @@
 
             #git
             main.step( "Git checkout and pull " + checkoutBranch )
-            if gitPull == 'on':
+            if gitPull == 'True':
                 checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
                 pullResult = main.ONOSbench.gitPull()
 
@@ -70,7 +68,7 @@
         # -- END OF INIT SECTION --#
          
         clusterCount = int(scale[0])
-        scale.remove(scale[0])       
+        scale.remove(scale[0])
         
         #kill off all onos processes 
         main.log.step("Safety check, killing all ONOS processes")
@@ -90,7 +88,7 @@
         for node in range (1, clusterCount + 1):
             cellIp.append(ONOSIp[node])
 
-        main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,str(Apps), *cellIp)
+        main.ONOSbench.createCellFile(BENCHIp,cellName,"",str(Apps), *cellIp)
 
         main.step( "Set Cell" )
         main.ONOSbench.setCell(cellName)
@@ -101,7 +99,7 @@
         main.step( "verify cells" )
         verifyCellResult = main.ONOSbench.verifyCell()
       
-        main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+        main.log.report( "Initializing " + str( clusterCount ) + " node cluster." )
         for node in range(1, clusterCount + 1):
             main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
             main.ONOSbench.onosInstall( ONOSIp[node])