[patchew-devel] [PATCH 7/7] tester: Test multiple projects

Fam Zheng posted 7 patches 7 years, 9 months ago
[patchew-devel] [PATCH 7/7] tester: Test multiple projects
Posted by Fam Zheng 7 years, 9 months ago
Allow project list in --project option, and round-robin test them one by
one.

Signed-off-by: Fam Zheng <famz@redhat.com>
---
 patchew-cli           | 50 +++++++++++++++++++++----------------
 tests/test_testing.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/patchew-cli b/patchew-cli
index 52329e1..51a89c5 100755
--- a/patchew-cli
+++ b/patchew-cli
@@ -449,13 +449,15 @@ class TesterCommand(SubCommand):
         parser.add_argument("--singleton", "-S", action="store_true",
                             help="quit if another singleton mode tester is running")
         parser.add_argument("--project", "-p", required=True,
-                            help="which project to run test")
+                            help="comma separated project names to run test")
         parser.add_argument("--name", "-n",
                             help="name of this tester (default is the logged in username)")
         parser.add_argument("--num", "-N", type=int, default=0,
                             help="max number of tests to run")
         parser.add_argument("--no-clean-up", action="store_true",
                             help="skip cleaning up after finish")
+        parser.add_argument("--no-wait", action="store_true",
+                            help="don't wait if nothing to test")
 
     def _make_script(self, wd, name, content):
         filename = os.path.join(wd, name)
@@ -484,17 +486,18 @@ class TesterCommand(SubCommand):
                 pass
         return ret
 
-    def test_one(self, args, capabilities):
-        r = self.api_do("testing-get", project=args.project, tester=args.name,
-                                    capabilities=capabilities)
+    def test_one(self, name, project, no_clean_up, capabilities):
+        r = self.api_do("testing-get", project=project, tester=name,
+                        capabilities=capabilities)
         if not r:
             return False
         print("Running test '%s'" % r["test"]["name"])
-        if r["project"] != args.project:
+        if r["project"] != project:
             return
 
         wd = tempfile.mkdtemp(prefix="patchew-tester-tmp-", dir="/var/tmp/")
         print("  Workdir:", wd)
+        print("  Project:", r["project"])
         print("  Identity:", str(r["identity"]))
         logf = open(os.path.join(wd, "log"), "w+", encoding="utf-8",
                     errors="ignore")
@@ -565,7 +568,7 @@ class TesterCommand(SubCommand):
                 self.api_do("testing-report", project=r["project"],
                                               identity=r["identity"],
                                               test=r["test"]["name"],
-                                              tester=args.name,
+                                              tester=name,
                                               head=r["head"],
                                               base=r["base"],
                                               passed=passed,
@@ -573,7 +576,7 @@ class TesterCommand(SubCommand):
                                               is_timeout=is_timeout)
                 logf.close()
             finally:
-                if not args.no_clean_up:
+                if not no_clean_up:
                     shutil.rmtree(wd)
             return True
 
@@ -591,25 +594,30 @@ class TesterCommand(SubCommand):
         if args.singleton:
             self._check_singleton()
         subprocess.check_output(["git", "version"])
-        rest = False
         count = 0
         cap_refresh = 10
+        projects = [x.strip() for x in args.project.split(",") if len(x.strip())]
+        if not projects:
+            raise Exception("No project specified")
+        capabilities = {}
         while True:
-            if count % cap_refresh == 0:
-                capabilities = self._refresh_capabilities(args.project,
-                                                          args.name)
-            count += 1
-            if self.test_one(args, capabilities=capabilities):
+            progress = False
+            for p in projects:
+                if count % cap_refresh == 0:
+                    for sp in projects:
+                        capabilities[sp] = self._refresh_capabilities(sp, args.name)
+                if self.test_one(args.name, p, args.no_clean_up,
+                                 capabilities=capabilities[p]):
+                    progress = True
+                    count += 1
                 if count == args.num:
-                    break
-                rest = False
-                continue
-            if count == args.num:
-                break
-            if not rest:
+                    return 0
+            if not progress:
+                if args.no_wait:
+                    print("Nothing to test")
+                    return 0
                 print("No more work, having a rest...")
-                rest = True
-            time.sleep(60)
+                time.sleep(60)
         return 0
 
 class ApplyFailedException(Exception):
