diff --git a/run-autopkgtest b/run-autopkgtest new file mode 100755 index 0000000..2c0c95f --- /dev/null +++ b/run-autopkgtest @@ -0,0 +1,141 @@ +#!/usr/bin/python3 +# Request re-runs of autopkgtests for packages + +import os +import sys +import argparse +import json +import urllib.parse + +import amqplib.client_0_8 as amqp + +my_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + + +def parse_args(): + '''Parse command line arguments''' + + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', + help='britney config file (default: britney.conf.ubuntu.)') + parser.add_argument('-s', '--series', required=True, + help='Distro series name (required).') + parser.add_argument('-a', '--architecture', action='append', default=[], + help='Only run test(s) on given architecture name(s). ' + 'Can be specified multiple times (default: all).') + parser.add_argument('--trigger', action='append', default=[], + metavar='SOURCE/VERSION', + help='Add triggering package to request. ' + 'Can be specified multiple times.') + parser.add_argument('--ppa', metavar='LPUSER/PPANAME', action='append', + default=[], + help='Enable PPA for requested test(s). ' + 'Can be specified multiple times.') + parser.add_argument('--env', metavar='KEY=VALUE', action='append', + default=[], + help='List of VAR=value strings. ' + 'This can be used to influence a test\'s behaviour ' + 'from a test request. ' + 'Can be specified multiple times.') + parser.add_argument('--test-git', + metavar='URL [branchname]', + help='A single URL or URL branchname. ' + 'The test will be git cloned from that URL and ran ' + 'from the checkout. This will not build binary ' + 'packages from the branch and run tests against ' + 'those, the test dependencies will be taken from the ' + 'archive, or PPA if given. In this case the ' + 'srcpkgname will only be used for the result path in ' + 'swift and be irrelevant for the actual test.') + parser.add_argument('--build-git', + metavar='URL [branchname]', + help='A single URL or URL branchname. ' + 'Like --test-git`, but will first build binary ' + 'packages from the branch and run tests against those.') + parser.add_argument('--test-bzr', + help='A single URL. ' + 'The test will be checked out with bzr from that URL. ' + 'Otherwise this has the same behaviour as test-git.') + parser.add_argument('--all-proposed', action='store_true', + help='Disable apt pinning and use all of -proposed') + parser.add_argument('package', nargs='+', + help='Source package name(s) whose tests to run.') + args = parser.parse_args() + + if not args.trigger and not args.ppa: + parser.error('One of --trigger or --ppa must be given') + + # verify syntax of triggers + for t in args.trigger: + try: + (src, ver) = t.split('/') + except ValueError: + parser.error('Invalid trigger format "%s", must be "sourcepkg/version"' % t) + + # verify syntax of PPAs + for t in args.ppa: + try: + (user, name) = t.split('/') + except ValueError: + parser.error('Invalid ppa format "%s", must be "lpuser/ppaname"' % t) + + return args + + +def parse_config(config_file): + '''Parse config file (like britney.py)''' + + config = argparse.Namespace() + with open(config_file) as f: + for k, v in [r.split('=', 1) for r in f if '=' in r and not r.strip().startswith('#')]: + k = k.strip() + if not getattr(config, k.lower(), None): + setattr(config, k.lower(), v.strip()) + return config + + +if __name__ == '__main__': + args = parse_args() + britney_conf = os.path.join(my_dir, 'britney.conf') + if args.config: + config = parse_config(args.config) + elif os.path.exists(britney_conf + '.ubuntu.' + args.series): + config = parse_config(britney_conf + '.ubuntu.' + args.series) + else: + config = parse_config(britney_conf) + if not args.architecture: + args.architecture = config.adt_arches.split() + + context = '' + params = {} + if args.trigger: + params['triggers'] = args.trigger + if args.ppa: + params['ppas'] = args.ppa + context = 'ppa-' + if args.env: + params['env'] = args.env + if args.test_git: + params['test-git'] = args.test_git + context = 'upstream-' + elif args.build_git: + params['build-git'] = args.build_git + context = 'upstream-' + if args.test_bzr: + params['test-bzr'] = args.test_bzr + context = 'upstream-' + if args.all_proposed: + params['all-proposed'] = True + params = '\n' + json.dumps(params) + + creds = urllib.parse.urlsplit(config.adt_amqp, allow_fragments=False) + assert creds.scheme == 'amqp' + + with amqp.Connection(creds.hostname, userid=creds.username, + password=creds.password) as amqp_con: + with amqp_con.channel() as ch: + for arch in args.architecture: + queue = 'debci-%s%s-%s' % (context, args.series, arch) + for pkg in args.package: + ch.basic_publish(amqp.Message(pkg + params), + routing_key=queue)