Revision: 21131
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21131
Author:   jaguarandi
Date:     2009-06-24 16:18:34 +0200 (Wed, 24 Jun 2009)

Log Message:
-----------
*changed from .xml files to .json files (xml.marshal.generic was kinda "ugly")
*renamed Test.py to test.py
*config.py no longer has side effects
*used optparse for argument parsing

all those were Martin Poirier (theeth) suggestions
Thanks for the code review :)

Modified Paths:
--------------
    branches/soc-2009-jaguarandi/test/blendertest.py
    branches/soc-2009-jaguarandi/test/config.py
    branches/soc-2009-jaguarandi/test/html.py
    branches/soc-2009-jaguarandi/test/persistent.py

Added Paths:
-----------
    branches/soc-2009-jaguarandi/test/case/sample/simple.json
    branches/soc-2009-jaguarandi/test/default_machine.json
    branches/soc-2009-jaguarandi/test/test.py

Removed Paths:
-------------
    branches/soc-2009-jaguarandi/test/Test.py
    branches/soc-2009-jaguarandi/test/case/sample/simple.xml
    branches/soc-2009-jaguarandi/test/default_machine.xml

Deleted: branches/soc-2009-jaguarandi/test/Test.py
===================================================================
--- branches/soc-2009-jaguarandi/test/Test.py   2009-06-24 14:16:56 UTC (rev 
21130)
+++ branches/soc-2009-jaguarandi/test/Test.py   2009-06-24 14:18:34 UTC (rev 
21131)
@@ -1,123 +0,0 @@
-import os
-import string
-import config
-import time
-import subprocess
-import persistent
-
-class Case(dict):
-       def __init__(self, arg = {}):
-               dict.__init__(self, arg)
-               
-       def run(self, res):
-               print self["name"]+":","test not implemented",self["type"]
-               return TestRun.RESULT_NONE
-               
-       def run_cmd(self, cmd, test):
-               dt = time.time()
-               proc = subprocess.Popen(cmd,stdout=subprocess.PIPE, 
stderr=subprocess.PIPE)
-               out, err = proc.communicate()
-               dt = time.time()-dt
-
-               test["cmdline"] = cmd
-               test["time"] = dt
-               test["stderr"] = err
-               test["stdout"] = out
-               test["exit_status"] = proc.returncode
-               
-               return proc.returncode
-
-
-class Render(Case):
-       __name__ = "render"
-       
-       def __init__(self, arg = {}):
-               Case.__init__(self, arg)
-               
-       def run(self, test):
-               #prepare cmdline
-               filename = os.path.join(test.path, self["filename"])
-               cmd = [ test["build"]["path"], "-b", self["scene"], "-o", 
filename, "-F", "PNG", "-x", "0", "-f", "%d"%self["frame"]]
-
-               if self.run_cmd(cmd, test) == 0:
-                       test["result"] = TestRun.RESULT_OK
-               else:
-                       test["result"] = TestRun.RESULT_FAIL
-
-
-################################
-class TestRun(dict):
-       RESULT_NONE = "none"
-       RESULT_OK       = "ok"
-       RESULT_FAIL     = "fail"
-
-       def __init__(self, machine, build, case):
-               self.path = os.path.join( config.run_path, machine["hash"], 
build["hash"], case["hash"] )
-               self.result_path = os.path.join( self.path, "result.xml" )
-               
-               if os.path.isfile(self.result_path):
-                       dict.__init__(self, 
persistent.load(file(self.result_path, "r")))
-                       if "result" not in self:
-                               self["result"] = TestRun.RESULT_NONE
-               else:
-                       self["machine"] = machine
-                       self["build"]   = build
-                       self["case"]    = case
-                       self["result"]  = TestRun.RESULT_NONE
-               
-       # Save results
-       def save_results(self):
-               dirname = os.path.dirname( self.result_path )
-               if not os.path.isdir(dirname):
-                       os.makedirs(dirname)
-               persistent.dump( dict(self), file(self.result_path, "w") )
-
-
-       def getResult(self):
-               return self["result"]
-       
-       # get a path to an image generated by the test run
-       def getImageResult(self):
-               img  = os.path.join(self.path,'1.png')
-               if os.path.isfile( img ):
-                       return img
-               return None
-
-
-       #Short run description:
-       # MM:SS.mmm <name> <result description>
-       def getResultDescription(self):
-               if self["result"] == TestRun.RESULT_NONE:
-                       return self["case"]["name"] + " (not available)"
-               res = ""
-
-               if "time" in self:
-                       time = self["time"]*1000
-                       res += "%02d:%02d.%03d "%(time/60000, (time/1000)%60, 
time%1000)
-               res += self["case"]["name"]
-               
-               if "returncode" in self and self["returncode"] != 0:
-                       res += " (non zero return)"
-               if "sdderr" in self and len(self["stderr"].splitlines()):
-                       res += " (%d stderr 
lines)"%(len(self["stderr"].splitlines()))
-               return res
-
-       
-       # TODO should be atomic (if it crashs while saving result it can create 
a wrong xml file)
-       def run(self, force = False):
-               try:    
-                       if self["result"] != TestRun.RESULT_NONE and force == 
False:
-                               return
-               
-                       if self["case"]["type"] == Render.__name__:
-                               Render(self["case"]).run(self)
-
-                       self.save_results()
-               except:
-                       #TODO print exception
-                       print "Failed to process test run:",self.result_path
-                       os._exit(-1)
-       
-##########################################################################################
-def get(machine,build,case):
-       return TestRun(machine,build,case)

