-
-int main()
-{
- boost::tiny_xml::element_ptr tree( boost::tiny_xml::parse( std::cin ) );
- boost::tiny_xml::write( *tree, std::cout );
- return 0;
-}
-
diff --git a/src/detail/tiny_xml_test.txt b/src/detail/tiny_xml_test.txt
deleted file mode 100644
index b248cbf..0000000
--- a/src/detail/tiny_xml_test.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-// (C) Copyright Beman Dawes 2002. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-
-
-It's Howdy Doody time!
-
-It's not Howdy Doody time!
-
-
-It's
-Eastern Standard time!
-
-
diff --git a/src/git.py b/src/git.py
deleted file mode 100755
index 1bc39fb..0000000
--- a/src/git.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/python
-
-# Copyright Rene Rivera 2012-2013
-#
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
-
-import os
-import sys
-
-root = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
-sys.path.insert(0,os.path.join(root,'dulwich'))
-
-import shutil
-import stat
-import dulwich
-import dulwich.index
-from dulwich.client import get_transport_and_path
-from dulwich.repo import Repo
-from dulwich.objects import ZERO_SHA, Tree
-from dulwich.file import ensure_dir_exists
-from dulwich.index import changes_from_tree, Index, index_entry_from_stat
-
-if __name__ == '__main__':
- print "# Using dulwich version %s.%s.%s"%(dulwich.__version__)
-
-class RemoteRepo(Repo):
- def __init__(self, root, remote_uri, branch='develop', reset=False):
- if reset:
- if os.path.exists(root):
- shutil.rmtree(root)
- if not os.path.isdir(root):
- dulwich.file.ensure_dir_exists(root)
- controldir = os.path.join(root, ".git")
- os.mkdir(controldir)
- Repo._init_maybe_bare(controldir, False)
- Repo.__init__(self,root)
- self.remote_uri = remote_uri
- self.client, self.host_path = get_transport_and_path(self.remote_uri)
- self.want_branch = branch
- self.want_reset = reset
- print "# Remote repo %s @ %s => %s"%(self.remote_uri,self._branch_ref(),self.path)
-
- def _branch_ref(self):
- return "refs/heads/"+self.want_branch
-
- def _head_ref(self):
- return 'HEAD'
-
- def _determine_wants(self,refs):
- result = []
- for (ref,sha) in refs.iteritems():
- if sha == ZERO_SHA:
- continue
- if sha in self.object_store:
- continue
- if ref == self._branch_ref():
- result.append(sha)
- return result
-
- def _fetch(self):
- print "# Fetching repo %s => %s.."%(self.remote_uri,self.path)
- remote_refs = self.client.fetch(
- self.host_path,
- self,
- determine_wants=self._determine_wants,
- progress=sys.stdout.write)
- self[self._branch_ref()] = remote_refs[self._branch_ref()]
-
- def _get_tree(self, sha=None):
- if not sha:
- return self[self._branch_ref()].tree
- else:
- return self[sha].tree
-
- def _get_entry_at_path(self, path, sha=None):
- for entry in self.object_store.iter_tree_contents(self._get_tree(sha)):
- if entry.path == path:
- return entry
- return None
-
- def _init_subrepos(self, sha=None):
- self.subrepo = {}
- gitmodules_entry = self._get_entry_at_path(".gitmodules",sha)
- if gitmodules_entry:
- modules = self.object_store.get_raw(gitmodules_entry.sha)[1].splitlines()
- modules.append(None)
- submodule = None
- submodule_path = None
- submodule_url = None
- for l in modules:
- if None == l or l.startswith("[submodule "):
- if None != submodule and None != submodule_path and \
- None != submodule_url:
- submodule_entry = self._get_entry_at_path(submodule_path)
- self.subrepo[submodule_path] \
- = (submodule_entry.sha,
- RemoteRepo(
- os.path.join(self.path,submodule_path),
- submodule_url,
- branch = self.want_branch,
- reset = self.want_reset))
- if None != l:
- submodule = l.split("\"")[1]
- submodule_path = None
- submodule_url = None
- elif l.strip().startswith("path = "):
- submodule_path = l.strip().rsplit(" ",1)[-1]
- elif l.strip().startswith("url = "):
- submodule_url = l.strip().rsplit(" ",1)[-1]
- if submodule_url.startswith('git:'):
- submodule_url = submodule_url.replace("git:","https:")
- if submodule_url.startswith('.'):
- submodule_url = self.remote_uri+"/"+submodule_url
-
- def _checkout_entry(self,index,path,mode,sha):
- full_path = os.path.join(self.path, path)
- checked_out_entry = False
- if stat.S_ISREG(mode):
- if not os.path.exists(os.path.dirname(full_path)):
- os.makedirs(os.path.dirname(full_path))
- f = open(full_path, 'wb')
- try:
- f.write(self.object_store[sha].as_raw_string())
- finally:
- f.close()
- os.chmod(full_path, mode)
- checked_out_entry = True
- elif dulwich.objects.S_ISGITLINK(mode) and path in self.subrepo:
- self.subrepo[path][1].checkout(self.subrepo[path][0])
- checked_out_entry = True
- if checked_out_entry:
- st = os.lstat(full_path)
- index[path] = index_entry_from_stat(st, sha, 0, mode=mode)
- index.write()
-
- def checkout(self, sha=None):
- self._fetch()
- print "# Checkout repo %s @ %s => %s.."%(self.remote_uri,sha,self.path)
- self._init_subrepos(sha)
- target = self['HEAD']
- if sha:
- target = self[sha]
- target_tree = target.tree
- index = Index(self.index_path())
- for e_path,e_mode,e_sha in index.changes_from_tree(self.object_store, target_tree, want_unchanged=True):
- e_source = (e_path[1],e_mode[1],e_sha[1])
- e_target = (e_path[0],e_mode[0],e_sha[0])
- e_to_checkout = None
- if e_source[0] and e_target[0]:
- if not os.path.exists(os.path.join(self.path, e_target[0])):
- e_to_checkout = ("A",e_target)
- elif e_source[2] != e_target[2]:
- e_to_checkout = ("U",e_target)
- elif not e_target[0]:
- print "D %s"%(os.path.join(self.path, e_source[0]))
- if stat.S_ISREG(e_source[1]):
- os.unlink(os.path.join(self.path, e_source[0]))
- del index[e_source[0]]
- else:
- e_to_checkout = ("A",e_target)
- if e_to_checkout:
- print "%s %s"%(e_to_checkout[0],os.path.join(self.path,e_to_checkout[1][0]))
- self._checkout_entry(index, *e_to_checkout[1])
- self._init_subrepos(sha)
- for subrepo in self.subrepo.values():
- subrepo[1].checkout(subrepo[0])
-
- def status(self, sha=None):
- print "# Status.."
- target = self['HEAD']
- if sha:
- target = self[sha]
- target_tree = target.tree
- index = Index(self.index_path())
- for e_path,e_mode,e_sha in index.changes_from_tree(self.object_store, target_tree, want_unchanged=True):
- e_source = (e_path[0],e_mode[0],e_sha[0])
- e_target = (e_path[1],e_mode[1],e_sha[1])
- if e_source[0] and e_target[0]:
- if not os.path.exists(os.path.join(self.path, e_source[0])):
- print "D %s"%(os.path.join(self.path, e_source[0]))
- elif e_source[2] != e_target[2]:
- print "M %s"%(os.path.join(self.path, e_source[0]))
- elif not e_target[0]:
- print "D %s"%(os.path.join(self.path, e_source[0]))
- else:
- print "A %s"%(os.path.join(self.path, e_target[0]))
-
-if __name__ == '__main__':
- if True:
- g = RemoteRepo(
- 'git_test_boost',
- 'https://github.com/boostorg/boost.git',
- branch='master',
- reset=False)
- g.checkout()
- g.status()
- if False:
- g = RemoteRepo(
- 'git_test_predef',
- 'https://github.com/grafikrobot/boost-predef.git',
- branch='master',
- reset=True)
- g.checkout()
- g.status()
diff --git a/src/process_jam_log.py b/src/process_jam_log.py
deleted file mode 100755
index a7722b9..0000000
--- a/src/process_jam_log.py
+++ /dev/null
@@ -1,468 +0,0 @@
-#!/usr/bin/python
-# Copyright 2008 Rene Rivera
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
-
-import re
-import optparse
-import time
-import xml.dom.minidom
-import xml.dom.pulldom
-from xml.sax.saxutils import unescape, escape
-import os.path
-
-#~ Process a bjam XML log into the XML log format for Boost result processing.
-class BJamLog2Results:
-
- def __init__(self,args=None):
- opt = optparse.OptionParser(
- usage="%prog [options] input")
- opt.add_option( '--output',
- help="output file" )
- opt.add_option( '--runner',
- help="runner ID (e.g. 'Metacomm')" )
- opt.add_option( '--comment',
- help="an HTML comment file to be inserted in the reports" )
- opt.add_option( '--tag',
- help="the tag for the results" )
- opt.add_option( '--incremental',
- help="do incremental run (do not remove previous binaries)",
- action='store_true' )
- opt.add_option( '--platform' )
- opt.add_option( '--source' )
- opt.add_option( '--revision' )
- self.output = None
- self.runner = None
- self.comment='comment.html'
- self.tag='trunk'
- self.incremental=False
- self.platform=''
- self.source='SVN'
- self.revision=None
- self.input = []
- ( _opt_, self.input ) = opt.parse_args(args,self)
- if self.incremental:
- run_type = 'incremental'
- else:
- run_type = 'full'
- self.results = xml.dom.minidom.parseString('''
-
-
-''' % {
- 'source' : self.source,
- 'runner' : self.runner,
- 'platform' : self.platform,
- 'tag' : self.tag,
- 'run-type' : run_type,
- 'revision' : self.revision,
- } )
-
- self.test = {}
- self.target_to_test = {}
- self.target = {}
- self.parent = {}
- self.log = {}
-
- self.add_log()
- self.gen_output()
-
- #~ print self.test
- #~ print self.target
-
- def add_log(self):
- if self.input[0]:
- bjam_xml = self.input[0]
- else:
- bjam_xml = self.input[1]
- events = xml.dom.pulldom.parse(bjam_xml)
- context = []
- test_run = self.results.documentElement
- for (event,node) in events:
- if event == xml.dom.pulldom.START_ELEMENT:
- context.append(node)
- if node.nodeType == xml.dom.Node.ELEMENT_NODE:
- x_f = self.x_name_(*context)
- if x_f:
- events.expandNode(node)
- # expanding eats the end element, hence walking us out one level
- context.pop()
- # call the translator, and add returned items to the result
- items = (x_f[1])(node)
- if items:
- for item in items:
- if item:
- test_run.appendChild(self.results.createTextNode("\n"))
- test_run.appendChild(item)
- elif event == xml.dom.pulldom.END_ELEMENT:
- context.pop()
- #~ Add the log items nwo that we've collected all of them.
- items = self.log.values()
- if items:
- for item in items:
- if item:
- test_run.appendChild(self.results.createTextNode("\n"))
- test_run.appendChild(item)
-
- def gen_output(self):
- if self.output:
- out = open(self.output,'w')
- else:
- out = sys.stdout
- if out:
- self.results.writexml(out,encoding='utf-8')
-
- def tostring(self):
- return self.results.toxml('utf-8')
-
- def x_name_(self, *context, **kwargs):
- node = None
- names = [ ]
- for c in context:
- if c:
- if not isinstance(c,xml.dom.Node):
- suffix = '_'+c.replace('-','_').replace('#','_')
- else:
- suffix = '_'+c.nodeName.replace('-','_').replace('#','_')
- node = c
- names.append('x')
- names = map(lambda x: x+suffix,names)
- if node:
- for name in names:
- if hasattr(self,name):
- return (name,getattr(self,name))
- return None
-
- def x(self, *context, **kwargs):
- node = None
- names = [ ]
- for c in context:
- if c:
- if not isinstance(c,xml.dom.Node):
- suffix = '_'+c.replace('-','_').replace('#','_')
- else:
- suffix = '_'+c.nodeName.replace('-','_').replace('#','_')
- node = c
- names.append('x')
- names = map(lambda x: x+suffix,names)
- if node:
- for name in names:
- if hasattr(self,name):
- return getattr(self,name)(node,**kwargs)
- else:
- assert False, 'Unknown node type %s'%(name)
- return None
-
- #~ The timestamp goes to the corresponding attribute in the result.
- def x_build_timestamp( self, node ):
- test_run = self.results.documentElement
- test_run.setAttribute('timestamp',self.get_data(node).strip())
- return None
-
- #~ Comment file becomes a comment node.
- def x_build_comment( self, node ):
- comment = None
- if self.comment:
- comment_f = open(self.comment)
- if comment_f:
- comment = comment_f.read()
- comment_f.close()
- if not comment:
- comment = ''
- return [self.new_text('comment',comment)]
-
- #~ Tests are remembered for future reference.
- def x_build_test( self, node ):
- test_run = self.results.documentElement
- test_node = node
- test_name = test_node.getAttribute('name')
- self.test[test_name] = {
- 'library' : '/'.join(test_name.split('/')[0:-1]),
- 'test-name' : test_name.split('/')[-1],
- 'test-type' : test_node.getAttribute('type').lower(),
- 'test-program' : self.get_child_data(test_node,tag='source',strip=True),
- 'target' : self.get_child_data(test_node,tag='target',strip=True),
- 'info' : self.get_child_data(test_node,tag='info',strip=True)
- }
- #~ Add a lookup for the test given the test target.
- self.target_to_test[self.test[test_name]['target']] = test_name
- #~ print "--- %s\n => %s" %(self.test[test_name]['target'],test_name)
- return None
-
- #~ Process the target dependency DAG into an ancestry tree so we can look up
- #~ which top-level library and test targets specific build actions correspond to.
- def x_build_targets_target( self, node ):
- test_run = self.results.documentElement
- target_node = node
- name = self.get_child_data(target_node,tag='name',strip=True)
- path = self.get_child_data(target_node,tag='path',strip=True)
- jam_target = self.get_child_data(target_node,tag='jam-target',strip=True)
- #~ print "--- target :: %s" %(name)
- #~ Map for jam targets to virtual targets.
- self.target[jam_target] = {
- 'name' : name,
- 'path' : path
- }
- #~ 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=True)
- child_jam_target = '%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')
- return None
-
- #~ Given a build action log, process into the corresponding test log and
- #~ specific test log sub-part.
- def x_build_action( self, node ):
- test_run = self.results.documentElement
- action_node = node
- name = self.get_child(action_node,tag='name')
- if name:
- name = self.get_data(name)
- #~ Based on the action, we decide what sub-section the log
- #~ should go into.
- action_type = None
- if re.match('[^%]+%[^.]+[.](compile)',name):
- action_type = 'compile'
- elif re.match('[^%]+%[^.]+[.](link|archive)',name):
- 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)
- #~ Skip action that have no correspoding test as they are
- #~ regular build actions and don't need to show up in the
- #~ regression results.
- if not test:
- return None
- #~ 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,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_tag)
- if action_node.getAttribute('status') == '0':
- action_result = 'succeed'
- else:
- action_result = 'fail'
- if not result_node:
- #~ If we don't have one already, create it and add the result.
- result_node = self.new_text(action_tag,result_data,
- result = action_result,
- 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, except for result
- #~ status.
- if action_type != 'result':
- result = result_node.getAttribute('result')
- if action_node.getAttribute('status') != '0':
- result = 'fail'
- else:
- result = action_result
- result_node.setAttribute('result',result)
- result_node.appendChild(self.results.createTextNode("\n"))
- result_node.appendChild(self.results.createTextNode(result_data))
- return None
-
- #~ The command executed for the action. For run actions we omit the command
- #~ as it's just noise.
- def get_action_command( self, action_node, action_type ):
- if action_type != 'run':
- return self.get_child_data(action_node,tag='command')
- else:
- return ''
-
- #~ The command output.
- def get_action_output( self, action_node, action_type ):
- return self.get_child_data(action_node,tag='output',default='')
-
- #~ Some basic info about the action.
- def get_action_info( self, action_node, action_type ):
- info = ""
- #~ The jam action and target.
- info += "%s %s\n" %(self.get_child_data(action_node,tag='name'),
- self.get_child_data(action_node,tag='path'))
- #~ The timing of the action.
- info += "Time: (start) %s -- (end) %s -- (user) %s -- (system) %s\n" %(
- action_node.getAttribute('start'), action_node.getAttribute('end'),
- action_node.getAttribute('user'), action_node.getAttribute('system'))
- #~ And for compiles some context that may be hidden if using response files.
- if action_type == 'compile':
- define = self.get_child(self.get_child(action_node,tag='properties'),name='define')
- while define:
- info += "Define: %s\n" %(self.get_data(define,strip=True))
- define = self.get_sibling(define.nextSibling,name='define')
- return info
-
- #~ Find the test corresponding to an action. For testing targets these
- #~ 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 ):
- jam_target = self.get_child_data(node,tag='jam-target')
- base = self.target[jam_target]['name']
- target = jam_target
- while target in self.parent:
- target = self.parent[target]
- #~ print "--- TEST: %s ==> %s" %(jam_target,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)
- if main_type == 'LIB' and type:
- 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(lib),
- 'target' : lib
- }
- test = self.test[lib]
- else:
- target_name_ = self.target[target]['name']
- if self.target_to_test.has_key(target_name_):
- test = self.test[self.target_to_test[target_name_]]
- else:
- test = None
- 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'.*[/\\]bin[.]v2[/\\]','',target_directory)
- target_directory = re.sub(r'[\\]','/',target_directory)
- if not target_directory in self.log:
- if 'info' in test and test['info'] == 'always_show_run_output':
- show_run_output = 'true'
- else:
- show_run_output = 'false'
- self.log[target_directory] = self.new_node('test-log',
- library=test['library'],
- test_name=test['test-name'],
- test_type=test['test-type'],
- test_program=test['test-program'],
- toolset=self.get_toolset(node),
- target_directory=target_directory,
- show_run_output=show_run_output)
- return self.log[target_directory]
-
- #~ The precise toolset from the build properties.
- def get_toolset( self, node ):
- toolset = self.get_child_data(self.get_child(node,tag='properties'),
- name='toolset',strip=True)
- toolset_version = self.get_child_data(self.get_child(node,tag='properties'),
- name='toolset-%s:version'%toolset,strip=True)
- return '%s-%s' %(toolset,toolset_version)
-
- #~ XML utilities...
-
- def get_sibling( self, sibling, tag = None, id = None, name = None, type = None ):
- n = sibling
- while n:
- found = True
- if type and found:
- found = found and type == n.nodeType
- if tag and found:
- found = found and tag == n.nodeName
- if (id or name) and found:
- found = found and n.nodeType == xml.dom.Node.ELEMENT_NODE
- if id and found:
- if n.hasAttribute('id'):
- found = found and n.getAttribute('id') == id
- else:
- found = found and n.hasAttribute('id') and n.getAttribute('id') == id
- if name and found:
- found = found and n.hasAttribute('name') and n.getAttribute('name') == name
- if found:
- return n
- n = n.nextSibling
- return None
-
- def get_child( self, root, tag = None, id = None, name = None, type = None ):
- return self.get_sibling(root.firstChild,tag=tag,id=id,name=name,type=type)
-
- def get_data( self, node, strip = False, default = None ):
- data = None
- if node:
- data_node = None
- if not data_node:
- data_node = self.get_child(node,tag='#text')
- if not data_node:
- data_node = self.get_child(node,tag='#cdata-section')
- data = ""
- while data_node:
- data += data_node.data
- data_node = data_node.nextSibling
- if data_node:
- if data_node.nodeName != '#text' \
- and data_node.nodeName != '#cdata-section':
- data_node = None
- if not data:
- data = default
- else:
- if strip:
- data = data.strip()
- return data
-
- def get_child_data( self, root, tag = None, id = None, name = None, strip = False, default = None ):
- return self.get_data(self.get_child(root,tag=tag,id=id,name=name),strip=strip,default=default)
-
- def new_node( self, tag, *child, **kwargs ):
- result = self.results.createElement(tag)
- for k in kwargs.keys():
- if kwargs[k] != '':
- if k == 'id':
- result.setAttribute('id',kwargs[k])
- elif k == 'klass':
- result.setAttribute('class',kwargs[k])
- else:
- result.setAttribute(k.replace('_','-'),kwargs[k])
- for c in child:
- if c:
- result.appendChild(c)
- return result
-
- def new_text( self, tag, data, **kwargs ):
- result = self.new_node(tag,**kwargs)
- data = data.strip()
- if len(data) > 0:
- result.appendChild(self.results.createTextNode(data))
- return result
-
-
-if __name__ == '__main__': BJamLog2Results()
diff --git a/src/regression-logs.pl b/src/regression-logs.pl
deleted file mode 100644
index 97cd4e9..0000000
--- a/src/regression-logs.pl
+++ /dev/null
@@ -1,197 +0,0 @@
-#!/usr/bin/perl
-
-#~ Copyright 2003, Rene Rivera.
-#~ Use, modification and distribution are subject to the Boost Software
-#~ License Version 1.0. (See accompanying file LICENSE_1_0.txt or
-#~ http://www.boost.org/LICENSE_1_0.txt)
-
-use FileHandle;
-use Time::Local;
-
-# Get the whle percent value
-#
-sub percent_value
-{
- my ($count,$total) = @_;
- my $percent = int (($count/$total)*100+0.5);
- if ($count > 0 && $percent == 0) { $percent = 1; }
- if ($count < $total && $percent == 100) { $percent = 99; }
- return $percent;
-}
-
-# Generate item html for the pass column.
-#
-sub result_info_pass
-{
- my ($color,$pass,$warn,$fail,$missing) = @_;
- my $percent = 100-percent_value($fail+$missing,$pass+$warn+$fail+$missing);
- return "$percent% ($warn warnings) ";
-}
-
-# Generate item html for the fail column.
-#
-sub result_info_fail
-{
- my ($color,$pass,$warn,$fail,$missing) = @_;
- my $percent = percent_value($fail+$missing,$pass+$warn+$fail+$missing);
- return "$percent% ($fail) ";
-}
-
-# Generate an age highlighted run date string.
-# Use as: data_info(run-date-html)
-#
-sub date_info
-{
- my %m = ('January',0,'February',1,'March',2,'April',3,'May',4,'June',5,
- 'July',6,'August',7,'September',8,'October',9,'November',10,'December',11);
- my @d = split(/ |:/,$_[0]);
- my ($hour,$min,$sec,$day,$month,$year) = ($d[0],$d[1],$d[2],$d[4],$m{$d[5]},$d[6]);
- #print "\n";
- my $test_t = timegm($sec,$min,$hour,$day,$month,$year);
- my $age = time-$test_t;
- my $age_days = $age/(60*60*24);
- #print "\n";
- my $age_html = "";
- if ($age_days <= 2) { }
- elsif ($age_days <= 14) { $age_html = ""; }
- else { $age_html = ""; }
- return $age_html.$_[0]." ";
-}
-
-# Generate an age string based on the run date.
-# Use as: age_info(run-date-html)
-#
-sub age_info
-{
- my %m = ('January',0,'February',1,'March',2,'April',3,'May',4,'June',5,
- 'July',6,'August',7,'September',8,'October',9,'November',10,'December',11);
- my @d = split(/ |:/,$_[0]);
- my ($hour,$min,$sec,$day,$month,$year) = ($d[0],$d[1],$d[2],$d[4],$m{$d[5]},$d[6]);
- #print "\n";
- my $test_t = timegm($sec,$min,$hour,$day,$month,$year);
- my $age = time-$test_t;
- my $age_days = $age/(60*60*24);
- #print "\n";
- my $age_html = "";
- if ($age_days <= 2) { }
- elsif ($age_days <= 14) { $age_html = ""; }
- else { $age_html = ""; }
- if ($age_days <= 1) { $age_html = $age_html."today"; }
- elsif ($age_days <= 2) { $age_html = $age_html."yesterday"; }
- elsif ($age_days < 14) { my $days = int $age_days; $age_html = $age_html.$days." days"; }
- elsif ($age_days < 7*8) { my $weeks = int $age_days/7; $age_html = $age_html.$weeks." weeks"; }
- else { my $months = int $age_days/28; $age_html = $age_html.$months." months"; }
- return $age_html." ";
-}
-
-#~ foreach my $k (sort keys %ENV)
-#~ {
- #~ print "\n";
-#~ }
-my $logdir = "$ENV{PWD}";
-#~ my $logdir = "C:\\CVSROOTs\\Boost\\boost\\status";
-opendir LOGS, "$logdir";
-my @logs = grep /.*links[^.]*\.html$/, readdir LOGS;
-closedir LOGS;
-my @bgcolor = ( "bgcolor=\"#EEEEFF\"", "" );
-my $row = 0;
-print "\n";
-print "\n",
- "Platform \n",
- "Run Date \n",
- "Age \n",
- "Compilers \n",
- "Pass \n",
- "Fail \n",
- " \n";
-foreach $l (sort { lc($a) cmp lc($b) } @logs)
-{
- my $log = $l;
- $log =~ s/-links//s;
- my ($spec) = ($log =~ /cs-([^\.]+)/);
- my $fh = new FileHandle;
- if ($fh->open("<$logdir/$log"))
- {
- my $content = join('',$fh->getlines());
- $fh->close;
- my ($status) = ($content =~ /(Compiler(.(?!<\/td>))+.)/si);
- my ($platform) = ($status =~ /Status: ([^<]+)/si);
- my ($run_date) = ($status =~ /Date:<\/b> ([^<]+)/si);
- $run_date =~ s/, / /g;
- my ($compilers) = ($content =~ /Test Type<\/a><\/t[dh]>((.(?!<\/tr>))+.)/si);
- if ($compilers eq "") { next; }
- $compilers =~ s/- //g;
- $compilers =~ s/<\/td>//g;
- my @compiler = ($compilers =~ /(.*)$/gim);
- my $count = @compiler;
- my @results = ($content =~ /(>Pass<|>Warn<|>Fail<|>Missing<)/gi);
- my $test_count = (scalar @results)/$count;
- my @pass = map { 0 } (1..$count);
- my @warn = map { 0 } (1..$count);
- my @fail = map { 0 } (1..$count);
- my @missing = map { 0 } (1..$count);
- my @total = map { 0 } (1..$count);
- #~ print "\n";
- for my $t (1..$test_count)
- {
- my $r0 = (($t-1)*$count);
- my $r1 = (($t-1)*$count+$count-1);
- my @r = @results[(($t-1)*$count)..(($t-1)*$count+$count-1)];
- #~ print "\n";
- for my $c (1..$count)
- {
- if ($r[$c-1] =~ /Pass/i) { ++$pass[$c-1]; }
- elsif ($r[$c-1] =~ /Warn/i) { ++$warn[$c-1]; }
- elsif ($r[$c-1] =~ /Fail/i) { ++$fail[$c-1]; }
- elsif ($r[$c-1] =~ /Missing/i) { ++$missing[$c-1]; }
- ++$total[$c-1];
- }
- }
- #~ print "\n";
- for my $comp (1..(scalar @compiler))
- {
- my @lines = split(/ /,$compiler[$comp-1]);
- if (@lines > 2) { $compiler[$comp-1] = join(' ',@lines[0..(scalar @lines)-2])." ".$lines[(scalar @lines)-1]; }
- }
- print
- " \n",
- "$platform ($spec ) \n",
- "",$run_date," \n",
- "",age_info($run_date)," \n",
- "",$compiler[0]," \n",
- "",result_info_pass("#000000",$pass[0],$warn[0],$fail[0],$missing[0])," \n",
- "",result_info_fail("#FF0000",$pass[0],$warn[0],$fail[0],$missing[0])," \n",
- " \n";
- $row = ($row+1)%2;
- foreach my $c (1..($count-1))
- {
- print
- "\n",
- "",$compiler[$c]," \n",
- "",result_info_pass("#000000",$pass[$c],$warn[$c],$fail[$c],$missing[$c])," \n",
- "",result_info_fail("#FF0000",$pass[$c],$warn[$c],$fail[$c],$missing[$c])," \n",
- " \n";
- $row = ($row+1)%2;
- }
- print
- "\n",
- " \n",
- " \n";
- }
-}
-print "
\n";
diff --git a/src/regression.py b/src/regression.py
deleted file mode 100644
index e138c0e..0000000
--- a/src/regression.py
+++ /dev/null
@@ -1,1008 +0,0 @@
-#!/usr/bin/python
-
-# Copyright MetaCommunications, Inc. 2003-2007
-# Copyright Rene Rivera 2007-2013
-#
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or copy at
-# http://www.boost.org/LICENSE_1_0.txt)
-
-import glob
-import optparse
-import os
-import os.path
-import platform
-import sys
-import time
-
-#~ Place holder for xsl_reports/util module
-utils = None
-
-git_info = {
- 'build' : {
- 'git' : 'https://github.com/boostorg/build.git',
- 'dir' : 'boost_bb',
- 'subdir' : '',
- },
- 'regression' : {
- 'git' : 'https://github.com/boostorg/regression.git',
- 'dir' : 'boost_regression',
- 'subdir' : '',
- },
- 'boost-build.jam' : {
- 'raw' : 'https://raw.githubusercontent.com/boostorg/boost/%s/boost-build.jam'
- },
- 'boost' : {
- 'git' : 'https://github.com/boostorg/boost.git',
- 'dir' : 'boost_root',
- 'subdir' : '',
- },
- }
-
-git_branch = {
- 'trunk' : 'develop',
- 'release' : 'master',
- 'develop' : 'develop',
- 'master' : 'master',
- }
-
-class runner:
-
- def __init__(self,root):
- commands = map(
- lambda m: m[8:].replace('_','-'),
- filter(
- lambda m: m.startswith('command_'),
- runner.__dict__.keys())
- )
- commands.sort()
- commands = "commands: %s" % ', '.join(commands)
-
- opt = optparse.OptionParser(
- usage="%prog [options] [commands]",
- description=commands)
-
- #~ Base Options:
- opt.add_option( '--runner',
- help="runner ID (e.g. 'Metacomm')" )
- opt.add_option( '--comment',
- help="an HTML comment file to be inserted in the reports" )
- opt.add_option( '--tag',
- help="the tag for the results" )
- opt.add_option( '--group',
- help="the group in which the results are reported, defaults to the tag")
- opt.add_option( '--toolsets',
- help="comma-separated list of toolsets to test with" )
- opt.add_option( '--libraries',
- help="comma separated list of libraries to test")
- opt.add_option( '--incremental',
- help="do incremental run (do not remove previous binaries)",
- action='store_true' )
- opt.add_option( '--timeout',
- help="specifies the timeout, in minutes, for a single test run/compilation",
- type='int' )
- opt.add_option( '--bjam-options',
- help="options to pass to the regression test" )
- opt.add_option( '--bjam-toolset',
- help="bootstrap toolset for 'bjam' executable" )
- opt.add_option( '--pjl-toolset',
- help="bootstrap toolset for 'process_jam_log' executable" )
- opt.add_option( '--platform' )
-
- #~ Source Options:
- opt.add_option( '--local',
- help="the name of the boost tarball" )
- opt.add_option( '--force-update',
- help="do an update (if applicable) instead of a clean checkout, even when performing a full run",
- action='store_true' )
- opt.add_option( '--have-source',
- help="do neither a tarball download nor a repo update; used primarily for testing script changes",
- action='store_true' )
- opt.add_option( '--use-dulwich',
- help="use dulwich git implementation for git access",
- action='store_true')
-
- #~ Connection Options:
- opt.add_option( '--ftp',
- help="FTP URL to upload results to." )
- opt.add_option( '--proxy',
- help="HTTP proxy server address and port (e.g.'http://www.someproxy.com:3128')" )
- opt.add_option( '--ftp-proxy',
- help="FTP proxy server (e.g. 'ftpproxy')" )
- opt.add_option( '--dart-server',
- help="the dart server to send results to" )
-
- #~ Debug Options:
- opt.add_option( '--debug-level',
- help="debugging level; controls the amount of debugging output printed",
- type='int' )
- opt.add_option( '--send-bjam-log',
- help="send full bjam log of the regression run",
- action='store_true' )
- opt.add_option( '--mail',
- help="email address to send run notification to" )
- opt.add_option( '--smtp-login',
- help="STMP server address/login information, in the following form: :@[:]" )
- opt.add_option( '--skip-tests',
- help="do not run bjam; used for testing script changes",
- action='store_true' )
- opt.add_option( '--verbose-log-processing',
- help="enable verbose processing of bjam logs",
- action='store_true' )
-
- #~ Defaults
- self.runner = None
- self.comment='comment.html'
- self.tag='develop'
- self.group=None
- self.toolsets=None
- self.libraries=None
- self.incremental=False
- self.timeout=5
- self.bjam_options=''
- self.bjam_toolset=''
- self.pjl_toolset=''
- self.platform=self.platform_name()
- self.local=None
- self.force_update=False
- self.have_source=False
- self.ftp=None
- self.proxy=None
- self.ftp_proxy=None
- self.dart_server=None
- self.debug_level=0
- self.send_bjam_log=False
- self.mail=None
- self.smtp_login=None
- self.skip_tests=False
- self.use_git=True
- self.use_dulwich=False
- self.verbose_log_processing=False
- ( _opt_, self.actions ) = opt.parse_args(None,self)
- if not self.actions or self.actions == []:
- self.actions = [ 'regression' ]
-
- #~ Set the reporting group if it wasn't specified.
- if not self.group:
- self.group = self.git_branch()
-
- #~ Initialize option dependent values.
- self.regression_root = root
-
- #~ Boost paths.
- self.boost_root = os.path.join( self.regression_root, 'boost_root' )
- self.regression_results = os.path.join( self.regression_root, 'results' )
- 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' )
-
- #~ Boost Build paths.
- self.tools_bb_root = os.path.join( self.regression_root,'boost_bb' )
- self.tools_bb_root = os.path.join( self.tools_bb_root, 'src')
- self.tools_bjam_root = os.path.join( self.regression_root,'boost_bb', 'src', 'engine' )
-
- #~ Regression tools paths.
- self.tools_regression_root = os.path.join( self.regression_root,'boost_regression' )
- self.xsl_reports_dir = os.path.join( self.tools_regression_root, 'xsl_reports' )
-
- self.timestamp_path = os.path.join( self.regression_root, 'timestamp' )
- if sys.platform == 'win32':
- self.patch_boost = 'patch_boost.bat'
- self.bjam = { 'name' : 'bjam.exe' }
- self.process_jam_log = { 'name' : 'process_jam_log.exe' }
- elif sys.platform == 'cygwin':
- self.patch_boost = 'patch_boost'
- self.bjam = { 'name' : 'bjam.exe' }
- self.process_jam_log = { 'name' : 'process_jam_log.exe' }
- else:
- self.patch_boost = 'patch_boost'
- self.bjam = { 'name' : 'bjam' }
- self.process_jam_log = { 'name' : 'process_jam_log' }
- self.bjam = {
- 'name' : self.bjam['name'],
- 'build_cmd' : self.bjam_build_cmd,
- 'path' : os.path.join(self.regression_root,self.bjam['name']),
- 'source_dir' : self.tools_bjam_root,
- 'build_dir' : self.tools_bjam_root,
- 'build_args' : ''
- }
- self.process_jam_log = {
- 'name' : self.process_jam_log['name'],
- 'build_cmd' : self.bjam_cmd,
- 'path' : os.path.join(self.regression_root,self.process_jam_log['name']),
- 'source_dir' : os.path.join(self.tools_regression_root,'build'),
- 'build_dir' : os.path.join(self.tools_regression_root,'build'),
- 'build_args' : 'process_jam_log -d2'
- }
-
- if self.debug_level > 0:
- self.log('Regression root = %s'%self.regression_root)
- self.log('Boost root = %s'%self.boost_root)
- self.log('Regression results = %s'%self.regression_results)
- self.log('Regression log = %s'%self.regression_log)
- self.log('BB root = %s'%self.tools_bb_root)
- self.log('Bjam root = %s'%self.tools_bjam_root)
- self.log('Tools root = %s'%self.tools_regression_root)
- self.log('XSL reports dir = %s'%self.xsl_reports_dir)
- self.log('Timestamp = %s'%self.timestamp_path)
- self.log('Patch Boost script = %s'%self.patch_boost)
-
- if self.libraries is not None:
- self.libraries = self.libraries.split(",")
- # Boost.Build depends on any having run
- if "build" in self.libraries and "any" not in self.libraries:
- self.libraries += ["any"]
-
- self.bjam_options += ' "--limit-tests=' + \
- "|".join(lib for lib in self.libraries if lib != "build") + '"'
-
- # if no -m bjam option add -m64 (limit target to 64 kb of output)
- if self.bjam_options.find('-m') == -1:
- self.bjam_options += ' -m64'
-
- self.main()
-
- #~ The various commands that make up the testing sequence...
-
- def command_cleanup(self,*args):
- if not args or args == None or args == []: args = [ 'source', 'bin' ]
-
- if 'source' in args:
- self.log( 'Cleaning up "%s" directory ...' % self.boost_root )
- self.git_source_checkout(True)
-
- if 'bin' in args:
- boost_bin_dir = os.path.join( self.boost_root, 'bin' )
- self.log( 'Cleaning up "%s" directory ...' % boost_bin_dir )
- self.rmtree( boost_bin_dir )
-
- boost_binv2_dir = os.path.join( self.boost_root, 'bin.v2' )
- self.log( 'Cleaning up "%s" directory ...' % boost_binv2_dir )
- self.rmtree( boost_binv2_dir )
-
- self.log( 'Cleaning up "%s" directory ...' % self.regression_results )
- self.rmtree( self.regression_results )
-
- def command_get_tools(self):
- #~ Get Boost.Build v2...
- self.log( 'Getting Boost.Build v2...' )
- if self.use_git:
- self.git_checkout(
- git_info['build'],
- 'develop')
-# else:
-# self.retry( lambda: self.download_tarball(
-# os.path.basename(self.tools_bb_root)+".tar.bz2",
-# self.tarball_url(repo_path['build']) ) )
-# self.unpack_tarball(
-# self.tools_bb_root+".tar.bz2",
-# os.path.basename(self.tools_bb_root) )
- #~ Get the regression tools and utilities...
- self.log( 'Getting regression tools and utilities...' )
- if self.use_git:
- self.git_checkout(
- git_info['regression'],
- 'develop')
-# else:
-# self.retry( lambda: self.download_tarball(
-# os.path.basename(self.tools_regression_root)+".tar.bz2",
-# self.tarball_url(repo_path['regression']) ) )
-# self.unpack_tarball(
-# self.tools_regression_root+".tar.bz2",
-# os.path.basename(self.tools_regression_root) )
-
- #~ We get a boost-build.jam to make the tool build work even if there's
- #~ an existing boost-build.jam above the testing root.
- self.log( 'Getting boost-build.jam...' )
- self.http_get(
- git_info['boost-build.jam']['raw']%(self.git_branch()),
- os.path.join(self.regression_root, 'boost-build.jam') )
-
- def command_get_source(self):
- self.refresh_timestamp()
- self.log( 'Getting sources (%s)...' % self.timestamp() )
-
- if self.use_git:
- self.retry(self.git_source_checkout)
-# else:
-# self.retry( self.get_tarball )
- pass
-
- def command_update_source(self):
- self.refresh_timestamp()
- self.log( 'Updating sources (%s)...' % self.timestamp() )
- if self.use_git:
- self.retry(self.git_source_checkout)
-# else:
-# self.retry( self.get_tarball )
- pass
-
- def command_patch(self):
- self.import_utils()
- patch_boost_path = os.path.join( self.regression_root, self.patch_boost )
- if os.path.exists( patch_boost_path ):
- self.log( 'Found patch file "%s". Executing it.' % patch_boost_path )
- os.chdir( self.regression_root )
- utils.system( [ patch_boost_path ] )
- pass
-
- def command_setup(self):
- self.command_patch()
- self.build_if_needed(self.bjam,self.bjam_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" ]
- self.import_utils()
-
- self.log( 'Making "%s" directory...' % self.regression_results )
- utils.makedirs( self.regression_results )
-
- results_libs = os.path.join( self.regression_results, 'libs' )
- results_status = os.path.join( self.regression_results, 'status' )
-
- if "clean" in args:
- self.command_test_clean()
-
- if "test" in args:
- self.command_test_run()
- self.command_test_boost_build()
-
- if "process" in args:
- if self.pjl_toolset != 'python':
- self.command_test_process()
-
- def command_test_clean(self):
- results_libs = os.path.join( self.regression_results, 'libs' )
- results_status = os.path.join( self.regression_results, 'status' )
- self.rmtree( results_libs )
- self.rmtree( results_status )
-
- def command_test_run(self):
- self.import_utils()
- if self.pjl_toolset != 'python':
- test_cmd = '%s -d2 preserve-test-targets=off --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 preserve-test-targets=off --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 )
- headers_cmd = self.bjam_cmd(None, 'headers')
- cd = os.getcwd()
- self.log( 'Updating headers (%s)...' % headers_cmd )
- os.chdir( self.boost_root )
- utils.system( [ headers_cmd ] )
- self.log( 'Starting tests (%s)...' % test_cmd )
- os.chdir( os.path.join( self.boost_root, 'status' ) )
- utils.system( [ test_cmd ] )
- os.chdir( cd )
-
- def command_test_boost_build(self):
- if self.libraries is not None and "build" not in self.libraries:
- return
-
- self.import_utils()
- self.log( 'Running Boost.Build tests' )
- # Find the true names of the toolsets used for testing
- toolsets = os.listdir(os.path.join(self.regression_results,
- "boost/bin.v2/libs/any/test/any_test.test"));
- for t in toolsets:
- d = os.path.join(self.regression_results, ("boost-build-%s" % (t)))
- utils.makedirs (d)
- fn = os.path.join(d, "test_log.xml")
- cd = os.getcwd()
- try:
- os.chdir (os.path.join (self.boost_root, 'tools/build/test'))
- bjam_path = os.path.dirname (self.tool_path( self.bjam ))
- self.log( "Using bjam binary in '%s'" % (bjam_path))
- os.putenv('PATH', bjam_path + os.pathsep + os.environ['PATH'])
- utils.system ( [ '"%s" test_all.py --default-bjam --xml %s > %s' % (sys.executable, t, fn) ] )
- finally:
- os.chdir( cd )
-
- def command_test_process(self):
- self.import_utils()
- self.log( 'Getting test case results out of "%s"...' % self.regression_log )
- cd = os.getcwd()
- os.chdir( os.path.join( self.boost_root, 'status' ) )
- utils.checked_system( [
- '"%s" %s "%s" <"%s"' % (
- self.tool_path(self.process_jam_log),
- '--echo' if self.verbose_log_processing else '',
- self.regression_results,
- self.regression_log )
- ] )
- os.chdir( cd )
-
- def command_collect_logs(self):
- self.import_utils()
- comment_path = os.path.join( self.regression_root, self.comment )
- if not os.path.exists( comment_path ):
- self.log( 'Comment file "%s" not found; creating default comment.' % comment_path )
- f = open( comment_path, 'w' )
- f.write( 'Tests are run on %s platform.
' % self.platform_name() )
- f.close()
-
- source = 'tarball'
- revision = self.git_revision(self.boost_root)
-
- # Generate expanded comment file that has extra status
- # information. In particular the revisions of all the git
- # repos in the test tree.
- base_comment_path = comment_path
- comment_path = os.path.join(
- os.path.dirname(base_comment_path),
- 'full-'+os.path.basename(base_comment_path))
- comment_file = open(comment_path, 'w')
- try:
- comment_file.write("\n")
- base_comment_file = open(base_comment_path, 'r')
- try:
- comment_file.write(base_comment_file.read())
- finally:
- base_comment_file.close()
- comment_file.write(" \n")
- comment_file.write("Repo Revision \n")
- for dir_root, dir_names, file_names in os.walk( self.regression_root ):
- for dir_name in dir_names:
- if dir_name == '.git':
- repo_dir = dir_root.replace(self.regression_root, '')
- repo_revision = self.git_revision(dir_root)
- comment_file.write(
- "%s %s \n"
- %(repo_dir, repo_revision))
- for file_name in file_names:
- if file_name == '.git':
- repo_dir = dir_root.replace(self.regression_root, '')
- repo_revision = self.git_revision(dir_root)
- comment_file.write(
- "%s %s \n"
- %(repo_dir, repo_revision))
- comment_file.write("
\n")
- finally:
- comment_file.close()
-
- if self.pjl_toolset != 'python':
- from collect_and_upload_logs import collect_logs
- if self.incremental:
- run_type = 'incremental'
- else:
- run_type = 'full'
- collect_logs(
- self.regression_results,
- self.runner, self.tag, self.platform, comment_path,
- self.timestamp_path,
- "",
- source, run_type,
- self.dart_server, self.proxy,
- revision )
- else:
- from process_jam_log import BJamLog2Results
- if self.incremental:
- run_type = '--incremental'
- else:
- run_type = ''
- 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,
- run_type,
- 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()
- from collect_and_upload_logs import upload_logs
- if self.ftp:
- self.retry(
- lambda:
- upload_logs(
- self.regression_results,
- self.runner, self.group,
- "",
- self.ftp_proxy,
- self.debug_level, self.send_bjam_log,
- self.timestamp_path,
- self.dart_server,
- ftp_url = self.ftp )
- )
- else:
- self.retry(
- lambda:
- upload_logs(
- self.regression_results,
- self.runner, self.group,
- "",
- self.ftp_proxy,
- self.debug_level, self.send_bjam_log,
- self.timestamp_path,
- self.dart_server )
- )
-
- def command_regression(self):
- import socket
- import string
- try:
- mail_subject = 'Boost regression for %s on %s' % ( self.tag,
- string.split(socket.gethostname(), '.')[0] )
- start_time = time.localtime()
- if self.mail:
- self.log( 'Sending start notification to "%s"' % self.mail )
- self.send_mail(
- '%s started at %s.' % ( mail_subject, format_time( start_time ) )
- )
-
- self.command_get_tools()
-
- if self.local is not None:
- self.log( 'Using local file "%s"' % self.local )
- b = os.path.basename( self.local )
- tag = b[ 0: b.find( '.' ) ]
- self.log( 'Tag: "%s"' % tag )
- self.unpack_tarball( self.local, self.boost_root )
-
- elif self.have_source:
- if not self.incremental: self.command_cleanup( 'bin' )
-
- else:
- if self.incremental or self.force_update:
- if not self.incremental: self.command_cleanup( 'bin' )
- else:
- self.command_cleanup()
- self.command_get_source()
-
- self.command_setup()
-
- # Not specifying --toolset in command line is not enough
- # that would mean to use Boost.Build default ones
- # We can skip test only we were explictly
- # told to have no toolsets in command line "--toolset="
- if self.toolsets != '': # --toolset=,
- if not self.skip_tests:
- self.command_test()
- self.command_collect_logs()
- self.command_upload_logs()
-
- if self.mail:
- self.log( 'Sending report to "%s"' % self.mail )
- end_time = time.localtime()
- self.send_mail(
- '%s completed successfully at %s.' % ( mail_subject, format_time( end_time ) )
- )
- except:
- if self.mail:
- self.log( 'Sending report to "%s"' % self.mail )
- traceback_ = '\n'.join( apply( traceback.format_exception, sys.exc_info() ) )
- end_time = time.localtime()
- self.send_mail(
- '%s failed at %s.' % ( mail_subject, format_time( end_time ) ),
- traceback_ )
- raise
-
- def command_show_revision(self):
- modified = '$Date: 2013-02-28 12:09:13 -0600 (Thu, 28 Feb 2013) $'
- revision = '$Revision: 83205 $'
-
- import re
- re_keyword_value = re.compile( r'^\$\w+:\s+(.*)\s+\$$' )
- print '\n\tRevision: %s' % re_keyword_value.match( revision ).group( 1 )
- print '\tLast modified on: %s\n' % re_keyword_value.match( modified ).group( 1 )
-
- #~ Utilities...
-
- def main(self):
- for action in self.actions:
- action_m = "command_"+action.replace('-','_')
- if hasattr(self,action_m):
- getattr(self,action_m)()
-
- def platform_name(self):
- # See http://article.gmane.org/gmane.comp.lib.boost.testing/933
- if sys.platform == 'win32':
- return 'Windows'
- elif sys.platform == 'cygwin':
- return 'Windows/Cygwin'
- return platform.system()
-
- def log(self,message):
- sys.stdout.flush()
- sys.stderr.flush()
- sys.stderr.write( '# %s\n' % message )
- sys.stderr.flush()
-
- def rmtree(self,path):
- if os.path.exists( path ):
- import shutil
- #~ shutil.rmtree( unicode( path ) )
- if sys.platform == 'win32':
- os.system( 'del /f /s /q "%s" >nul 2>&1' % path )
- shutil.rmtree( unicode( path ) )
- else:
- os.system( 'rm -f -r "%s"' % path )
-
- def refresh_timestamp( self ):
- if os.path.exists( self.timestamp_path ):
- os.unlink( self.timestamp_path )
- open( self.timestamp_path, 'w' ).close()
-
- def timestamp( self ):
- return time.strftime(
- '%Y-%m-%dT%H:%M:%SZ',
- time.gmtime( os.stat( self.timestamp_path ).st_mtime ) )
-
- def retry( self, f, max_attempts=5, sleep_secs=10 ):
- for attempts in range( max_attempts, -1, -1 ):
- try:
- return f()
- except Exception, msg:
- self.log( '%s failed with message "%s"' % ( f.__name__, msg ) )
- if attempts == 0:
- self.log( 'Giving up.' )
- raise
-
- self.log( 'Retrying (%d more attempts).' % attempts )
- time.sleep( sleep_secs )
-
- def http_get( self, source_url, destination_file ):
- import urllib
-
- proxies = None
- if hasattr(self,'proxy') and self.proxy is not None:
- proxies = { 'https' : self.proxy }
-
- src = urllib.urlopen( source_url, proxies = proxies )
-
- f = open( destination_file, 'wb' )
- while True:
- data = src.read( 16*1024 )
- if len( data ) == 0: break
- f.write( data )
-
- f.close()
- src.close()
-
- def import_utils(self):
- global utils
- if utils is None:
- sys.path.append( self.xsl_reports_dir )
- import utils as utils_module
- utils = utils_module
-
- def build_if_needed( self, tool, toolset ):
- self.import_utils()
- if os.path.exists( tool[ 'path' ] ):
- self.log( 'Found preinstalled "%s"; will use it.' % tool[ 'path' ] )
- return
-
- self.log( 'Preinstalled "%s" not found; building one...' % tool[ 'path' ] )
-
- if toolset is None:
- if self.toolsets is not None:
- toolset = string.split( self.toolsets, ',' )[0]
- else:
- toolset = tool[ 'default_toolset' ]
- self.log( 'Warning: No bootstrap toolset for "%s" was specified.' % tool[ 'name' ] )
- self.log( ' Using default toolset for the platform (%s).' % toolset )
-
- if os.path.exists( tool[ 'source_dir' ] ):
- self.log( 'Found "%s" source directory "%s"' % ( tool[ 'name' ], tool[ 'source_dir' ] ) )
- build_cmd = tool[ 'build_cmd' ]( toolset, tool['build_args'] )
- self.log( 'Building "%s" (%s)...' % ( tool[ 'name'], build_cmd ) )
- utils.system( [ 'cd "%s"' % tool[ 'source_dir' ], build_cmd ] )
- else:
- raise 'Could not find "%s" source directory "%s"' % ( tool[ 'name' ], tool[ 'source_dir' ] )
-
- if not tool.has_key( 'build_path' ):
- tool[ 'build_path' ] = self.tool_path( tool )
-
- if not os.path.exists( tool[ 'build_path' ] ):
- raise 'Failed to find "%s" after build.' % tool[ 'build_path' ]
-
- self.log( '%s succesfully built in "%s" location' % ( tool[ 'name' ], tool[ 'build_path' ] ) )
-
- def tool_path( self, name_or_spec ):
- if isinstance( name_or_spec, basestring ):
- return os.path.join( self.regression_root, name_or_spec )
-
- if os.path.exists( name_or_spec[ 'path' ] ):
- return name_or_spec[ 'path' ]
-
- if name_or_spec.has_key( 'build_path' ):
- return name_or_spec[ 'build_path' ]
-
- build_dir = name_or_spec[ 'build_dir' ]
- self.log( 'Searching for "%s" in "%s"...' % ( name_or_spec[ 'name' ], build_dir ) )
- for root, dirs, files in os.walk( build_dir ):
- if name_or_spec[ 'name' ] in files:
- return os.path.join( root, name_or_spec[ 'name' ] )
-
- raise Exception( 'Cannot find "%s" in any of the following locations:\n%s' % (
- name_or_spec[ 'name' ]
- , '\n'.join( [ name_or_spec[ 'path' ], build_dir ] )
- ) )
-
- def bjam_build_cmd( self, *rest ):
- if sys.platform == 'win32':
- cmd = 'build.bat %s' % self.bjam_toolset
- else:
- cmd = './build.sh %s' % self.bjam_toolset
- env_setup_key = 'BJAM_ENVIRONMENT_SETUP'
- if os.environ.has_key( env_setup_key ):
- return '%s & %s' % ( os.environ[env_setup_key], cmd )
- return cmd
-
- def bjam_cmd( self, toolsets, args = '', *rest ):
- build_path = self.regression_root
- if build_path[-1] == '\\': build_path += '\\'
-
- if self.timeout > 0:
- args += ' -l%s' % (self.timeout*60)
-
- cmd = '"%(bjam)s"' +\
- ' "-sBOOST_BUILD_PATH=%(bbpath)s"' +\
- ' "-sBOOST_ROOT=%(boost)s"' +\
- ' "--boost=%(boost)s"' +\
- ' "--boost-root=%(boost)s"' +\
- ' "--boost-build=%(bb)s"' +\
- ' "--debug-configuration"' +\
- ' %(arg)s'
- cmd %= {
- 'bjam' : self.tool_path( self.bjam ),
- 'bbpath' : os.pathsep.join([build_path,self.tools_bb_root]),
- 'bb' : self.tools_bb_root,
- 'boost' : self.boost_root,
- 'arg' : args }
-
- if toolsets:
- import string
- cmd += ' toolset=' + toolsets
-
- return cmd
-
- def send_mail( self, subject, msg = '' ):
- import smtplib
- if not self.smtp_login:
- server_name = 'mail.%s' % mail.split( '@' )[-1]
- user_name = None
- password = None
- else:
- server_name = self.smtp_login.split( '@' )[-1]
- ( user_name, password ) = string.split( self.smtp_login.split( '@' )[0], ':' )
-
- log( ' Sending mail through "%s"...' % server_name )
- smtp_server = smtplib.SMTP( server_name )
- smtp_server.set_debuglevel( self.debug_level )
- if user_name:
- smtp_server.login( user_name, password )
-
- 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 )
-
- #~ Downloading source, from GIT...
-
- def git_command(self, command, *args):
- git_cli = "git %(command)s" % { 'command': command }
- for a in args:
- git_cli += " \""+a+"\""
- self.log( 'Executing GIT command: %s> %s' % (os.getcwd(), git_cli) )
- rc = os.system( git_cli )
- if rc != 0:
- raise Exception( 'GIT command "%s" failed with code %d' % (git_cli, rc) )
- return rc
-
- def git_checkout(self, info, branch, clean = False):
- git_root = os.path.join(self.regression_root, info['dir'])
- if self.use_dulwich:
- import git;
- g = git.RemoteRepo(git_root, info['git'], branch=branch, reset=False)
- g.checkout()
- else:
- if os.path.exists( os.path.join(git_root, ".git") ):
- os.chdir( git_root )
- self.git_command( 'remote', 'set-branches', '--add', 'origin',
- branch)
- self.git_command( 'pull', '--recurse-submodules' )
- self.git_command( 'submodule', 'update', '--init' )
- self.git_command( 'checkout', branch)
- if clean:
- self.git_command( 'submodule foreach', 'git reset --quiet --hard ; git clean -fxd')
- self.git_command( 'reset', '--hard' )
- self.git_command( 'clean', '-fxd')
- # self.git_command( 'status' )
- else:
- self.git_command(
- 'init',
- git_root)
- os.chdir( git_root )
- self.git_command(
- 'remote', 'add', '--no-tags', '-t', branch, 'origin',
- info[ 'git' ] )
- self.git_command(
- 'fetch', '--depth=1' )
- self.git_command(
- 'checkout', branch )
- self.git_command(
- 'submodule', 'update', '--init' )
- os.chdir( self.regression_root )
-
- def git_source_checkout(self, clean = False):
- os.chdir( self.regression_root )
- self.git_checkout(git_info['boost'], self.git_branch(), clean)
-
- def git_branch(self):
- if git_branch.has_key(self.tag):
- return git_branch[self.tag]
- else:
- return self.tag
-
- def git_revision(self, root):
- result = ''
- if self.use_git:
- dot_git = os.path.join(root, '.git')
- if os.path.isfile(dot_git):
- f = open(dot_git, 'r')
- try:
- subref = f.read().strip().rpartition(' ')[2]
- git_rev_file = os.path.join(
- root, subref, 'HEAD')
- finally:
- f.close()
- else:
- f = open(os.path.join(dot_git, 'HEAD'), 'r')
- try:
- git_head_info = f.read().strip().rpartition(' ')[2]
- git_rev_file = os.path.join(dot_git, git_head_info)
- finally:
- f.close()
- f = open( git_rev_file, 'r' )
- try:
- result = f.read().strip()
- finally:
- f.close()
- return result
-
- #~ Downloading and extracting source archives, from tarballs or zipballs...
-
- def get_tarball( self, *args ):
- if not args or args == []:
- args = [ 'download', 'unpack' ]
-
- tarball_path = None
-
- if hasattr(self,'local') and self.local is not None:
- tarball_path = self.local
- elif 'download' in args:
- tarball_path = self.download_tarball(self.boost_tarball_name(),self.boost_tarball_url())
- if not tarball_path:
- tarball_path = os.path.join( self.regression_root, self.boost_tarball_url() )
-
- if 'unpack' in args:
- self.unpack_tarball( tarball_path, self.boost_root )
- pass
-
- def download_tarball( self, tarball_name, tarball_url ):
- tarball_path = os.path.join( self.regression_root, tarball_name )
-
- self.log( 'Downloading "%s" to "%s"...' % ( tarball_url, os.path.dirname( tarball_path ) ) )
-
- if os.path.exists( tarball_path ):
- os.unlink( tarball_path )
- self.http_get( tarball_url, tarball_path )
-
- return tarball_path
-
- def tarball_url( self, path ):
- return 'http://beta.boost.org/development/snapshot.php/%s' % path
-
- def boost_tarball_name( self ):
- return 'boost-%s.tar.bz2' % self.tag.split( '/' )[-1]
-
- def boost_tarball_url( self ):
- return self.tarball_url( self.tag )
-
- def unpack_tarball( self, tarball_path, target_path ):
- self.log( 'Looking for old unpacked archives...' )
- old_boost_dirs = self.find_boost_dirs( )
-
- for old_boost_dir in old_boost_dirs:
- if old_boost_dir != tarball_path:
- self.log( 'Deleting old directory %s.' % old_boost_dir )
- self.rmtree( old_boost_dir )
-
- self.log( 'Unpacking boost tarball ("%s")...' % tarball_path )
-
- tarball_name = os.path.basename( tarball_path )
- extension = tarball_name[ tarball_name.find( '.' ) : ]
-
- if extension in ( ".tar.gz", ".tar.bz2" ):
- import tarfile
- import stat
-
- mode = os.path.splitext( extension )[1][1:]
- tar = tarfile.open( tarball_path, 'r:%s' % mode )
- for tarinfo in tar:
- tar.extract( tarinfo, self.regression_root )
- if sys.platform == 'win32' and not tarinfo.isdir():
- # workaround what appears to be a Win32-specific bug in 'tarfile'
- # (modification times for extracted files are not set properly)
- f = os.path.join( self.regression_root, tarinfo.name )
- os.chmod( f, stat.S_IWRITE )
- os.utime( f, ( tarinfo.mtime, tarinfo.mtime ) )
- tar.close()
- elif extension in ( ".zip" ):
- import zipfile
-
- z = zipfile.ZipFile( tarball_path, 'r', zipfile.ZIP_DEFLATED )
- for f in z.infolist():
- destination_file_path = os.path.join( self.regression_root, f.filename )
- if destination_file_path[-1] == "/": # directory
- if not os.path.exists( destination_file_path ):
- os.makedirs( destination_file_path )
- else: # file
- result = open( destination_file_path, 'wb' )
- result.write( z.read( f.filename ) )
- result.close()
- z.close()
- else:
- raise 'Do not know how to unpack archives with extension \"%s\"' % extension
-
- boost_dir = self.find_boost_dirs()[0]
- self.log( ' Unpacked into directory "%s"' % boost_dir )
-
- if os.path.exists( target_path ):
- self.log( 'Deleting "%s" directory...' % target_path )
- self.rmtree( target_path )
-
- self.log( 'Renaming "%s" into "%s"' % ( boost_dir, target_path ) )
- os.rename( boost_dir, target_path )
-
- def find_boost_dirs( self ):
- return [
- x for x in
- glob.glob( os.path.join( self.regression_root, 'boost[-_]*' ) )
- if os.path.isdir( x )
- ]
-
-
diff --git a/src/report/add_expected_results.cpp b/src/report/add_expected_results.cpp
deleted file mode 100644
index 32cc624..0000000
--- a/src/report/add_expected_results.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2007.
-// Copyright Steven Watanabe 2010
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "add_expected_results.hpp"
-#include "common.hpp"
-#include "xml.hpp"
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-bool target_result(const test_structure_t::test_log_t& test_log, const std::string& name) {
- boost::unordered_map::const_iterator pos = test_log.targets.find(name);
- if(pos != test_log.targets.end()) {
- return pos->second.result;
- } else {
- return false;
- }
-}
-
-bool is_test_log_complete(const test_structure_t::test_log_t& test_log) {
- // FIXME: The original XSL function is buggy and
- // Boost.Build relies on its behavior
- return true;
- if(test_log.test_type == "compile" || test_log.test_type == "compile_fail" ||
- !target_result(test_log, "compile")) {
- return test_log.targets.count("compile") == 1 &&
- test_log.targets.count("link") == 0 &&
- test_log.targets.count("run") == 0;
- } else if(test_log.test_type == "link" || test_log.test_type == "link_fail" ||
- test_log.test_type == "" || test_log.test_type == "lib" ||
- !target_result(test_log, "link")) {
- return test_log.targets.count("compile") == 1 &&
- test_log.targets.count("link") == 1 &&
- test_log.targets.count("run") == 0;
- } else if(test_log.test_type == "run" || test_log.test_type == "run_fail" ||
- test_log.test_type == "run_pyd" || test_log.test_type == "run_mpi") {
- return test_log.targets.count("compile") == 1 &&
- test_log.targets.count("link") == 1 &&
- test_log.targets.count("run") == 1;
- } else {
- throw std::runtime_error("Unknown test type " + test_log.test_type);
- }
-}
-
-std::string get_toolset_name(const std::string& toolset, const expected_results_t& expected_results) {
- expected_results_t::toolset_aliases_t::const_iterator pos = expected_results.toolset_aliases.find(toolset);
- if(pos != expected_results.toolset_aliases.end()) {
- return pos->second;
- } else {
- return toolset;
- }
-}
-
-void add_note(test_structure_t::test_log_t& test_log, const std::string& text, const std::string& class_name = "auto-note") {
- test_log.notes.push_back("" + text + " ");
-}
-
-void process_test_log(test_structure_t::test_log_t& test_log,
- const failures_markup_t& failures_markup,
- const expected_results_t& expected_results,
- const std::string& source) {
-
- bool is_complete = is_test_log_complete(test_log);
-
- bool has_failures = false;
- typedef boost::unordered_map::const_reference target_ref;
- BOOST_FOREACH(target_ref target, test_log.targets) {
- if(!target.second.result) {
- has_failures = true;
- break;
- }
- }
-
- bool actual_result = !(has_failures || !is_complete);
-
- std::string toolset_name = get_toolset_name(test_log.toolset, expected_results);
-
- const bool* expected_results_test_case = 0;
- {
- test_case_t test_id;
- test_id.library = test_log.library;
- test_id.test_name = test_log.test_name;
- test_id.toolset_name = toolset_name;
- expected_results_t::tests_t::const_iterator pos = expected_results.tests.find(test_id);
- if(pos != expected_results.tests.end()) {
- expected_results_test_case = &pos->second;
- }
- }
-
- std::string category = "0";
- node_ptr test_failures_markup = 0;
- {
- boost::unordered_map::const_iterator pos = failures_markup.libraries.find(test_log.library);
- if(pos != failures_markup.libraries.end()) {
- node_ptr library_markup = pos->second;
- FOR_EACH_ELEMENT(elem, library_markup) {
- if(check_name(elem, "test")) {
- std::string test_name;
- if(lookup_attr(elem, "name", test_name) && re_match(test_name, test_log.test_name)) {
- lookup_attr(elem, "category", category);
- FOR_EACH_ELEMENT(mark_failure, elem) {
- FOR_EACH_ELEMENT(toolset, mark_failure) {
- std::string toolset_name;
- if(lookup_attr(toolset, "name", toolset_name) && re_match(toolset_name, test_log.toolset)) {
- test_failures_markup = mark_failure;
- goto found_explicit_failure_markup;
- }
- }
- }
- }
- } else if(check_name(elem, "mark-expected-failures")) {
- bool has_test = false;
- bool has_toolset = false;
- FOR_EACH_ELEMENT(subelem, elem) {
- std::string name;
- bool has_name = lookup_attr(subelem, "name", name);
- if(has_name && check_name(subelem, "test") && re_match(name, test_log.test_name)) {
- has_test = true;
- } else if(has_name && check_name(subelem, "toolset") && re_match(name, test_log.toolset)) {
- has_toolset = true;
- }
- if(has_toolset && has_test) {
- test_failures_markup = elem;
- goto found_explicit_failure_markup;
- }
- }
- }
- }
- }
- found_explicit_failure_markup:;
- }
-
- bool is_new = (expected_results_test_case == 0);
- bool has_explicit_markup = (test_failures_markup != 0);
-
- bool expected_result = !(has_explicit_markup || (expected_results_test_case && !*expected_results_test_case));
-
- bool status = (expected_result == actual_result);
-
- bool unexpected_success = (expected_result == false && actual_result == true);
- std::string expected_reason;
- lookup_attr(test_failures_markup, "reason", expected_reason);
-
- if(unexpected_success && has_explicit_markup) {
- add_note(test_log,
- "This test case was explicitly marked up in \n"
- "\n"
- " status/explicit-failures-markup.xml file in the Boost repository as \"expected to fail\",\n"
- "but is passing. Please consult the notes/output below for more details.\n");
- }
- if(has_explicit_markup && lookup_element(test_failures_markup, "note") == 0) {
- if(unexpected_success) {
- add_note(test_log,
- "No explanation was provided for this markup. Please contact the library \n"
- "author(s)/maintainer(s) for more details.\n");
- } else {
- add_note(test_log,
- "This failure was explicitly marked as expected in \n"
- "\n"
- "status/explicit-failures-markup.xml file in the Boost repository. \n"
- "Please contact the library author(s)/maintainer(s) for the explanation of this markup.\n");
- }
- }
- if(node_ptr elem = lookup_element(test_failures_markup, "note")) {
- test_log.notes.push_back(elem);
- }
-
- if(expected_results_test_case && !*expected_results_test_case) {
- if(unexpected_success) {
- add_note(test_log,
- "This test case used to fail in the reference (\"last-known-good\") release.\n");
- } else {
- add_note(test_log,
- "This failure was present in the reference (\"last-known-good\") release.\n");
- }
- }
-
- if(!is_complete && !has_failures) {
- add_note(test_log,
- "[Reporting Tools Internal Error] This test case's XML is missing one or more log entries\n"
- "of the regression run's steps associated with the test case's type (\"" + test_log.test_type + "\").\n"
- "Please contact reporting tools \n"
- "maintainers about this problem.\n", "internal-error-note");
- }
-
- test_log.result = actual_result;
- test_log.expected_result = expected_result;
- test_log.expected_reason = expected_reason;
- test_log.status = status;
- test_log.is_new = is_new;
- test_log.category = category;
-}
-
-// requires: source is a Git branch name
-void boost::regression::add_expected_results(
- test_structure_t::run_t& tests,
- const failures_markup_t& failures_markup,
- const expected_results_t& expected_results,
- const std::string& source)
-{
- BOOST_FOREACH(test_structure_t::toolset_group_t::reference toolset, tests.toolsets) {
- BOOST_FOREACH(test_structure_t::toolset_t::reference library, toolset.second) {
- BOOST_FOREACH(test_structure_t::library_t::reference test_case, library.second) {
- BOOST_FOREACH(test_structure_t::test_case_t::reference test_log, test_case.second) {
- process_test_log(test_log, failures_markup, expected_results, source);
- }
- }
- }
- }
-}
diff --git a/src/report/add_expected_results.hpp b/src/report/add_expected_results.hpp
deleted file mode 100644
index 73aa6a0..0000000
--- a/src/report/add_expected_results.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// add_expected_results.hpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef ADD_EXPECTED_RESULTS_HPP_INCLUDED
-#define ADD_EXPECTED_RESULTS_HPP_INCLUDED
-
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-void add_expected_results(
- test_structure_t::run_t& tests,
- const failures_markup_t& failures_markup,
- const expected_results_t& expected_results,
- const std::string& source);
-
-}
-}
-
-#endif
diff --git a/src/report/boost_report.cpp b/src/report/boost_report.cpp
deleted file mode 100644
index f44f647..0000000
--- a/src/report/boost_report.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-// boost_report.cpp
-//
-// Copyright (c) 2013
-// Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENCE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "issues_page.hpp"
-#include "links_page.hpp"
-#include "result_page.hpp"
-#include "issues_page.hpp"
-#include "summary_page.hpp"
-#include "add_expected_results.hpp"
-#include "produce_expected_results.hpp"
-#include "runners.hpp"
-#include "xml.hpp"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-boost::shared_ptr global_zip;
-
-int main(int argc, char* argv[]) {
- boost::program_options::options_description desc;
- boost::program_options::variables_map vm;
- desc.add_options()
- ("input-file", boost::program_options::value >(), "Runner XML files")
- ("expected,e", boost::program_options::value()->required(), "Expected results file")
- ("markup,m", boost::program_options::value()->required(), "Failures markup file")
- ("tag", boost::program_options::value()->required(), "the tag for the results (i.e. 'trunk')")
- ("run-date", boost::program_options::value()->default_value(boost::posix_time::second_clock::universal_time()), "the timestamp of the report")
- ("reports,r", boost::program_options::value >(), "The reports to generate")
- ("css", boost::program_options::value(), "The CSS file")
- ("comment", boost::program_options::value()->required(), "The report comment file")
- ("help,h", "produce a help message")
- ;
-
- boost::program_options::positional_options_description p;
- p.add("input-file", -1);
-
- try {
-
- boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
- .options(desc).positional(p).run(), vm);
- boost::program_options::notify(vm);
-
- boost::posix_time::ptime now = vm["run-date"].as();
- std::string tag = vm["tag"].as();
- std::set reports;
- if(vm.count("reports")) {
- BOOST_FOREACH(const std::string& report, vm["reports"].as >())
- reports.insert(report);
- }
- std::vector warnings;
-
- test_structure_t structure;
- failures_markup_t markup;
- expected_results_t expected;
- std::vector runs;
-
- std::cout << "Reading expected results" << std::endl;
- boost::shared_ptr expected_results = read_xml_file(vm["expected"].as().c_str());
- load_expected_results(&*expected_results, expected);
-
- std::cout << "Reading failures markup" << std::endl;
- boost::shared_ptr failures_markup = read_xml_file(vm["markup"].as().c_str());
- load_failures_markup(&*failures_markup, markup);
-
- std::ofstream zip_file("report.zip", std::ios_base::binary);
- zip_file.exceptions(std::ios_base::failbit);
- global_zip.reset(new boost::zip::zip_archive(zip_file));
-
- if(vm.count("input-file")) {
- std::vector input_files = vm["input-file"].as >();
- boost::sort(input_files);
- BOOST_FOREACH(const std::string& file, input_files) {
- boost::shared_ptr test_results;
- try {
- std::cout << "Reading " << file << std::endl;
- test_results = read_xml_file(file.c_str());
- load_test_structure(&*test_results, structure, runs);
- test_structure_t::run_t* test_run = runs.back();
- std::cout << "Merging expected results" << std::endl;
- add_expected_results(*test_run, markup, expected, tag);
- std::cout << "Generating links pages" << std::endl;
- // must be run before test_results is discarded
- if(reports.count("l"))
- links_page(markup, *test_run);
- } catch(std::ios_base::failure& e) {
- std::cerr << e.what() << std::endl;
- } catch(boost::property_tree::detail::rapidxml::parse_error& e) {
- std::cerr << e.what() << std::endl;
- }
- }
- }
-
- std::vector modes;
- modes.push_back("developer");
- modes.push_back("user");
-
- if (reports.count("i") != 0) {
- std::cout << "Generating issues page" << std::endl;
- issues_list("developer", structure, markup,
- true, tag, now, warnings, "");
- }
-
- BOOST_FOREACH(const std::string& mode, modes) {
- if(reports.count(mode.substr(0, 1) + "d"))
- result_page(structure, markup,
- false, tag, now, warnings, mode, vm["comment"].as());
- }
-
- BOOST_FOREACH(const std::string& mode, modes) {
- if(reports.count(mode.substr(0, 1) + "s"))
- summary_page(mode, tag, now, std::vector(),
- structure, markup, false);
- }
-
- BOOST_FOREACH(const std::string& mode, modes) {
- if(reports.count(mode.substr(0, 1) + "dr"))
- result_page(structure, markup,
- true, tag, now, warnings, mode, vm["comment"].as());
- }
-
- BOOST_FOREACH(const std::string& mode, modes) {
- if(reports.count(mode.substr(0, 1) + "sr"))
- summary_page(mode, tag, now, std::vector(),
- structure, markup, true);
- }
-
- if (reports.count("e")) {
- produce_expected_results(structure);
- }
-
- if(reports.count("n")) {
- runners(structure);
- }
-
- if(vm.count("css")) {
- std::cout << "Writing file master.css" << std::endl;
- html_writer css("master.css");
- std::string filename = vm["css"].as();
- std::ifstream input(filename.c_str());
- if (input) {
- std::string data(std::istreambuf_iterator(input.rdbuf()), std::istreambuf_iterator());
- css << data;
- } else {
- std::cerr << "warning: Could not open file: " << filename << std::endl;
- }
- }
-
- global_zip.reset();
-
- } catch(boost::program_options::error& e) {
- if(vm.count("help")) {
- std::cerr << desc << std::endl;
- } else {
- std::cerr << e.what() << std::endl;
- return EXIT_FAILURE;
- }
- } catch(boost::exception& e) {
- std::cerr << boost::diagnostic_information(e) << std::endl;
- return EXIT_FAILURE;
- } catch(std::exception& e) {
- std::cerr << e.what() << std::endl;
- return EXIT_FAILURE;
- }
-}
diff --git a/src/report/common.cpp b/src/report/common.cpp
deleted file mode 100644
index e0e81ce..0000000
--- a/src/report/common.cpp
+++ /dev/null
@@ -1,671 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2005.
-// Copyright Steven Watanabe 2010
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "common.hpp"
-#include "xml.hpp"
-#include "html.hpp"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-std::string boost::regression::alternate_mode(const std::string& mode) {
- if(mode == "user") {
- return "developer";
- } else {
- return "user";
- }
-}
-
-std::string boost::regression::release_postfix(bool is_release) {
- if(is_release) {
- return "_release";
- } else {
- return "";
- }
-}
-
-// safe
-void boost::regression::get_libraries(const test_structure_t& test_structure, std::set& out) {
- typedef boost::unordered_map::const_reference outer_elem;
- BOOST_FOREACH(outer_elem platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- BOOST_FOREACH(test_structure_t::toolset_t::const_reference library, toolset.second) {
- out.insert(library.first);
- }
- }
- }
- }
-}
-
-#if 0
-
-
-
-
-
-
-
-
- unusable
-
-
- fail-unexpected
-
-
- fail-unexpected-new
-
-
- success-unexpected
-
-
- expected
-
-
- other
-
-
-
-
-
-
-
-
-
-
-
-#endif
-
-bool boost::regression::is_library_beta(const failures_markup_t& explicit_markup, const std::string& library) {
- boost::unordered_map::const_iterator pos = explicit_markup.libraries.find(library);
- if(pos != explicit_markup.libraries.end()) {
- return check_attr(pos->second, "status", "beta");
- }
- return false;
-}
-
-bool boost::regression::is_test_log_a_test_case(const test_structure_t::test_log_t& test_log) {
- const std::string& type = test_log.test_type;
- return type == "compile" || type == "compile_fail" || type == "link" || type == "link_fail" ||
- type == "run" || type == "run_fail" || type == "run_pyd" || type == "run_mpi";
-}
-
-// Does not assume any constraints on contents of the strings
-bool boost::regression::is_unusable(const failures_markup_t& markup, const std::string& library, const std::string& toolset) {
- boost::unordered_map::const_iterator pos = markup.libraries.find(library);
- if(pos != markup.libraries.end()) {
- FOR_EACH_ELEMENT(mark_unusable, pos->second) {
- if(check_name(mark_unusable, "mark-unusable")) {
- FOR_EACH_ELEMENT(toolset_node, mark_unusable) {
- std::string name;
- if(lookup_attr(toolset_node, "name", name) && re_match(name, toolset)) {
- return true;
- }
- }
- }
- }
- }
- return false;
-}
-
-void boost::regression::get_unusable(const failures_markup_t& markup,
- const std::string& library,
- const test_structure_t& test_structure,
- boost::unordered_map& out,
- std::vector& notes) {
- boost::unordered_map::const_iterator pos = markup.libraries.find(library);
- if(pos != markup.libraries.end()) {
- FOR_EACH_ELEMENT(mark_unusable, pos->second) {
- if(check_name(mark_unusable, "mark-unusable")) {
- node_ptr note = 0;
- std::vector toolsets;
- FOR_EACH_ELEMENT(toolset_node, mark_unusable) {
- std::string name;
- if(check_name(toolset_node, "toolset") && lookup_attr(toolset_node, "name", name)) {
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- if(re_match(name, toolset.first)) {
- toolsets.push_back(toolset.first);
- }
- }
- }
- }
- } else if(check_name(toolset_node, "note")) {
- note = toolset_node;
- }
- }
- if(note != 0 && !toolsets.empty()) {
- notes.push_back(note);
- BOOST_FOREACH(const std::string& toolset, toolsets) {
- out[toolset] = notes.size();
- }
- }
- }
- }
- }
-}
-
-// There are no restrictions on the pattern or the
-// string. The only special character in the pattern
-// is '*', which matches any number of consecutive characters.
-bool boost::regression::re_match(const std::string& pattern, const std::string& text) {
- std::size_t pattern_start = 0;
- std::size_t pattern_end = 0;
- std::size_t text_start = 0;
- // check that the leading portion of the string matches
- std::size_t first = pattern.find('*');
- if(first == std::string::npos) return pattern == text;
- if(pattern.substr(0, first) != text.substr(0, first)) return false;
- text_start = first;
- pattern_start = pattern_end = first + 1;
- for(; pattern_end != pattern.size(); ++pattern_end) {
- // split into blocks at '*'
- if(pattern[pattern_end] == '*') {
- // and search for each block
- std::size_t size = pattern_end - pattern_start;
- std::size_t off = text.find(pattern.data() + pattern_start, text_start, size);
- // if not found, the pattern doesn't match
- if(off == std::string::npos) return false;
- text_start = off + size;
- pattern_start = pattern_end + 1; // skip past the '*'
- }
- }
- // check that the tails of the strings are the same
- std::size_t tail_size = pattern_end - pattern_start;
- return tail_size <= text.size() - text_start &&
- pattern.substr(pattern_start, tail_size) == text.substr(text.size() - tail_size, tail_size);
-}
-
-// date-time
-
-// The result is clamped to the range [0,30]
-int boost::regression::timestamp_difference(const boost::posix_time::ptime& x, const boost::posix_time::ptime& y) {
- boost::posix_time::time_duration diff = y - x;
- int result = diff.hours() / 24;
- if(result < 0) return 0;
- else if(result > 30) return 30;
- else return result;
-}
-
-std::string boost::regression::format_timestamp(const boost::posix_time::ptime& timestamp) {
- std::ostringstream stream;
- stream.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_facet("%a, %d %b %Y %H:%M:%S +0000")));
- stream << timestamp;
- return stream.str();
-}
-
-// path
-
-// FIXME: The result MUST be a valid filesystem path.
-std::string boost::regression::encode_path(const std::string& path) {
- std::string result;
- BOOST_FOREACH(char ch, path) {
- if(ch == '.' || ch == '/') {
- ch = '-';
- }
- // FIXME: allow only characters from the following set:
- // "[a-z][A-Z][0-9][-+_. ,()$!~?]...
- result += ch;
- }
- return result;
-}
-
-std::string boost::regression::escape_uri(const std::string& path) {
- std::string result;
- BOOST_FOREACH(char ch, path) {
- if (('a' <= ch && ch <= 'z') ||
- ('A' <= ch && ch <= 'Z') ||
- ('0' <= ch && ch <= '9') ||
- ch == '-' || ch == '_' || ch == '~' || ch == '.' ||
- // We're intentionally allowing '/' to go through.
- // to escape it as well, use escape_literal_uri
- ch == '/' ||
- // FIXME: reserved characters
- ch == '+')
- result += ch;
- else {
- unsigned digit = ch;
- ch &= 0xFF;
- const char * xdigits = "0123456789ABCDEF";
- result += '%';
- result += xdigits[digit >> 4];
- result += xdigits[digit & 0xF];
- }
- }
- return result;
-}
-
-std::string boost::regression::escape_literal_uri(const std::string& path) {
- std::string result;
- BOOST_FOREACH(char ch, path) {
- // FIXME: Assumes UTF-8
- if (('a' <= ch && ch <= 'z') ||
- ('A' <= ch && ch <= 'Z') ||
- ('0' <= ch && ch <= '9') ||
- ch == '-' || ch == '_' || ch == '~' || ch == '.')
- result += ch;
- else {
- unsigned digit = ch;
- ch &= 0xFF;
- const char * xdigits = "0123456789ABCDEF";
- result += '%';
- result += xdigits[digit >> 4];
- result += xdigits[digit & 0xF];
- }
- }
- return result;
-}
-
-// okay
-std::string boost::regression::output_file_path(const std::string& path) {
- return("output/" + (encode_path(path) + ".html"));
-}
-
-// okay
-std::string boost::regression::log_file_path(
- const failures_markup_t& explicit_markup,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner,
- const std::string& release_postfix)
-{
- if(show_output(explicit_markup, test_log)) {
- return output_file_path(runner + "-" + test_log.target_directory + release_postfix);
- } else {
- return "";
- }
-}
-
-bool boost::regression::show_library(const failures_markup_t& explicit_markup, const std::string& library, bool release) {
- return !release || !is_library_beta(explicit_markup, library);
-}
-
-bool boost::regression::show_output(const failures_markup_t& explicit_markup, const test_structure_t::test_log_t& test_log) {
- return ((!test_log.result || test_log.show_run_output) ||
- (test_log.result && !test_log.status))
- && !(is_unusable(explicit_markup, test_log.library, test_log.toolset));
-}
-
-bool boost::regression::show_toolset(const failures_markup_t& explicit_markup, const std::string& toolset, bool release) {
- return !release || explicit_markup.required_toolsets.find(toolset) != explicit_markup.required_toolsets.end();
-}
-
-// safe: no assumptions, enumerated result
-std::string boost::regression::result_cell_class(const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_log_group_t& test_logs) {
- if(is_unusable(explicit_markup, library, toolset)) {
- return "unusable";
- }
- if(test_logs.empty()) {
- return "missing";
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && log->expected_result && !log->is_new) {
- return "fail-unexpected";
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && log->expected_result && log->is_new) {
- return "fail-unexpected-new";
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && log->expected_reason != "") {
- return "fail-expected-unreasearched";
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result) {
- return "fail-expected";
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(log->result && !log->expected_result) {
- return "success-unexpected";
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(log->result && log->expected_result) {
- return "success-expected";
- }
- }
- return "unknown";
-}
-// safe
-std::string boost::regression::result_cell_class(const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_structure_t::library_t& test_logs)
-{
- test_log_group_t tmp;
- BOOST_FOREACH(test_structure_t::library_t::const_reference test_case, test_logs) {
- BOOST_FOREACH(test_structure_t::test_case_t::const_reference log, test_case.second) {
- tmp.push_back(&log);
- }
- }
- return result_cell_class(explicit_markup, library, toolset, tmp);
-}
-
-// requires: purpose must be well-formed html
-void boost::regression::insert_report_header(
- html_writer& document,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& purpose)
-{
- document << "\n";
- document << "
\n";
- document << " Report Time: " << format_timestamp(run_date) << "\n";
- document << "
\n";
-
- if(!purpose.empty()) {
- document << "
\n";
- document << " Purpose: " << purpose << "\n";
- document << "
\n";
- }
-
- BOOST_FOREACH(const std::string& warning, warnings) {
- document << "
\n";
- }
-
- document << "
\n";
-}
-
-// requires class_ is enumerated
-void boost::regression::insert_view_link(html_writer& out, const std::string& page, const std::string& class_, bool release) {
- if(release) {
- out << ""
- "Full View"
- " \n";
- } else {
- out << ""
- "Release View"
- " ";
- }
-
-}
-
-// requires: mode = developer | user (Should be the opposite of the current page)
-// requires: page is the base name of the current page. It should be valid
-// according to encode_path, but should not be URI escaped.
-void boost::regression::insert_page_links(html_writer& document,
- const std::string& page,
- bool release,
- const std::string& mode) {
- document << "\n";
-
- // yes, really. The class is set to ""
- insert_view_link(document, page, "", release);
-
- std::string release_postfix(release? "_release" : "");
-
- document << " | "
- "
"
- << mode << " View"
- " "
- " | "
- "
Legend \n"
-
- "
\n";
-
-}
-
-// requires: mode = summary | details
-// requires: top_or_bottom = top | bottom
-void boost::regression::insert_runners_rows(html_writer& document,
- const std::string& mode,
- const std::string& top_or_bottom,
- const test_structure_t& test_structure,
- const boost::posix_time::ptime& run_date) {
- std::string colspan = (mode == "summary") ? "1" : "2";
-
- if(top_or_bottom == "top") {
- document << "\n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- std::size_t count = 0;
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- count += run.toolsets.size();
- }
- if(count > 0) {
- document << " \n"
- " " << escape_xml(platform.first) << "\n"
- " \n";
- }
- }
- document << " \n"
- " \n";
- }
-
- document << "\n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- if(run.toolsets.size() > 0) {
- document << " \n"
- " \n"
- " " << escape_xml(run.runner) << "\n"
- " \n"
- " \n";
- }
- }
- }
- document << " \n"
- " \n";
-
- document << "\n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- if(run.toolsets.size() > 0) {
- document << " \n"
- " rev " << run.revision.substr(0, 6) << "\n"
- " \n";
- }
- }
- }
- document << " \n"
- " \n";
-
- document << "\n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- if(run.toolsets.size() > 0) {
- int age = timestamp_difference(run.timestamp, run_date);
- document << " \n"
- " " << format_timestamp(run.timestamp) << " ";
- if(run.run_type != "full") {
- document << "" << run.run_type[0] << " \n";
- }
- document << " \n";
- }
- }
- }
- document << " \n"
- " \n";
-
- if(top_or_bottom == "bottom") {
- document << "\n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- std::size_t count = 0;
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- count += run.toolsets.size();
- }
- if(count > 0) {
- document << " \n"
- " " << escape_xml(platform.first) << "\n"
- " \n";
- }
- }
- document << " \n"
- " \n";
- }
-}
-
-// requires mode = summary | details
-void boost::regression::insert_toolsets_row(html_writer& document,
- const test_structure_t& test_structure,
- const failures_markup_t& explicit_markup,
- const std::string& mode,
- const boost::posix_time::ptime& run_date,
- const std::string& library,
- const boost::unordered_map& library_marks) {
-
- document << "\n";
-
- std::string colspan = (mode == "summary") ? "1" : "2";
- std::string title = (mode == "summary") ?
- " library / toolset " :
- " test / toolset ";
-
- document << " " << title << " \n";
- BOOST_FOREACH(const test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(const test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(const test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- std::string name = toolset.first;
- std::string class_ = (explicit_markup.required_toolsets.find(name) != explicit_markup.required_toolsets.end())?
- "required-toolset-name" :
- "toolset-name";
-
- document << "\n";
- int age = timestamp_difference(run.timestamp, run_date);
-
- document << "\n";
-
- // break toolset names into words
- BOOST_FOREACH(char ch, name) {
- document << ch;
- if(ch == '-') {
- document << ' ';
- }
- }
-
- if(mode == "details") {
- //
- std::set toolset_notes;
- typedef boost::unordered_map::const_reference ref_type;
- BOOST_FOREACH(ref_type toolset_markup, library_marks.equal_range(name)) {
- toolset_notes.insert(toolset_markup.second);
- }
- if(!toolset_notes.empty()) {
- document << "\n";
- bool first = true;
- BOOST_FOREACH(std::size_t note_index, toolset_notes) {
- if(!first) document << ", "; else first = false;
- document << "\n"
- " " << note_index << "\n"
- " \n";
- }
- document << " \n";
- }
- }
-
- document << " \n"
- " \n";
- }
- }
- }
- document << "" << title << " \n"
- " \n";
-}
-
-namespace {
-
-std::string get_note_attr(const test_structure_t::note_t& note, const std::string& name) {
- if(const node_ptr* node = boost::get(¬e)) {
- std::string result;
- lookup_attr(*node, name, result);
- return result;
- } else {
- return std::string();
- }
-}
-
-}
-
-// requires: if note is a string, it is well-formed html
-void boost::regression::show_note(
- html_writer& document,
- const test_structure_t::note_t& note,
- const std::string& references,
- const failures_markup_t& explicit_markup)
-{
- document << "\n";
-
- std::string author = get_note_attr(note, "author");
- std::string date = get_note_attr(note, "date");
-
- document << " \n";
-
- if(references != "") {
- // lookup references (refid="17,18")
- std::vector refs;
- boost::algorithm::split(refs, references, boost::is_any_of(","));
- BOOST_FOREACH(const std::string& refid, refs) {
- boost::unordered_map::const_iterator pos = explicit_markup.notes.find(refid);
- if(pos != explicit_markup.notes.end()) {
- write_contents(document, pos->second);
- } else {
- document << " " << escape_xml(refid) << "\n";
- }
- }
- }
- if(const node_ptr* node_note = boost::get(¬e)) {
- write_contents(document, *node_note);
- } else if(const std::string* string_note = boost::get(¬e)) {
- document << *string_note; // not escaped--can contain html markup
- }
-
- document << "
\n";
-}
-
-// requires: any note that is a string contains well-formed html
-void boost::regression::show_notes(html_writer& document,
- const std::vector& notes,
- const failures_markup_t& explicit_markup)
-{
- document << "\n";
-
- BOOST_FOREACH(const test_structure_t::note_t& note, notes) {
-
- document << "
\n";
-
- std::string refid = get_note_attr(note, "refid");
- ::show_note(document, note, refid, explicit_markup);
-
- document << "
\n";
-
- }
-
- document << "
\n";
-}
diff --git a/src/report/common.hpp b/src/report/common.hpp
deleted file mode 100644
index 24f1fa3..0000000
--- a/src/report/common.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// common.hpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef COMMON_HPP_INCLUDED
-#define COMMON_HPP_INCLUDED
-
-#include
-#include
-#include
-#include
-#include
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-class html_writer;
-typedef std::vector test_log_group_t;
-
-bool is_library_beta(const failures_markup_t& explicit_markup, const std::string& library);
-bool is_test_log_a_test_case(const test_structure_t::test_log_t& test_log);
-
-bool is_unusable(const failures_markup_t& markup, const std::string& library, const std::string& toolset);
-
-void get_unusable(const failures_markup_t& markup,
- const std::string& library,
- const test_structure_t& test_structure,
- boost::unordered_map& out,
- std::vector& notes);
-
-bool re_match(const std::string& pattern, const std::string& text);
-
-int timestamp_difference(const boost::posix_time::ptime& x, const boost::posix_time::ptime& y);
-std::string format_timestamp(const boost::posix_time::ptime& timestamp);
-
-std::string encode_path(const std::string& path);
-std::string escape_uri(const std::string& path); // escapes a URI path (leaves '/' alone)
-std::string escape_literal_uri(const std::string& path); // escapes all special characters in a URI
-std::string output_file_path(const std::string& path);
-std::string log_file_path(
- const failures_markup_t& explicit_markup,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner,
- const std::string& release_postfix = "");
-
-bool show_library(const failures_markup_t& explicit_markup, const std::string& library, bool release);
-bool show_output(const failures_markup_t& markup, const test_structure_t::test_log_t& test_log);
-bool show_toolset(const failures_markup_t& explicit_markup, const std::string& toolset, bool release);
-
-void insert_report_header(html_writer& document,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& purpose = "");
-
-void insert_view_link(html_writer& document,
- const std::string& page,
- const std::string& class_,
- bool release);
-
-void insert_page_links(html_writer& document,
- const std::string& page,
- bool release,
- const std::string& mode);
-
-void insert_runners_rows(html_writer& document,
- const std::string& mode,
- const std::string& top_or_bottom,
- const test_structure_t& test_structure,
- const boost::posix_time::ptime& run_date);
-
-void insert_toolsets_row(html_writer& document,
- const test_structure_t& test_structure,
- const failures_markup_t& explicit_markup,
- const std::string& mode,
- const boost::posix_time::ptime& run_date,
- const std::string& library = std::string(),
- const boost::unordered_map& library_marks = boost::unordered_map());
-
-void show_note(
- html_writer& document,
- const test_structure_t::note_t& note,
- const std::string& references,
- const failures_markup_t& explicit_markup);
-void show_notes(html_writer& document, const std::vector& notes, const failures_markup_t& explicit_markup);
-
-std::string result_cell_class(const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_log_group_t& test_logs);
-
-std::string result_cell_class(const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_structure_t::library_t& test_logs);
-
-std::string alternate_mode(const std::string& mode);
-std::string release_postfix(bool is_release);
-
-void get_libraries(const test_structure_t& test_structure, std::set& out);
-
-}
-}
-
-#endif
diff --git a/src/report/html.cpp b/src/report/html.cpp
deleted file mode 100644
index f6fe280..0000000
--- a/src/report/html.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-// html.cpp
-//
-// Copyright (c) 2010
-// Steven Watanabe
-//
-// Distributed Under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "html.hpp"
-
-const char* const boost::regression::issues_legend =
- "\n"
- "
\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Failure on a newly added test/compiler. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Unexpected failure. \n"
- " \n"
- "
\n"
- " \n"
- " \n"
- "
\n"
- "
\n"
-;
-
-const char* const boost::regression::library_user_legend =
- "\n"
- "
\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " The test successfully passes. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " A known failure that the library maintainers are aware about. Please follow the link to \n"
- " find out how it affects the library's functionality.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " The library author marked it as unusable on this particular platform/toolset. Please\n"
- " see the corresponding footnote.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " An unsearched failure : the library maintainers are aware of it, but need help with \n"
- " investigating/addressing it for future releases. Please follow the link to \n"
- " access the details and find out how it affects library functionality. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " A new failure on the test/compiler added in this release that hasn't been accounted for yet. \n"
- " Please follow the link to access the details.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " A regression comparing to the previous release. Please follow the link to \n"
- " access the details.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "
\n"
- "
\n"
- "
\n"
- " \n"
- " i \n"
- " An incremental run. \n"
- " \n"
- "
\n"
- "
\n"
-;
-
-const char* const boost::regression::library_developer_legend =
- "\n"
- "
\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Success. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Unexpected success; follow the link for more details. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Expected failure; follow the link for more details. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " The library author marked it as unusable on this particular platform/toolset. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Unsearched failure; follow the link for more details. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Failure on a newly added test/compiler. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Unexpected failure/regression. \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "
\n"
- "
\n"
- "
\n"
- " \n"
- " i \n"
- " An incremental run. \n"
- " \n"
- "
\n"
- "
\n"
-;
-
-const char * const boost::regression::summary_user_legend =
- "\n"
- "
\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " All library's tests pass.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Most of the library's tests pass, but there are some known failures which might affect the library's\n"
- " functionality. Please follow the link to see the detailed report.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Some of the newly added library's tests fail, or some of the library's tests fail on\n"
- " the newly added compiler , or some of the tests fail due to unresearched \n"
- " reasons . Please follow the link to see the detailed report.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " There are some regressions in the library comparing to the previous release. \n"
- " Please follow the link to see the detailed report.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " The library author marked it as unusable on the particular platform/toolset.\n"
- " Please follow the link to see the detailed report.\n"
- " \n"
- " \n"
- "
\n"
- "
\n"
- "
\n"
- " \n"
- " i \n"
- " An incremental run. \n"
- " \n"
- "
\n"
- "
\n"
-;
-
-const char * const boost::regression::summary_developer_legend =
- "\n"
- "
\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " All expected tests pass.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " All expected tests pass, and some other tests that were expected to fail \n"
- " unexpectedly pass as well.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " There are some failures on the newly added tests/compiler(s).\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " Tests that the library author expects to pass are currently failing.\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " The library author marked it as unusable on particular platform/toolset.\n"
- " \n"
- " \n"
- "
\n"
- "
\n"
- "
\n"
- " \n"
- " i \n"
- " An incremental run. \n"
- " \n"
- "
\n"
- "
\n"
-;
diff --git a/src/report/html.hpp b/src/report/html.hpp
deleted file mode 100644
index 3a8b464..0000000
--- a/src/report/html.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// html.hpp
-//
-// Copyright (c) 2010
-// Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef HTML_HPP_INCLUDED
-#define HTML_HPP_INCLUDED
-
-namespace boost {
-namespace regression {
-
-extern const char* const issues_legend;
-extern const char* const library_user_legend;
-extern const char* const library_developer_legend;
-extern const char* const summary_user_legend;
-extern const char* const summary_developer_legend;
-
-}
-}
-
-#endif
diff --git a/src/report/html_writer.hpp b/src/report/html_writer.hpp
deleted file mode 100644
index 1fec222..0000000
--- a/src/report/html_writer.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// html_writer.hpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef HTML_WRITER_HPP_INCLUDED
-#define HTML_WRITER_HPP_INCLUDED
-
-#include
-#include
-#include
-#include
-#include
-#include "zip.hpp"
-
-#include
-
-extern boost::shared_ptr global_zip;
-
-namespace boost {
-namespace regression {
-
-class html_writer : boost::noncopyable {
-public:
- // path must be UTF-8 encoded. The separator is '/'
- explicit html_writer(const std::string& path)
- : sink(*global_zip, path)
- {}
- ~html_writer() {
- }
- html_writer& operator<<(const std::string& arg) {
- sink.write(arg.data(), arg.size());
- return *this;
- }
- html_writer& operator<<(const char* arg) {
- sink.write(arg, ::std::strlen(arg));
- return *this;
- }
- html_writer& operator<<(char arg) {
- sink.write(&arg, 1);
- return *this;
- }
- html_writer& operator<<(std::size_t arg) {
- char buf[30];
- char* pos = &buf[0] + 30;
- if(arg == 0) {
- *--pos = '0';
- }
- for(; arg > 0; arg /= 10) {
- *--pos = static_cast('0' + (arg % 10));
- }
- sink.write(pos, buf + 30 - pos);
- return *this;
- }
- html_writer& operator<<(int arg) {
- if(arg < 0) *this << '-' << std::size_t(-arg);
- else *this << std::size_t(arg);
- return *this;
- }
-private:
- boost::zip::nocompression_sink sink;
-};
-
-}
-}
-
-#endif
diff --git a/src/report/issues_page.cpp b/src/report/issues_page.cpp
deleted file mode 100644
index 9b9ab32..0000000
--- a/src/report/issues_page.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-// issues_page.cpp
-//
-// Copyright MetaCommunications, Inc. 2003-2004.
-// Copyright Steven Watanabe 2010
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "issues_page.hpp"
-#include "html_writer.hpp"
-#include "xml.hpp"
-#include "html.hpp"
-#include "common.hpp"
-
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-typedef std::pair test_failure_t;
-typedef std::map > > library_test_names_t;
-typedef std::map libraries_t;
-
-namespace {
-
-void failing_tests(const test_structure_t& tests,
- const failures_markup_t& explicit_markup,
- bool release,
- libraries_t& out)
-{
- typedef boost::unordered_map test_structure_top;
- BOOST_FOREACH(test_structure_top::const_reference platform, tests.platforms) {
- BOOST_FOREACH(const test_structure_t::run_t& runs, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, runs.toolsets) {
- BOOST_FOREACH(test_structure_t::toolset_t::const_reference library, toolset.second) {
- BOOST_FOREACH(test_structure_t::library_t::const_reference test_case, library.second) {
- BOOST_FOREACH(test_structure_t::test_case_t::const_reference test_log, test_case.second) {
- if(test_log.status == false && test_log.result == false &&
- explicit_markup.required_toolsets.find(test_log.toolset) != explicit_markup.required_toolsets.end() &&
- is_test_log_a_test_case(test_log) &&
- show_library(explicit_markup, library.first, release) &&
- show_toolset(explicit_markup, toolset.first, release) &&
- !(is_unusable(explicit_markup, library.first, toolset.first))) {
- out[library.first][test_log.test_name][test_log.toolset].push_back(std::make_pair(&test_log, &runs.runner));
- }
- }
- }
- }
- }
- }
- }
-}
-
-std::size_t count_failures(const library_test_names_t& library) {
- std::size_t result = 0;
- BOOST_FOREACH(library_test_names_t::const_reference test, library) {
- BOOST_FOREACH(library_test_names_t::mapped_type::const_reference toolset, test.second) {
- result += toolset.second.size();
- }
- }
- return result;
-}
-
-// okay
-void write_issues_list_reference_file(const std::string& out,
- const std::string& source,
- bool release,
- const std::string& issues_list)
-{
- html_writer document(out);
- document << "\n";
- document << "\n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " Boost regression unresolved issues: " << source << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << "\n";
-}
-
-void print_failure_cell(html_writer& document,
- const failures_markup_t& explicit_markup,
- const std::string& output_directory,
- const test_structure_t::test_log_t& test_log,
- const std::string& toolset,
- const std::string& runner,
- const std::string& release_postfix)
-{
- std::string log_link = log_file_path(explicit_markup, test_log, runner, release_postfix);
-
- const char* class_ = test_log.is_new?
- "library-fail-unexpected-new" :
- "library-fail-unexpected";
-
- document << "\n";
- document << " \n";
- document << " \n";
- document << " " << escape_xml(toolset) << "\n";
- document << " \n";
- document << " \n";
- document << " \n";
-}
-
-void write_issues_list(const std::string& path,
- const failures_markup_t& explicit_markup,
- const std::string& output_directory,
- const libraries_t& libraries,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& purpose,
- bool release)
-{
- //utils::log("Writing document " + path);
-
- const char* release_postfix = release? "_release" : "";
-
- html_writer document(path);
-
- document << "\n";
-
- document << "\n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " Boost regression unresolved issues: " << source << " \n";
- document << " \n";
- document << " \n";
- document << "\n";
- document << " \n";
- document << " Unresolved Issues: \n";
- document << " " << source << " \n";
- document << " \n";
- document << "\n";
-
- insert_report_header(document, run_date, warnings, purpose);
-
- // Emit the index
- document << " Libraries with unresolved failures \n";
- document << " \n";
-
- BOOST_FOREACH(libraries_t::const_reference library, libraries) {
- document << "
\n";
- document << " " << escape_xml(library.first) << "\n";
- document << " \n";
- }
-
- BOOST_FOREACH(libraries_t::const_reference library, libraries) {
- std::string library_page(encode_path(library.first));
- const library_test_names_t& library_test_names(library.second);
- std::size_t failures = count_failures(library.second);
-
- document << "
\n";
-
- document << "
\n";
- document << " \n";
- document << " \n";
- document << " test \n";
- document << " failures \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " test \n";
- document << " failures \n";
- document << " \n";
- document << " \n";
-
- document << " \n";
-
- BOOST_FOREACH(library_test_names_t::const_reference test, library_test_names) {
- const std::string& test_name = test.first;
- const std::string& test_program = test.second.begin()->second.front().first->test_program;
-
- document << " \n";
- document << " \n";
- document << " \n";
- document << " " << escape_xml(test_name) << "\n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
- document << " \n";
-
- typedef library_test_names_t::mapped_type::const_reference toolset_t;
- BOOST_FOREACH(toolset_t toolset, test.second) {
- BOOST_FOREACH(const test_failure_t& failure, toolset.second) {
- print_failure_cell(document, explicit_markup, output_directory, *failure.first, toolset.first, *failure.second, release_postfix);
- }
- }
-
- document << " \n";
- document << "
\n";
- document << " \n";
- document << " \n";
- }
- document << " \n";
-
- document << "
\n";
- }
- document << "
\n";
- document << issues_legend;
- document << " \n";
- document << "\n";
-}
-
-// okay
-void write_issues_email(const std::string& path,
- const boost::posix_time::ptime& run_date,
- const std::string& source,
- const libraries_t& libraries)
-{
- boost::filesystem::ofstream document(path);
- std::cout << "Writing document " << path << std::endl;
- //utils::log(boost::format("Writing document %s") % path);
-
- std::size_t failing_tests = 0;
- BOOST_FOREACH(libraries_t::const_reference library, libraries) {
- failing_tests += count_failures(library.second);
- }
-
- document << "Boost regression test failures\n"
-"------------------------------\n"
-"Report time: " << run_date << "\n"
-"\n"
-"This report lists all regression test failures on release platforms.\n"
-"\n"
-"Detailed report: \n"
-" http://beta.boost.org/development/tests/" << source << "/developer/issues.html\n"
-"\n"
-<< failing_tests << " failure" << (failing_tests == 1? "" : "s")
-<< " in " << libraries.size() << " librar" << (libraries.size() == 1? "y" : "ies") << ":\n";
-
- BOOST_FOREACH(libraries_t::const_reference library, libraries) {
- document << " " << library.first << " (" << count_failures(library.second) << ")\n";
- }
-
- BOOST_FOREACH(libraries_t::const_reference library, libraries) {
-
- std::string library_page = encode_path(library.first);
- document << "\n"
- "|" << library.first << "|\n";
-
- BOOST_FOREACH(libraries_t::mapped_type::const_reference test_name, library.second) {
- document << " " << test_name.first << ":";
- BOOST_FOREACH(libraries_t::mapped_type::mapped_type::const_reference toolset, test_name.second) {
- document << " " << toolset.first;
- }
- document << "\n";
- }
- }
-}
-
-}
-
-void boost::regression::issues_list(const std::string& output_dir,
- const test_structure_t& tests,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& purpose)
-{
- ::libraries_t libraries;
- failing_tests(tests, explicit_markup, release, libraries);
-
- std::string release_postfix_(release_postfix(release));
- std::string issues_list("issues" + release_postfix_ + "_.html");
-
- write_issues_list_reference_file(output_dir + "/issues.html", source, release, issues_list);
- write_issues_list(output_dir + "/" + issues_list, explicit_markup, output_dir, libraries, source, run_date, warnings, purpose, release);
-
- write_issues_email(output_dir + "/issues-email.txt",
- run_date,
- source,
- libraries);
-}
diff --git a/src/report/issues_page.hpp b/src/report/issues_page.hpp
deleted file mode 100644
index ccc54bd..0000000
--- a/src/report/issues_page.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// issues_page.hpp
-//
-// Copyright (c) 2010
-// Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "xml.hpp"
-
-#include
-#include
-
-#include
-#include
-
-namespace boost {
-namespace regression {
-
-void issues_list(const std::string& output_dir,
- const test_structure_t& tests,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& purpose);
-
-}
-}
\ No newline at end of file
diff --git a/src/report/links_page.cpp b/src/report/links_page.cpp
deleted file mode 100644
index c6256cb..0000000
--- a/src/report/links_page.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2006.
-// Copyright Steven Watanabe 2010
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "links_page.hpp"
-#include "xml.hpp"
-#include "common.hpp"
-#include "html_writer.hpp"
-#include "html.hpp"
-
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-namespace {
-
-void links_page(const failures_markup_t& explicit_markup,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp,
- const std::string& library_name,
- const std::string& toolset_name,
- const std::string& test_name,
- const std::vector& test_logs);
-void write_variants_reference_file(const std::string& path,
- const std::string& variants_file_path,
- const std::string release_postfix,
- const std::vector& test_logs,
- const std::string& runner_id);
-std::string output_page_header(node_ptr test_log, const std::string& runner_id);
-void write_variants_file(const failures_markup_t& explicit_markup,
- const std::string& path,
- const std::vector& test_logs,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp);
-void write_test_result_file(const failures_markup_t& explicit_markup,
- const std::string& path,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp);
-void write_test_results_reference_file(const std::string& path,
- const std::string& log_file_path,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner_id);
-
-// requires: revision must be a SVN revision. i.e. of the form nnnnn
-void links_page(const failures_markup_t& explicit_markup,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp,
- const std::string& library_name,
- const std::string& toolset_name,
- const std::string& test_name,
- const std::vector& test_logs) {
- //utils::log("Processing test \"" + runner_id + "/" + library_name + "/" + test_name + "/" + toolset_name + "\"");
-
- const char* postfixes[] = {"", "_release"};
- const char* dirs[] = { "developer", "user" };
-
- if(test_logs.size() > 1) {
- // utils::log(" Processing variants");
-
- std::string variants_file_path = output_file_path(runner_id + "-" + library_name + "-" + toolset_name + "-" + test_name + "-variants");
-
- write_variants_file(explicit_markup, variants_file_path, test_logs, runner_id, revision, timestamp);
-
- BOOST_FOREACH(const std::string& release_postfix, postfixes) {
- BOOST_FOREACH(const std::string& directory, dirs) {
- std::string variants__file_path = directory + "/" + (encode_path(runner_id + "-" + library_name + "-" + toolset_name + "-" + test_name + "-variants_" + release_postfix) + ".html");
- write_variants_reference_file(variants__file_path, "../" + variants_file_path, release_postfix, test_logs, runner_id);
- }
- }
- }
-
- BOOST_FOREACH(const test_structure_t::test_log_t& test_log, test_logs) {
- //utils::log(" Processing test-log");
-
- if(show_output(explicit_markup, test_log)) {
- std::string log_path = log_file_path(explicit_markup, test_log, runner_id);
- write_test_result_file(explicit_markup, log_path, test_log, runner_id, revision, timestamp);
-
- BOOST_FOREACH(const std::string& release_postfix, postfixes) {
- BOOST_FOREACH(const std::string& directory, dirs) {
- std::string reference_file_path = directory + "/" + log_file_path(explicit_markup, test_log, runner_id, release_postfix);
- write_test_results_reference_file(reference_file_path, log_path, test_log, runner_id);
- }
- }
- }
- }
-}
-
-// okay. result is unconstrained
-std::string output_page_header(const test_structure_t::test_log_t& test_log, const std::string& runner_id) {
- if(test_log.test_name != "") {
- return runner_id + " - " + test_log.library + " - " + test_log.test_name + " / " + test_log.toolset;
- } else {
- return test_log.target_directory;
- }
-}
-
-// requires: path must be a valid file path.
-// requires: variants_file_path must be the path to the variants file relative to path
-void write_variants_reference_file(const std::string& path,
- const std::string& variants_file_path,
- const std::string release_postfix,
- const std::vector& test_logs,
- const std::string& runner_id)
-{
- //utils::log(" Writing variants reference file %s" % path);
- std::string component = output_page_header(test_logs[0], runner_id);
-
- html_writer document(path);
-
- document << "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " Test output: " << escape_xml(component) << " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n";
-}
-
-// requires revision is an SVN revision #
-// requires path is a valid path
-void write_variants_file(const failures_markup_t& explicit_markup,
- const std::string& path,
- const std::vector& test_logs,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp)
-{
- //utils::log(" Writing variants file " + path.string());
- html_writer document(path);
-
- std::string component = output_page_header(test_logs[0], runner_id);
- int age = 0; // timestamp_difference(timestamp, run_date);
-
- document << "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " Test output: " << escape_xml(component) << " \n"
- " \n"
- " \n"
- " \n"
- "\n"
- " Output by test variants:
\n"
- " \n";
-
- BOOST_FOREACH(const test_structure_t::test_log_t& log, test_logs) {
-
- document << " \n"
- " \n";
-
- std::string log_file = log_file_path(explicit_markup, log, runner_id);
- if(!log_file.empty()) {
-
- document << " \n"
- " " << escape_xml(log.target_directory) << "\n"
- " \n";
-
- } else {
-
- document << " " << escape_xml(log.target_directory) << "\n";
-
- }
-
- document << " \n"
- " \n";
-
- }
-
- document << "
\n"
- " \n"
- "\n";
-}
-
-// okay
-const test_structure_t::target_t* lookup_target(const test_structure_t::test_log_t& test_log, const std::string& name) {
- boost::unordered_map::const_iterator pos = test_log.targets.find(name);
- if(pos != test_log.targets.end()) {
- return &pos->second;
- } else {
- return 0;
- }
-}
-
-// requires: path is a valid path
-// requires: revision is an SVN revision
-void write_test_result_file(const failures_markup_t& explicit_markup,
- const std::string& path,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner_id,
- const std::string& revision,
- const boost::posix_time::ptime& timestamp)
-{
- //utils::log(boost::format(" Writing log file document %s") % path);
-
- html_writer document(path);
-
- std::string component = output_page_header(test_log, runner_id);
- int age = 0; // timestamp_difference(timestamp, run_date);
-
- document << "\n"
- "\n";
-
- document << " \n"
- " \n"
- " \n"
- " Test output: " << escape_xml(component) << " \n"
- " \n";
-
- document << " \n"
- " \n";
-
- if(!test_log.notes.empty()) {
-
- document << " \n"
- "
Notes
\n";
-
- show_notes(document, test_log.notes, explicit_markup);
-
- document << "
\n";
-
- }
-
- if(const test_structure_t::target_t* compile = lookup_target(test_log, "compile")) {
- const char* compile_result = compile->result? "succeed" : "fail";
- document << " \n";
- document << "
Compile [" << escape_xml(compile->timestamp) << "]:"
- " " << compile_result << "
\n";
- document << "
\n";
- write_contents(document, compile->contents, true);
- document << " \n";
- document << "
\n";
- }
-
- if(const test_structure_t::target_t* link = lookup_target(test_log, "link")) {
- const char* link_result = link->result? "succeed" : "fail";
- document << " \n";
- document << "
Link [" << escape_xml(link->timestamp) << "]:"
- " " << link_result << "
\n";
- document << "
\n";
- write_contents(document, link->contents, true);
- document << " \n";
- document << "
\n";
- }
-
- if(const test_structure_t::target_t* lib = lookup_target(test_log, "lib")) {
- const char* lib_result = lib->result? "succeed" : "fail";
- std::string lib_name(lib->contents->value(), lib->contents->value_size());
- document << " \n";
- }
-
- if(const test_structure_t::target_t* run = lookup_target(test_log, "run")) {
- const char* run_result = run->result? "succeed" : "fail";
- document << " \n";
- document << "
Run [" << escape_xml(run->timestamp) << "]:"
- " " << run_result << "
\n";
- document << "
\n";
- write_contents(document, run->contents, true);
- document << " \n";
- document << "
\n";
- }
-
- document << " \n";
- document << "\n";
-}
-
-// requires path is a valid path
-// requires: log_file_path is the location of the log file relative to path
-void write_test_results_reference_file(const std::string& path,
- const std::string& log_file_path,
- const test_structure_t::test_log_t& test_log,
- const std::string& runner_id)
-{
- std::string component = output_page_header(test_log, runner_id);
-
- html_writer document(path);
-
- document << "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " Test output: " << escape_xml(component) << " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n";
-}
-
-}
-
-// okay
-void boost::regression::links_page(
- const failures_markup_t& explicit_markup,
- const test_structure_t::run_t& test_run)
-{
- BOOST_FOREACH(const test_structure_t::toolset_group_t::const_reference toolset, test_run.toolsets) {
- BOOST_FOREACH(const test_structure_t::toolset_t::const_reference library, toolset.second) {
- BOOST_FOREACH(const test_structure_t::library_t::const_reference test_case, library.second) {
- ::links_page(explicit_markup,
- test_run.runner,
- test_run.revision,
- test_run.timestamp,
- library.first,
- toolset.first,
- test_case.first,
- test_case.second);
- }
- }
- }
- BOOST_FOREACH(const test_structure_t::toolset_group_t::const_reference toolset, test_run.non_test_case_targets) {
- BOOST_FOREACH(const test_structure_t::toolset_t::const_reference library, toolset.second) {
- BOOST_FOREACH(const test_structure_t::library_t::const_reference test_case, library.second) {
- ::links_page(explicit_markup,
- test_run.runner,
- test_run.revision,
- test_run.timestamp,
- library.first,
- toolset.first,
- test_case.first,
- test_case.second);
- }
- }
- }
-}
diff --git a/src/report/links_page.hpp b/src/report/links_page.hpp
deleted file mode 100644
index d8d10ab..0000000
--- a/src/report/links_page.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// links_page.hpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef LINKS_PAGE_HPP_INCLUDED
-#define LINKS_PAGE_HPP_INCLUDED
-
-#include "xml.hpp"
-#include
-
-namespace boost {
-namespace regression {
-
-void links_page(
- const failures_markup_t& explicit_markup,
- const test_structure_t::run_t& test_run);
-
-}
-}
-
-#endif
diff --git a/src/report/produce_expected_results.cpp b/src/report/produce_expected_results.cpp
deleted file mode 100644
index a25a8a5..0000000
--- a/src/report/produce_expected_results.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2005.
-// Copyright Steven Watanabe 2013
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "produce_expected_results.hpp"
-#include "html_writer.hpp"
-#include
-
-void boost::regression::produce_expected_results(const test_structure_t& tests) {
- std::cout << "Warning: expected results not implemented" << std::endl;
- return;
-
- html_writer document("expected_results.xml");
- document << "\n";
- document << "\n";
- document << " \n";
-#if 0
- foreach test-log
-
-
-
-#endif
- document << " \n";
- document << " \n";
-}
diff --git a/src/report/produce_expected_results.hpp b/src/report/produce_expected_results.hpp
deleted file mode 100644
index 7c9e2b9..0000000
--- a/src/report/produce_expected_results.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// result_page.cpp
-//
-// Copyright Steven Watanabe 2013
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_REGRESSION_PRODUCE_EXPECTED_RESULTS_HPP
-#define BOOST_REGRESSION_PRODUCE_EXPECTED_RESULTS_HPP
-
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-void produce_expected_results(const test_structure_t& tests);
-
-}
-}
-
-#endif
diff --git a/src/report/result_page.cpp b/src/report/result_page.cpp
deleted file mode 100644
index 9b133c1..0000000
--- a/src/report/result_page.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-// result_page.cpp
-//
-// Copyright MetaCommunications, Inc. 2003-2007.
-// Copyright Steven Watanabe 2010-2011
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "result_page.hpp"
-#include "common.hpp"
-#include "html.hpp"
-#include "html_writer.hpp"
-#include "xml.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-namespace {
-
-// safe: no assumptions, no unconstrained output
-void test_type_col(html_writer& document, const std::string& test_type) {
- document << "\n";
- document << " ";
-
- if(test_type == "run_pyd") {
- document << "r";
- } else if(test_type == "run_mpi") {
- document << "r";
- } else if(test_type == "run") {
- document << "r";
- } else if(test_type == "run_fail") {
- document << "rf";
- } else if(test_type == "compile") {
- document << "c";
- } else if(test_type == "compile_fail") {
- document << "cf";
- } else if(test_type == "link") {
- document << "l";
- } else if(test_type == "link_fail") {
- document << "lf";
- } else {
- throw std::runtime_error("Incorrect test type \"" + test_type + "\"");
- }
-
- document << " \n";
- document << " \n";
-}
-
-// category/name
-typedef std::pair test_case_id_t;
-// runner/toolset
-typedef std::pair test_toolset_id_t;
-
-typedef std::vector test_log_group_t;
-typedef boost::unordered_map test_logs_by_run_t;
-typedef std::map test_logs_t;
-
-// requires: result contains no HTML special characters
-// requires: log_link must not contain a '/' derived from the input (This won't actually break anything, though)
-void insert_cell_link(html_writer& document, const std::string& result, const std::string& log_link) {
- if(log_link != "") {
- document << " "
- ""
- << result <<
- " "
- " ";
- } else {
- document << " " << result << " ";
- }
-}
-
-// requires:
-void insert_cell_developer(html_writer& document,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& library,
- const std::string& test_name,
- const std::string& runner,
- const std::string& toolset,
- const test_log_group_t& test_logs) {
- std::string class_ = "library-" + result_cell_class(explicit_markup, library, toolset, test_logs);
-
- std::string cell_link = (test_logs.size() > 1)?
- encode_path(runner + "-" + library + "-" + toolset + "-" + test_logs.front()->test_name + "-variants_" + release_postfix(release)) + ".html" :
- (test_logs.empty())?
- std::string("") :
- log_file_path(explicit_markup, *test_logs.front(), runner, release_postfix(release));
-
- document << "\n";
-
- if(is_unusable(explicit_markup, library, toolset)) {
- insert_cell_link(document, "n/a", cell_link);
- } else if(test_logs.empty()) {
- document << " \n";
- } else {
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && log->status) {
- insert_cell_link(document, (log->expected_reason != "")? "fail?" : "fail*", cell_link);
- goto done;
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && !log->status) {
- insert_cell_link(document, "fail", cell_link);
- goto done;
- }
- }
- insert_cell_link(document, "pass", cell_link);
- }
-done:
- document << " \n";
-}
-
-// requires:
-void insert_cell_user(html_writer& document,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& library,
- const std::string& test_name,
- const std::string& runner,
- const std::string& toolset,
- const test_log_group_t& test_logs) {
- std::string class_ = "library-" + result_cell_class(explicit_markup, library, toolset, test_logs);
-
- std::string cell_link = (test_logs.size() > 1)?
- encode_path(runner + "-" + library + "-" + toolset + "-" + test_logs.front()->test_name + "-variants_" + release_postfix(release)) + ".html" :
- (test_logs.empty())?
- std::string("") :
- log_file_path(explicit_markup, *test_logs.front(), runner, release_postfix(release));
-
- document << "\n";
-
- if(is_unusable(explicit_markup, library, toolset)) {
- insert_cell_link(document, "unusable", cell_link);
- } else if(test_logs.empty()) {
- document << " \n";
- } else {
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && log->status) {
- insert_cell_link(document, (log->expected_reason != "")? "fail?" : "fail*", cell_link);
- goto done;
- }
- }
- BOOST_FOREACH(test_log_group_t::value_type log, test_logs) {
- if(!log->result && !log->status) {
- insert_cell_link(document, "fail", cell_link);
- goto done;
- }
- }
- insert_cell_link(document, "pass", cell_link);
- }
-done:
- document << " \n";
-}
-
-// requires: line_mod should be from an enumerated set
-// requires: source is a Git branch name
-// requires: mode = developer | user
-void insert_test_line(html_writer& document,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& library,
- test_logs_t::const_reference test_results,
- const std::vector >& all_toolsets,
- const std::string& line_mod,
- const std::string& source,
- const std::string& mode) {
- // This is guaranteed to exist because of the way the nested maps are created
- const test_structure_t::test_log_t * first_log = (*test_results.second.begin()).second.front();
- std::string test_program(first_log->test_program);
-
- std::string::size_type pos = test_program.find(library);
- if (pos != std::string::npos)
- test_program.erase(0, pos + library.size());
-
- std::string test_header =
- "\n"
- " \n"
- " " + escape_xml(test_results.first.second) + "\n" // FIXME: sanitize test name
- " \n"
- " \n";
-
- document << "\n"
- << test_header;
-
- test_log_group_t empty_test_log;
- test_type_col(document, first_log->test_type);
- BOOST_FOREACH(const test_toolset_id_t& run, all_toolsets) {
- const std::string& toolset = run.second;
- const std::string& runner = run.first;
-
- test_logs_by_run_t::const_iterator pos = test_results.second.find(run);
-
- const test_log_group_t* test_result_for_toolset =
- (pos != test_results.second.end())?
- &pos->second :
- &empty_test_log;
-
- if(mode == "user") {
- insert_cell_user(document, explicit_markup, release, library, test_results.first.second, runner, toolset, *test_result_for_toolset);
- } else {
- insert_cell_developer(document, explicit_markup, release, library, test_results.first.second, runner, toolset, *test_result_for_toolset);
- }
- }
-
- document << test_header
- << " \n";
-}
-
-// requires: source is a Git branch name
-// requires: mode = developer | user
-void insert_test_section(html_writer& document,
- const test_structure_t& test_structure,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& library,
- const test_logs_t& logs,
- const std::vector >& all_toolsets,
- const std::string& source,
- const std::string& mode) {
- std::size_t category_span = 3;
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, test_structure.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- category_span += (run.toolsets.size());
- }
- }
-
- for(test_logs_t::const_iterator pos = logs.begin(), end = logs.end(); pos != end; ++pos) {
- std::string test_name = pos->first.second;
- bool category_start = (pos == logs.begin()) || (pos->first.first != boost::prior(pos)->first.first);
- bool category_end = (boost::next(pos) == end) || (pos->first.first != boost::next(pos)->first.first);
-
- std::string line_mod =
- (category_start && category_end)? "-single" :
- category_start? "-first" :
- category_end? "-last" :
- "";
-
- if(category_start && pos->first.first != "0") {
- document << "\n"
- " \n"
- " \n";
- }
-
- insert_test_line(document, explicit_markup, release, library, *pos, all_toolsets, line_mod, source, mode);
- }
-}
-
-}
-
-// requires: mode = developer | user
-// requires: source = Boost SVN branch name
-void boost::regression::result_page(const test_structure_t& tests,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& mode,
- const boost::filesystem::path& comment_file)
-{
- // skip debug.xml
-
- std::string index_path("index" + release_postfix(release) + "_.html");
-
- {
-
- std::cout << "Writing document " << "index" << release_postfix(release) << ".html" << std::endl;
-
- html_writer index(mode + "/" + "index" + release_postfix(release) + ".html");
- index << "\n"
- "\n"
- "\n"
- " \n"
- " \n"
- " Boost regression: " << source << " \n"
- "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- "\n";
- }
-
- std::cout << "Writing document " << index_path << std::endl;
-
- {
- html_writer index(mode + "/" + index_path);
- index << "\n"
- "\n"
- "\n"
- " \n"
- " \n"
- " Boost regression: " << source << " \n"
- "\n"
- "\n"
- "\n"
- " \n"
- "\n"
- " \n"
- << mode << " report: "
- " " << source << " \n"
- " \n"
- "\n";
-
- std::string purpose = (mode == "user")?
- "The purpose of this report is to help a user to find out whether a particular library "
- "works on the particular compiler(s). For SVN \"health report\", see "
- " developer summary ."
- :
- "Provides Boost developers with visual indication of the SVN \"health\". For user-level "
- "report, see user summary .";
-
- insert_report_header(index, run_date, warnings, purpose);
-
- index << " \n";
-
- index << "\n";
- index << "\n";
- }
-
- std::set libraries;
- get_libraries(tests, libraries);
-
- {
- std::string toc_path("toc" + release_postfix(release) + ".html");
-
- std::cout << "Writing document " << toc_path << std::endl;
-
- html_writer toc(mode + "/" + toc_path);
-
- toc << "\n"
- << "\n"
- << "\n"
- << " \n"
- << " \n"
- << " Boost regression: " << source << " \n"
- << "\n"
- << "\n"
- << " \n"
- << " \n";
-
- if(mode == "developer") {
- toc << " \n";
- }
-
- toc << " \n";
-
- toc << " \n";
-
- BOOST_FOREACH(const std::string& library, libraries) {
- std::string library_page(encode_path(library));
- toc << " \n";
- }
-
- toc << "\n"
- "\n";
- }
-
- BOOST_FOREACH(const std::string& library, libraries) {
- if(show_library(explicit_markup, library, release)) {
-
- std::string library_results(encode_path(library) + release_postfix(release) + "_.html");
- std::string library_page(encode_path(library) + release_postfix(release) + ".html");
-
- std::cout << "Writing document " << library_page << std::endl;
-
- {
- html_writer document(mode + "/" + library_page);
-
- document << "\n"
- "\n"
- "\n"
- " \n"
- " \n"
- " Boost regression: " << escape_xml(library) << "/" << source << " \n"
- "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- "\n";
- }
-
- std::cout << "Writing document " << library_results << std::endl;
-
- {
- html_writer document(mode + "/" + library_results);
-
- document << "\n"
- "\n"
- "\n"
- " \n"
- " \n"
- " Boost regression: " << escape_xml(library) << "/" << source << " \n"
- "\n"
- "\n"
- "\n";
-
- insert_page_links(document, encode_path(library), release, alternate_mode(mode));
-
- document << "\n";
-
- insert_report_header(document, run_date, warnings);
-
- // toolset/note/index
- boost::unordered_map library_marks;
- std::vector notes;
- get_unusable(explicit_markup, library, tests, library_marks, notes);
-
- document << "\n"
- " \n";
-
- insert_runners_rows(document, "details", "top", tests, run_date); // okay
- insert_toolsets_row(document, tests, explicit_markup, "details", run_date, library, library_marks);
-
- document << " \n"
- " \n";
-
- insert_toolsets_row(document, tests, explicit_markup, "details", run_date, library, library_marks);
- insert_runners_rows(document, "details", "bottom", tests, run_date);
- document << " \n"
- " \n";
-
- test_logs_t lib_tests;
- std::vector > all_toolsets;
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, tests.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- all_toolsets.push_back(std::make_pair(run.runner, toolset.first));
- test_structure_t::toolset_t::const_iterator pos = toolset.second.find(library);
- if(pos != toolset.second.end()) {
- BOOST_FOREACH(test_structure_t::library_t::const_reference test_case, pos->second) {
- test_log_group_t test_logs;
- BOOST_FOREACH(test_structure_t::test_case_t::const_reference log, test_case.second) {
- if(is_test_log_a_test_case(log)) {
- test_logs.push_back(&log);
- }
- }
- if(!test_logs.empty()) {
- std::string category = test_logs.front()->category;
- lib_tests[std::make_pair(category, test_case.first)][std::make_pair(run.runner, toolset.first)] = test_logs;
- }
- }
- }
- }
- }
- }
-
- insert_test_section(document, tests, explicit_markup, release, library, lib_tests, all_toolsets, source, mode);
-
- document << " \n"
- "
\n";
-
- if(!notes.empty()) {
- document << "\n";
- for(std::size_t i = 0; i < notes.size(); ++i) {
- document << "\n"
- " \n"
- " \n"
- " " << (i + 1) << " \n"
- " \n"
- " \n"
- " \n";
- std::string refid;
- lookup_attr(notes[i], "refid", refid);
- show_note(document, notes[i], refid, explicit_markup);
- document << " \n"
- " \n";
- }
- document << "
\n";
- }
-
- document << "\n"
- << (mode == "developer"? library_developer_legend : library_user_legend) << "\n"
- "
\n";
-
- insert_page_links(document, encode_path(library), release, alternate_mode(mode));
-
- document << "\n";
- document << "\n";
- }
- }
- }
-}
diff --git a/src/report/result_page.hpp b/src/report/result_page.hpp
deleted file mode 100644
index e8f00b8..0000000
--- a/src/report/result_page.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// result_page.cpp
-//
-// Copyright MetaCommunications, Inc. 2003-2007.
-// Copyright Steven Watanabe 2010-2011
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include
-#include
-#include
-#include
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-void result_page(const test_structure_t& tests,
- const failures_markup_t& explicit_markup,
- bool release,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const std::string& mode,
- const boost::filesystem::path& comment_file);
-
-}
-}
diff --git a/src/report/runners.cpp b/src/report/runners.cpp
deleted file mode 100644
index 48772e7..0000000
--- a/src/report/runners.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2004.
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "runners.hpp"
-#include "html_writer.hpp"
-#include "common.hpp"
-#include
-#include
-
-void boost::regression::runners(const test_structure_t& tests) {
- {
- html_writer document("runners.html");
- document << "\n"
- "\n"
- " \n"
- " \n"
- " runners \n"
- " \n"
- " \n";
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, tests.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- document << " \n";
- }
- }
- document << " \n"
- "\n";
- }
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, tests.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
-
- std::cout << "Writing runner document " << encode_path(run.runner) << ".html" << std::endl;
-
- html_writer document(encode_path(run.runner) + ".html");
-
- document << "\n"
- "\n"
- "\n"
- "" << escape_xml(run.runner) << " \n"
- "\n"
- "\n"
- "" << escape_xml(run.runner) << " \n"
- " "
- << run.comment // Intentionally not escaped--contains html formatting
- << "\n"
- "\n";
- }
- }
-}
diff --git a/src/report/runners.hpp b/src/report/runners.hpp
deleted file mode 100644
index 920aa37..0000000
--- a/src/report/runners.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// result_page.cpp
-//
-// Copyright Steven Watanabe 2013
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_REGRESSION_RUNNERS_HPP
-#define BOOST_REGRESSION_RUNNERS_HPP
-
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-void runners(const test_structure_t& tests);
-
-}
-}
-
-#endif
diff --git a/src/report/summary_page.cpp b/src/report/summary_page.cpp
deleted file mode 100644
index b70772d..0000000
--- a/src/report/summary_page.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright MetaCommunications, Inc. 2003-2004.
-// Copyright Steven Watanabe 2013
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include
-#include
-#include "common.hpp"
-#include "summary_page.hpp"
-#include "html_writer.hpp"
-#include "html.hpp"
-#include
-
-using namespace boost::regression;
-
-namespace {
-
-// report developer status
-// safe
-void insert_cell_developer(html_writer& document,
- const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_structure_t::library_t& current_cell,
- bool release) {
-
- std::string class_ = "summary-" + result_cell_class(explicit_markup, library, toolset, current_cell);
-
- std::string library_page = encode_path(library);
-
- document << "\n";
-
- if(class_ == "summary-unusable") {
- document << " "
- ""
- "n/a"
- " "
- " ";
- } else if(class_ == "summary-missing") {
- document << " ";
- } else if(class_ == "summary-fail-unexpected") {
- document << ""
- "broken"
- " ";
- } else if(class_ == "summary-fail-unexpected-new") {
- document << " "
- ""
- "fail"
- " "
- " ";
- } else {
- document << " OK ";
- }
- document << " \n";
-}
-
-// report user status
-// safe
-void insert_cell_user(html_writer& document,
- const failures_markup_t& explicit_markup,
- const std::string& library,
- const std::string& toolset,
- const test_structure_t::library_t& current_cell,
- bool release) {
- std::string class_ = "summary-" + result_cell_class(explicit_markup, library, toolset, current_cell);
-
- std::string library_page = encode_path(library);
-
- document << "\n";
-
- if(class_ == "summary-unusable") {
- document << " "
- ""
- "unusable"
- " "
- " ";
- } else if(class_ == "summary-missing") {
- document << " no results ";
- } else if(class_ == "summary-fail-unexpected") {
- document << " "
- ""
- "regress."
- " "
- " ";
- } else if(class_ == "summary-fail-unexpected-new" ||
- class_ == "summary-fail-expected" ||
- class_ == "summary-unknown-status" ||
- class_ == "summary-fail-unexpected-unresearched") {
- document << " "
- ""
- "details"
- " "
- " ";
- } else {
- document << " pass ";
- }
- document << " \n";
-}
-
-}
-
-// requires: mode = developer | user
-// requires: source is the name of an SVN branch
-void boost::regression::summary_page(const std::string& mode,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const test_structure_t& tests,
- const failures_markup_t & explicit_markup,
- bool release) {
-
- std::set sorted_libraries;
- get_libraries(tests, sorted_libraries);
-
- std::string summary_results("summary" + release_postfix(release) + "_.html");
-
- std::cout << "Writing document " << "summary" << release_postfix(release) << ".html" << std::endl;
-
- {
- html_writer document(mode + "/" + "summary" + release_postfix(release) + ".html");
-
- document << "\n"
- "\n"
- " \n"
- " \n"
- " \n"
- " Boost regression summary: " << source << " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n";
- }
-
- // Summary results
- std::cout << "Writing document " << summary_results << std::endl;
-
- {
- html_writer document(mode + "/" + summary_results);
-
- document << "\n"
- "\n"
- "\n"
- " \n"
- " \n"
- " Boost regression summary: " << source << " \n"
- "\n"
- "\n";
-
- insert_page_links(document, "summary", release, alternate_mode(mode));
-
- document << "\n";
-
- insert_report_header(document, run_date, warnings);
-
- std::size_t num_unusable = 0;
- std::size_t num_regressions = 0;
- std::size_t num_new_failures = 0;
-
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, tests.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- BOOST_FOREACH(test_structure_t::toolset_t::const_reference library, toolset.second) {
- bool unusable = is_unusable(explicit_markup, library.first, toolset.first);
- BOOST_FOREACH(test_structure_t::library_t::const_reference test_case, library.second) {
- BOOST_FOREACH(test_structure_t::test_case_t::const_reference test_log, test_case.second) {
- if(unusable) ++num_unusable;
- else if(!test_log.result && !test_log.status) {
- if(test_log.is_new) ++num_new_failures;
- else ++num_regressions;
- }
- }
- }
- }
- }
- }
- }
-
- document << "\n"
- "Unusable: " << num_unusable << "\n"
- " | \n"
- "Regressions: " << num_regressions << "\n"
- " | \n"
- "New failures: " << num_new_failures << "\n"
- "
\n";
-
- // summary table
-
- document << "\n";
-
- document << "\n";
- insert_runners_rows(document, "summary", "top", tests, run_date);
- insert_toolsets_row(document, tests, explicit_markup, "summary", run_date);
- document << " \n";
-
- document << "\n";
- insert_toolsets_row(document, tests, explicit_markup, "summary", run_date);
- insert_runners_rows(document, "summary", "bottom", tests, run_date);
- document << " \n";
-
- document << "\n";
-
- BOOST_FOREACH(const std::string& library, sorted_libraries) {
- std::string library_page = encode_path(library);
-
- std::string library_header =
- "\n"
- " \n"
- " " + escape_xml(library) + "\n"
- " \n"
- " \n";
-
- std::string line_mod;
- if(sorted_libraries.size() == 1) line_mod = "-single";
- else if(library == *sorted_libraries.begin()) line_mod = "-first";
- else if(library == *boost::prior(sorted_libraries.end())) line_mod = "-last";
-
- document << "\n";
- document << library_header;
-
- test_structure_t::library_t empty_library;
- BOOST_FOREACH(test_structure_t::platform_group_t::const_reference platform, tests.platforms) {
- BOOST_FOREACH(test_structure_t::platform_t::const_reference run, platform.second) {
- BOOST_FOREACH(test_structure_t::toolset_group_t::const_reference toolset, run.toolsets) {
- test_structure_t::toolset_t::const_iterator pos = toolset.second.find(library);
- const test_structure_t::library_t * current_cell =
- (pos != toolset.second.end())?
- &pos->second : &empty_library;
- if(mode == "user") {
- insert_cell_user(document, explicit_markup, library, toolset.first, *current_cell, release);
- } else {
- insert_cell_developer(document, explicit_markup, library, toolset.first, *current_cell, release);
- }
- }
- }
- }
-
- document << library_header;
- document << " \n";
- }
-
- document << " \n";
- document << "
\n";
-
- document << "\n"
- << (mode == "developer"? summary_developer_legend : summary_user_legend) << "\n"
- "
\n";
-
- insert_page_links(document, "summary", release, alternate_mode(mode));
-
- document << "\n";
- document << "\n";
- }
-}
diff --git a/src/report/summary_page.hpp b/src/report/summary_page.hpp
deleted file mode 100644
index 8ddd0a3..0000000
--- a/src/report/summary_page.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// result_page.cpp
-//
-// Copyright Steven Watanabe 2013
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_REGRESSION_SUMMARY_PAGE_HPP
-#define BOOST_REGRESSION_SUMMARY_PAGE_HPP
-
-#include
-#include
-#include
-#include
-#include "xml.hpp"
-
-namespace boost {
-namespace regression {
-
-void summary_page(const std::string& mode,
- const std::string& source,
- const boost::posix_time::ptime& run_date,
- const std::vector& warnings,
- const test_structure_t& tests,
- const failures_markup_t & explicit_markup,
- bool release);
-
-}
-}
-
-#endif
diff --git a/src/report/xml.cpp b/src/report/xml.cpp
deleted file mode 100644
index f8a7cb7..0000000
--- a/src/report/xml.cpp
+++ /dev/null
@@ -1,387 +0,0 @@
-// xml.cpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#include "xml.hpp"
-#include "common.hpp"
-
-#include
-#include
-#include
-#include
-#include
-
-using namespace boost::regression;
-
-std::size_t boost::regression::hash_value(const test_case_t& test_case) {
- std::size_t result = 0;
- boost::hash_combine(result, test_case.test_name);
- boost::hash_combine(result, test_case.library);
- boost::hash_combine(result, test_case.toolset_name);
- return result;
-}
-
-bool boost::regression::operator==(const test_case_t& lhs, const test_case_t& rhs) {
- return lhs.test_name == rhs.test_name &&
- lhs.library == rhs.library &&
- lhs.toolset_name == rhs.toolset_name;
-}
-
-boost::regression::attr_ptr boost::regression::lookup_attr(node_ptr element, const std::string& name) {
- if(element == 0) return 0;
- return element->first_attribute(name.data(), name.size());
-}
-
-bool boost::regression::lookup_attr(node_ptr element, const std::string& name, std::string& result) {
- if(element == 0) return false;
- if(attr_ptr attr = lookup_attr(element, name)) {
- result = std::string(attr->value(), attr->value_size());
- return true;
- } else {
- return false;
- }
-}
-
-void require_attr(node_ptr element, const std::string& name, std::string& result) {
- if(!lookup_attr(element, name, result)) {
- throw xml_error("Missing attribute " + name + " in element " + std::string(element->name(), element->name_size()));
- }
-}
-
-bool boost::regression::check_attr(node_ptr element, const std::string& name, const std::string& expected) {
- if(attr_ptr attr = lookup_attr(element, name)) {
- return std::string(attr->value(), attr->value_size()) == expected;
- } else {
- return false;
- }
-}
-
-bool boost::regression::check_name(node_ptr element, const std::string& name) {
- return std::string(element->name(), element->name_size()) == name;
-}
-
-bool boost::regression::check_attr(node_ptr element,
- const std::string& element1,
- const std::string& attr,
- const std::string& expected) {
- if(element == 0) return false;
- else if(element1 == "*") {
- FOR_EACH_ELEMENT(nested, element) {
- if(check_attr(nested, attr, expected)) {
- return true;
- }
- }
- return false;
- } else {
- return check_attr(lookup_element(element, element1), attr, expected);
- }
-}
-
-boost::regression::node_ptr boost::regression::lookup_element(node_ptr element, const std::string& name) {
- if(element == 0) {
- return 0;
- } else {
- return element->first_node(name.data(), name.size());
- }
-}
-
-int boost::regression::count_element(node_ptr element, const std::string& name) {
- int result = 0;
- element = element->first_node(name.data(), name.size());
- while(element != 0) {
- ++result;
- element = element->next_sibling(name.data(), name.size());
- }
- return result;
-}
-
-std::string boost::regression::value_of(node_ptr element) {
- if(element && element->value() != 0) {
- return std::string(element->value(), element->value_size());
- } else {
- return std::string();
- }
-}
-
-void boost::regression::load_failures_markup(node_ptr root, failures_markup_t& failures_markup) {
- if(check_name(root, "library")) {
- std::string library;
- lookup_attr(root, "name", library);
- failures_markup.libraries.insert(std::make_pair(library, root));
- } else if(check_name(root, "mark-toolset")) {
- if(check_attr(root, "status", "required")) {
- std::string name;
- if(lookup_attr(root, "name", name)) {
- failures_markup.required_toolsets.insert(name);
- }
- }
- } else if(check_name(root, "note")) {
- std::string refid;
- if(lookup_attr(root, "id", refid)) {
- failures_markup.notes.insert(std::make_pair(refid, root));
- }
- } else {
- FOR_EACH_ELEMENT(elem, root) {
- load_failures_markup(elem, failures_markup);
- }
- }
-}
-
-namespace {
-
-void load_test_log(node_ptr root, test_structure_t::test_log_t& test_log) {
- lookup_attr(root, "library", test_log.library);
- lookup_attr(root, "test-program", test_log.test_program);
- test_log.show_run_output = check_attr(root, "show-run-output", "true");
- lookup_attr(root, "toolset", test_log.toolset);
- lookup_attr(root, "test-type", test_log.test_type);
- lookup_attr(root, "test-name", test_log.test_name);
- lookup_attr(root, "target-directory", test_log.target_directory);
- // these are set by add_expected_results
- test_log.result = false; // check_attr(root, "result", "success");
- test_log.expected_result = false; // check_attr(root, "expected-result", "success");
- // lookup_attr(root, "expected-reason", test_log.expected_reason);
- test_log.status = check_attr(root, "status", "expected");
- test_log.is_new = check_attr(root, "is-new", "yes");
- lookup_attr(root, "category", test_log.category);
-
- // process compile/run/etc.
- FOR_EACH_ELEMENT(elem, root) {
- std::string name(elem->name(), elem->name_size());
- if(name != "") {
- test_structure_t::target_t& target = test_log.targets[name];
- target.type = name;
- lookup_attr(elem, "timestamp", target.timestamp);
- target.result = !check_attr(elem, "result", "fail");
- target.contents = elem;
- }
- }
-}
-
-void collect_toolsets(node_ptr root, test_structure_t::toolset_group_t& out, test_structure_t::toolset_group_t& non_test_case_targets) {
- if(check_name(root, "test-log")) {
- std::string toolset;
- if(lookup_attr(root, "toolset", toolset)) {
- std::string library, test_name;
- lookup_attr(root, "library", library);
- lookup_attr(root, "test-name", test_name);
-
- test_structure_t::test_log_t log;
- load_test_log(root, log);
- if(is_test_log_a_test_case(log))
- out[toolset][library][test_name].push_back(log);
- else
- non_test_case_targets[toolset][library][test_name].push_back(log);
- }
- } else {
- FOR_EACH_ELEMENT(elem, root) {
- collect_toolsets(elem, out, non_test_case_targets);
- }
- }
-}
-
-// FIXME: Make sure that Boost.DateTime handles parsing errors correctly
-boost::posix_time::ptime parse_time(std::string arg) {
- // fix up some formatting problems
- if(!arg.empty() && arg[arg.size() - 1] == 'Z') arg.resize(arg.size() - 1);
- std::replace(arg.begin(), arg.end(), 'T', ' ');
- return boost::posix_time::time_from_string(arg);
-}
-
-void validate_run(const test_structure_t::run_t& run) {
- if(run.run_type != "incremental" && run.run_type != "full") {
- BOOST_THROW_EXCEPTION(xml_error("Expected run-type to be \"incremental\" or \"full\""));
- }
-// For Git, revision is a SHA, and thus may contain alpha characters
-// BOOST_FOREACH(char ch, run.revision) {
-// if(!('0' <= ch && ch <= '9')) {
-// BOOST_THROW_EXCEPTION(xml_error("Expected revision to be a numeric constant"));
-// }
-// }
-}
-
-}
-
-void boost::regression::load_test_structure(node_ptr root, test_structure_t& structure, std::vector& runs) {
- if(check_name(root, "test-run")) {
- test_structure_t::run_t run;
- std::string timestamp;
- require_attr(root, "runner", run.runner);
- require_attr(root, "platform", run.platform);
- require_attr(root, "run-type", run.run_type);
- require_attr(root, "source", run.source);
- require_attr(root, "revision", run.revision);
- require_attr(root, "timestamp", timestamp);
- // "2010-05-11T18:29:17Z"
- run.timestamp = parse_time(timestamp);
- run.comment = value_of(lookup_element(root, "comment"));
- validate_run(run);
- collect_toolsets(root, run.toolsets, run.non_test_case_targets);
- structure.platforms[run.platform].push_back(run);
- runs.push_back(&structure.platforms[run.platform].back());
- } else {
- FOR_EACH_ELEMENT(elem, root) {
- load_test_structure(elem, structure, runs);
- }
- }
-}
-
-namespace {
-
-struct escaped {
- const char* input;
- std::size_t size;
- bool trim;
-};
-
-// okay
-void write_characters(html_writer& document, const char* input, std::size_t size) {
- for(std::size_t i = 0; i < size; ++i) {
- if(input[i] == '<') {
- document << "<";
- } else if(input[i] == '>') {
- document << ">";
- } else if(input[i] == '&') {
- document << "&";
- } else {
- document << input[i];
- }
- }
-}
-
-// FIXME: do not break in the middle of a code point
-html_writer& operator<<(html_writer& document, const escaped& text) {
- std::size_t max_size = 1 << 16;
- if(text.trim && (text.size > max_size)) {
- write_characters(document, text.input, max_size);
- document << str(boost::format("...\n\n[The content has been trimmed by the report system because it exceeds %d bytes]") % max_size);
- } else {
- write_characters(document, text.input, text.size);
- }
- return document;
-}
-
-escaped make_escaped(const char* input, std::size_t size, bool trim) {
- escaped result = { input, size, trim };
- return result;
-}
-
-std::string escape_characters(const char* input, std::size_t size) {
- std::string result;
- for(std::size_t i = 0; i < size; ++i) {
- if(input[i] == '<') {
- result += "<";
- } else if(input[i] == '>') {
- result += ">";
- } else if(input[i] == '&') {
- result += "&";
- } else if(input[i] == '\'') {
- result += "'";
- } else if(input[i] == '"') {
- result += """;
- } else {
- result += input[i];
- }
- }
- return result;
-}
-}
-
-std::string boost::regression::escape_xml(const std::string& s) {
- return escape_characters(s.data(), s.size());
-}
-
-void boost::regression::write_to_stream(html_writer& os, node_ptr node, bool trim) {
- using namespace boost::property_tree::detail::rapidxml;
- switch(node->type()) {
- case node_document:
- FOR_EACH_ELEMENT(elem, node) {
- write_to_stream(os, elem);
- }
- break;
- case node_element:
- os << '<' << escape_characters(node->name(), node->name_size());
- for(attr_ptr attr = node->first_attribute(); attr != 0; attr = attr->next_attribute()) {
- os << ' ' << std::string(attr->name(), attr->name_size()) << '=' << '"' << escape_characters(attr->value(), attr->value_size()) << '"';
- }
- os << '>';
- FOR_EACH_ELEMENT(elem, node) {
- write_to_stream(os, elem);
- }
- os << '<' << '/' << escape_characters(node->name(), node->name_size()) << '>';
- break;
- case node_data:
- os << make_escaped(node->value(), node->value_size(), trim);
- break;
- default:
- throw xml_error("Don't know how to handle element type");
- }
-}
-
-void boost::regression::write_contents(html_writer& os, node_ptr node, bool trim) {
- FOR_EACH_ELEMENT(elem, node) {
- write_to_stream(os, elem, trim);
- }
-}
-
-namespace {
-struct node_storage : document_type {
- std::vector storage;
-};
-}
-
-boost::shared_ptr boost::regression::read_xml_file(const char* filename) {
- std::ifstream input(filename);
- if(!input) {
- throw(std::ios_base::failure(std::string("Could not open file: ") + filename));
- }
- boost::shared_ptr result(new node_storage());
- std::streambuf* buf = input.rdbuf();
- std::streambuf::int_type ch;
- while((ch = buf->sbumpc()) != std::char_traits::eof()) {
- result->storage.push_back(ch);
- }
- result->storage.push_back('\0');
- result->parse(&result->storage[0]);
- return result;
-}
-
-namespace {
-
-void load_expected_results(node_ptr root, test_case_t id, expected_results_t& expected_results) {
- if(check_name(root, "test-result")) {
- lookup_attr(root, "test-name", id.test_name);
- bool result = !check_attr(root, "result", "fail");
- expected_results.tests.insert(std::make_pair(id, result));
- } else {
- if(check_name(root, "toolset")) {
- std::string name;
- lookup_attr(root, "name", name);
- id.toolset_name = name;
- FOR_EACH_ELEMENT(elem, root) {
- if(check_name(elem, "toolset-alias")) {
- std::string alias_name;
- if(lookup_attr(elem, "name", alias_name)) {
- expected_results.toolset_aliases.insert(std::make_pair(alias_name, name));
- }
- }
- }
- } else if(check_name(root, "library")) {
- lookup_attr(root, "name", id.library);
- }
- FOR_EACH_ELEMENT(elem, root) {
- load_expected_results(elem, id, expected_results);
- }
- }
-}
-
-}
-
-void boost::regression::load_expected_results(node_ptr root, expected_results_t& expected_results) {
- test_case_t id;
- ::load_expected_results(root, id, expected_results);
-}
diff --git a/src/report/xml.hpp b/src/report/xml.hpp
deleted file mode 100644
index b795005..0000000
--- a/src/report/xml.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-// xml.hpp
-//
-// Copyright (c) 2010 Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanyiong file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef XML_HPP_INCLUDED
-#define XML_HPP_INCLUDED
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "html_writer.hpp"
-
-namespace boost {
-namespace regression {
-
-class xml_error : public std::exception {
-public:
- explicit xml_error(const std::string& m) : message(m) {}
- virtual ~xml_error() throw() {}
- virtual const char * what() const throw() { return message.c_str(); }
-private:
- std::string message;
-};
-
-typedef boost::property_tree::detail::rapidxml::xml_node<> node_type;
-typedef boost::property_tree::detail::rapidxml::xml_attribute<> attr_type;
-typedef boost::property_tree::detail::rapidxml::xml_document<> document_type;
-typedef node_type* node_ptr;
-typedef attr_type* attr_ptr;
-typedef document_type* document_ptr;
-
-struct test_case_t {
- std::string toolset_name;
- std::string library;
- std::string test_name;
-};
-
-std::size_t hash_value(const test_case_t& test_case);
-bool operator==(const test_case_t& lhs, const test_case_t& rhs);
-
-struct expected_results_t {
- typedef boost::unordered_map tests_t;
- typedef boost::unordered_map toolset_aliases_t;
- tests_t tests;
- toolset_aliases_t toolset_aliases;
-};
-void load_expected_results(node_ptr root, expected_results_t& expected_results);
-
-struct test_structure_t {
- struct target_t {
- std::string type;
- std::string timestamp;
- bool result;
- node_ptr contents;
- };
- typedef boost::variant note_t;
- struct test_log_t {
- std::string library;
- std::string test_program;
- bool show_run_output;
- std::string toolset;
- std::string test_type;
- std::string test_name;
- std::string target_directory;
- bool result;
- bool expected_result;
- std::string expected_reason;
- bool status;
- bool is_new;
- std::string category;
- boost::unordered_map targets;
- std::vector notes;
- };
- typedef std::vector test_case_t;
- typedef std::map library_t;
- typedef std::map toolset_t;
- typedef std::map toolset_group_t;
- struct run_t {
- std::string runner;
- std::string platform;
- std::string run_type;
- std::string source;
- std::string revision;
- std::string comment;
- boost::posix_time::ptime timestamp;
- toolset_group_t toolsets;
- toolset_group_t non_test_case_targets;
- };
- typedef std::vector platform_t;
- typedef std::map platform_group_t;
- platform_group_t platforms;
-};
-void load_test_structure(node_ptr root, test_structure_t& structure, std::vector& runs);
-
-struct failures_markup_t {
- boost::unordered_map libraries;
- boost::unordered_set required_toolsets;
- boost::unordered_map notes;
-};
-void load_failures_markup(node_ptr root, failures_markup_t& failures_markup);
-
-#define FOR_EACH_ELEMENT(name, node)\
- for(::boost::regression::node_ptr name = (node)->first_node(); name != 0; name = name->next_sibling())
-
-attr_ptr lookup_attr(node_ptr element, const std::string& name);
-bool lookup_attr(node_ptr element, const std::string& name, std::string& result);
-bool check_attr(node_ptr element, const std::string& name, const std::string& expected);
-bool check_name(node_ptr element, const std::string& name);
-bool check_attr(node_ptr element, const std::string& element1, const std::string& attr, const std::string& expected);
-node_ptr lookup_element(node_ptr element, const std::string& name);
-int count_element(node_ptr element, const std::string& name);
-std::string value_of(node_ptr element);
-
-std::string escape_xml(const std::string& s);
-void write_to_stream(html_writer& os, node_ptr node, bool trim=false);
-void write_contents(html_writer& document, node_ptr node, bool trim=false);
-boost::shared_ptr read_xml_file(const char* filename);
-
-}
-}
-
-#endif
diff --git a/src/report/zip.hpp b/src/report/zip.hpp
deleted file mode 100644
index 6c67b4b..0000000
--- a/src/report/zip.hpp
+++ /dev/null
@@ -1,768 +0,0 @@
-// zip.hpp
-//
-// Copyright (c) 2010, 2013
-// Steven Watanabe
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_ZIP_ZIP_HPP_INCLUDED
-#define BOOST_ZIP_ZIP_HPP_INCLUDED
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace zip {
-
-// TODO: Handle endian conversions
-#define BOOST_ZIP_DEFINE_HEADER(name, type, offset) \
- static const int name##_offset = (offset); \
- static type get_##name(const char* header) { \
- type result; \
- ::std::memcpy(&result, header + (offset), sizeof(type)); \
- return result; \
- } \
- static void set_##name(char* header, type x) { \
- ::std::memcpy(header + (offset), &x, sizeof(type)); \
- }
-
-class zip_archive {
-public:
- zip_archive(std::ostream& file) : output_file(file), current_offset(0), num_files(0) {}
- ~zip_archive() {
- close();
- }
-
- class file_handle;
- friend class file_handle;
- class file_handle {
- public:
- typedef char char_type;
-
- struct category :
- ::boost::iostreams::sink_tag,
- ::boost::iostreams::closable_tag
- {};
-
- file_handle(zip_archive& archive,
- const std::string& path,
- boost::uint16_t creator_version,
- boost::uint16_t minimum_required_version,
- boost::uint16_t flags,
- boost::uint16_t compression_method,
- const boost::posix_time::ptime& modification_time)
- {
- self = 0;
- archive.open_file(path, creator_version, minimum_required_version, flags, compression_method, modification_time, this);
- }
-
- file_handle(zip_archive& archive,
- const std::string& path,
- boost::uint16_t creator_version,
- boost::uint16_t minimum_required_version,
- boost::uint16_t flags,
- boost::uint16_t compression_method)
- {
- self = 0;
- archive.open_file(path.data(), path.size(), creator_version, minimum_required_version, flags, compression_method, 0, 0, this);
- }
- ::std::streamsize write(const char* data, ::std::streamsize size) {
- assert(self != 0);
- self->output_file.write(data, size);
- compressed_size += size;
- self->current_offset += size;
- return size;
- }
- void write_uncompressed(const char* data, ::std::streamsize size) {
- assert(self != 0);
- crc.process_bytes(data, static_cast(size));
- uncompressed_size += size;
- }
- void close() {
- central_directory_entry::set_crc32(&self->central_directory[offset], crc.checksum());
- // These lines cause a warning. Since the warning is legitimate,
- // I'm leaving it.
- central_directory_entry::set_compressed_size(&self->central_directory[offset], compressed_size);
- central_directory_entry::set_uncompressed_size(&self->central_directory[offset], uncompressed_size);
-
- boost::array buffer;
- data_descriptor::set_crc32(&buffer[0], crc.checksum());
- data_descriptor::set_compressed_size(&buffer[0], compressed_size);
- data_descriptor::set_uncompressed_size(&buffer[0], uncompressed_size);
- std::streamsize current_pos = self->output_file.tellp();
- self->output_file.seekp(pos);
- self->output_file.write(&buffer[0], 12);
- self->output_file.seekp(current_pos);
- self = 0;
- }
- private:
- friend class zip_archive;
- file_handle(const file_handle&);
- file_handle& operator=(const file_handle&);
-
- boost::crc_32_type crc;
- std::streamsize pos;
- std::size_t offset;
- std::streamsize compressed_size;
- std::streamsize uncompressed_size;
- zip_archive* self;
- };
-
- void open_file(const std::string& path,
- boost::uint16_t creator_version,
- boost::uint16_t minimum_required_version,
- boost::uint16_t flags,
- boost::uint16_t compression_method,
- const boost::posix_time::ptime& modification_time,
- file_handle* out
- )
- {
- boost::uint16_t date =
- modification_time.date().day() +
- (modification_time.date().month() << 5) +
- ((modification_time.date().year() - 1980) << 9);
- boost::uint16_t time =
- (modification_time.time_of_day().seconds() / 2) +
- (modification_time.time_of_day().minutes() << 5) +
- (modification_time.time_of_day().hours() << 11);
- open_file(path.data(), path.size(), creator_version, minimum_required_version, flags, compression_method, time, date, out);
- }
-
- void open_file(const char* path, std::size_t path_size,
- boost::uint16_t creator_version,
- boost::uint16_t minimum_required_version,
- boost::uint16_t flags,
- boost::uint16_t compression_method,
- boost::uint16_t modification_time,
- boost::uint16_t modification_date,
- file_handle* handle
- )
- {
- // The file_handle should not be open
- assert(handle->self == 0);
-
- handle->pos = static_cast(output_file.tellp()) + local_file_header::crc32_offset;
-
- std::vector header(30);
- local_file_header::set_signature(&header[0], local_file_header::signature);
- local_file_header::set_minimum_required_version(&header[0], minimum_required_version);
- local_file_header::set_flags(&header[0], flags);
- local_file_header::set_compression_method(&header[0], compression_method);
-
- local_file_header::set_filename_size(&header[0], path_size);
- // TODO: handle Zip64
- header.insert(header.end(), path, path + path_size);
-
- output_file.write(&header[0], header.size());
-
- std::size_t offset = central_directory.size();
- central_directory.resize(offset + 46);
- central_directory_entry::set_signature(¢ral_directory[offset], central_directory_entry::signature);
- central_directory_entry::set_creator_version(¢ral_directory[offset], creator_version);
- central_directory_entry::set_minimum_required_version(¢ral_directory[offset], minimum_required_version);
- central_directory_entry::set_flags(¢ral_directory[offset], flags);
- central_directory_entry::set_compression_method(¢ral_directory[offset], compression_method);
- central_directory_entry::set_modification_time(¢ral_directory[offset], modification_time);
- central_directory_entry::set_modification_date(¢ral_directory[offset], modification_date);
- central_directory_entry::set_filename_size(¢ral_directory[offset], path_size);
- central_directory_entry::set_extra_size(¢ral_directory[offset], 0);
- central_directory_entry::set_comment_size(¢ral_directory[offset], 0);
- central_directory_entry::set_file_start_disk(¢ral_directory[offset], 0);
- central_directory_entry::set_internal_attributes(¢ral_directory[offset], 0);
- central_directory_entry::set_external_attributes(¢ral_directory[offset], 0);
- central_directory_entry::set_local_header_offset(¢ral_directory[offset], current_offset);
- central_directory.insert(central_directory.end(), path, path + path_size);
-
- handle->crc.reset();
- handle->offset = offset;
- handle->compressed_size = 0;
- handle->uncompressed_size = 0;
- handle->self = this;
-
- current_offset += header.size();
- ++num_files;
- }
-
- void write_file(const std::string& path, const char* contents, std::size_t size) {
- std::vector header(30);
- local_file_header::set_signature(&header[0], local_file_header::signature);
- local_file_header::set_minimum_required_version(&header[0], 10);
- local_file_header::set_flags(&header[0], 0);
- local_file_header::set_compression_method(&header[0], compression_method::none);
-
- crc_32_type crc;
- crc.process_bytes(contents, size);
- local_file_header::set_crc32(&header[0], crc.checksum());
- local_file_header::set_compressed_size(&header[0], size);
- local_file_header::set_uncompressed_size(&header[0], size);
- local_file_header::set_filename_size(&header[0], path.size());
- // TODO: handle Zip64
- header.insert(header.end(), path.begin(), path.end());
-
- output_file.write(&header[0], header.size());
- output_file.write(contents, size);
-
- std::size_t offset = central_directory.size();
- central_directory.resize(offset + 46);
- central_directory_entry::set_signature(¢ral_directory[offset], central_directory_entry::signature);
- central_directory_entry::set_creator_version(¢ral_directory[offset], 10);
- central_directory_entry::set_minimum_required_version(¢ral_directory[offset], 10);
- central_directory_entry::set_flags(¢ral_directory[offset], 0);
- central_directory_entry::set_compression_method(¢ral_directory[offset], compression_method::none);
- // FIXME: find correct date and time
- central_directory_entry::set_modification_time(¢ral_directory[offset], 0);
- central_directory_entry::set_modification_date(¢ral_directory[offset], 0);
- central_directory_entry::set_crc32(¢ral_directory[offset], crc.checksum());
- central_directory_entry::set_compressed_size(¢ral_directory[offset], size);
- central_directory_entry::set_uncompressed_size(¢ral_directory[offset], size);
- central_directory_entry::set_filename_size(¢ral_directory[offset], path.size());
- central_directory_entry::set_extra_size(¢ral_directory[offset], 0);
- central_directory_entry::set_comment_size(¢ral_directory[offset], 0);
- central_directory_entry::set_file_start_disk(¢ral_directory[offset], 0);
- central_directory_entry::set_internal_attributes(¢ral_directory[offset], 0);
- central_directory_entry::set_external_attributes(¢ral_directory[offset], 0);
- central_directory_entry::set_local_header_offset(¢ral_directory[offset], current_offset);
- central_directory.insert(central_directory.end(), path.begin(), path.end());
- current_offset = current_offset + header.size() + size;
-
- ++num_files;
- }
- void close() {
- output_file.write(¢ral_directory[0], central_directory.size());
-
- if(num_files >= 65536) {
- boost::array data;
- zip64_end_of_central_directory::set_signature(&data[0], zip64_end_of_central_directory::signature);
- zip64_end_of_central_directory::set_size(&data[0], zip64_end_of_central_directory::size - 12);
- zip64_end_of_central_directory::set_creator_version(&data[0], 45);
- zip64_end_of_central_directory::set_minimum_required_version(&data[0], 45);
- zip64_end_of_central_directory::set_disk_number(&data[0], 0);
- zip64_end_of_central_directory::set_directory_start_disk(&data[0], 0);
- zip64_end_of_central_directory::set_entries_on_disk(&data[0], num_files);
- zip64_end_of_central_directory::set_total_entries(&data[0], num_files);
- zip64_end_of_central_directory::set_directory_size(&data[0], central_directory.size());
- zip64_end_of_central_directory::set_directory_offset(&data[0], current_offset);
- output_file.write(&data[0], data.size());
-
- boost::array locator;
- zip64_end_of_central_directory_locator::set_signature(&locator[0], zip64_end_of_central_directory_locator::signature);
- zip64_end_of_central_directory_locator::set_end_of_directory_disk(&locator[0], 0);
- zip64_end_of_central_directory_locator::set_end_of_directory_offset(&locator[0], current_offset + central_directory.size());
- zip64_end_of_central_directory_locator::set_total_disks(&locator[0], 1);
- output_file.write(&locator[0], locator.size());
-
- std::vector