Merge ppa-dev-tools:trigger-action-urls into ppa-dev-tools:main

Proposed by Bryce Harrington
Status: Merged
Merge reported by: Bryce Harrington
Merged at revision: 6c02046c2d30b1f59b30cb5485c57d806de3afaa
Proposed branch: ppa-dev-tools:trigger-action-urls
Merge into: ppa-dev-tools:main
Diff against target: 237 lines (+84/-29)
4 files modified
ppa/ppa.py (+6/-7)
ppa/trigger.py (+31/-5)
scripts/ppa (+19/-4)
tests/test_trigger.py (+28/-13)
Reviewer Review Type Date Requested Status
Christian Ehrhardt  (community) Approve
Canonical Server Pending
Canonical Server Reporter Pending
Review via email: mp+431541@code.launchpad.net

Description of the change

Starts integrating Trigger objects into the `ppa tests` command, and adds the action urls (the urls that actually cause autopkgtest to fire up the tests). Also adds the PPA element to the Triggers, which for now are required but later I think I could make that optional in order to make this code work for triggering directly against -proposed.

For now this just dumps the action urls to the output.

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

I'm generally +1 this is small and a good step forward.
One question on URL escaping and testing it below.
Feel free to add it here or putting it onto your known-todo-list.

review: Approve
Revision history for this message
Bryce Harrington (bryce) wrote :

Thanks, I'll get the encoding added for the urls, and accompanying tests, then will land.

Revision history for this message
Bryce Harrington (bryce) wrote :

