diff --git a/boottest.py b/boottest.py
deleted file mode 100644
index d402655..0000000
--- a/boottest.py
+++ /dev/null
@@ -1,293 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2015 Canonical Ltd.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-
-from collections import defaultdict
-from contextlib import closing
-import os
-import subprocess
-import tempfile
-from textwrap import dedent
-import time
-import urllib.request
-
-import apt_pkg
-
-from consts import BINARIES
-
-
-FETCH_RETRIES = 3
-
-
-class TouchManifest(object):
- """Parses a corresponding touch image manifest.
-
- Based on http://cdimage.u.c/ubuntu-touch/daily-preinstalled/pending/vivid-preinstalled-touch-armhf.manifest
-
- Assumes the deployment is arranged in a way the manifest is available
- and fresh on:
-
- '{britney_cwd}/boottest/images/{distribution}/{series}/manifest'
-
- Only binary name matters, version is ignored, so callsites can:
-
- >>> manifest = TouchManifest('ubuntu-touch', 'vivid')
- >>> 'webbrowser-app' in manifest
- True
- >>> 'firefox' in manifest
- False
-
- """
-
- def __init__(self, project, series, verbose=False, fetch=True):
- self.verbose = verbose
- self.path = "boottest/images/{}/{}/manifest".format(
- project, series)
- success = False
- if fetch:
- retries = FETCH_RETRIES
- success = self.__fetch_manifest(project, series)
-
- while retries > 0 and not success:
- success = self.__fetch_manifest(project, series)
- retries -= 1
- if not success:
- print("E: [%s] - Unable to fetch manifest: %s %s" % (
- time.asctime(), project, series))
-
- self._manifest = self._load()
-
- def __fetch_manifest(self, project, series):
- # There are two url formats that may lead to the proper manifest
- # file. The first form is for series that have been released,
- # the second form is for the current development series.
- # Only one of these is expected to exist for any given series.
- url_list = [
- "http://cdimage.ubuntu.com/{}/{}/daily-preinstalled/pending/" \
- "{}-preinstalled-touch-armhf.manifest".format(
- project, series, series),
- "http://cdimage.ubuntu.com/{}/daily-preinstalled/pending/" \
- "{}-preinstalled-touch-armhf.manifest".format(
- project, series),
- ]
-
- success = False
- for url in url_list:
- if self.verbose:
- print("I: [%s] - Fetching manifest from %s" %
- (time.asctime(), url))
- print("I: [%s] - saving it to %s" %
- (time.asctime(), self.path))
- try:
- response = urllib.request.urlopen(url)
- if response.code == 200:
- # Only [re]create the manifest file if one was successfully
- # downloaded. This allows for an existing image to be used
- # if the download fails.
- path_dir = os.path.dirname(self.path)
- if not os.path.exists(path_dir):
- os.makedirs(path_dir)
- with open(self.path, 'wb') as fp:
- fp.write(response.read())
- success = True
- break
-
- except IOError as e:
- print("W: [%s] - error connecting to %s: %s" % (
- time.asctime(), self.path, e))
-
- return success
-
- def _load(self):
- pkg_list = []
-
- if not os.path.exists(self.path):
- return pkg_list
-
- with open(self.path) as fd:
- for line in fd.readlines():
- # skip headers and metadata
- if 'DOCTYPE' in line:
- continue
- name, version = line.split()
- name = name.split(':')[0]
- if name == 'click':
- continue
- pkg_list.append(name)
-
- return sorted(pkg_list)
-
- def __contains__(self, key):
- return key in self._manifest
-
-
-class BootTest(object):
- """Boottest criteria for Britney.
-
- This class provides an API for handling the boottest-jenkins
- integration layer (mostly derived from auto-package-testing/adt):
- """
- VALID_STATUSES = ('PASS',)
-
- EXCUSE_LABELS = {
- "PASS": 'Pass',
- "FAIL": 'Regression',
- "RUNNING": 'Test in progress',
- }
-
- script_path = os.path.expanduser(
- "~/auto-package-testing/jenkins/boottest-britney")
-
- def __init__(self, britney, distribution, series, debug=False):
- self.britney = britney
- self.distribution = distribution
- self.series = series
- self.debug = debug
- self.rc_path = None
- self._read()
- manifest_fetch = getattr(
- self.britney.options, "boottest_fetch", "no") == "yes"
- self.phone_manifest = TouchManifest(
- 'ubuntu-touch', self.series, fetch=manifest_fetch,
- verbose=self.britney.options.verbose)
-
- @property
- def _request_path(self):
- return "boottest/work/adt.request.%s" % self.series
-
- @property
- def _result_path(self):
- return "boottest/work/adt.result.%s" % self.series
-
- def _ensure_rc_file(self):
- if self.rc_path:
- return
- self.rc_path = os.path.abspath("boottest/rc.%s" % self.series)
- with open(self.rc_path, "w") as rc_file:
- home = os.path.expanduser("~")
- print(dedent("""\
- release: %s
- aptroot: ~/.chdist/%s-proposed-armhf/
- apturi: file:%s/mirror/%s
- components: main restricted universe multiverse
- rsync_host: rsync://tachash.ubuntu-ci/boottest/
- datadir: ~/proposed-migration/boottest/data""" %
- (self.series, self.series, home, self.distribution)),
- file=rc_file)
-
- def _run(self, *args):
- self._ensure_rc_file()
- if not os.path.exists(self.script_path):
- print("E: [%s] - Boottest/Jenking glue script missing: %s" % (
- time.asctime(), self.script_path))
- return '-'
- command = [
- self.script_path,
- "-c", self.rc_path,
- "-r", self.series,
- "-PU",
- ]
- if self.debug:
- command.append("-d")
- command.extend(args)
- return subprocess.check_output(command).strip()
-
- def _read(self):
- """Loads a list of results (sources tests and their status).
-
- Provides internal data for `get_status()`.
- """
- self.pkglist = defaultdict(dict)
- if not os.path.exists(self._result_path):
- return
- with open(self._result_path) as f:
- for line in f:
- line = line.strip()
- if line.startswith("Suite:") or line.startswith("Date:"):
- continue
- linebits = line.split()
- if len(linebits) < 2:
- print("W: Invalid line format: '%s', skipped" % line)
- continue
- (src, ver, status) = linebits[:3]
- if not (src in self.pkglist and ver in self.pkglist[src]):
- self.pkglist[src][ver] = status
-
- def get_status(self, name, version):
- """Return test status for the given source name and version."""
- try:
- return self.pkglist[name][version]
- except KeyError:
- # This error handling accounts for outdated apt caches, when
- # `boottest-britney` erroneously reports results for the
- # current source version, instead of the proposed.
- # Returning None here will block source promotion with:
- # 'UNKNOWN STATUS' excuse. If the jobs are retried and its
- # results find an up-to-date cache, the problem is gone.
- print("E: [%s] - Missing boottest results for %s_%s" % (
- time.asctime(), name, version))
- return None
-
- def request(self, packages):
- """Requests boottests for the given sources list ([(src, ver),])."""
- request_path = self._request_path
- if os.path.exists(request_path):
- os.unlink(request_path)
- with closing(tempfile.NamedTemporaryFile(mode="w")) as request_file:
- for src, ver in packages:
- if src in self.pkglist and ver in self.pkglist[src]:
- continue
- print("%s %s" % (src, ver), file=request_file)
- # Update 'pkglist' so even if submit/collect is not called
- # (dry-run), britney has some results.
- self.pkglist[src][ver] = 'RUNNING'
- request_file.flush()
- self._run("request", "-O", request_path, request_file.name)
-
- def submit(self):
- """Submits the current boottests requests for processing."""
- self._run("submit", self._request_path)
-
- def collect(self):
- """Collects boottests results and updates internal registry."""
- self._run("collect", "-O", self._result_path)
- self._read()
- if not self.britney.options.verbose:
- return
- for src in sorted(self.pkglist):
- for ver in sorted(self.pkglist[src]):
- status = self.pkglist[src][ver]
- print("I: [%s] - Collected boottest status for %s_%s: "
- "%s" % (time.asctime(), src, ver, status))
-
- def needs_test(self, name, version):
- """Whether or not the given source and version should be tested.
-
- Sources are only considered for boottesting if they produce binaries
- that are part of the phone image manifest. See `TouchManifest`.
- """
- # Discover all binaries for the 'excused' source.
- unstable_sources = self.britney.sources['unstable']
- # Dismiss if source is not yet recognized (??).
- if name not in unstable_sources:
- return False
- # Binaries are a seq of "/" and, practically, boottest
- # is only concerned about armhf binaries mentioned in the phone
- # manifest. Anything else should be skipped.
- phone_binaries = [
- b for b in unstable_sources[name][BINARIES]
- if b.split('/')[1] in self.britney.options.boottest_arches.split()
- and b.split('/')[0] in self.phone_manifest
- ]
- return bool(phone_binaries)
diff --git a/britney.conf b/britney.conf
index 99991ec..bf278c2 100644
--- a/britney.conf
+++ b/britney.conf
@@ -72,8 +72,3 @@ ADT_SWIFT_URL = https://objectstorage.prodstack4-5.canonical.com/v1/AUTH_77e
# space separate list of PPAs to add for test requests and for polling results;
# the *last* one determines the swift container name
ADT_PPAS =
-
-BOOTTEST_ENABLE = no
-BOOTTEST_DEBUG = yes
-BOOTTEST_ARCHES = armhf amd64
-BOOTTEST_FETCH = yes
diff --git a/britney.py b/britney.py
index 5751867..941989d 100755
--- a/britney.py
+++ b/britney.py
@@ -213,7 +213,6 @@ from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC,
SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS,
PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL)
from autopkgtest import AutoPackageTest, srchash
-from boottest import BootTest
__author__ = 'Fabio Tranchitella and the Debian Release Team'
@@ -1454,7 +1453,6 @@ class Britney(object):
# the starting point is that we will update the candidate and run autopkgtests
update_candidate = True
run_autopkgtest = True
- run_boottest = True
# if the version in unstable is older, then stop here with a warning in the excuse and return False
if source_t and apt_pkg.version_compare(source_u[VERSION], source_t[VERSION]) < 0:
@@ -1468,7 +1466,6 @@ class Britney(object):
excuse.addhtml("%s source package doesn't exist" % (src))
update_candidate = False
run_autopkgtest = False
- run_boottest = False
# retrieve the urgency for the upload, ignoring it if this is a NEW package (not present in testing)
urgency = self.urgencies.get(src, self.options.default_urgency)
@@ -1487,7 +1484,6 @@ class Britney(object):
excuse.addreason("remove")
update_candidate = False
run_autopkgtest = False
- run_boottest = False
# check if there is a `block' or `block-udeb' hint for this package, or a `block-all source' hint
blocked = {}
@@ -1570,7 +1566,6 @@ class Britney(object):
else:
update_candidate = False
run_autopkgtest = False
- run_boottest = False
excuse.addreason("age")
if suite in ['pu', 'tpu']:
@@ -1606,8 +1601,6 @@ class Britney(object):
update_candidate = False
if arch in self.options.adt_arches:
run_autopkgtest = False
- if arch in self.options.boottest_arches.split():
- run_boottest = False
excuse.addreason("arch")
excuse.addreason("arch-%s" % arch)
excuse.addreason("build-arch")
@@ -1650,8 +1643,6 @@ class Britney(object):
update_candidate = False
if arch in self.options.adt_arches:
run_autopkgtest = False
- if arch in self.options.boottest_arches.split():
- run_boottest = False
# if there are out-of-date packages, warn about them in the excuse and set update_candidate
# to False to block the update; if the architecture where the package is out-of-date is
@@ -1678,8 +1669,6 @@ class Britney(object):
update_candidate = False
if arch in self.options.adt_arches:
run_autopkgtest = False
- if arch in self.options.boottest_arches.split():
- run_boottest = False
excuse.addreason("arch")
excuse.addreason("arch-%s" % arch)
if uptodatebins:
@@ -1697,13 +1686,11 @@ class Britney(object):
excuse.addreason("no-binaries")
update_candidate = False
run_autopkgtest = False
- run_boottest = False
elif not built_anywhere:
excuse.addhtml("%s has no up-to-date binaries on any arch" % src)
excuse.addreason("no-binaries")
update_candidate = False
run_autopkgtest = False
- run_boottest = False
# if the suite is unstable, then we have to check the release-critical bug lists before
# updating testing; if the unstable package has RC bugs that do not apply to the testing
@@ -1736,7 +1723,6 @@ class Britney(object):
["#%s" % (quote(a), a) for a in new_bugs])))
update_candidate = False
run_autopkgtest = False
- run_boottest = False
excuse.addreason("buggy")
if len(old_bugs) > 0:
@@ -1755,7 +1741,6 @@ class Britney(object):
excuse.force()
update_candidate = True
run_autopkgtest = True
- run_boottest = True
# if the package can be updated, it is a valid candidate
if update_candidate:
@@ -1765,7 +1750,6 @@ class Britney(object):
# TODO
excuse.addhtml("Not considered")
excuse.run_autopkgtest = run_autopkgtest
- excuse.run_boottest = run_boottest
self.excuses.append(excuse)
return update_candidate
@@ -2010,90 +1994,6 @@ class Britney(object):
e.addreason("autopkgtest")
e.is_valid = False
- if (getattr(self.options, "boottest_enable", "no") == "yes" and
- self.options.series):
- # trigger 'boottest'ing for valid candidates.
- boottest_debug = getattr(
- self.options, "boottest_debug", "no") == "yes"
- boottest = BootTest(
- self, self.options.distribution, self.options.series,
- debug=boottest_debug)
- boottest_excuses = []
- for excuse in self.excuses:
- # Skip already invalid excuses.
- if not excuse.run_boottest:
- continue
- # Also skip removals, binary-only candidates, proposed-updates
- # and unknown versions.
- if (excuse.name.startswith("-") or
- "/" in excuse.name or
- "_" in excuse.name or
- excuse.ver[1] == "-"):
- continue
- # Allows hints to skip boottest attempts
- hints = self.hints.search(
- 'force-skiptest', package=excuse.name)
- forces = [x for x in hints
- if same_source(excuse.ver[1], x.version)]
- if forces:
- excuse.addhtml(
- "boottest skipped from hints by %s" % forces[0].user)
- continue
- # Only sources whitelisted in the boottest context should
- # be tested (currently only sources building phone binaries).
- if not boottest.needs_test(excuse.name, excuse.ver[1]):
- # Silently skipping.
- continue
- # Okay, aggregate required boottests requests.
- boottest_excuses.append(excuse)
- boottest.request([(e.name, e.ver[1]) for e in boottest_excuses])
- # Dry-run avoids data exchange with external systems.
- if not self.options.dry_run:
- boottest.submit()
- boottest.collect()
- # Boottest Jenkins views location.
- jenkins_public = "https://jenkins.qa.ubuntu.com/job"
- jenkins_private = (
- "http://d-jenkins.ubuntu-ci:8080/view/%s/view/BootTest/job" %
- self.options.series.title())
- # Update excuses from the boottest context.
- for excuse in boottest_excuses:
- status = boottest.get_status(excuse.name, excuse.ver[1])
- label = BootTest.EXCUSE_LABELS.get(status, 'UNKNOWN STATUS')
- public_url = "%s/%s-boottest-%s/lastBuild" % (
- jenkins_public, self.options.series,
- excuse.name.replace("+", "-"))
- private_url = "%s/%s-boottest-%s/lastBuild" % (
- jenkins_private, self.options.series,
- excuse.name.replace("+", "-"))
- excuse.addhtml(
- "Boottest result: %s (Jenkins: public"
- ", private)" % (
- label, public_url, private_url))
- # Allows hints to force boottest failures/attempts
- # to be ignored.
- hints = self.hints.search('force', package=excuse.name)
- hints.extend(
- self.hints.search('force-badtest', package=excuse.name))
- forces = [x for x in hints
- if same_source(excuse.ver[1], x.version)]
- if forces:
- excuse.addhtml(
- "Should wait for %s %s boottest, but forced by "
- "%s" % (excuse.name, excuse.ver[1],
- forces[0].user))
- continue
- # Block promotion if the excuse is still valid (adt tests
- # passed) but the boottests attempt has failed or still in
- # progress.
- if status not in BootTest.VALID_STATUSES:
- excuse.addreason("boottest")
- if excuse.is_valid:
- excuse.is_valid = False
- excuse.addhtml("Not considered")
- upgrade_me.remove(excuse.name)
- unconsidered.append(excuse.name)
-
# invalidate impossible excuses
for e in self.excuses:
# parts[0] == package name
diff --git a/excuse.py b/excuse.py
index 85900bf..bcb1e26 100644
--- a/excuse.py
+++ b/excuse.py
@@ -60,7 +60,6 @@ class Excuse(object):
self._dontinvalidate = False
self.forced = False
self.run_autopkgtest = False
- self.run_boottest = False
self.distribution = "ubuntu"
self.invalid_deps = []
diff --git a/tests/test_autopkgtest.py b/tests/test_autopkgtest.py
index 8a3fee4..d0c8f14 100755
--- a/tests/test_autopkgtest.py
+++ b/tests/test_autopkgtest.py
@@ -41,11 +41,9 @@ class T(TestBase):
super().setUp()
self.fake_amqp = os.path.join(self.data.path, 'amqp')
- # Disable boottests and set fake AMQP and Swift server
+ # Set fake AMQP and Swift server
for line in fileinput.input(self.britney_conf, inplace=True):
- if 'BOOTTEST_ENABLE' in line:
- print('BOOTTEST_ENABLE = no')
- elif 'ADT_AMQP' in line:
+ if 'ADT_AMQP' in line:
print('ADT_AMQP = file://%s' % self.fake_amqp)
elif 'ADT_SWIFT_URL' in line:
print('ADT_SWIFT_URL = http://localhost:18085')
diff --git a/tests/test_boottest.py b/tests/test_boottest.py
deleted file mode 100755
index 3a78a09..0000000
--- a/tests/test_boottest.py
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/usr/bin/python3
-# (C) 2014 Canonical Ltd.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import os
-import shutil
-import sys
-import tempfile
-import fileinput
-import unittest
-from unittest import mock
-
-
-PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.insert(0, PROJECT_DIR)
-
-import boottest
-from tests import TestBase
-
-
-def create_manifest(manifest_dir, lines):
- """Helper function for writing touch image manifests."""
- os.makedirs(manifest_dir)
- with open(os.path.join(manifest_dir, 'manifest'), 'w') as fd:
- fd.write('\n'.join(lines))
-
-
-class FakeResponse(object):
-
- def __init__(self, code=404, content=''):
- self.code = code
- self.content = content
-
- def read(self):
- return self.content
-
-
-class TestTouchManifest(unittest.TestCase):
-
- def setUp(self):
- super(TestTouchManifest, self).setUp()
- self.path = tempfile.mkdtemp(prefix='boottest')
- os.chdir(self.path)
- self.imagesdir = os.path.join(self.path, 'boottest/images')
- os.makedirs(self.imagesdir)
- self.addCleanup(shutil.rmtree, self.path)
- _p = mock.patch('urllib.request.urlopen')
- self.mocked_urlopen = _p.start()
- self.mocked_urlopen.side_effect = [
- FakeResponse(code=404),
- FakeResponse(code=404),
- ]
- self.addCleanup(_p.stop)
- self.fetch_retries_orig = boottest.FETCH_RETRIES
-
- def restore_fetch_retries():
- boottest.FETCH_RETRIES = self.fetch_retries_orig
- boottest.FETCH_RETRIES = 0
- self.addCleanup(restore_fetch_retries)
-
- def test_missing(self):
- # Missing manifest file silently results in empty contents.
- manifest = boottest.TouchManifest('I-dont-exist', 'vivid')
- self.assertEqual([], manifest._manifest)
- self.assertNotIn('foo', manifest)
-
- def test_fetch(self):
- # Missing manifest file is fetched dynamically
- self.mocked_urlopen.side_effect = [
- FakeResponse(code=200, content=b'foo 1.0'),
- ]
- manifest = boottest.TouchManifest('ubuntu-touch', 'vivid')
- self.assertNotEqual([], manifest._manifest)
-
- def test_fetch_disabled(self):
- # Manifest auto-fetching can be disabled.
- manifest = boottest.TouchManifest('ubuntu-touch', 'vivid', fetch=False)
- self.mocked_urlopen.assert_not_called()
- self.assertEqual([], manifest._manifest)
-
- def test_fetch_fails(self):
- project = 'fake'
- series = 'fake'
- manifest_dir = os.path.join(self.imagesdir, project, series)
- manifest_lines = [
- 'foo:armhf 1~beta1',
- ]
- create_manifest(manifest_dir, manifest_lines)
- manifest = boottest.TouchManifest(project, series)
- self.assertEqual(1, len(manifest._manifest))
- self.assertIn('foo', manifest)
-
- def test_fetch_exception(self):
- self.mocked_urlopen.side_effect = [
- IOError("connection refused"),
- IOError("connection refused"),
- ]
- manifest = boottest.TouchManifest('not-real', 'not-real')
- self.assertEqual(0, len(manifest._manifest))
-
- def test_simple(self):
- # Existing manifest file allows callsites to properly check presence.
- manifest_dir = os.path.join(self.imagesdir, 'ubuntu/vivid')
- manifest_lines = [
- 'bar 1234',
- 'foo:armhf 1~beta1',
- 'boing1-1.2\t666',
- 'click:com.ubuntu.shorts 0.2.346'
- ]
- create_manifest(manifest_dir, manifest_lines)
-
- manifest = boottest.TouchManifest('ubuntu', 'vivid')
- # We can dig deeper on the manifest package names list ...
- self.assertEqual(
- ['bar', 'boing1-1.2', 'foo'], manifest._manifest)
- # but the ' in manifest' API reads better.
- self.assertIn('foo', manifest)
- self.assertIn('boing1-1.2', manifest)
- self.assertNotIn('baz', manifest)
- # 'click' name is blacklisted due to the click package syntax.
- self.assertNotIn('click', manifest)
-
-
-class TestBoottestEnd2End(TestBase):
- """End2End tests (calling `britney`) for the BootTest criteria."""
-
- def setUp(self):
- super(TestBoottestEnd2End, self).setUp()
-
- # Modify shared configuration file.
- with open(self.britney_conf, 'r') as fp:
- original_config = fp.read()
- # Disable autopkgtests.
- new_config = original_config.replace(
- 'ADT_ENABLE = yes', 'ADT_ENABLE = no')
- # Enable boottest.
- new_config = new_config.replace(
- 'BOOTTEST_ENABLE = no', 'BOOTTEST_ENABLE = yes')
- # Disable TouchManifest auto-fetching.
- new_config = new_config.replace(
- 'BOOTTEST_FETCH = yes', 'BOOTTEST_FETCH = no')
- with open(self.britney_conf, 'w') as fp:
- fp.write(new_config)
-
- self.data.add('libc6', False, {'Architecture': 'armhf'}),
-
- self.data.add(
- 'libgreen1',
- False,
- {'Source': 'green', 'Architecture': 'armhf',
- 'Depends': 'libc6 (>= 0.9)'})
- self.data.add(
- 'green',
- False,
- {'Source': 'green', 'Architecture': 'armhf',
- 'Depends': 'libc6 (>= 0.9), libgreen1'})
- self.create_manifest([
- 'green 1.0',
- 'pyqt5:armhf 1.0',
- 'signon 1.0',
- 'purple 1.1',
- ])
-
- def create_manifest(self, lines):
- """Create a manifest for this britney run context."""
- path = os.path.join(
- self.data.path,
- 'boottest/images/ubuntu-touch/{}'.format(self.data.series))
- create_manifest(path, lines)
-
- def make_boottest(self):
- """Create a stub version of boottest-britney script."""
- script_path = os.path.expanduser(
- "~/auto-package-testing/jenkins/boottest-britney")
- if not os.path.exists(os.path.dirname(script_path)):
- os.makedirs(os.path.dirname(script_path))
- with open(script_path, 'w') as f:
- f.write('''#!%(py)s
-import argparse
-import os
-import shutil
-import sys
-
-template = """
-green 1.1~beta RUNNING
-pyqt5-src 1.1~beta PASS
-pyqt5-src 1.1 FAIL
-signon 1.1 PASS
-purple 1.1 RUNNING
-"""
-
-def request():
- work_path = os.path.dirname(args.output)
- os.makedirs(work_path)
- shutil.copy(args.input, os.path.join(work_path, 'test_input'))
- with open(args.output, 'w') as f:
- f.write(template)
-
-def submit():
- pass
-
-def collect():
- with open(args.output, 'w') as f:
- f.write(template)
-
-p = argparse.ArgumentParser()
-p.add_argument('-r')
-p.add_argument('-c')
-p.add_argument('-d', default=False, action='store_true')
-p.add_argument('-P', default=False, action='store_true')
-p.add_argument('-U', default=False, action='store_true')
-
-sp = p.add_subparsers()
-
-psubmit = sp.add_parser('submit')
-psubmit.add_argument('input')
-psubmit.set_defaults(func=submit)
-
-prequest = sp.add_parser('request')
-prequest.add_argument('-O', dest='output')
-prequest.add_argument('input')
-prequest.set_defaults(func=request)
-
-pcollect = sp.add_parser('collect')
-pcollect.add_argument('-O', dest='output')
-pcollect.set_defaults(func=collect)
-
-args = p.parse_args()
-args.func()
- ''' % {'py': sys.executable})
- os.chmod(script_path, 0o755)
-
- def do_test(self, context, expect=None, no_expect=None):
- """Process the given package context and assert britney results."""
- for (pkg, fields) in context:
- self.data.add(pkg, True, fields, testsuite='autopkgtest')
- self.make_boottest()
- (excuses_yaml, excuses, out) = self.run_britney()
- # print('-------\nexcuses: %s\n-----' % excuses)
- # print('-------\nout: %s\n-----' % out)
- if expect:
- for re in expect:
- self.assertRegex(excuses, re)
- if no_expect:
- for re in no_expect:
- self.assertNotRegex(excuses, re)
-
- def test_runs(self):
- # `Britney` runs and considers binary packages for boottesting
- # when it is enabled in the configuration, only binaries needed
- # in the phone image are considered for boottesting.
- # The boottest status is presented along with its corresponding
- # jenkins job urls for the public and the private servers.
- # 'in progress' tests blocks package promotion.
- context = [
- ('green', {'Source': 'green', 'Version': '1.1~beta',
- 'Architecture': 'armhf', 'Depends': 'libc6 (>= 0.9)'}),
- ('libgreen1', {'Source': 'green', 'Version': '1.1~beta',
- 'Architecture': 'armhf',
- 'Depends': 'libc6 (>= 0.9)'}),
- ]
- public_jenkins_url = (
- 'https://jenkins.qa.ubuntu.com/job/series-boottest-green/'
- 'lastBuild')
- private_jenkins_url = (
- 'http://d-jenkins.ubuntu-ci:8080/view/Series/view/BootTest/'
- 'job/series-boottest-green/lastBuild')
- self.do_test(
- context,
- [r'\bgreen\b.*>1 to .*>1.1~beta<',
- r'
Not considered'])
-
- # The `boottest-britney` input (recorded for testing purposes),
- # contains a line matching the requested boottest attempt.
- # '