[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21131] branches/soc-2009-jaguarandi/test: *changed from .xml files to .json files (xml.marshal.generic was kinda " ugly")
André Pinto
andresusanopinto at gmail.com
Wed Jun 24 16:18:34 CEST 2009
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. @@
More information about the Bf-blender-cvs
mailing list