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)
-- 
Mailing list: https://launchpad.net/~canonical-ubuntu-qa
Post to     : canonical-ubuntu-qa@lists.launchpad.net
Unsubscribe : https://launchpad.net/~canonical-ubuntu-qa
More help   : https://help.launchpad.net/ListHelp

Reply via email to