diff --git a/tests/test_testing.py b/tests/test_testing.py
index 300201b..a68e237 100755
--- a/tests/test_testing.py
+++ b/tests/test_testing.py
@@ -11,10 +11,20 @@
 import sys
 import os
 import datetime
+import subprocess
 sys.path.append(os.path.dirname(__file__))
 from patchewtest import PatchewTestCase, main
 from api.models import Message, Project
 
+def create_test(project, name):
+    prefix = "testing.tests." + name + "."
+    project.set_property(prefix + "timeout", 3600)
+    project.set_property(prefix + "enabled", True)
+    project.set_property(prefix + "script", "#!/bin/bash\ntrue")
+    project.set_property(prefix + "requirements", "")
+    project.set_property(prefix + "users", "")
+    project.set_property(prefix + "tester", "")
+
 class TestingTest(PatchewTestCase):
 
     def setUp(self):
@@ -22,12 +32,7 @@ class TestingTest(PatchewTestCase):
         self.p = self.add_project("QEMU", "qemu-devel@nongnu.org")
         self.PROJECT_BASE = '%sprojects/%d/' % (self.REST_BASE, self.p.id)
 
-        self.p.set_property("testing.tests.a.timeout", 3600)
-        self.p.set_property("testing.tests.a.enabled", True)
-        self.p.set_property("testing.tests.a.script", "#!/bin/bash\ntrue")
-        self.p.set_property("testing.tests.a.requirements", "")
-        self.p.set_property("testing.tests.a.users", "")
-        self.p.set_property("testing.tests.a.tester", "")
+        create_test(self.p, "a")
 
         self.cli_login()
         self.cli_import('0001-simple-patch.mbox.gz')
@@ -85,5 +90,57 @@ class TestingTest(PatchewTestCase):
         self.assertEquals(log.status_code, 200)
         self.assertEquals(log.content, b'sorry no good')
 
+class TesterTest(PatchewTestCase):
+
+    def setUp(self):
+        self.create_superuser()
+
+        p1 = self.add_project("QEMU", "qemu-devel@nongnu.org")
+        create_test(p1, "a")
+        p2 = self.add_project("UMEQ", "qemu-devel@nongnu.org")
+        create_test(p2, "b")
+
+        self.cli_login()
+        self.cli_import('0001-simple-patch.mbox.gz')
+        self.cli_logout()
+
+        self.repo = os.path.join(self.get_tmpdir(), "repo")
+        os.mkdir(self.repo)
+        subprocess.check_output(["git", "init"], cwd=self.repo)
+        for f in ["foo", "bar"]:
+            subprocess.check_output(["touch", f], cwd=self.repo)
+            subprocess.check_output(["git", "add", f], cwd=self.repo)
+            subprocess.check_output(["git", "commit", "-m", "add " + f],
+                                    cwd=self.repo)
+        base = subprocess.check_output(["git", "rev-parse", "HEAD~1"],
+                                       cwd=self.repo).decode()
+        subprocess.check_output(["git", "tag", "test"], cwd=self.repo)
+
+        for msg in Message.objects.all():
+            msg.set_property("git.repo", self.repo)
+            msg.set_property("git.tag", "test")
+            msg.set_property("git.base", base)
+
+    def test_tester(self):
+        self.cli_login()
+        out, err = self.check_cli(["tester", "-p", "QEMU,UMEQ",
+                                   "--no-wait"])
+        self.assertIn("Project: QEMU\n", out)
+        self.assertIn("Project: UMEQ\n", out)
+        self.cli_logout()
+
+    def test_tester_single(self):
+        self.cli_login()
+        out, err = self.check_cli(["tester", "-p", "QEMU,UMEQ",
+                                   "--no-wait", "-N", "1"])
+        self.assertIn("Project: QEMU\n", out)
+        out, err = self.check_cli(["tester", "-p", "QEMU,UMEQ",
+                                   "--no-wait", "-N", "1"])
+        self.assertIn("Project: UMEQ\n", out)
+        out, err = self.check_cli(["tester", "-p", "QEMU,UMEQ",
+                                   "--no-wait", "-N", "1"])
+        self.assertIn("Nothing to test", out)
+        self.cli_logout()
+
 if __name__ == '__main__':
     main()
-- 
2.14.3