r2205 - in zope.testrunner/trunk/debian (2 files)
jinty-guest at users.alioth.debian.org
jinty-guest at users.alioth.debian.org
Sat Apr 30 17:00:07 UTC 2011
Date: Saturday, April 30, 2011 @ 16:59:59
Author: jinty-guest
Revision: 2205
A very hacky script to run tests from debian/test/control in virtual machines.
Added:
zope.testrunner/trunk/debian/test_one_package_in_throwaway_vm.py
Modified:
zope.testrunner/trunk/debian/python3-zope.testrunner.install
Modified: zope.testrunner/trunk/debian/python3-zope.testrunner.install
===================================================================
--- zope.testrunner/trunk/debian/python3-zope.testrunner.install 2011-04-30 16:57:46 UTC (rev 2204)
+++ zope.testrunner/trunk/debian/python3-zope.testrunner.install 2011-04-30 16:59:59 UTC (rev 2205)
@@ -1 +1,2 @@
debian/test_helper_3 usr/share/python3-zope.testrunner
+debian/test_one_package_in_throwaway_vm.py usr/share/python3-zope.testrunner
Added: zope.testrunner/trunk/debian/test_one_package_in_throwaway_vm.py
===================================================================
--- zope.testrunner/trunk/debian/test_one_package_in_throwaway_vm.py (rev 0)
+++ zope.testrunner/trunk/debian/test_one_package_in_throwaway_vm.py 2011-04-30 16:59:59 UTC (rev 2205)
@@ -0,0 +1,171 @@
+#!/usr/bin/python3
+"""A very quick and dirty script to test a package using the debian/test/control file in a throw away VM.
+
+This script needs to run as root and installs a lot of packages arbitrarily. If
+it breaks the installation it's run on, you get to keep both pieces.
+
+Usage:
+
+ test_one_package_in_throwaway_vm.py zope.interface
+ (apt-get source zope.interface, unpack and test)
+"""
+
+import shutil
+import tempfile
+import os
+import stat
+import sys
+import unittest
+import logging
+import subprocess
+
+class Dependency(object):
+
+ def __init__(self, package):
+ self.package = package
+
+class _Test(unittest.TestCase):
+
+ def __init__(self, tests_dir, name, restrictions=frozenset(), features=frozenset(), depends=(), parse_context=None):
+ unittest.TestCase.__init__(self, methodName='runTest')
+ self._name = name
+ self._restrictions = restrictions
+ self._features = features
+ self._depends = depends
+ self._tests_dir = tests_dir
+ if parse_context is None:
+ parse_context = {}
+ self._parse_context = parse_context
+
+ def assertDependencies(self):
+ """Install dependencies/check if they are installed or error"""
+ for d in self._depends:
+ logging.info("Installing: %s", d.package)
+ subprocess.check_call(['apt-get', '--force-yes', '-y', 'install', d.package])
+
+ def runTest(self):
+ self.assertDependencies()
+ logging.info("RUNNING %s", self._name)
+ binary = os.path.join(self._tests_dir, self._name)
+ binary = os.path.abspath(binary)
+ subprocess.check_call(['/bin/chmod', 'a+x', binary])
+ tmpdir = tempfile.mkdtemp()
+ try:
+ env = {'TMPDIR': tmpdir}
+ env.update(os.environ) # ???
+ p = subprocess.Popen(['sudo', '-u', 'nobody', binary],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=env)
+ stdout, stderr = p.communicate()
+ finally:
+ shutil.rmtree(tmpdir)
+ msg = ""
+ if stdout:
+ msg = msg + "Test Printed:\n\n%s\n" % stdout.decode('utf-8')
+ if stderr:
+ msg = msg + "Test Printed to stderr:\n\n%s\n" % stderr.decode('utf-8')
+ self.assertFalse(stderr, msg)
+ if p.returncode != 0:
+ logging.error(msg)
+ self.assertEquals(p.returncode, 0)
+
+class Parser(object):
+
+ def __init__(self):
+ self.tests = []
+
+ def _add_test(self, stanza, filename, lineno):
+ pc = dict(filename=filename, lineno=lineno)
+ tests = stanza.pop('tests')
+ tests_dir = stanza.pop('tests_dir', 'debian/tests')
+ if 'depends' not in stanza:
+ stanza['depends'] = tuple(self._normalize_dep('@'))
+ for test in tests:
+ self.tests.append(_Test(tests_dir, test, parse_context=pc, **stanza))
+
+ def _normalize_dep(self, dep):
+ dep = dep.strip()
+ assert ' ' not in dep, dep
+ assert dep, dep
+ if dep != '@':
+ return [Dependency(dep)]
+ deps = []
+ data = open('debian/control', 'r').read()
+ for line in data.splitlines():
+ if not line.startswith("Package:"):
+ continue
+ line = line[8:].strip()
+ deps.append(Dependency(line))
+ return deps
+
+ def parse(self):
+ filename = 'debian/tests/control'
+ data = open(filename, 'r').read()
+ stanza = {}
+ skipping = False
+ startline = 1
+ for lineno, line in enumerate(data.splitlines()):
+ if not line:
+ if skipping:
+ skipping = False
+ stanza = {}
+ startline = lineno + 1
+ continue
+ if stanza:
+ self._add_test(stanza, filename, startline)
+ stanza = {}
+ startline = lineno + 1
+ elif skipping:
+ continue
+ elif line.startswith("Tests:"):
+ line = line[6:].strip()
+ stanza['tests'] = frozenset(line.split())
+ elif line.startswith("Depends:"):
+ line = line[8:].strip()
+ deps = []
+ for d in line.split(','):
+ deps.extend(self._normalize_dep(d))
+ stanza['depends'] = tuple(deps)
+ elif line.startswith("Features:"):
+ line = line[9:].strip()
+ stanza['features'] = features= frozenset(line.split())
+ elif line.startswith("Restrictions:"):
+ line = line[13:].strip()
+ stanza['restrictions'] = restrictions = frozenset(line.split())
+ elif line.startswith("Tests-Directory:"):
+ line = line[16:].strip()
+ stanza['tests_dir'] = frozenset(line.split())
+ else:
+ logging.warn("Skipped stanza due to unknown field: %s: %s" % (lineno, line))
+ skipping = True
+ if stanza and not skipping:
+ # catch last parsed stanza
+ self._add_test(stanza, filename, startline)
+
+if __name__ == '__main__':
+ logging.basicConfig(level=logging.INFO)
+ logging.info("Updating")
+ subprocess.check_call(['apt-get', 'install', 'sudo'])
+ subprocess.check_call(['apt-get', 'update'])
+ mytemp = tempfile.mkdtemp()
+ subprocess.check_call(['/bin/chmod', 'a+rx', mytemp])
+ os.chdir(mytemp)
+ logging.info("Getting and un-packing source")
+ subprocess.check_call(['apt-get', 'source', sys.argv[1]])
+ for d in os.listdir(mytemp):
+ sourcedir = os.path.join(mytemp, d)
+ if os.path.isdir(sourcedir):
+ break
+ else:
+ raise Exception("Could not find unpacked source in %s" % mytemp)
+ os.chdir(sourcedir)
+ logging.info("Running tests from %s" % sourcedir)
+ p = Parser()
+ p.parse()
+ suite = unittest.TestSuite(tests=p.tests)
+ runner = unittest.TextTestRunner()
+ result = runner.run(suite)
+ logging.info("Tests were run in %s" % sourcedir)
+ sys.exit(not result.wasSuccessful())
Property changes on: zope.testrunner/trunk/debian/test_one_package_in_throwaway_vm.py
___________________________________________________________________
Added: svn:eol-style
+ native
More information about the pkg-zope-developers
mailing list