I did a minor reimplementation of action_url() to use urlencode, updated test cases, and landed the branch. Thanks again!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/ppa/ppa.py b/ppa/ppa.py
index 763ed7f..f26a1ea 100755
--- a/ppa/ppa.py
+++ b/ppa/ppa.py
@@ -108,13 +108,12 @@ class Ppa:
108 f'ppa_name={self.ppa_name!r}, team_name={self.team_name!r})')108 f'ppa_name={self.ppa_name!r}, team_name={self.team_name!r})')
109109
110 def __str__(self):110 def __str__(self):
111 s = ''111 """Returns a displayable string identifying the PPA.
112 s += "ppa: {}\n".format(self.name)112
113 s += "address: {}\n".format(self.address)113 :rtype: str
114 s += "url: {}\n".format(self.url)114 :returns: Displayable representation of the PPA.
115 s += "description:\n"115 """
116 s += indent(self.description, 4)116 return f"{self.team_name}/{self.name}"
117 return s
118117
119 @property118 @property
120 def archive(self):119 def archive(self):
diff --git a/ppa/trigger.py b/ppa/trigger.py
index 79276da..42e4d00 100755
--- a/ppa/trigger.py
+++ b/ppa/trigger.py
@@ -26,18 +26,20 @@ class Trigger:
26 package and/or architectures, but all such Triggers must be against26 package and/or architectures, but all such Triggers must be against
27 the same series as the Job itself.27 the same series as the Job itself.
28 """28 """
29 def __init__(self, package, version, arch, series):29 def __init__(self, package, version, arch, series, ppa):
30 """Initializes a new Trigger for a given package and version.30 """Initializes a new Trigger for a given package and version.
3131
32 :param str package: The source package name.32 :param str package: The source package name.
33 :param str version: The version of the source package to install.33 :param str version: The version of the source package to install.
34 :param str arch: The architecture for the trigger.34 :param str arch: The architecture for the trigger.
35 :param str series: The distro release series codename.35 :param str series: The distro release series codename.
36 :param Ppa ppa: (Optional) PPA wrapper object to run tests against.
36 """37 """
37 self.package = package38 self.package = package
38 self.version = version39 self.version = version
39 self.arch = arch40 self.arch = arch
40 self.series = series41 self.series = series
42 self.ppa = ppa
4143
42 def __repr__(self) -> str:44 def __repr__(self) -> str:
43 """Machine-parsable unique representation of object.45 """Machine-parsable unique representation of object.
@@ -47,7 +49,7 @@ class Trigger:
47 """49 """
48 return (f'{self.__class__.__name__}('50 return (f'{self.__class__.__name__}('
49 f'package={self.package!r}, version={self.version!r}, '51 f'package={self.package!r}, version={self.version!r}, '
50 f'arch={self.arch!r}, series={self.series!r})')52 f'arch={self.arch!r}, series={self.series!r}, ppa={self.ppa!r})')
5153
52 def __str__(self) -> str:54 def __str__(self) -> str:
53 """Human-readable summary of the object.55 """Human-readable summary of the object.
@@ -58,11 +60,11 @@ class Trigger:
58 return f"{self.package}/{self.version}"60 return f"{self.package}/{self.version}"
5961
60 @cached_property62 @cached_property
61 def autopkgtest_url(self) -> str:63 def history_url(self) -> str:
62 """Renders the trigger as a URL to the job history.64 """Renders the trigger as a URL to the job history.
6365
64 :rtype: str66 :rtype: str
65 :returns: tbd67 :returns: Job history URL
66 """68 """
67 if self.package.startswith('lib'):69 if self.package.startswith('lib'):
68 prefix = self.package[0:4]70 prefix = self.package[0:4]
@@ -71,10 +73,34 @@ class Trigger:
71 pkg_str = f"{prefix}/{self.package}"73 pkg_str = f"{prefix}/{self.package}"
72 return f"{URL_AUTOPKGTEST}/packages/{pkg_str}/{self.series}/{self.arch}"74 return f"{URL_AUTOPKGTEST}/packages/{pkg_str}/{self.series}/{self.arch}"
7375
76 @cached_property
77 def action_url(self) -> str:
78 """Renders the trigger as a URL to start running the test.
79
80 :rtype: str
81 :returns: Trigger action URL
82 """
83 elements = [
84 f"release={self.series}",
85 f"package={self.package}",
86 f"arch={self.arch}",
87 ]
88
89 # Trigger for the source package itself
90 elements.append(f"trigger={self.package}/{self.version}")
91
92 # TODO: Additional triggers...
93
94 # The PPA, if one is defined for this trigger
95 if self.ppa:
96 elements.append(f"ppa={self.ppa}")
97
98 return f"{URL_AUTOPKGTEST}/request.cgi?" + "&".join(elements)
99
74100
75if __name__ == "__main__":101if __name__ == "__main__":
76 print("### Trigger class smoke test ###")102 print("### Trigger class smoke test ###")
77103
78 trigger = Trigger('my-package', '1.2.3', 'amd64', 'kinetic')104 trigger = Trigger('my-package', '1.2.3', 'amd64', 'kinetic')
79 print(trigger)105 print(trigger)
80 print(trigger.autopkgtest_url)106 print(trigger.history_url)
diff --git a/scripts/ppa b/scripts/ppa
index 1607342..55a6211 100755
--- a/scripts/ppa
+++ b/scripts/ppa
@@ -83,6 +83,7 @@ from ppa.result import (
83 get_results83 get_results
84)84)
85from ppa.text import o2str85from ppa.text import o2str
86from ppa.trigger import Trigger
8687
87import ppa.debug88import ppa.debug
88from ppa.debug import dbg, die, warn89from ppa.debug import dbg, die, warn
@@ -373,7 +374,12 @@ def command_show(lp, config):
373 arch = None374 arch = None
374 try:375 try:
375 ppa = get_ppa(lp, config)376 ppa = get_ppa(lp, config)
376 print(ppa)377 print(f"ppa: {self.name}")
378 print(f"address: {self.address}")
379 print(f"url: {self.url}")
380 print(f"description:")
381 print(indent(self.description, 4))
382
377 print("sources:")383 print("sources:")
378 for source in ppa.get_source_publications(distro, series, arch):384 for source in ppa.get_source_publications(distro, series, arch):
379 print(" %s (%s) %s" % (385 print(" %s (%s) %s" % (
@@ -486,7 +492,16 @@ def command_tests(lp, config):
486492
487 try:493 try:
488 ppa = get_ppa(lp, config)494 ppa = get_ppa(lp, config)
489 target = "%s/%s" % (ppa.team_name, ppa.name)495 for source_pub in ppa.get_source_publications():
496 # Triggers
497 for arch in ARCHES_AUTOPKGTEST:
498 trigger = Trigger(
499 package=source_pub.source_package_name,
500 version=source_pub.source_package_version,
501 arch=arch,
502 series=source_pub.distro_series.name,
503 ppa=ppa)
504 print(trigger.action_url)
490505
491 # Results506 # Results
492 base_results_fmt = f"{URL_AUTOPKGTEST}/results/autopkgtest-%s-%s-%s/"507 base_results_fmt = f"{URL_AUTOPKGTEST}/results/autopkgtest-%s-%s-%s/"
@@ -507,13 +522,13 @@ def command_tests(lp, config):
507 # Running Queue522 # Running Queue
508 response = open_url(f"{URL_AUTOPKGTEST}/static/running.json", "running autopkgtests")523 response = open_url(f"{URL_AUTOPKGTEST}/static/running.json", "running autopkgtests")
509 if response:524 if response:
510 show_running(sorted(get_running(response, series=release, ppa=target),525 show_running(sorted(get_running(response, series=release, ppa=str(ppa)),
511 key=lambda k: str(k.submit_time)))526 key=lambda k: str(k.submit_time)))
512527
513 # Waiting Queue528 # Waiting Queue
514 response = open_url(f"{URL_AUTOPKGTEST}/queues.json", "waiting autopkgtests")529 response = open_url(f"{URL_AUTOPKGTEST}/queues.json", "waiting autopkgtests")
515 if response:530 if response:
516 show_waiting(get_waiting(response, series=release, ppa=target))531 show_waiting(get_waiting(response, series=release, ppa=str(ppa)))
517532
518 return os.EX_OK533 return os.EX_OK
519 except KeyboardInterrupt:534 except KeyboardInterrupt:
diff --git a/tests/test_trigger.py b/tests/test_trigger.py
index c6b6a6b..318f034 100644
--- a/tests/test_trigger.py
+++ b/tests/test_trigger.py
@@ -21,35 +21,50 @@ from ppa.trigger import Trigger
2121
22def test_object():22def test_object():
23 """Checks that Trigger objects can be instantiated."""23 """Checks that Trigger objects can be instantiated."""
24 trigger = Trigger('a', 'b', 'c', 'd')24 trigger = Trigger('a', 'b', 'c', 'd', 'e')
25 assert trigger25 assert trigger
2626
2727
28def test_repr():28def test_repr():
29 """Checks Trigger object representation."""29 """Checks Trigger object representation."""
30 trigger = Trigger('a', 'b', 'c', 'd')30 trigger = Trigger('a', 'b', 'c', 'd', 'e')
31 assert repr(trigger) == "Trigger(package='a', version='b', arch='c', series='d')"31 assert repr(trigger) == "Trigger(package='a', version='b', arch='c', series='d', ppa='e')"
3232
3333
34def test_str():34def test_str():
35 """Checks Trigger object textual presentation."""35 """Checks Trigger object textual presentation."""
36 trigger = Trigger('a', 'b', 'c', 'd')36 trigger = Trigger('a', 'b', 'c', 'd', 'e')
37 assert f"{trigger}" == 'a/b'37 assert f"{trigger}" == 'a/b'
3838
39 trigger = Trigger('dovecot', '1:2.3.19.1+dfsg1-2ubuntu2', 'i386', 'kinetic')39 trigger = Trigger('dovecot', '1:2.3.19.1+dfsg1-2ubuntu2', 'i386', 'kinetic', None)
40 assert f"{trigger}" == 'dovecot/1:2.3.19.1+dfsg1-2ubuntu2'40 assert f"{trigger}" == 'dovecot/1:2.3.19.1+dfsg1-2ubuntu2'
4141
4242
43def test_autopkgtest_url():43def test_history_url():
44 """Checks that Trigger objects generate valid autopkgtest urls"""44 """Checks that Trigger objects generate valid autopkgtest history urls"""
45 trigger = Trigger('a', 'b', 'c', 'd')45 trigger = Trigger('a', 'b', 'c', 'd', 'e')
46 expected = "https://autopkgtest.ubuntu.com/packages/a/a/d/c"46 expected = "https://autopkgtest.ubuntu.com/packages/a/a/d/c"
47 assert trigger.autopkgtest_url == expected47 assert trigger.history_url == expected
4848
49 trigger = Trigger('apache2', '2.4', 'amd64', 'kinetic')49 trigger = Trigger('apache2', '2.4', 'amd64', 'kinetic', None)
50 expected = "https://autopkgtest.ubuntu.com/packages/a/apache2/kinetic/amd64"50 expected = "https://autopkgtest.ubuntu.com/packages/a/apache2/kinetic/amd64"
51 assert trigger.autopkgtest_url == expected51 assert trigger.history_url == expected
5252
53 trigger = Trigger('libwebsockets', '4.1.6-3', 'armhf', 'jammy')53 trigger = Trigger('libwebsockets', '4.1.6-3', 'armhf', 'jammy', None)
54 expected = "https://autopkgtest.ubuntu.com/packages/libw/libwebsockets/jammy/armhf"54 expected = "https://autopkgtest.ubuntu.com/packages/libw/libwebsockets/jammy/armhf"
55 assert trigger.autopkgtest_url == expected55 assert trigger.history_url == expected
56
57
58def test_action_url():
59 """Checks that Trigger objects generate valid autopkgtest action urls"""
60 trigger = Trigger('a', 'b', 'c', 'd', 'e')
61 expected = "https://autopkgtest.ubuntu.com/request.cgi?release=d&package=a&arch=c&trigger=a/b&ppa=e"
62 assert trigger.action_url == expected
63
64 trigger = Trigger('apache2', '2.4', 'amd64', 'kinetic', None)
65 expected = "https://autopkgtest.ubuntu.com/request.cgi?release=kinetic&package=apache2&arch=amd64&trigger=apache2/2.4"
66 assert trigger.action_url == expected
67
68 trigger = Trigger('libwebsockets', '4.1.6-3', 'armhf', 'jammy', None)
69 expected = "https://autopkgtest.ubuntu.com/request.cgi?release=jammy&package=libwebsockets&arch=armhf&trigger=libwebsockets/4.1.6-3"
70 assert trigger.action_url == expected

Subscribers

People subscribed via source and target branches

to all changes: