Boost logo

Boost-Commit :

From: grafikrobot_at_[hidden]
Date: 2008-05-02 11:52:43


Author: grafik
Date: 2008-05-02 11:52:42 EDT (Fri, 02 May 2008)
New Revision: 45026
URL: http://svn.boost.org/trac/boost/changeset/45026

Log:
Add support for test log processing with process_jam_log.py instead of C++ PJL. (also fixes #1889)
Text files modified:
   trunk/tools/regression/src/process_jam_log.py | 84 ++++++++++++++++++++++-------------
   trunk/tools/regression/src/regression.py | 93 ++++++++++++++++++++++++++++++++-------
   trunk/tools/regression/src/run.py | 2
   3 files changed, 128 insertions(+), 51 deletions(-)

Modified: trunk/tools/regression/src/process_jam_log.py
==============================================================================
--- trunk/tools/regression/src/process_jam_log.py (original)
+++ trunk/tools/regression/src/process_jam_log.py 2008-05-02 11:52:42 EDT (Fri, 02 May 2008)
@@ -13,7 +13,7 @@
 #~ Process a bjam XML log into the XML log format for Boost result processing.
 class BJamLog2Results:
 
- def __init__(self):
+ def __init__(self,args=None):
         opt = optparse.OptionParser(
             usage="%prog [options] input")
         opt.add_option( '--output',
@@ -39,7 +39,7 @@
         self.source='SVN'
         self.revision=None
         self.input = []
- ( _opt_, self.input ) = opt.parse_args(None,self)
+ ( _opt_, self.input ) = opt.parse_args(args,self)
         self.results = xml.dom.minidom.parseString('''<?xml version="1.0" encoding="UTF-8"?>
 <test-run
   source="%(source)s"
@@ -61,7 +61,6 @@
         
         self.test = {}
         self.target = {}
- self.child = {}
         self.parent = {}
         self.log = {}
         
@@ -166,18 +165,20 @@
         target_node = self.get_child(self.get_child(node,tag='targets'),tag='target')
         while target_node:
             name = self.get_child_data(target_node,tag='name').strip()
+ path = self.get_child_data(target_node,tag='path').strip()
+ jam_target = self.get_child_data(target_node,tag='jam-target').strip()
             #~ Map for jam targets to virtual targets.
- self.target[self.get_child_data(target_node,tag='jam-target').strip()] = {
+ self.target[jam_target] = {
                 'name' : name,
- 'path' : self.get_child_data(target_node,tag='path').strip()
+ 'path' : path
                 }
- #~ Create the bidirectional ancestry.
- self.child[name] = []
+ #~ Create the ancestry.
             dep_node = self.get_child(self.get_child(target_node,tag='dependencies'),tag='dependency')
             while dep_node:
                 child = self.get_data(dep_node).strip()
- self.child[name].append(child)
- self.parent[child] = name
+ child_jam_target = '<p%s>%s' % (path,child.split('//',1)[1])
+ self.parent[child_jam_target] = jam_target
+ #~ print "--- %s\n ^ %s" %(jam_target,child_jam_target)
                 dep_node = self.get_sibling(dep_node.nextSibling,tag='dependency')
             target_node = self.get_sibling(target_node.nextSibling,tag='target')
         return None
@@ -200,33 +201,53 @@
                     action_type = 'link'
                 elif re.match('[^%]+%testing[.](capture-output)',name):
                     action_type = 'run'
+ elif re.match('[^%]+%testing[.](expect-failure|expect-success)',name):
+ action_type = 'result'
+ #~ print "+ [%s] %s %s :: %s" %(action_type,name,'','')
                 if action_type:
                     #~ Get the corresponding test.
                     (target,test) = self.get_test(action_node,type=action_type)
                     #~ And the log node, which we will add the results to.
                     log = self.get_log(action_node,test)
- #~ print "--- [%s] %s %s :: %s" %(action_type,name,target,log)
+ #~ print "--- [%s] %s %s :: %s" %(action_type,name,target,test)
                     #~ Collect some basic info about the action.
                     result_data = "%(info)s\n\n%(command)s\n%(output)s\n" % {
                         'command' : self.get_action_command(action_node,action_type),
                         'output' : self.get_action_output(action_node,action_type),
                         'info' : self.get_action_info(action_node,action_type)
                         }
+ #~ For the test result status we find the appropriate node
+ #~ based on the type of test. Then adjust the result status
+ #~ acorrdingly. This makes the result status reflect the
+ #~ expectation as the result pages post processing does not
+ #~ account for this inversion.
+ action_tag = action_type
+ if action_type == 'result':
+ if re.match(r'^compile',test['test-type']):
+ action_tag = 'compile'
+ elif re.match(r'^link',test['test-type']):
+ action_tag = 'link'
+ elif re.match(r'^run',test['test-type']):
+ action_tag = 'run'
                     #~ The result sub-part we will add this result to.
- result_node = self.get_child(log,tag=action_type)
+ result_node = self.get_child(log,tag=action_tag)
                     if not result_node:
                         #~ If we don't have one already, create it and add the result.
- result_node = self.new_text(action_type,result_data,
+ result_node = self.new_text(action_tag,result_data,
                             result='succeed' if action_node.getAttribute('status') == '0' else 'fail',
                             timestamp=action_node.getAttribute('start'))
                         log.appendChild(self.results.createTextNode("\n"))
                         log.appendChild(result_node)
                     else:
                         #~ For an existing result node we set the status to fail
- #~ when any of the individual actions fail.
- result = result_node.getAttribute('result')
- if action_node.getAttribute('status') != '0':
- result = 'fail'
+ #~ when any of the individual actions fail, except for result
+ #~ status.
+ if action_type != 'result':
+ result = result_node.getAttribute('result')
+ if action_node.getAttribute('status') != '0':
+ result = 'fail'
+ else:
+ result = 'succeed' if action_node.getAttribute('status') == '0' else 'fail'
                         result_node.setAttribute('result',result)
                         result_node.appendChild(self.results.createTextNode("\n"))
                         result_node.appendChild(self.results.createTextNode(result_data))
@@ -267,35 +288,34 @@
     #~ are the ones pre-declared in the --dump-test option. For libraries
     #~ we create a dummy test as needed.
     def get_test( self, node, type = None ):
- base = self.target[self.get_child_data(node,tag='jam-target')]['name']
+ target = self.get_child_data(node,tag='jam-target')
+ base = self.target[target]['name']
+ while target in self.parent:
+ target = self.parent[target]
         #~ main-target-type is a precise indicator of what the build target is
         #~ proginally meant to be.
         main_type = self.get_child_data(self.get_child(node,tag='properties'),
             name='main-target-type',strip=True)
- target = base
         if main_type == 'LIB' and type:
- if type == 'compile':
- target = self.parent[target]
- if not target in self.test:
- self.test[target] = {
- 'library' : re.search(r'libs/([^/]+)',target).group(1),
- 'test-name' : os.path.basename(target),
+ lib = self.target[target]['name']
+ if not lib in self.test:
+ self.test[lib] = {
+ 'library' : re.search(r'libs/([^/]+)',lib).group(1),
+ 'test-name' : os.path.basename(lib),
                     'test-type' : 'lib',
- 'test-program' : os.path.basename(target),
- 'target' : target
+ 'test-program' : os.path.basename(lib),
+ 'target' : lib
                     }
- test = self.test[target]
+ test = self.test[lib]
         else:
- while target in self.parent:
- target = self.parent[target]
- test = self.test[self.target[target]]
+ test = self.test[self.target[self.target[target]['name']]]
         return (base,test)
     
     #~ Find, or create, the test-log node to add results to.
     def get_log( self, node, test ):
         target_directory = os.path.dirname(self.get_child_data(
             node,tag='path',strip=True))
- target_directory = re.sub(r'[.][.][/\\]','',target_directory)
+ target_directory = re.sub(r'.*[/\\]bin[.]v2[/\\]','',target_directory)
         target_directory = re.sub(r'[\\]','/',target_directory)
         if not target_directory in self.log:
             self.log[target_directory] = self.new_node('test-log',
@@ -380,4 +400,4 @@
         return result
 
 
-BJamLog2Results()
+if __name__ == '__main__': BJamLog2Results()

Modified: trunk/tools/regression/src/regression.py
==============================================================================
--- trunk/tools/regression/src/regression.py (original)
+++ trunk/tools/regression/src/regression.py 2008-05-02 11:52:42 EDT (Fri, 02 May 2008)
@@ -140,7 +140,10 @@
         self.regression_root = root
         self.boost_root = os.path.join( self.regression_root, 'boost' )
         self.regression_results = os.path.join( self.regression_root, 'results' )
- self.regression_log = os.path.join( self.regression_results, 'bjam.log' )
+ if self.pjl_toolset != 'python':
+ self.regression_log = os.path.join( self.regression_results, 'bjam.log' )
+ else:
+ self.regression_log = os.path.join( self.regression_results, 'bjam.xml' )
         self.tools_bb_root = os.path.join( self.regression_root,'tools_bb' )
         self.tools_bjam_root = os.path.join( self.regression_root,'tools_bjam' )
         self.tools_regression_root = os.path.join( self.regression_root,'tools_regression' )
@@ -289,7 +292,8 @@
     def command_setup(self):
         self.command_patch()
         self.build_if_needed(self.bjam,self.bjam_toolset)
- self.build_if_needed(self.process_jam_log,self.pjl_toolset)
+ if self.pjl_toolset != 'python':
+ self.build_if_needed(self.process_jam_log,self.pjl_toolset)
     
     def command_test(self, *args):
         if not args or args == None or args == []: args = [ "test", "process" ]
@@ -308,7 +312,8 @@
             self.command_test_run()
 
         if "process" in args:
- self.command_test_process()
+ if self.pjl_toolset != 'python':
+ self.command_test_process()
     
     def command_test_clean(self):
         results_libs = os.path.join( self.regression_results, 'libs' )
@@ -318,11 +323,18 @@
     
     def command_test_run(self):
         self.import_utils()
- test_cmd = '%s -d2 --dump-tests %s "--build-dir=%s" >>"%s" 2>&1' % (
- self.bjam_cmd( self.toolsets ),
- self.bjam_options,
- self.regression_results,
- self.regression_log )
+ if self.pjl_toolset != 'python':
+ test_cmd = '%s -d2 --dump-tests %s "--build-dir=%s" >>"%s" 2>&1' % (
+ self.bjam_cmd( self.toolsets ),
+ self.bjam_options,
+ self.regression_results,
+ self.regression_log )
+ else:
+ test_cmd = '%s -d1 --dump-tests --verbose-test %s "--build-dir=%s" "--out-xml=%s"' % (
+ self.bjam_cmd( self.toolsets ),
+ self.bjam_options,
+ self.regression_results,
+ self.regression_log )
         self.log( 'Starting tests (%s)...' % test_cmd )
         cd = os.getcwd()
         os.chdir( os.path.join( self.boost_root, 'status' ) )
@@ -362,7 +374,7 @@
         svn_info_file = os.path.join( self.boost_root, 'svn_info.txt' )
         if os.path.exists( svn_root_file ):
             source = 'SVN'
- self.svn_command( 'info --xml "%s" >%s' % (self.boost_root,svn_info_file) )
+ self.svn_command( 'info --xml "%s" >"%s"' % (self.boost_root,svn_info_file) )
 
         if os.path.exists( svn_info_file ):
             f = open( svn_info_file, 'r' )
@@ -376,15 +388,33 @@
                   revision += svn_info[i]
                   i += 1
 
- from collect_and_upload_logs import collect_logs
- collect_logs(
- self.regression_results,
- self.runner, self.tag, self.platform, comment_path,
- self.timestamp_path,
- self.user,
- source, run_type,
- self.dart_server, self.proxy,
- revision )
+ if self.pjl_toolset != 'python':
+ from collect_and_upload_logs import collect_logs
+ collect_logs(
+ self.regression_results,
+ self.runner, self.tag, self.platform, comment_path,
+ self.timestamp_path,
+ self.user,
+ source, run_type,
+ self.dart_server, self.proxy,
+ revision )
+ else:
+ from process_jam_log import BJamLog2Results
+ BJamLog2Results([
+ '--output='+os.path.join(self.regression_results,self.runner+'.xml'),
+ '--runner='+self.runner,
+ '--comment='+comment_path,
+ '--tag='+self.tag,
+ '--platform='+self.platform,
+ '--source='+source,
+ '--revision='+revision,
+ '--incremental' if run_type == 'incremental' else '',
+ self.regression_log
+ ])
+ self.compress_file(
+ os.path.join(self.regression_results,self.runner+'.xml'),
+ os.path.join(self.regression_results,self.runner+'.zip')
+ )
         
     def command_upload_logs(self):
         self.import_utils()
@@ -673,6 +703,33 @@
         smtp_server.sendmail( self.mail, [ self.mail ],
             'Subject: %s\nTo: %s\n\n%s' % ( subject, self.mail, msg ) )
 
+ def compress_file( self, file_path, archive_path ):
+ self.import_utils()
+ utils.log( 'Compressing "%s"...' % file_path )
+
+ try:
+ import zipfile
+ z = zipfile.ZipFile( archive_path, 'w', zipfile.ZIP_DEFLATED )
+ z.write( file_path, os.path.basename( file_path ) )
+ z.close()
+ utils.log( 'Done writing "%s".'% archive_path )
+ except Exception, msg:
+ utils.log( 'Warning: Compressing falied (%s)' % msg )
+ utils.log( ' Trying to compress using a platform-specific tool...' )
+ try:
+ import zip_cmd
+ except ImportError:
+ script_dir = os.path.dirname( os.path.abspath( sys.argv[0] ) )
+ utils.log( 'Could not find \'zip_cmd\' module in the script directory (%s).' % script_dir )
+ raise Exception( 'Compressing failed!' )
+ else:
+ if os.path.exists( archive_path ):
+ os.unlink( archive_path )
+ utils.log( 'Removing stale "%s".' % archive_path )
+
+ zip_cmd.main( file_path, archive_path )
+ utils.log( 'Done compressing "%s".' % archive_path )
+
     #~ Dowloading source, from SVN...
 
     def svn_checkout( self ):

Modified: trunk/tools/regression/src/run.py
==============================================================================
--- trunk/tools/regression/src/run.py (original)
+++ trunk/tools/regression/src/run.py 2008-05-02 11:52:42 EDT (Fri, 02 May 2008)
@@ -23,7 +23,7 @@
 root = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
 print '# Running regressions in %s...' % root
 
-script_sources = [ 'collect_and_upload_logs.py', 'regression.py' ]
+script_sources = [ 'collect_and_upload_logs.py', 'process_jam_log.py', 'regression.py' ]
 script_local = os.path.join(root,'tools','regression','src')
 script_remote = 'http://svn.boost.org/svn/boost/trunk/tools/regression/src'
 script_dir = os.path.join(root,'tools_regression_src')


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk