[PyObjC-svn] r2482 - in trunk/pyobjc/build-support: . templates virtualenv-src virtualenv3-src
[email protected] Sun, 16 May 2010 16:24:33 -0500
| Newsgroups | gmane.comp.python.pyobjc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: ronaldoussoren
Date: Sun May 16 16:24:33 2010
New Revision: 2482
Log:
* Small tweaks to build_framework
* Run_tests now actually does something useful
The run_test script only runs the 2.6 and 2.7 tests
for now, I once again ran into what seems like distribute and/or 2to3
related issues when testing using python 3.x.
The run_test script generates an HTML file with a report
of the build and test results. This is basicly a summary
with the number of problems for every project and some
coloring to make it easier to check the state of the project
at a glance.
Added:
trunk/pyobjc/build-support/Makefile (contents, props changed)
trunk/pyobjc/build-support/distribute_setup.py (contents, props changed)
trunk/pyobjc/build-support/templates/
trunk/pyobjc/build-support/templates/index.html
Modified:
trunk/pyobjc/build-support/ (props changed)
trunk/pyobjc/build-support/build_frameworks.py
trunk/pyobjc/build-support/run_tests.py
trunk/pyobjc/build-support/virtualenv-src/ (props changed)
trunk/pyobjc/build-support/virtualenv3-src/ (props changed)
Modified: trunk/pyobjc/build-support/build_frameworks.py
==============================================================================
--- trunk/pyobjc/build-support/build_frameworks.py (original)
+++ trunk/pyobjc/build-support/build_frameworks.py Sun May 16 16:24:33 2010
@@ -2,21 +2,44 @@
"""
Script that builds a number of python frameworks as
used by the run_tests.py script
+
+FIXME:
+- Both variants need to be build with simular options
+ to the official builds: 32-bit with SDK 10.4u and deployment
+ target 10.3, 3-way without SDK and depl. target 10.5.
+
+ This will have to wait until my sdkroot patches get committed,
+ without that patch I cannot build the 32-bit variant on
+ SL.
+- get rid of the global variables
"""
-import subprocess, getopt, logging, os, sys, shutil
+import sys
+sys.dont_write_bytecode = True
+
+import subprocess, getopt, logging, os, shutil
from urllib.request import urlopen
+
gUsage="""\
build_frameworks.py [-v versions] [--versions=versions] [-a archs] [--arch archs]
- versions: comma seperated list of python versiosn, defaults to "2.6,2.7,3.1,3.2"
-- archs: comma seperated list of build variations, defaults to "32-bit,intel"
+- archs: comma seperated list of build variations, defaults to "32-bit,3-way"
"""
gBaseDir = os.path.dirname(os.path.abspath(__file__))
-gArchs = ("32-bit", "intel")
+gArchs = ("32-bit", "3-way")
+
+# Name of the Python framework and any additional arguments
+# passed to the configure command.
+gFrameworkNameTemplate="DbgPython-{archs}"
+gExtraConfigureArgs=[
+ "--with-pydebug",
+]
+
+# Location of the SVN branches to be used
gURLMap = {
'2.6': 'http://svn.python.org/projects/python/branches/release26-maint',
'2.7': 'http://svn.python.org/projects/python/trunk',
@@ -26,10 +49,32 @@
}
+# Name of the OSX SDK used to build the framework, keyed of the architecture
+# variant.
+gSdkMap={
+ '32-bit': '/',
+ '3-way': '/',
+}
+
+# Name of the OSX Deployment Target used to build the framework, keyed of
+# the architecture variant.
+gDeploymentTargetMap={
+ #'32-bit': '10.4',
+ '32-bit': '10.5',
+ '3-way': '10.5',
+}
+
+
+
class ShellError (Exception):
+ """ An error occurred while running a shell command """
pass
def create_checkout(version):
+ """
+ Create or update the checkout of the given version
+ of Python.
+ """
lg = logging.getLogger("create_checkout")
lg.info("Create checkout for %s", version)
@@ -56,56 +101,67 @@
raise ShellError(xit)
def build_framework(version, archs):
+ """
+ Build the given version of Python in the given architecture
+ variant.
+
+ This also installs distribute and virtualenv (the latter using
+ a local copy of the package).
+ """
lg = logging.getLogger("build_framework")
lg.info("Build framework version=%r archs=%r", version, archs)
builddir = os.path.join(gBaseDir, "checkouts", version, "build")
-# if os.path.exists(builddir):
-# lg.debug("Remove existing build tree")
-# shutil.rmtree(builddir)
-#
-# lg.debug("Create build tree %r", builddir)
-# os.mkdir(builddir)
-#
-# lg.debug("Running 'configure'")
-# p = subprocess.Popen([
-# "../configure",
-# "--enable-framework",
-# "--with-framework-name=DbgPython-{0}".format(archs),
-# "--enable-universalsdk=/",
-# "--with-universal-archs={0}".format(archs),
-# "--with-pydebug",
-# "MACOSX_DEPLOYMENT_TARGET=10.6",
-# ], cwd=builddir)
-#
-# xit = p.wait()
-# if xit != 0:
-# lg.debug("Configure failed for %s", version)
-# raise ShellError(xit)
-#
-# lg.debug("Running 'make'")
-# p = subprocess.Popen([
-# "make",
-# ], cwd=builddir)
-#
-# xit = p.wait()
-# if xit != 0:
-# lg.debug("Make failed for %s", version)
-# raise ShellError(xit)
-#
-# lg.debug("Running 'make install'")
-# p = subprocess.Popen([
-# "make",
-# "install",
-# ], cwd=builddir)
-#
-# xit = p.wait()
-# if xit != 0:
-# lg.debug("Install failed for %r", version)
-# raise ShellError(xit)
-#
+ if os.path.exists(builddir):
+ lg.debug("Remove existing build tree")
+ shutil.rmtree(builddir)
+
+ lg.debug("Create build tree %r", builddir)
+ os.mkdir(builddir)
+
+ lg.debug("Running 'configure'")
+ p = subprocess.Popen([
+ "../configure",
+ "--enable-framework",
+ "--with-framework-name={0}".format(gFrameworkNameTemplate.format(version=version, archs=archs)),
+ "--enable-universalsdk={0}".format(gSdkMap[archs]),
+ "--with-universal-archs={0}".format(archs),
+ ] + gExtraConfigureArgs + [
+ "MACOSX_DEPLOYMENT_TARGET={0}".format(gDeploymentTargetMap[archs]),
+ ], cwd=builddir)
+
+ xit = p.wait()
+ if xit != 0:
+ lg.debug("Configure failed for %s", version)
+ raise ShellError(xit)
+
+ lg.debug("Running 'make'")
+ p = subprocess.Popen([
+ "make",
+ ], cwd=builddir)
+
+ xit = p.wait()
+ if xit != 0:
+ lg.debug("Make failed for %s", version)
+ raise ShellError(xit)
+
+ lg.debug("Running 'make install'")
+ p = subprocess.Popen([
+ "make",
+ "install",
+ ], cwd=builddir)
+
+ xit = p.wait()
+ if xit != 0:
+ lg.debug("Install failed for %r", version)
+ raise ShellError(xit)
+
+def install_distribute(version, archs):
+ lg = logging.getLogger("install_distribute")
lg.debug("Installing distribute")
+ builddir = os.path.join(gBaseDir, "checkouts", version, "build")
+
lg.debug("Download distribute_setup script")
fd = urlopen("http://python-distribute.org/distribute_setup.py")
data = fd.read()
@@ -116,8 +172,10 @@
fd.write(data)
fd.close()
- python = "/Library/Frameworks/DbgPython-{0}.framework/Versions/{1}/bin/python".format(
- archs, version)
+ frameworkName=gFrameworkNameTemplate.format(archs=archs, version=version)
+
+ python = "/Library/Frameworks/{0}.framework/Versions/{1}/bin/python".format(
+ frameworkName, version)
if version[0] == '3':
python += '3'
@@ -133,16 +191,28 @@
lg.warning("Running 2to3 failed")
raise ShellError(xit)
- lg.debug("Run distribute_setup script")
+ lg.debug("Run distribute_setup script '%s' with '%s'", scriptfn, python)
p = subprocess.Popen([
python,
- scriptfn])
+ scriptfn],
+ cwd=os.path.join(gBaseDir, "checkouts"))
xit = p.wait()
if xit != 0:
lg.warning("Installing 'distribute' failed")
raise ShellError(xit)
- lg.debug("Installing virtualenv")
+
+def install_virtualenv(version, archs):
+ lg = logging.getLogger("install_virtualenv")
+
+ lg.info("Installing virtualenv from local source")
+
+ frameworkName=gFrameworkNameTemplate.format(archs=archs, version=version)
+
+ python = "/Library/Frameworks/{0}.framework/Versions/{1}/bin/python".format(
+ frameworkName, version)
+ if version[0] == '3':
+ python += '3'
# Sadly enough plain virtualenv doens't support
# python3 yet, but there is a fork that does.
@@ -158,10 +228,9 @@
xit = p.wait()
if xit != 0:
- lg.warning("Installing 'distribute' failed")
+ lg.warning("Installing 'virtualenv' failed")
raise ShellError(xit)
- lg.info("Installation of %r done", version)
def main():
logging.basicConfig(level=logging.DEBUG)
@@ -181,6 +250,8 @@
print(gUsage, file=sys.stderr)
sys.exit(1)
+
+
for k, v in opts:
if k in ('-h', '-?', '--help'):
print(gUsage)
@@ -209,12 +280,21 @@
file=sys.stderr)
sys.exit(2)
+ lg = logging.getLogger("build_frameworks")
+ lg.info("Building versions: %s", versions)
+ lg.info("Building architectures: %s", archs)
try:
for version in sorted(versions):
create_checkout(version)
for arch in sorted(archs):
+ lg.info('Building framework for python %s (%s)', version, arch)
build_framework(version, arch)
+ lg.info('Installing distribute for python %s (%s)', version, arch)
+ install_distribute(version, arch)
+ lg.info('Installing virtualenv for python %s (%s)', version, arch)
+ install_virtualenv(version, arch)
+ lg.info('Done python %s (%s)', version, arch)
except ShellError:
sys.exit(1)
Modified: trunk/pyobjc/build-support/run_tests.py
==============================================================================
--- trunk/pyobjc/build-support/run_tests.py (original)
+++ trunk/pyobjc/build-support/run_tests.py Sun May 16 16:24:33 2010
@@ -17,11 +17,28 @@
- there are python frameworks for the various architectures: DbgPython-VARIANT.framework
- those frameworks contain distribute and virtualenv
-(TODO: create script that builds a fresh copy of these frameworks from svn checkouts)
"""
-import getopt, sys, os, shutil, logging, subprocess
+import sys
+sys.dont_write_bytecode = True
+
+import distribute_setup
+distribute_setup.use_setuptools()
+
+import pkg_resources
+# Use Jinja2 for templating because that's the
+# only one that supports Python3 at this time.
+pkg_resources.require('Jinja2')
+
+import getopt, os, shutil, logging, subprocess, time
from topsort import topological_sort
+from jinja2 import Template
+
+gBaseDir = '.'
+gIndexTemplate = os.path.join(gBaseDir, 'templates', 'index.html')
+gTestResults = os.path.join(gBaseDir, "testresults")
+
+
gUsage = """\
run_tests.py [-a archs] [--archs=archs] [-v versions] [--versions,versions]
@@ -31,10 +48,36 @@
gBaseDir = os.path.dirname(os.path.abspath(__file__))
gRootDir = os.path.dirname(gBaseDir)
+gTestResults = os.path.join(gBaseDir, "testresults")
+
+gFrameworkNameTemplate="DbgPython-{archs}"
gVersions=["2.6", "2.7", "3.1", "3.2"]
gArchs=["32-bit", "3-way"]
+gVersions=["2.6", "2.7", ] #"3.2"]
+gArchs=["3-way"]
+
+gArchMap={
+ '3-way': ['ppc', 'i386', 'x86_64'],
+ '32-bit': ['ppc', 'i386'],
+ 'intel': ['i386', 'x86_64'],
+}
+
+# XXX: Temporary workaround for structure of
+# my local work environment.
+gPyObjCCore="pyobjc-core"
+if os.path.exists(os.path.join(gRootDir, "pyobjc-core-py3k")):
+ gPyObjCCore="pyobjc-core-py3k"
+
+
+def supports_arch_command(version):
+ major, minor = map(int, version.split('.'))
+ if major == 2:
+ return minor >= 7
+ else:
+ return minor >= 2
+
def main():
logging.basicConfig(level=logging.DEBUG)
@@ -82,23 +125,9 @@
all_results = []
for ver in versions:
for arch in archs:
- test_results = run_tests(ver, arch)
- all_results.append([ver, arch, test_results])
-
- report_results(all_results)
-
-def report_results(all_results):
- for version, archs, test_results in all_results:
- title = "Architectures {1} for Python {0}".format(version, archs)
- print(title)
- print("="*len(title))
- print()
-
- for pkg, stdout, stderr in test_results:
- summary = stdout.splitlines()[-1]
- print("{0:>20}: {1}".format(pkg, summary))
+ run_tests(ver, arch)
- print()
+ gen_summary(versions, archs)
def detect_frameworks():
@@ -136,24 +165,34 @@
partial_order.append((dep, subdir))
frameworks = topological_sort(frameworks, partial_order)
- return frameworks[:2]
+ return frameworks
def run_tests(version, archs):
- test_results = []
lg = logging.getLogger("run_tests")
lg.info("Run tests for Python %s with archs %s", version, archs)
- subdir = os.path.join(gBaseDir, "virtualenvs", "{0}.{1}".format(version, archs))
+ subdir = os.path.join(gBaseDir, "virtualenvs", "{0}--{1}".format(version, archs))
if os.path.exists(subdir):
lg.debug("Remove existing virtualenv")
shutil.rmtree(subdir)
- base_python = "/Library/Frameworks/DbgPython-{0}.framework/Versions/{1}/bin/python".format(
- archs, version)
+ if not os.path.exists(os.path.dirname(subdir)):
+ os.mkdir(os.path.dirname(subdir))
+
+ resultdir = os.path.join(gTestResults, "{0}--{1}".format(version, archs))
+ if os.path.exists(resultdir):
+ lg.debug("Remove existing results directory")
+ shutil.rmtree(resultdir)
+
+ if not os.path.exists(os.path.dirname(resultdir)):
+ os.mkdir(os.path.dirname(resultdir))
+
+ base_python = "/Library/Frameworks/{0}.framework/Versions/{1}/bin/python".format(
+ gFrameworkNameTemplate.format(archs=archs, version=version), version)
if version[0] == '3':
base_python += '3'
@@ -175,7 +214,7 @@
subdir])
xit = p.wait()
- if p != 0:
+ if xit != 0:
lg.warning("Cannot create virtualenv in %s", subdir)
raise RuntimeError(subdir)
@@ -187,8 +226,14 @@
# There are circular dependencies w.r.t. testing the Cocoa and Quartz wrappers,
# install pyobjc-core, pyobjc-framework-Cocoa and pyobjc-framework-Quartz
# to ensure we avoid those problems.
- for pkg in ["pyobjc-core-py3k", "pyobjc-framework-Cocoa", "pyobjc-framework-Quartz"]:
- pkgroot = os.path.join(gRootDir, pkg)
+ for pkg in ["pyobjc-core", "pyobjc-framework-Cocoa", "pyobjc-framework-Quartz"]:
+ if not os.path.exists(os.path.join(resultdir, pkg)):
+ os.makedirs(os.path.join(resultdir, pkg))
+
+ if pkg == "pyobjc-core":
+ pkgroot = os.path.join(gRootDir, gPyObjCCore)
+ else:
+ pkgroot = os.path.join(gRootDir, pkg)
pkgbuild = os.path.join(pkgroot, "build")
if os.path.exists(pkgbuild):
lg.debug("Remove build directory for %s", pkg)
@@ -198,7 +243,12 @@
p = subprocess.Popen([
os.path.join(subdir, "bin", "python"),
"setup.py", "install"],
- cwd=pkgroot)
+ cwd=pkgroot, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+ stdout, _ = p.communicate()
+
+ with open(os.path.join(resultdir, pkg, "pre-build-stdout.txt"), "wb") as fd:
+ fd.write(stdout)
xit = p.wait()
if xit != 0:
@@ -206,48 +256,86 @@
raise RuntimeError(pkg)
lg.debug("Start testing cycle")
- for pkg in ["pyobjc-core-py3k"] + detect_frameworks():
- pkgroot = os.path.join(gRootDir, pkg)
+ for pkg in ["pyobjc-core"] + detect_frameworks():
+ if not os.path.exists(os.path.join(resultdir, pkg)):
+ os.makedirs(os.path.join(resultdir, pkg))
+
+ if pkg == "pyobjc-core":
+ pkgroot = os.path.join(gRootDir, gPyObjCCore)
+ else:
+ pkgroot = os.path.join(gRootDir, pkg)
+
pkgbuild = os.path.join(pkgroot, "build")
if os.path.exists(pkgbuild):
lg.debug("Remove build directory for %s", pkg)
shutil.rmtree(pkgbuild)
- lg.debug("Build %s for %s", pkg.os.path.basename(subdir))
+ lg.debug("Build %s for %s", pkg, os.path.basename(subdir))
p = subprocess.Popen([
os.path.join(subdir, "bin", "python"),
- "setup.py", "build"],
- cwd=pkgroot)
+ "setup.py", "install"],
+ cwd=pkgroot, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+ stdout, _ = p.communicate()
+ with open(os.path.join(resultdir, pkg, "build-stdout.txt"), "wb") as fd:
+ fd.write(stdout)
xit = p.wait()
if xit != 0:
+ print(stdout)
lg.warning("Build %s failed", pkg)
- raise RuntimeError(pkg)
+ #raise RuntimeError(pkg)
+ continue
# TODO:
# - For python2.7/3.2: use `arch` to run tests with all architectures
# - For python2.6/3.1: run tests using 'python-32' and 'python-64'
# when those are available
- lg.debug("Test %s for %s", pkg.os.path.basename(subdir))
- p = subprocess.Popen([
- os.path.join(subdir, "bin", "python"),
- "setup.py", "test"],
- cwd=pkgroot, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
-
- print("====STDOUT===")
- print(stdout)
- print("====STDERR===")
- print(stderr)
- print("====ENDEND===")
-
- test_results.append((pkg, stdout, stderr))
-
- xit = p.wait()
- if xit != 0:
- lg.warning("Test %s failed", pkg)
- raise RuntimeError(pkg)
+ if supports_arch_command(version):
+ for a in gArchMap[archs]:
+ lg.info("Test %s for %s (%s)", pkg, os.path.basename(subdir), a)
+ p = subprocess.Popen([
+ '/usr/bin/arch', '-' + a,
+ os.path.join(subdir, "bin", "python"),
+ "setup.py", "test"],
+ cwd=pkgroot, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdout, _ = p.communicate()
+
+ with open(os.path.join(resultdir, pkg, "test-stdout-{0}.txt".format(a)), "wb") as fd:
+ fd.write(stdout)
+
+ status = stdout.splitlines()
+ if status[-1].startswith(b'['):
+ status = status[-2]
+ else:
+ status = status[-1]
+ status = status.decode('UTF-8')
+ lg.info("Test %s for %s (%s): %s", pkg, os.path.basename(subdir), a, status)
+
+ xit = p.wait()
+ if xit != 0:
+ lg.warning("Test %s failed", pkg)
+
+ else:
+ lg.debug("Test %s for %s", pkg, os.path.basename(subdir))
+ p = subprocess.Popen([
+ os.path.join(subdir, "bin", "python"),
+ "setup.py", "test"],
+ cwd=pkgroot, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdout, _ = p.communicate()
+
+ with open(os.path.join(resultdir, pkg, "test-stdout.txt"), "wb") as fd:
+ fd.write(stdout)
+
+ status = stdout.splitlines()[-1]
+ lg.info("Test %s for %s: %s", pkg, os.path.basename(subdir), status)
+
+ xit = p.wait()
+ if xit != 0:
+ lg.warning("Test %s failed", pkg)
+ continue
+ #raise RuntimeError(pkg)
lg.debug("Install %s into %s", pkg, os.path.basename(subdir))
@@ -262,7 +350,171 @@
raise RuntimeError(pkg)
- return test_results
+
+def parse_tests(inputfile):
+ result = {
+ 'test_pass': 0,
+ 'test_fail': 0,
+ 'test_error': 0,
+ }
+ with open(inputfile) as stream:
+ for ln in stream:
+ ln = ln.rstrip()
+ if ln.endswith('... ok'):
+ result['test_pass'] += 1
+ elif ln.endswith('... FAIL'):
+ result['test_fail'] += 1
+ elif ln.endswith('... ERROR'):
+ result['test_error'] += 1
+
+ result['class_pass'] = ''
+ result['class_fail'] = ''
+ result['class_error'] = ''
+ if result['test_pass'] == 0 \
+ and result['test_fail'] == 0 \
+ and result['test_error'] == 0:
+ result['class_pass'] = 'error'
+ if result['test_fail']:
+ result['class_fail'] = 'warning'
+ if result['test_error']:
+ result['class_error'] = 'error'
+
+ if result['test_error'] + result['test_fail'] == 0:
+ result['class_pass'] = 'ok'
+
+ return result
+
+def parse_build(inputfile):
+ result = {
+ 'build_warnings': 0,
+ 'build_errors': 0,
+ }
+ with open(inputfile) as stream:
+ for ln in stream:
+ if 'error:' in ln:
+ result['build_errors'] += 1
+
+ elif 'warning:' in ln:
+ result['build_warnings'] += 1
+
+ result['class_warnings'] = ''
+ result['class_errors'] = ''
+ if result['build_warnings']:
+ result['class_warnings'] = 'warning'
+ if result['build_errors']:
+ result['class_errors'] = 'error'
+
+ if result['build_warnings'] + result['build_errors'] == 0:
+ result['class_warnings'] = 'ok'
+ result['class_errors'] = 'ok'
+
+ return result
+
+def get_svnversion():
+ p = subprocess.Popen([
+ 'svnversion',
+ ], cwd='..', stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ xit = p.wait()
+ if xit != 0:
+ raise RuntimeError(xit)
+
+ return stdout.decode('UTF-8')
+
+def get_svnurl():
+ p = subprocess.Popen([
+ 'svn', 'info', '.'
+ ], cwd='..', stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ xit = p.wait()
+ if xit != 0:
+ raise RuntimeError(xit)
+
+ for ln in stdout.splitlines():
+ if ln.startswith(b'URL'):
+ return ln.split(None, 1)[1].decode('UTF-8')
+
+def get_osx_version():
+ p = subprocess.Popen([
+ 'sw_vers',
+ ], cwd='..', stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ xit = p.wait()
+ if xit != 0:
+ raise RuntimeError(xit)
+
+ r = {}
+ for ln in stdout.splitlines():
+ k, v = ln.decode('UTF-8').split(':', 1)
+ r[k.strip()] = v.strip()
+
+ return "{ProductName} {ProductVersion} ({BuildVersion})".format(**r)
+
+def gen_summary(versions, archs):
+ with open(gIndexTemplate) as fp:
+ tmpl = Template(fp.read())
+
+ svn={}
+ svn['revision'] = get_svnversion()
+ svn['url'] = get_svnurl()
+
+ osx={}
+ osx['version'] = get_osx_version()
+
+ versions = {}
+
+ for subdir in os.listdir(gTestResults):
+ if subdir == 'index.html': continue
+ version, style = subdir.split('--')
+
+ if version not in versions: continue
+ if style not in archs: continue
+
+ versions[(version, style)] = modules = []
+
+ for mod in os.listdir(os.path.join(gTestResults, subdir)):
+ moddir = os.path.join(gTestResults, subdir, mod)
+ info = parse_build(os.path.join(moddir, 'build-stdout.txt'))
+ info['name'] = mod
+ modules.append(info)
+ info['archs'] = []
+ info['class'] = None
+
+ if info['build_errors']:
+ info['class'] = 'error'
+ #elif info['build_warnings']:
+ #info['class'] = 'warning'
+
+ for fn in os.listdir(moddir):
+ if not fn.startswith('test'): continue
+
+ if fn == 'test-stdout.txt':
+ a = 'all'
+
+ else:
+ a = fn.split('-')[-1].split('.')[0]
+
+ info['archs'].append(a)
+ info[a] = parse_tests(os.path.join(moddir, fn))
+
+ if info[a]['test_fail'] and (info['class'] is None):
+ info['class'] = 'warning'
+
+ if info[a]['test_error']:
+ info['class'] = 'error'
+
+
+ if info['class'] is None:
+ info['class'] = 'ok'
+
+ with open(os.path.join(gTestResults, 'index.html'), 'w') as fp:
+ fp.write(tmpl.render(
+ svn=svn,
+ osx=osx,
+ versions=versions,
+ sorted=sorted,
+ timestamp=time.ctime(),
+ ))
if __name__ == "__main__":
try:
------------------------------------------------------------------------------