canonical-ubuntu-qa team mailing list archive
-
canonical-ubuntu-qa team
-
Mailing list archive
-
Message #02917
[Merge] ~andersson123/autopkgtest-cloud:test-name into autopkgtest-cloud:master
Tim Andersson has proposed merging ~andersson123/autopkgtest-cloud:test-name into autopkgtest-cloud:master.
Requested reviews:
Canonical's Ubuntu QA (canonical-ubuntu-qa)
For more details, see:
https://code.launchpad.net/~andersson123/autopkgtest-cloud/+git/autopkgtest-cloud/+merge/456883
--
Your team Canonical's Ubuntu QA is requested to review the proposed merge of ~andersson123/autopkgtest-cloud:test-name into autopkgtest-cloud:master.
diff --git a/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/tools/run-autopkgtest b/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/tools/run-autopkgtest
index 9383aa2..53323b2 100755
--- a/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/tools/run-autopkgtest
+++ b/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/tools/run-autopkgtest
@@ -42,6 +42,13 @@ def parse_args():
"Can be specified multiple times.",
)
parser.add_argument(
+ "--test-name",
+ required=False,
+ default=None,
+ help="Specific test name for a packages individual tests, "
+ "rather than running the whole test suit."
+ )
+ parser.add_argument(
"--ppa",
metavar="LPUSER/PPANAME",
action="append",
@@ -170,6 +177,8 @@ if __name__ == "__main__":
params["readable-by"] = args.readable_by
if args.all_proposed:
params["all-proposed"] = True
+ if args.test_name is not None:
+ params["test-name"] = args.test_name
try:
params["requester"] = os.environ["SUDO_USER"]
except KeyError:
diff --git a/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/worker/worker b/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/worker/worker
index 0f992c6..4130403 100755
--- a/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/worker/worker
+++ b/charms/focal/autopkgtest-cloud-worker/autopkgtest-cloud/worker/worker
@@ -80,7 +80,7 @@ ARCH_RELEASE_ALLOW_MAPPING = {
FAIL_CODES = (4, 6, 12, 14, 20)
-KEYS_FOR_ADDITIONAL_PARAMS = ["all-proposed"]
+KEYS_FOR_ADDITIONAL_PARAMS = ["all-proposed", "test-name"]
# In the case of a tmpfail, look for these strings in the log and if they're
# found, consider this a real failure instead. This is useful if the test
@@ -351,6 +351,8 @@ def process_output_dir(
# we might need to fake testinfo.json up too, depending on how
# autopkgtest failed. britney uses this to associate results with
# requests
+
+ # need to use the changes in the all-proposed MP here.
if "testinfo.json" not in files and triggers:
logging.warning("...testinfo.json is missing too, faking one up")
triggers = " ".join(triggers)
@@ -759,6 +761,9 @@ def request(msg):
argv = ["autopkgtest"]
argv += ["--output-dir", out_dir, "--timeout-copy=6000"]
+ if params.get("test-name"):
+ argv += ["--test-name", params.get("test-name")]
+
if i386_cross_series(release) and architecture == "i386":
argv += ["-a", "i386"]
@@ -1239,6 +1244,9 @@ def request(msg):
duration = int(time.time() - retry_start_time)
+ if params.get("test-name"):
+ code = 20 # "other unexpected failures including bad usage" from autopkgtest man page
+
logging.info("autopkgtest exited with code %i", code)
submit_metric(
architecture, code, pkgname, current_region, False, release
diff --git a/charms/focal/autopkgtest-web/layer.yaml b/charms/focal/autopkgtest-web/layer.yaml
index 5c81bdb..fddc96e 100644
--- a/charms/focal/autopkgtest-web/layer.yaml
+++ b/charms/focal/autopkgtest-web/layer.yaml
@@ -21,4 +21,5 @@ options:
- python3-flask-openid
- python3-swiftclient
- python3-werkzeug
+ - python3-git
include_system_packages: true
diff --git a/charms/focal/autopkgtest-web/webcontrol/download-all-results b/charms/focal/autopkgtest-web/webcontrol/download-all-results
index a3ae78d..1f14a8b 100755
--- a/charms/focal/autopkgtest-web/webcontrol/download-all-results
+++ b/charms/focal/autopkgtest-web/webcontrol/download-all-results
@@ -29,6 +29,8 @@ from helpers.utils import get_test_id, init_db
LOGGER = logging.getLogger(__name__)
+ADDITIONAL_PARAM_KEYS = ["all-proposed", "test-name"]
+
config = None
db_con = None
@@ -175,12 +177,15 @@ def fetch_one_result(url):
exitcode,
)
env_vars = []
- env_spec = {
- "all-proposed": "all-proposed=1",
- }
- for env, spec in env_spec.items():
- if env in testinfo.keys():
- env_vars.append(spec)
+ # env_spec = {
+ # "all-proposed": "all-proposed=1",
+ # }
+ # for env, spec in env_spec.items():
+ # if env in testinfo.keys():
+ # env_vars.append(spec)
+ for key in ADDITIONAL_PARAM_KEYS:
+ if key in testinfo.keys():
+ env_vars.append("%s=%s" % (key, testinfo[key]))
while True:
try:
diff --git a/charms/focal/autopkgtest-web/webcontrol/request/submit.py b/charms/focal/autopkgtest-web/webcontrol/request/submit.py
index 2255509..daa413d 100644
--- a/charms/focal/autopkgtest-web/webcontrol/request/submit.py
+++ b/charms/focal/autopkgtest-web/webcontrol/request/submit.py
@@ -8,8 +8,12 @@ import configparser
import json
import logging
import os
+import gzip
+import subprocess
import re
import sqlite3
+from git import Repo
+import shutil
import urllib.parse
import urllib.request
import uuid
@@ -35,6 +39,7 @@ VERSION = re.compile("^[a-zA-Z0-9.+:~-]+$")
ENV = re.compile(r"^[a-zA-Z][a-zA-Z0-9_]+=[a-zA-Z0-9.:~/ -=]*$")
# URL and optional branch name
GIT = re.compile(r"^https?://[a-zA-Z0-9._/~+-]+(#[a-zA-Z0-9._/-]+)?$")
+WRITE_DIR = "/run/autopkgtest_webcontrol/"
ALLOWED_TEAMS = [
"canonical-kernel-distro-team",
@@ -94,6 +99,65 @@ class Submit:
"migration-reference/0 and all-proposed=1 are not compatible arguments."
)
+
+ def get_git_url_for_package(self, package, sources_url):
+ sources = ""
+ with urllib.request.urlopen(sources_url, timeout=10) as req:
+ sources = gzip.decompress(req.read()).decode()
+ sources_list = sources.split("Package: ")
+ for src in sources_list:
+ src_lines = src.splitlines()
+ if len(src_lines) > 0:
+ if package == src_lines[0].rstrip():
+ for line in src_lines:
+ if line.startswith("Vcs-Git: "):
+ git_url = line.replace("Vcs-Git: ", "")
+ return git_url
+
+
+ def get_tests_for_package(self, package, release):
+ global WRITE_DIR
+ source_dir = "%s/source-packages" % WRITE_DIR
+ packages_testlist_file = "%s/packages-testlist.json" % WRITE_DIR
+ packages_testlist = {}
+ if not os.path.exists(source_dir):
+ os.mkdir(source_dir)
+ if os.path.isfile(packages_testlist_file):
+ with open(packages_testlist_file, "r") as f:
+ packages_testlist = json.load(f)
+ if packages_testlist.get(package):
+ return packages_testlist.get(package)
+
+ sources_url = "http://archive.ubuntu.com/ubuntu/dists/%s/main/source/Sources.gz" % release
+ git_url = self.get_git_url_for_package(package, sources_url)
+ clone_destination = "%s/%s" % (source_dir, package)
+ if os.path.exists(clone_destination):
+ shutil.rmtree(clone_destination)
+ https_proxy = os.environ["https_proxy"]
+ os.environ["https_proxy"] = ""
+ Repo.clone_from(git_url, clone_destination)
+ os.environ["https_proxy"] = https_proxy
+ if not os.path.exists("%s/debian/tests" % clone_destination):
+ return False
+ tests_file = ""
+ with open("%s/debian/tests/control" % clone_destination, "r") as f:
+ tests_file = f.read()
+ individual_tests = tests_file.split("Tests: ")
+ tests_for_package = []
+ for test in individual_tests:
+ test_lines = test.splitlines()
+ if len(test_lines) > 0:
+ tests_for_package.append(test_lines[0])
+
+ packages_testlist[package] = tests_for_package
+ with open(packages_testlist_file, "w") as f:
+ json.dump(packages_testlist, f)
+ # Need to also clean up the cloned location.
+ shutil.rmtree(clone_destination)
+
+ return tests_for_package
+
+
# pylint: disable=dangerous-default-value
def validate_distro_request(
self, release, arch, package, triggers, requester, ppas=[], **kwargs
@@ -113,6 +177,7 @@ class Submit:
self.migration_reference_all_proposed_check(triggers, kwargs)
can_upload_any_trigger = False
+ test_name = None
try:
if kwargs["delete"] != "1":
@@ -132,9 +197,17 @@ class Submit:
del kwargs["readable-by"]
except KeyError:
pass
+ if kwargs.get("test-name"):
+ test_name = kwargs.get("test-name")
+ del kwargs["test-name"]
# no other kwargs supported
if kwargs:
raise ValueError("Invalid argument %s" % list(kwargs)[0])
+
+ if test_name is not None:
+ package_tests = self.get_tests_for_package(package, release)
+ if test_name not in package_tests:
+ raise BadRequest("Provided test name %s doesn't exist in package %s. Full list of tests for this package: \n%s" % (test_name, package, "\n".join(package_tests)))
if release not in self.releases:
raise NotFound("release", release)