launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #22800
[Merge] lp:~cjwatson/launchpad/snap-build-request-date-attrs into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/snap-build-request-date-attrs into lp:launchpad.
Commit message:
Add and export SnapBuildRequest.date_requested and SnapBuildRequest.date_finished.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1770400 in Launchpad itself: "Support snapcraft architectures keyword"
https://bugs.launchpad.net/launchpad/+bug/1770400
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/snap-build-request-date-attrs/+merge/352468
This will let build.snapcraft.io intersperse these appropriately with builds.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/snap-build-request-date-attrs into lp:launchpad.
=== modified file 'lib/lp/snappy/interfaces/snap.py'
--- lib/lp/snappy/interfaces/snap.py 2018-06-18 22:08:58 +0000
+++ lib/lp/snappy/interfaces/snap.py 2018-08-06 15:25:54 +0000
@@ -289,6 +289,14 @@
id = Int(title=_("ID"), required=True, readonly=True)
+ date_requested = exported(Datetime(
+ title=_("The time when this request was made"),
+ required=True, readonly=True))
+
+ date_finished = exported(Datetime(
+ title=_("The time when this request finished"),
+ required=False, readonly=True))
+
snap = exported(Reference(
# Really ISnap, patched in lp.snappy.interfaces.webservice.
Interface,
=== modified file 'lib/lp/snappy/interfaces/snapjob.py'
--- lib/lp/snappy/interfaces/snapjob.py 2018-06-15 13:21:14 +0000
+++ lib/lp/snappy/interfaces/snapjob.py 2018-08-06 15:25:54 +0000
@@ -19,6 +19,7 @@
)
from zope.schema import (
Choice,
+ Datetime,
Dict,
List,
TextLine,
@@ -74,6 +75,14 @@
"supported."),
key_type=TextLine(), required=False, readonly=True)
+ date_created = Datetime(
+ title=_("Time when this job was created."),
+ required=True, readonly=True)
+
+ date_finished = Datetime(
+ title=_("Time when this job finished."),
+ required=True, readonly=True)
+
error_message = TextLine(
title=_("Error message resulting from running this job."),
required=False, readonly=True)
=== modified file 'lib/lp/snappy/model/snap.py'
--- lib/lp/snappy/model/snap.py 2018-07-30 09:07:30 +0000
+++ lib/lp/snappy/model/snap.py 2018-08-06 15:25:54 +0000
@@ -182,6 +182,16 @@
self.id = id
@property
+ def date_requested(self):
+ """See `ISnapBuildRequest`."""
+ return self._job.date_created
+
+ @property
+ def date_finished(self):
+ """See `ISnapBuildRequest`."""
+ return self._job.date_finished
+
+ @property
def status(self):
"""See `ISnapBuildRequest`."""
status_map = {
=== modified file 'lib/lp/snappy/model/snapjob.py'
--- lib/lp/snappy/model/snapjob.py 2018-06-15 13:21:14 +0000
+++ lib/lp/snappy/model/snapjob.py 2018-08-06 15:25:54 +0000
@@ -233,6 +233,16 @@
return self.metadata["channels"]
@property
+ def date_created(self):
+ """See `ISnapRequestBuildsJob`."""
+ return self.context.job.date_created
+
+ @property
+ def date_finished(self):
+ """See `ISnapRequestBuildsJob`."""
+ return self.context.job.date_finished
+
+ @property
def error_message(self):
"""See `ISnapRequestBuildsJob`."""
return self.metadata.get("error_message")
=== modified file 'lib/lp/snappy/tests/test_snap.py'
--- lib/lp/snappy/tests/test_snap.py 2018-07-30 09:07:30 +0000
+++ lib/lp/snappy/tests/test_snap.py 2018-08-06 15:25:54 +0000
@@ -16,6 +16,7 @@
from urlparse import urlsplit
from fixtures import MockPatch
+import iso8601
from lazr.lifecycle.event import ObjectModifiedEvent
from pymacaroons import Macaroon
import pytz
@@ -26,7 +27,10 @@
AfterPreprocessing,
ContainsDict,
Equals,
+ GreaterThan,
Is,
+ LessThan,
+ MatchesAll,
MatchesDict,
MatchesSetwise,
MatchesStructure,
@@ -65,7 +69,10 @@
UTC_NOW,
)
from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import flush_database_caches
+from lp.services.database.sqlbase import (
+ flush_database_caches,
+ get_transaction_timestamp,
+ )
from lp.services.features.testing import (
FeatureFixture,
MemoryFeatureFixture,
@@ -372,12 +379,15 @@
# requestBuilds schedules a job and returns a corresponding
# SnapBuildRequest.
snap = self.factory.makeSnap()
+ now = get_transaction_timestamp(IStore(snap))
with person_logged_in(snap.owner.teamowner):
request = snap.requestBuilds(
snap.owner.teamowner, snap.distro_series.main_archive,
PackagePublishingPocket.UPDATES,
channels={"snapcraft": "edge"})
self.assertThat(request, MatchesStructure(
+ date_requested=Equals(now),
+ date_finished=Is(None),
snap=Equals(snap),
status=Equals(SnapBuildRequestStatus.PENDING),
error_message=Is(None),
@@ -434,6 +444,9 @@
- build-on: avr
""")))
job = self.makeRequestBuildsJob(["sparc"])
+ self.assertEqual(
+ get_transaction_timestamp(IStore(job.snap)), job.date_created)
+ transaction.commit()
with person_logged_in(job.requester):
builds = job.snap.requestBuildsFromJob(
job.requester, job.archive, job.pocket,
@@ -446,6 +459,9 @@
# architectures.
self.useFixture(GitHostingFixture(blob="name: foo\n"))
job = self.makeRequestBuildsJob(["mips64el", "riscv64"])
+ self.assertEqual(
+ get_transaction_timestamp(IStore(job.snap)), job.date_created)
+ transaction.commit()
with person_logged_in(job.requester):
builds = job.snap.requestBuildsFromJob(
job.requester, job.archive, job.pocket,
@@ -460,6 +476,9 @@
repository_url="https://example.com/foo.git")
job = self.makeRequestBuildsJob(
["mips64el", "riscv64"], git_ref=git_ref)
+ self.assertEqual(
+ get_transaction_timestamp(IStore(job.snap)), job.date_created)
+ transaction.commit()
with person_logged_in(job.requester):
builds = job.snap.requestBuildsFromJob(
job.requester, job.archive, job.pocket,
@@ -2552,6 +2571,7 @@
[git_ref] = self.factory.makeGitRefs()
snap = self.makeSnap(
git_ref=git_ref, distroseries=distroseries, processors=processors)
+ now = get_transaction_timestamp(IStore(distroseries))
response = self.webservice.named_post(
snap["self_link"], "requestBuilds", archive=archive_url,
pocket="Updates", channels={"snapcraft": "edge"})
@@ -2559,6 +2579,9 @@
build_request_url = response.getHeader("Location")
build_request = self.webservice.get(build_request_url).jsonBody()
self.assertThat(build_request, ContainsDict({
+ "date_requested": AfterPreprocessing(
+ iso8601.parse_date, GreaterThan(now)),
+ "date_finished": Is(None),
"snap_link": Equals(snap["self_link"]),
"status": Equals("Pending"),
"error_message": Is(None),
@@ -2573,9 +2596,16 @@
[job] = getUtility(ISnapRequestBuildsJobSource).iterReady()
with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
JobRunner([job]).runAll()
+ date_requested = iso8601.parse_date(build_request["date_requested"])
+ now = get_transaction_timestamp(IStore(distroseries))
build_request = self.webservice.get(
build_request["self_link"]).jsonBody()
self.assertThat(build_request, ContainsDict({
+ "date_requested": AfterPreprocessing(
+ iso8601.parse_date, Equals(date_requested)),
+ "date_finished": AfterPreprocessing(
+ iso8601.parse_date,
+ MatchesAll(GreaterThan(date_requested), LessThan(now))),
"snap_link": Equals(snap["self_link"]),
"status": Equals("Completed"),
"error_message": Is(None),
@@ -2608,6 +2638,7 @@
snap = self.makeSnap(
git_ref=git_ref, distroseries=distroseries,
processors=[processor])
+ now = get_transaction_timestamp(IStore(distroseries))
response = self.webservice.named_post(
snap["self_link"], "requestBuilds", archive=archive_url,
pocket="Updates")
@@ -2615,6 +2646,9 @@
build_request_url = response.getHeader("Location")
build_request = self.webservice.get(build_request_url).jsonBody()
self.assertThat(build_request, ContainsDict({
+ "date_requested": AfterPreprocessing(
+ iso8601.parse_date, GreaterThan(now)),
+ "date_finished": Is(None),
"snap_link": Equals(snap["self_link"]),
"status": Equals("Pending"),
"error_message": Is(None),
@@ -2627,9 +2661,16 @@
[job] = getUtility(ISnapRequestBuildsJobSource).iterReady()
with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
JobRunner([job]).runAll()
+ date_requested = iso8601.parse_date(build_request["date_requested"])
+ now = get_transaction_timestamp(IStore(distroseries))
build_request = self.webservice.get(
build_request["self_link"]).jsonBody()
self.assertThat(build_request, ContainsDict({
+ "date_requested": AfterPreprocessing(
+ iso8601.parse_date, Equals(date_requested)),
+ "date_finished": AfterPreprocessing(
+ iso8601.parse_date,
+ MatchesAll(GreaterThan(date_requested), LessThan(now))),
"snap_link": Equals(snap["self_link"]),
"status": Equals("Failed"),
"error_message": Equals("Something went wrong"),
=== modified file 'lib/lp/snappy/tests/test_snapjob.py'
--- lib/lp/snappy/tests/test_snapjob.py 2018-06-15 12:54:27 +0000
+++ lib/lp/snappy/tests/test_snapjob.py 2018-08-06 15:25:54 +0000
@@ -13,7 +13,10 @@
AfterPreprocessing,
ContainsDict,
Equals,
+ GreaterThan,
Is,
+ LessThan,
+ MatchesAll,
MatchesSetwise,
MatchesStructure,
)
@@ -21,6 +24,8 @@
from lp.code.tests.helpers import GitHostingFixture
from lp.registry.interfaces.pocket import PackagePublishingPocket
from lp.services.config import config
+from lp.services.database.interfaces import IStore
+from lp.services.database.sqlbase import get_transaction_timestamp
from lp.services.job.interfaces.job import JobStatus
from lp.services.job.runner import JobRunner
from lp.services.mail.sendmail import format_address_for_person
@@ -97,6 +102,7 @@
[git_ref] = self.factory.makeGitRefs()
snap = self.factory.makeSnap(
git_ref=git_ref, distroseries=distroseries, processors=processors)
+ expected_date_created = get_transaction_timestamp(IStore(snap))
job = SnapRequestBuildsJob.create(
snap, snap.registrant, distroseries.main_archive,
PackagePublishingPocket.RELEASE, {"core": "stable"})
@@ -108,9 +114,13 @@
self.useFixture(GitHostingFixture(blob=snapcraft_yaml))
with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
JobRunner([job]).runAll()
+ now = get_transaction_timestamp(IStore(snap))
self.assertEmailQueueLength(0)
self.assertThat(job, MatchesStructure(
job=MatchesStructure.byEquality(status=JobStatus.COMPLETED),
+ date_created=Equals(expected_date_created),
+ date_finished=MatchesAll(
+ GreaterThan(expected_date_created), LessThan(now)),
error_message=Is(None),
builds=AfterPreprocessing(set, MatchesSetwise(*[
MatchesStructure.byEquality(
@@ -131,6 +141,7 @@
[git_ref] = self.factory.makeGitRefs()
snap = self.factory.makeSnap(
git_ref=git_ref, distroseries=distroseries, processors=processors)
+ expected_date_created = get_transaction_timestamp(IStore(snap))
job = SnapRequestBuildsJob.create(
snap, snap.registrant, distroseries.main_archive,
PackagePublishingPocket.RELEASE, {"core": "stable"})
@@ -138,6 +149,7 @@
CannotParseSnapcraftYaml("Nonsense on stilts"))
with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
JobRunner([job]).runAll()
+ now = get_transaction_timestamp(IStore(snap))
[notification] = self.assertEmailQueueLength(1)
self.assertThat(dict(notification), ContainsDict({
"From": Equals(config.canonical.noreply_from_address),
@@ -151,5 +163,8 @@
notification.get_payload(decode=True))
self.assertThat(job, MatchesStructure(
job=MatchesStructure.byEquality(status=JobStatus.FAILED),
+ date_created=Equals(expected_date_created),
+ date_finished=MatchesAll(
+ GreaterThan(expected_date_created), LessThan(now)),
error_message=Equals("Nonsense on stilts"),
builds=AfterPreprocessing(set, MatchesSetwise())))
Follow ups