Modified: branches/soc-2009-jaguarandi/test/blendertest.py
===================================================================
--- branches/soc-2009-jaguarandi/test/blendertest.py    2009-06-24 14:16:56 UTC 
(rev 21130)
+++ branches/soc-2009-jaguarandi/test/blendertest.py    2009-06-24 14:18:34 UTC 
(rev 21131)
@@ -4,19 +4,24 @@
        case/<path>.blend
        build/<path>.bin
        
-       run/<machine-hash>/<build_hash>/<case_hash>/result.xml
+       run/<machine-hash>/<build_hash>/<case_hash>/result.json
        run/<machine-hash>/<build_hash>/<case_hash>/1.png
 """
 import sys
 import os
 import re
+from optparse import OptionParser
+
 import config
-
-import Test
+import test
 import persistent
 import html
 import util
 
+
+
+
+
 OK = "\033[92m"
 WARNING = "\033[93m"
 FAIL = "\033[91m"
@@ -29,7 +34,7 @@
        return _valid_build.match( arg )
        
 def load_build(path):
-       #TODO test the existence of a .xml file with information about this 
build
+       #TODO test the existence of a .json file with information about this 
build
        conf = dict(config.default_build_config)
 
        conf["path"] = path
@@ -52,10 +57,10 @@
        conf["name"] = os.path.splitext(os.path.basename(path))[0]
        conf["hash"] = util.get_hash(open(path, 'rb'))
                
-       xml_conf = util.change_extension(path, ".xml")
-       if os.path.isfile(xml_conf):
-               conf["path"] = xml_conf
-               conf.update( persistent.load( open(xml_conf, "r" ) ) )
+       conf_path = util.change_extension(path, ".json")
+       if os.path.isfile(conf_path):
+               conf["path"] = conf_path
+               conf.update( persistent.load( open(conf_path, "r" ) ) )
        else:
                conf.update( config.default_case_config )
        
@@ -72,96 +77,112 @@
                return result_color[trun["result"]]
        return WARNING
 
-def update_test_runs( builds, cases ):
+def do_update( builds, cases ):
        tot = len(cases)
        for build in builds:
                i = 1
                print INFO+"=== "+build["path"]+" ==="+ENDC
                for case in cases:
-                       res = Test.get( config.machine, build, case )
+                       res = test.get( config.machine, build, case )
                        res.run()
                        print get_color(res)+"[%2d/%d] %s" % 
(i,tot,res.getResultDescription())+ENDC
                        i += 1
                                
                                
 #############################################
-def gen_html( builds, cases ):
+def do_html( builds, cases ):
        return html.generate( [config.machine], builds, cases)
        
        
 #############################################
-def do_help():
-       print """Usage:
-blender_test.py [action] [<paths for test cases or builds>]
+def do_info(builds, cases):
+       print INFO," Machine   : ",config.machine,ENDC
+       print INFO," test-cases: ",len(cases),ENDC
+       print INFO," builds    : ",len(builds),ENDC
 
-actions:
-       --update        runs tests cases between the given builds and cases
-                               test results are saved under:
-                                       
<config.run_path>/<machine-hash>/<build-hash>/<case-hash>/
+def main():
+       builds = []
+       cases = []
 
-       --html          outputs html comparison table to standart output
-                               test results are loaded from <config.run_path>
-                               auxiliary html files are created under 
<config.html_path>
-       
-       if no action is given it will just print information on the cases
-       and builds found on the given paths
+       persistent.dump(config.machine,  open(config.machine_path, "w") )
 
-paths:
-       All given paths will be recursively searched for files matching:
-               *.blend to represent test scenes
-               *.bin to represent builds
-       
-       if no test case is given it will scan directory "case"
-       if no build is given it will scan directory "build"
-"""
+       def load_path(arg):
+               if os.path.isdir(arg):
+                       for root, dirs, files in os.walk(arg):
+                                for file in files:
+                                       load_path(os.path.join(root, file))
+               else:
+                       if is_valid_case(arg):
+                               cases.append( load_case(arg) )          
+                       elif is_valid_build(arg):
+                               builds.append( load_build(arg) )
 
+       parser = OptionParser(usage="usage: %prog [options] <path> ...")
 
-builds = []
-cases = []
+       parser.add_option("--update",
+                       action="store_true",
+                       dest="update",
+                       default=False,
+                       help="runs tests cases between the given builds and 
cases, test results are saved under: 
<config.run_path>/<machine-hash>/<build-hash>/<case-hash>/"
+               )
 
-def load_path(arg):
-       if os.path.isdir(arg):
-               for root, dirs, files in os.walk(arg):
-                        for file in files:
-                               load_path(os.path.join(root, file))
+       parser.add_option("--machine",
+                       action="store",
+                       dest="machine",
+                       default=config.machine_path,
+                       help="load machine configuration from the given 
argument (read the supplied default_machine.json for an example)"
+               )
+               
+       parser.add_option( "--html",
+                       action="store_true",
+                       dest="html",
+                       default=False,
+                       help="outputs html comparison table to standart output 
test results are loaded from <config.run_path>; auxiliary html files are 
created under <config.html_path>"
+               )
+               
+       (options, args) = parser.parse_args()
+       
+       if os.path.isfile(options.machine):
+               config.machine = persistent.load( open(options.machine, "r") )
+
+               if "hash" not in config.machine:
+                       config.machine["hash"] = os.uname()[1]
+               if "hostname" not in config.machine:
+                       config.machine["hostname"] = os.uname()[1]
        else:
-               if is_valid_case(arg):
-                       cases.append( load_case(arg) )          
-               elif is_valid_build(arg):
-                       builds.append( load_build(arg) )
+               parser.error("No machine configuration found (use the --machine 
option) or configure "+config.machine_path)
 
+       
+       
+       for path in args:
+               load_path(path)
 
-do_update = False
-do_html = False
-do_info = True
+       if len(builds) == 0:
+               load_path( "build" )
+       
+       if len(cases) == 0:
+               load_path( "case" )
 
-if len(sys.argv) > 1:
+       if options.html == False:
+               do_info( builds, cases )
+               
+       if options.update:
+               if len(builds) == 0:
+                       parser.error( "at least one build (blender;*.bin) must 
be supplied on paths" )
+               if len(cases) == 0:
+                       parser.error( "at least one test case (*.blend) must be 
supplied on paths" )
 
-       for arg in sys.argv[1:]:
-               if arg == "--help":
-                       do_help()
-                       os._exit(-1)                    
-               if arg == "--update":
-                       do_update = True
-               if arg == "--html":
-                       do_info = False
-                       do_html = True
-               else:
-                       load_path(arg)
-                       
-if len(builds) == 0:
-       load_path( "build" )
+               do_update( builds, cases )
 
-if len(cases) == 0:
-       load_path( "case" )
+       if options.html:
+               if len(builds) == 0:
+                       parser.error( "at least one build (blender;*.bin) must 
be supplied on paths" )
+               if len(cases) == 0:
+                       parser.error( "at least one test case (*.blend) must be 
supplied on paths" )
+               
+               do_html( builds, cases )
+               
 
-if do_info:
-       print INFO," Machine   : ",config.machine,ENDC
-       print INFO," test-cases: ",len(cases),ENDC
-       print INFO," builds    : ",len(builds),ENDC
+if __name__ == "__main__":
+       main()
 
-if do_update:
-       update_test_runs( builds, cases )
-
-if do_html:
-       gen_html( builds, cases )               

Copied: branches/soc-2009-jaguarandi/test/case/sample/simple.json (from rev 
21124, branches/soc-2009-jaguarandi/test/case/sample/simple.xml)
===================================================================

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to