a.af = af
a.ah = arghandling
a.what = what
+ a.missing_tests_control = False
def __repr__(a):
return "<Action %s %s %s>" % (a.kind, a.what, `a.af`)
tb.scratch = None
if tb.sp is None: return
tb.command('close')
- def prepare(tb, deps_new):
- tb._debug('prepare, modified=%s, deps_processed=%s, deps_new=%s' %
+ def prepare1(tb, deps_new):
+ tb._debug('prepare1, modified=%s, deps_processed=%s, deps_new=%s' %
(tb.modified, tb.deps_processed, deps_new), 1)
if 'revert' in tb.caps and (tb.modified or
[d for d in tb.deps_processed if d not in deps_new]):
tb.command('revert')
tb.blamed = []
for af in tb._ephemeral: af.invalidate(True)
- binaries.publish()
tb.modified = False
+ def prepare2(tb, deps_new):
+ tb._debug('prepare2, deps_new=%s' % deps_new, 1)
+ binaries.publish()
tb._install_deps(deps_new)
+ def prepare(tb, deps_new):
+ tb.prepare1(deps_new)
+ tb.prepare2(deps_new)
def register_ephemeral(tb, af):
if not getattr(af,'spec_tbp',False): tb._ephemeral.append(af)
def _install_deps(tb, deps_new):
return rl[0]
def execute(tb, what, cmdl,
si='/dev/null', so='/dev/null', se=None, cwd=None,
- script=False):
+ script=False, tmpdir=None):
# Options for script:
# False - do not call debug_subprocess, no synch. reporting required
# None or string - call debug_subprocess with that value,
cmdl = [None,
','.join(map(urllib.quote, cmdl)),
si, so, se_use, cwd]
+
if xdump is not None and 'execute-debug' in tb.caps: cmdl += [xdump]
+ if tmpdir is not None: cmdl.append('env=TMPDIR=%s' % tmpdir)
+
rc = tb.commandr1('execute', cmdl)
try: rc = int(rc)
except ValueError: bomb("execute for %s gave invalid response `%s'"
except KeyError: raise Unsupported(lno,
'unknown restriction %s' % rname)
r = rclass(nrname, f.base)
+ f.base['restriction_names'].append(rname)
f.base['restrictions'].append(r)
+class Field_Features(FieldIgnore):
+ def parse(f):
+ for wle in f.words():
+ (lno, fname) = wle
+ f.base['feature_names'].append(fname)
+ nfname = fname.replace('-','_')
+ try: fclass = globals()['Feature_'+nfname]
+ except KeyError: continue
+ ft = fclass(nfname, f.base)
+ f.base['features'].append(ft)
+
class Field_Tests(FieldIgnore): pass
-class Field_Features(FieldIgnore): pass
class Field_Depends(FieldBase):
def parse(f):
print >>sys.stderr, "Field_Depends:", `f.stz`, `f.base`, `f.tnames`, `f.vl`
dl = map(lambda x: x.strip(),
flatten(map(lambda (lno, v): v.split(','), f.vl)))
- re = regexp.compile('[^-.+:~0-9a-z()<>=*]')
+ re = regexp.compile('[^-.+:~0-9a-z()<>=*@]')
for d in dl:
if re.search(d):
badpkg("Test Depends field contains dependency"
def run_tests(stanzas, tree):
global errorcode, testbed
+ if stanzas == ():
+ report('*', 'SKIP no tests in this package')
for stanza in stanzas:
tests = stanza[' tests']
if not tests:
- report('*', 'SKIP no tests in this package')
+ report('*', 'SKIP package has metadata but no tests')
errorcode |= 8
for t in tests:
t.prepare()
af = RelativeInputFile(t.what, tree, t.path)
so = stdouterr('stdout')
se = stdouterr('stderr')
+
tf = af.read(True)
+ tmpdir = None
+
if 'needs-root' not in t.restrictions:
tf = opts.user_wrap(tf)
+ tmpdir = '%s/%s-tmpdir' % (testbed.scratch.read(True), t.what)
+ script = 'rm -rf -- "$1"; mkdir -- "$1"'
+ if opts.user: script += '; chown %s "$1"' % opts.user
+ rc = testbed.execute('mktmpdir-'+t.what,
+ ['sh','-xec',script,'x',tmpdir])
+ if rc: bomb("could not create test tmpdir `%s', exit code %d"
+ % (tmpdir, rc))
+
rc = testbed.execute('test-'+t.what, [tf],
- so=so.write(True), se=se.write(True), cwd=tree.read(True))
+ so=so.write(True), se=se.write(True), cwd=tree.read(True),
+ tmpdir=tmpdir)
so_read = so.read()
se_read = se.read()
control_af = control_override
testbed.blame('arg:'+control_override.spec)
else:
+ if act.missing_tests_control:
+ return ()
control_af = RelativeInputFile(act.what+'-testcontrol',
tree, 'debian/tests/control')
try:
tnames = map((lambda lt: lt[1]), tnames)
tnames = string.join(tnames).split()
base = {
+ 'restriction_names': [],
'restrictions': [],
+ 'feature_names': [],
+ 'features': [],
'testsdir': 'debian/tests',
'depends' : '@'
}
rc = testbed.execute('%s-%s' % (what,which),
['sh','-ec',script]+xargs, script=script,
so=so.write(True), cwd=cwd)
- results = open(so.read()).read().rstrip('\n').split("\n")
+ results = open(so.read()).read().rstrip('\n')
+ if len(results): results = results.split("\n")
+ else: results = []
if rc: badpkg("%s failed with exit code %d" % (which,rc))
if results_lines is not None and len(results) != results_lines:
badpkg("got %d lines of results from %s where %d expected"
if results_lines==1: return results[0]
return results
-def build_source(act):
+def build_source(act, control_override):
act.blame = 'arg:'+act.af.spec
testbed.blame(act.blame)
+ testbed.prepare1([])
testbed.needs_reset()
what = act.what
basename = act.af.spec
+ debiancontrol = None
+ act.binaries = []
+
+ def debug_b(m): debug('* <%s:%s> %s' % (act.kind, act.what, m))
if act.kind == 'dsc':
dsc = act.af
print >>dsc_w, 'Binary: none-so-this-is-not-a-package-name'
dsc_w.close()
+ if act.kind == 'dsc':
+ testbed.prepare2([])
+ script = binaries.apt_pkg_gdebi_script('', [[
+ 'from GDebi.DebPackage import DebPackage',
+ 'd = DebPackage(cache)',
+ 'res = d.satisfyDependsStr("dpkg-source")',
+ ]])
+ cmdl = ['python','-c',script]
+ whatp = what+'-dpkgsource'
+ rc = testbed.execute(what, cmdl, script=script)
+ if rc: badpkg('dpkg-source install failed, exit code %d' % rc)
+
work = TemporaryDir(what+'-build')
+ act.work = work
- script = [
- 'spec="$1"',
- 'origpwd=`pwd`',
- 'cd '+work.write(True)
- ]
+ tmpdir = work.write(True)+'/tmpdir'
+ tmpdir_script = [
+ 'TMPDIR="$1"',
+ 'rm -rf -- "$TMPDIR"',
+ 'export TMPDIR',
+ opts.user_wrap('mkdir -- "$TMPDIR"'),
+ ]
if act.kind == 'ubtree':
spec = '%s/real-tree' % work.write(True)
'''
initcwd = work.write(True)
- if opts.user: script += [
- 'chown '+opts.user+' .',
- 'spec="$spec" origpwd="$origpwd" '+opts.user_wrap(create_command)
- ]
- else: script += [
- create_command
- ]
+ script = [
+ 'spec="$2"',
+ 'origpwd=`pwd`',
+ 'cd '+work.write(True)
+ ]
+
+ if opts.user:
+ script += ([ 'chown '+opts.user+' .' ] +
+ tmpdir_script +
+ [ 'spec="$spec" origpwd="$origpwd" '
+ +opts.user_wrap(create_command) ])
+ else:
+ script += (tmpdir_script +
+ [ create_command ])
script += [
'cd */.',
'pwd >&3',
+ 'set +e; test -f debian/tests/control; echo $? >&3'
]
- result_pwd = source_rules_command(act,script,what,'extract',work,
- cwd=initcwd, results_lines=1, xargs=['x',spec])
+ (result_pwd, control_test_rc) = source_rules_command(
+ act,script,what,'extract',work,
+ cwd=initcwd, results_lines=2, xargs=['x',tmpdir,spec])
- script = binaries.apt_pkg_gdebi_script(
- dsc.read(True), [[
- 'from GDebi.DscSrcPackage import DscSrcPackage',
- 'd = DscSrcPackage(cache, arg)',
- 'res = d.checkDeb()',
- ],[
- 'from GDebi.DebPackage import DebPackage',
- 'd = DebPackage(cache)',
- 'res = d.satisfyDependsStr("build-essential")',
- ]])
+ filter = act.ah['dsc_filter']
- cmdl = ['python','-c',script]
- whatp = what+'-builddeps'
- rc = testbed.execute(what, cmdl, script=script)
- if rc: badpkg('build-depends install failed, exit code %d' % rc)
+ if control_test_rc == '1': act.missing_tests_control = True
- script = [
- 'cd "$1"',
+ # For optional builds:
+ #
+ # We might need to build the package because:
+ # - we want its binaries (filter isn't _ and at least one of the
+ # deb_... isn't ignore)
+ # - the test control file says so
+ # (assuming we have any tests)
+
+ class NeedBuildException: pass
+ def build_needed(m):
+ debug_b('build needed for %s' % m)
+ raise NeedBuildException()
+
+ try:
+ if filter != '_' and (act.ah['deb_forbuilds'] != 'ignore' or
+ act.ah['deb_fortests'] != 'ignore'):
+ build_needed('binaries')
+
+ result_pwd_af = InputDir(what+'-treeforcontrol',
+ result_pwd, True)
+ stanzas = read_control(act, result_pwd_af, control_override)
+ for stanza in stanzas:
+ for t in stanza[' tests']:
+ if 'no-build-needed' not in t.feature_names:
+ build_needed('test %s' % t.name)
+ for d in t.depends:
+ if '@' in d:
+ build_needed('test %s '
+ 'dependency %s' % (t.name,d))
+
+ debug_b('build not needed')
+ built = False
+
+ except NeedBuildException:
+
+ if act.kind != 'dsc':
+ testbed.prepare2([])
+
+ script = binaries.apt_pkg_gdebi_script(
+ dsc.read(True), [[
+ 'from GDebi.DscSrcPackage import DscSrcPackage',
+ 'd = DscSrcPackage(cache, arg)',
+ 'res = d.checkDeb()',
+ ],[
+ 'from GDebi.DebPackage import DebPackage',
+ 'd = DebPackage(cache)',
+ 'res = d.satisfyDependsStr("build-essential")',
+ ]])
+
+ cmdl = ['python','-c',script]
+ whatp = what+'-builddeps'
+ rc = testbed.execute(what, cmdl, script=script)
+ if rc: badpkg('build-depends install failed,'
+ ' exit code %d' % rc)
+
+ script = tmpdir_script + [
+ 'cd "$2"',
'dpkg-checkbuilddeps',
opts.user_wrap('debian/rules build'),
- ]
- source_rules_command(act,script,what,'build',work,
- cwd=initcwd, xargs=['x',result_pwd])
+ ]
+ source_rules_command(act,script,what,'build',work,
+ cwd=initcwd, xargs=['x',tmpdir,result_pwd])
- if os.path.dirname(result_pwd)+'/' != work.read(True):
- badpkg("results dir `%s' is not in expected parent dir `%s'"
- % (result_pwd, work.read(True)))
+ if os.path.dirname(result_pwd)+'/' != work.read(True):
+ badpkg("results dir `%s' is not in expected parent"
+ " dir `%s'" % (result_pwd, work.read(True)))
+
+ built = True
- act.work = work
act.tests_tree = InputDir(what+'-tests-tree',
work.read(True)+os.path.basename(result_pwd),
True)
testbed.register_ephemeral(act.work)
testbed.register_ephemeral(act.tests_tree)
+ if not built: return
+
act.blamed = copy.copy(testbed.blamed)
- def debug_b(m): debug('* <%s:%s> %s' % (act.kind, act.what, m))
- act.binaries = []
- filter = act.ah['dsc_filter']
debug_b('filter=%s' % filter)
if filter != '_':
- script = [
+ script = tmpdir_script + [
'cd '+work.write(True)+'/*/.',
opts.user_wrap(opts.gainroot+' debian/rules binary'),
'cd ..',
'echo *.deb >&3',
]
result_debs = source_rules_command(act,script,what,
- 'binary',work,work.write(True),results_lines=1)
+ 'binary',work,work.write(True),
+ results_lines=1, xargs=['x',tmpdir])
if result_debs == '*': debs = []
else: debs = result_debs.split(' ')
debug_b('debs='+`debs`)
testbed.register_ephemeral(act.af)
binaries.reset()
+ control_override = None
debug_a1('builds ...')
for act in opts.actions:
debug_a2('%s %s' %
(act.kind, act.what))
- testbed.prepare([])
+ if act.kind == 'control':
+ control_override = act.af
if act.kind == 'deb':
testbed.blame('arg:'+act.af.spec)
determine_package(act)
binaries.register(act,act.pkg,act.af,
'forbuilds',testbed.blamed)
if act.kind == 'dsc' or act.kind == 'ubtree':
- build_source(act)
+ build_source(act, control_override)
if act.kind == 'tree':
act.binaries = []
+ if act.kind.endswith('tree') or act.kind == 'dsc':
+ control_override = None
debug_a1('builds done.')