← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~julian-edwards/launchpad/get-incomplete-ppa-copy-jobs into lp:launchpad

 

Julian Edwards has proposed merging lp:~julian-edwards/launchpad/get-incomplete-ppa-copy-jobs into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~julian-edwards/launchpad/get-incomplete-ppa-copy-jobs/+merge/86726

Add PlainPackageCopyJob.getIncompleteJobsForArchive() method which will return all the WAITING, RUNNING or FAILED copy jobs for the passed archive.

This is in preparation to show these jobs on the PPA page.
-- 
https://code.launchpad.net/~julian-edwards/launchpad/get-incomplete-ppa-copy-jobs/+merge/86726
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/launchpad/get-incomplete-ppa-copy-jobs into lp:launchpad.
=== modified file 'lib/lp/soyuz/interfaces/packagecopyjob.py'
--- lib/lp/soyuz/interfaces/packagecopyjob.py	2011-12-05 17:08:48 +0000
+++ lib/lp/soyuz/interfaces/packagecopyjob.py	2011-12-22 15:56:25 +0000
@@ -182,6 +182,15 @@
             `DistroSeriesDifference.parent_source_version`.
         """
 
+    def getIncompleteJobsForArchive(archive):
+        """Find incomplete jobs for each package in `archive`.
+
+        Incomplete jobs are ones in status WAITING, RUNNING or FAILED.
+
+        :param archive: The target `IArchive` for the job.
+        :return: An iterable of `PackageCopyJob`.
+        """
+
 
 class IPlainPackageCopyJob(IRunnableJob):
     """A no-frills job to copy packages between `IArchive`s."""

=== modified file 'lib/lp/soyuz/model/packagecopyjob.py'
--- lib/lp/soyuz/model/packagecopyjob.py	2011-12-21 14:58:31 +0000
+++ lib/lp/soyuz/model/packagecopyjob.py	2011-12-22 15:56:25 +0000
@@ -361,6 +361,19 @@
             result.setdefault(job.package_name, job)
         return result
 
+    @classmethod
+    def getIncompleteJobsForArchive(cls, archive):
+        """See `IPlainPackageCopyJobSource`."""
+        jobs = IStore(PackageCopyJob).find(
+            PackageCopyJob,
+            PackageCopyJob.target_archive == archive,
+            PackageCopyJob.job_type == cls.class_job_type,
+            Job.id == PackageCopyJob.job_id,
+            Job._status.is_in(
+                [JobStatus.WAITING, JobStatus.RUNNING, JobStatus.FAILED])
+            )
+        return DecoratedResultSet(jobs, cls)
+
     @property
     def target_pocket(self):
         return PackagePublishingPocket.items[self.metadata['target_pocket']]

=== modified file 'lib/lp/soyuz/tests/test_packagecopyjob.py'
--- lib/lp/soyuz/tests/test_packagecopyjob.py	2011-12-21 14:58:31 +0000
+++ lib/lp/soyuz/tests/test_packagecopyjob.py	2011-12-22 15:56:25 +0000
@@ -96,6 +96,22 @@
             target_distroseries, target_pocket, requester=requester,
             package_version=dsd.parent_source_version, **kwargs)
 
+    def makePPAJob(self, source_archive=None, target_archive=None, **kwargs):
+        if source_archive is None:
+            source_archive = self.factory.makeArchive(
+                purpose=ArchivePurpose.PPA)
+        if target_archive is None:
+            target_archive = self.factory.makeArchive(
+                purpose=ArchivePurpose.PPA)
+        source_name = self.factory.getUniqueString('src-name')
+        target_series = self.factory.makeDistroSeries()
+        target_pocket = self.factory.getAnyPocket()
+        requester = self.factory.makePerson()
+        return getUtility(IPlainPackageCopyJobSource).create(
+            source_name, source_archive, target_archive,
+            target_series, target_pocket, requester=requester,
+            package_version="1.0", **kwargs)
+
     def runJob(self, job):
         """Helper to switch to the right DB user and run the job."""
         # We are basically mimicking the job runner here.
@@ -530,6 +546,36 @@
         self.assertEqual(
             {}, job_source.getPendingJobsPerPackage(dsd.derived_series))
 
+    def test_getIncompleteJobsForArchive_finds_jobs_in_right_archive(self):
+        # getIncompleteJobsForArchive should return all the jobs in an
+        # specified archive.
+        target1 = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
+        target2 = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
+        job_source = getUtility(IPlainPackageCopyJobSource)
+        target1_jobs = [
+            self.makePPAJob(target_archive=target1)
+            for counter in xrange(2)]
+        self.makePPAJob(target2)
+
+        pending_jobs = list(job_source.getIncompleteJobsForArchive(target1))
+        self.assertContentEqual(pending_jobs, target1_jobs)
+
+    def test_getIncompleteJobsForArchive_finds_failed_and_running_jobs(self):
+        # getIncompleteJobsForArchive should return only waiting, failed
+        # and running jobs.
+        jobs = []
+        ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
+        for status in JobStatus.items:
+            job = self.makePPAJob(target_archive=ppa)
+            removeSecurityProxy(job).job._status = status
+
+        job_source = getUtility(IPlainPackageCopyJobSource)
+        found_jobs = job_source.getIncompleteJobsForArchive(ppa)
+        found_statuses = [job.status for job in found_jobs]
+        self.assertContentEqual(
+            [JobStatus.WAITING, JobStatus.RUNNING, JobStatus.FAILED],
+            found_statuses)
+
     def test_copying_to_main_archive_ancestry_overrides(self):
         # The job will complete right away for auto-approved copies to a
         # main archive and apply any ancestry overrides.

=== modified file 'lib/lp/testing/__init__.py'
--- lib/lp/testing/__init__.py	2011-12-21 19:44:48 +0000
+++ lib/lp/testing/__init__.py	2011-12-22 15:56:25 +0000
@@ -98,7 +98,11 @@
 import testtools
 from testtools.content import Content
 from testtools.content_type import UTF8_TEXT
-from testtools.matchers import MatchesRegex
+from testtools.matchers import (
+    Equals,
+    MatchesRegex,
+    MatchesSetwise,
+    )
 from testtools.testcase import ExpectedException as TTExpectedException
 import transaction
 from zope.component import (
@@ -519,10 +523,7 @@
 
     def assertContentEqual(self, iter1, iter2):
         """Assert that 'iter1' has the same content as 'iter2'."""
-        list1 = sorted(iter1)
-        list2 = sorted(iter2)
-        self.assertEqual(
-            list1, list2, '%s != %s' % (pformat(list1), pformat(list2)))
+        self.assertThat(iter1, MatchesSetwise(*(map(Equals, iter2))))
 
     def assertRaisesWithContent(self, exception, exception_content,
                                 func, *args):