~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/registry/tests/test_distroseriesdifference.py

Merge db-devel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2010 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2010-2011 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
"""Model tests for the DistroSeriesDifference class."""
9
9
from storm.store import Store
10
10
import transaction
11
11
from zope.component import getUtility
 
12
from zope.security.interfaces import Unauthorized
12
13
from zope.security.proxy import removeSecurityProxy
13
14
 
14
15
from canonical.launchpad.webapp.authorization import check_permission
35
36
    most_recent_publications,
36
37
    )
37
38
from lp.services.propertycache import get_property_cache
 
39
from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
38
40
from lp.soyuz.enums import PackageDiffStatus
39
41
from lp.soyuz.interfaces.publishing import PackagePublishingStatus
40
42
from lp.testing import (
111
113
        self.assertEqual(
112
114
            'foonew', ds_diff.parent_source_pub.source_package_name)
113
115
        self.assertEqual(
114
 
            ds_diff.derived_series.previous_series,
115
 
            ds_diff.parent_source_pub.distroseries)
 
116
            ds_diff.parent_series, ds_diff.parent_source_pub.distroseries)
116
117
 
117
118
    def test_parent_source_pub_gets_latest_pending(self):
118
119
        # The most recent publication is always returned, even if its pending.
120
121
            source_package_name_str="foonew")
121
122
        pending_pub = self.factory.makeSourcePackagePublishingHistory(
122
123
            sourcepackagename=ds_diff.source_package_name,
123
 
            distroseries=ds_diff.derived_series.previous_series,
 
124
            distroseries=ds_diff.parent_series,
124
125
            status=PackagePublishingStatus.PENDING)
125
126
 
126
127
        self.assertEqual(pending_pub, ds_diff.parent_source_pub)
150
151
                'parent': '1.0',
151
152
                'derived': '0.9',
152
153
                })
153
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
154
        self.factory.makeSourcePackagePublishingHistory(
154
155
            sourcepackagename=ds_diff.source_package_name,
155
156
            distroseries=ds_diff.derived_series,
156
157
            status=PackagePublishingStatus.PENDING,
171
172
            versions=['1.0', '1.2'])
172
173
        parent_changelog = self.factory.makeChangelog(
173
174
            versions=['1.0', '1.3'])
174
 
        transaction.commit() # Yay, librarian.
 
175
        transaction.commit()  # Yay, librarian.
175
176
        ds_diff = self.factory.makeDistroSeriesDifference(versions={
176
177
            'derived': '1.2',
177
178
            'parent': '1.3',
190
191
 
191
192
        # Resolve the DSD by making the same package version published
192
193
        # in parent and derived.
193
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
194
        self.factory.makeSourcePackagePublishingHistory(
194
195
            sourcepackagename=ds_diff.source_package_name,
195
196
            distroseries=ds_diff.derived_series,
196
197
            status=PackagePublishingStatus.PENDING,
197
198
            version='1.4')
198
 
        new_parent_pub = self.factory.makeSourcePackagePublishingHistory(
 
199
        self.factory.makeSourcePackagePublishingHistory(
199
200
            sourcepackagename=ds_diff.source_package_name,
200
 
            distroseries=ds_diff.derived_series.previous_series,
 
201
            distroseries=ds_diff.parent_series,
201
202
            status=PackagePublishingStatus.PENDING,
202
203
            version='1.4')
203
204
 
209
210
        self.assertIs(None, ds_diff.package_diff)
210
211
        self.assertIs(None, ds_diff.parent_package_diff)
211
212
 
212
 
    def test_update_re_opens_difference(self):
213
 
        # The status of a resolved difference will updated with new
214
 
        # uploads.
215
 
        ds_diff = self.factory.makeDistroSeriesDifference(
216
 
            source_package_name_str="foonew",
217
 
            versions={
218
 
                'parent': '1.0',
219
 
                'derived': '1.0',
220
 
                },
221
 
            status=DistroSeriesDifferenceStatus.RESOLVED)
222
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
213
    def test_parent_update_re_opens_difference(self):
 
214
        # The status of a resolved difference will be updated to
 
215
        # NEEDS_ATTENTION with parent uploads.
 
216
        ds_diff = self.factory.makeDistroSeriesDifference(
 
217
            source_package_name_str="foonew",
 
218
            versions=dict(parent='1.0', derived='1.0'),
 
219
            status=DistroSeriesDifferenceStatus.RESOLVED)
 
220
        new_parent_pub = self.factory.makeSourcePackagePublishingHistory(
 
221
            sourcepackagename=ds_diff.source_package_name,
 
222
            distroseries=ds_diff.parent_series,
 
223
            status=PackagePublishingStatus.PENDING,
 
224
            version='1.1')
 
225
 
 
226
        was_updated = ds_diff.update()
 
227
 
 
228
        self.assertTrue(was_updated)
 
229
        self.assertEqual(
 
230
            DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
 
231
            ds_diff.status)
 
232
 
 
233
    def test_child_update_re_opens_difference(self):
 
234
        # The status of a resolved difference will updated to
 
235
        # BLACKLISTED_CURRENT with child uploads.
 
236
        ds_diff = self.factory.makeDistroSeriesDifference(
 
237
            source_package_name_str="foonew",
 
238
            versions=dict(parent='1.0', derived='1.0'),
 
239
            status=DistroSeriesDifferenceStatus.RESOLVED)
 
240
        self.factory.makeSourcePackagePublishingHistory(
223
241
            sourcepackagename=ds_diff.source_package_name,
224
242
            distroseries=ds_diff.derived_series,
225
243
            status=PackagePublishingStatus.PENDING,
229
247
 
230
248
        self.assertTrue(was_updated)
231
249
        self.assertEqual(
232
 
            DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
 
250
            DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT,
233
251
            ds_diff.status)
234
252
 
235
253
    def test_update_new_version_doesnt_change_status(self):
241
259
                'parent': '1.0',
242
260
                'derived': '0.9',
243
261
                })
244
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
262
        self.factory.makeSourcePackagePublishingHistory(
245
263
            sourcepackagename=ds_diff.source_package_name,
246
264
            distroseries=ds_diff.derived_series,
247
265
            status=PackagePublishingStatus.PENDING,
267
285
                },
268
286
            difference_type=(
269
287
                DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES))
270
 
        new_parent_pub = self.factory.makeSourcePackagePublishingHistory(
 
288
        self.factory.makeSourcePackagePublishingHistory(
271
289
            sourcepackagename=ds_diff.source_package_name,
272
 
            distroseries=ds_diff.derived_series.previous_series,
 
290
            distroseries=ds_diff.parent_series,
273
291
            status=PackagePublishingStatus.PENDING,
274
292
            version='1.1')
275
293
 
291
309
            difference_type=(
292
310
                DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES),
293
311
            status=DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT)
294
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
312
        self.factory.makeSourcePackagePublishingHistory(
295
313
            sourcepackagename=ds_diff.source_package_name,
296
314
            distroseries=ds_diff.derived_series,
297
315
            status=PackagePublishingStatus.PENDING,
316
334
                'parent': '1.0',
317
335
                },
318
336
            status=DistroSeriesDifferenceStatus.BLACKLISTED_ALWAYS)
319
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
337
        self.factory.makeSourcePackagePublishingHistory(
320
338
            sourcepackagename=ds_diff.source_package_name,
321
339
            distroseries=ds_diff.derived_series,
322
340
            status=PackagePublishingStatus.PENDING,
331
349
 
332
350
    def test_title(self):
333
351
        # The title is a friendly description of the difference.
334
 
        previous_series = self.factory.makeDistroSeries(name="lucid")
335
 
        derived_series = self.factory.makeDistroSeries(
336
 
            previous_series=previous_series, name="derilucid")
 
352
        parent_series = self.factory.makeDistroSeries(name="lucid")
 
353
        derived_series = self.factory.makeDistroSeries(name="derilucid")
 
354
        self.factory.makeDistroSeriesParent(
 
355
            derived_series=derived_series, parent_series=parent_series)
337
356
        ds_diff = self.factory.makeDistroSeriesDifference(
338
357
            source_package_name_str="foonew", derived_series=derived_series,
339
358
            versions={
395
414
        person = self.factory.makePerson()
396
415
        with person_logged_in(person):
397
416
            self.assertTrue(check_permission('launchpad.Edit', ds_diff))
398
 
            diff_comment = ds_diff.addComment(
399
 
                ds_diff.derived_series.owner, "Boo")
 
417
            ds_diff.addComment(ds_diff.derived_series.owner, "Boo")
400
418
 
401
419
    def _setupPackageSets(self, ds_diff, distroseries, nb_packagesets):
402
420
        # Helper method to create packages sets.
409
427
                packagesets.append(ps)
410
428
        return packagesets
411
429
 
412
 
    def test_getParentPackageSets(self):
 
430
    def test_parent_packagesets(self):
413
431
        # All parent's packagesets are returned ordered alphabetically.
414
432
        ds_diff = self.factory.makeDistroSeriesDifference()
415
433
        packagesets = self._setupPackageSets(
416
 
            ds_diff, ds_diff.derived_series.previous_series, 5)
417
 
        parent_packagesets = ds_diff.getParentPackageSets()
 
434
            ds_diff, ds_diff.parent_series, 5)
 
435
        parent_packagesets = ds_diff.parent_packagesets
418
436
        self.assertEquals(
419
437
            sorted([packageset.name for packageset in packagesets]),
420
438
            [packageset.name for packageset in parent_packagesets])
421
439
 
422
 
    def test_getPackageSets(self):
 
440
    def test_packagesets(self):
423
441
        # All the packagesets are returned ordered alphabetically.
424
442
        ds_diff = self.factory.makeDistroSeriesDifference()
425
443
        packagesets = self._setupPackageSets(
426
444
            ds_diff, ds_diff.derived_series, 5)
427
445
        self.assertEquals(
428
446
            sorted([packageset.name for packageset in packagesets]),
429
 
            [packageset.name for packageset in ds_diff.getPackageSets()])
 
447
            [packageset.name for packageset in ds_diff.packagesets])
 
448
 
 
449
    def test_blacklist_unauthorised(self):
 
450
        # If you're not an archive admin, you don't get to blacklist or
 
451
        # unblacklist.
 
452
        ds_diff = self.factory.makeDistroSeriesDifference()
 
453
        random_joe = self.factory.makePerson()
 
454
        with person_logged_in(random_joe):
 
455
            self.assertRaises(Unauthorized, getattr, ds_diff, 'blacklist')
 
456
            self.assertRaises(Unauthorized, getattr, ds_diff, 'unblacklist')
430
457
 
431
458
    def test_blacklist_default(self):
432
459
        # By default the current version is blacklisted.
433
460
        ds_diff = self.factory.makeDistroSeriesDifference()
 
461
        admin = self.factory.makeArchiveAdmin(
 
462
            ds_diff.derived_series.main_archive)
434
463
 
435
 
        with person_logged_in(self.factory.makePerson()):
 
464
        with person_logged_in(admin):
436
465
            ds_diff.blacklist()
437
466
 
438
467
        self.assertEqual(
442
471
    def test_blacklist_all(self):
443
472
        # All versions are blacklisted with the all=True param.
444
473
        ds_diff = self.factory.makeDistroSeriesDifference()
 
474
        admin = self.factory.makeArchiveAdmin(
 
475
            ds_diff.derived_series.main_archive)
445
476
 
446
 
        with person_logged_in(self.factory.makePerson()):
 
477
        with person_logged_in(admin):
447
478
            ds_diff.blacklist(all=True)
448
479
 
449
480
        self.assertEqual(
454
485
        # Unblacklisting will return to NEEDS_ATTENTION by default.
455
486
        ds_diff = self.factory.makeDistroSeriesDifference(
456
487
            status=DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT)
 
488
        admin = self.factory.makeArchiveAdmin(
 
489
            ds_diff.derived_series.main_archive)
457
490
 
458
 
        with person_logged_in(self.factory.makePerson()):
 
491
        with person_logged_in(admin):
459
492
            ds_diff.unblacklist()
460
493
 
461
494
        self.assertEqual(
470
503
                'parent': '1.0',
471
504
                },
472
505
            status=DistroSeriesDifferenceStatus.BLACKLISTED_ALWAYS)
473
 
        new_derived_pub = self.factory.makeSourcePackagePublishingHistory(
 
506
        self.factory.makeSourcePackagePublishingHistory(
474
507
            sourcepackagename=ds_diff.source_package_name,
475
508
            distroseries=ds_diff.derived_series,
476
509
            status=PackagePublishingStatus.PENDING,
477
510
            version='1.0')
478
511
 
479
 
        with person_logged_in(self.factory.makePerson()):
 
512
        admin = self.factory.makeArchiveAdmin(
 
513
            ds_diff.derived_series.main_archive)
 
514
        with person_logged_in(admin):
480
515
            ds_diff.unblacklist()
481
516
 
482
517
        self.assertEqual(
508
543
    def test_base_version_none(self):
509
544
        # The attribute is set to None if there is no common base version.
510
545
        # Publish different versions in the series.
511
 
        derived_series = self.factory.makeDistroSeries(
512
 
            previous_series=self.factory.makeDistroSeries())
 
546
        dsp = self.factory.makeDistroSeriesParent()
513
547
        source_package_name = self.factory.getOrMakeSourcePackageName('foo')
514
548
        self.factory.makeSourcePackagePublishingHistory(
515
 
            distroseries=derived_series,
 
549
            distroseries=dsp.derived_series,
516
550
            version='1.0deri1',
517
551
            sourcepackagename=source_package_name,
518
552
            status=PackagePublishingStatus.PUBLISHED)
519
553
        self.factory.makeSourcePackagePublishingHistory(
520
 
            distroseries=derived_series.previous_series,
 
554
            distroseries=dsp.parent_series,
521
555
            version='1.0ubu2',
522
556
            sourcepackagename=source_package_name,
523
557
            status=PackagePublishingStatus.PUBLISHED)
527
561
 
528
562
    def test_base_version_multiple(self):
529
563
        # The latest common base version is set as the base-version.
530
 
        derived_series = self.factory.makeDistroSeries(
531
 
            previous_series=self.factory.makeDistroSeries())
532
 
        source_package_name = self.factory.getOrMakeSourcePackageName('foo')
 
564
        dsp = self.factory.makeDistroSeriesParent()
 
565
        self.factory.getOrMakeSourcePackageName('foo')
533
566
        # Create changelogs for both.
534
567
        changelog_lfa = self.factory.makeChangelog('foo', ['1.2', '1.1'])
535
568
        parent_changelog_lfa = self.factory.makeChangelog('foo', ['1.1'])
536
 
        transaction.commit() # Yay, librarian.
 
569
        transaction.commit()  # Yay, librarian.
537
570
 
538
571
        ds_diff = self.factory.makeDistroSeriesDifference(
539
 
            derived_series=derived_series, source_package_name_str='foo',
 
572
            derived_series=dsp.derived_series, source_package_name_str='foo',
540
573
            versions={
541
574
                'derived': '1.2',
542
575
                'parent': '1.3',
550
583
    def test_base_version_invalid(self):
551
584
        # If the maximum base version is invalid, it is discarded and not
552
585
        # set as the base version.
553
 
        derived_series = self.factory.makeDistroSeries(
554
 
            previous_series=self.factory.makeDistroSeries())
555
 
        source_package_name = self.factory.getOrMakeSourcePackageName('foo')
 
586
        dsp = self.factory.makeDistroSeriesParent()
 
587
        self.factory.getOrMakeSourcePackageName('foo')
556
588
        # Create changelogs for both.
557
589
        changelog_lfa = self.factory.makeChangelog(
558
590
            'foo', ['1:2.0-1', 'a1:1.8.8-070403-1~priv1', '1:1.7-1'])
559
591
        parent_changelog_lfa = self.factory.makeChangelog(
560
592
            'foo', ['1:2.0-2', 'a1:1.8.8-070403-1~priv1', '1:1.7-1'])
561
 
        transaction.commit() # Yay, librarian.
 
593
        transaction.commit()  # Yay, librarian.
562
594
 
563
595
        ds_diff = self.factory.makeDistroSeriesDifference(
564
 
            derived_series=derived_series, source_package_name_str='foo',
 
596
            derived_series=dsp.derived_series, source_package_name_str='foo',
565
597
            versions={
566
598
                'derived': '1:2.0-1',
567
599
                'parent': '1:2.0-2',
586
618
            versions=['1.0', '1.2'])
587
619
        parent_changelog = self.factory.makeChangelog(
588
620
            versions=['1.0', '1.3'])
589
 
        transaction.commit() # Yay, librarian.
 
621
        transaction.commit()  # Yay, librarian.
590
622
 
591
623
        ds_diff = self.factory.makeDistroSeriesDifference(versions={
592
624
            'derived': '1.2',
600
632
 
601
633
        base_pub = ds_diff.base_source_pub
602
634
        self.assertEqual('1.0', base_pub.source_package_version)
603
 
        self.assertEqual(
604
 
            ds_diff.derived_series.previous_series, base_pub.distroseries)
 
635
        self.assertEqual(ds_diff.parent_series, base_pub.distroseries)
605
636
 
606
637
    def test_base_source_pub_not_published(self):
607
638
        # If the base version isn't published, the base version is
610
641
            versions=['1.0', '1.2'])
611
642
        parent_changelog = self.factory.makeChangelog(
612
643
            versions=['1.0', '1.3'])
613
 
        transaction.commit() # Yay, librarian.
 
644
        transaction.commit()  # Yay, librarian.
614
645
 
615
646
        ds_diff = self.factory.makeDistroSeriesDifference(versions={
616
647
            'derived': '1.2',
630
661
            versions=['1.0', '1.2'])
631
662
        parent_changelog = self.factory.makeChangelog(
632
663
            versions=['1.0', '1.3'])
633
 
        transaction.commit() # Yay, librarian.
 
664
        transaction.commit()  # Yay, librarian.
634
665
 
635
666
        ds_diff = self.factory.makeDistroSeriesDifference(
636
667
            versions={
660
691
        # {derived,parent}_versions must be ordered (e.g. ['1.1',
661
692
        # '1.2', '1.3']).
662
693
        if status is None:
663
 
            status=DistroSeriesDifferenceStatus.NEEDS_ATTENTION
 
694
            status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION
664
695
        derived_changelog = self.factory.makeChangelog(
665
696
            versions=derived_versions)
666
697
        parent_changelog = self.factory.makeChangelog(
667
698
            versions=parent_versions)
668
 
        transaction.commit() # Yay, librarian.
 
699
        transaction.commit()  # Yay, librarian.
669
700
        ds_diff = self.factory.makeDistroSeriesDifference(
670
701
            status=status,
671
702
            versions={
743
774
    def test_source_package_release_pending(self):
744
775
        # source_package_release returns the package release of version
745
776
        # source_version with status PUBLISHED or PENDING.
746
 
        derived_series = self.factory.makeDistroSeries(
747
 
            previous_series=self.factory.makeDistroSeries())
 
777
        dsp = self.factory.makeDistroSeriesParent()
748
778
        source_package_name = self.factory.getOrMakeSourcePackageName('foo')
749
779
        versions = {'derived': u'1.2', 'parent': u'1.3'}
750
780
 
751
781
        ds_diff = self.factory.makeDistroSeriesDifference(
752
 
            derived_series=derived_series,
 
782
            derived_series=dsp.derived_series,
753
783
            source_package_name_str=source_package_name.name,
754
784
            versions=versions)
755
785
 
756
786
        # Create pending source package releases.
757
787
        self.factory.makeSourcePackagePublishingHistory(
758
 
            distroseries=derived_series,
 
788
            distroseries=dsp.derived_series,
759
789
            version='1.4',
760
790
            sourcepackagename=source_package_name,
761
791
            status=PackagePublishingStatus.PENDING)
762
792
        self.factory.makeSourcePackagePublishingHistory(
763
 
            distroseries=derived_series.previous_series,
 
793
            distroseries=dsp.parent_series,
764
794
            version='1.5',
765
795
            sourcepackagename=source_package_name,
766
796
            status=PackagePublishingStatus.PENDING)
778
808
    def createPublication(self, spn, versions, distroseries,
779
809
                          status=PackagePublishingStatus.PUBLISHED):
780
810
        changelog_lfa = self.factory.makeChangelog(spn.name, versions)
781
 
        transaction.commit() # Yay, librarian.
 
811
        transaction.commit()  # Yay, librarian.
782
812
        spr = self.factory.makeSourcePackageRelease(
783
813
            sourcepackagename=spn, version=versions[0],
784
814
            changelog=changelog_lfa)
789
819
    def test_existing_packagediff_is_linked_when_dsd_created(self):
790
820
        # When a relevant packagediff already exists, it is linked to the
791
821
        # DSD when it is created.
792
 
        derived_series = self.factory.makeDistroSeries(
793
 
            previous_series=self.factory.makeDistroSeries())
 
822
        dsp = self.factory.makeDistroSeriesParent()
794
823
        spn = self.factory.getOrMakeSourcePackageName(
795
824
            name=self.factory.getUniqueString())
796
 
        parent_spph = self.createPublication(
797
 
            spn, ['1.2-1', '1.0-1'], derived_series.previous_series)
 
825
        self.createPublication(
 
826
            spn, ['1.2-1', '1.0-1'], dsp.parent_series)
798
827
        spph = self.createPublication(
799
 
            spn, ['1.1-1', '1.0-1'], derived_series)
 
828
            spn, ['1.1-1', '1.0-1'], dsp.derived_series)
800
829
        base_spph = self.createPublication(
801
 
            spn, ['1.0-1'], derived_series,
 
830
            spn, ['1.0-1'], dsp.derived_series,
802
831
            status=PackagePublishingStatus.SUPERSEDED)
803
832
        pd = self.factory.makePackageDiff(
804
833
            from_source=base_spph.sourcepackagerelease,
806
835
        # factory.makeDistroSeriesDifference() will always create
807
836
        # publications to be helpful. We don't need the help in this case.
808
837
        dsd = getUtility(IDistroSeriesDifferenceSource).new(
809
 
            derived_series, spn)
 
838
            dsp.derived_series, spn)
810
839
        self.assertEqual(pd, dsd.package_diff)
811
840
 
812
841
    def _initDiffWithMultiplePendingPublications(self, versions, parent):
813
842
        ds_diff = self.factory.makeDistroSeriesDifference(versions=versions)
814
843
        if parent:
815
 
            series = ds_diff.derived_series.previous_series
 
844
            series = ds_diff.parent_series
816
845
            version = versions.get('parent')
817
846
        else:
818
847
            series = ds_diff.derived_series
876
905
 
877
906
        verifyObject(IDistroSeriesDifferenceSource, dsd_source)
878
907
 
879
 
    def makeDiffsForDistroSeries(self, derived_series):
 
908
    def makeDiffsForDistroSeries(self, derived_series, parent_series=None):
880
909
        # Helper that creates a range of differences for a derived
881
910
        # series.
882
911
        diffs = {
886
915
            }
887
916
        diffs['normal'].append(
888
917
            self.factory.makeDistroSeriesDifference(
889
 
                derived_series=derived_series))
 
918
                derived_series=derived_series, parent_series=parent_series))
890
919
        diffs['unique'].append(
891
920
            self.factory.makeDistroSeriesDifference(
892
921
                derived_series=derived_series,
 
922
                parent_series=parent_series,
893
923
                difference_type=(
894
924
                    DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES)))
895
925
        diffs['ignored'].append(
896
926
            self.factory.makeDistroSeriesDifference(
897
927
                derived_series=derived_series,
 
928
                parent_series=parent_series,
898
929
                status=DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT))
899
930
        return diffs
900
931
 
901
 
    def makeDerivedSeries(self):
 
932
    def makeDerivedSeries(self, derived_series=None):
902
933
        # Keep tests DRY.
903
 
        return self.factory.makeDistroSeries(
904
 
            previous_series=self.factory.makeDistroSeries())
 
934
        dsp = self.factory.makeDistroSeriesParent(
 
935
            derived_series=derived_series)
 
936
        return dsp.derived_series
 
937
 
 
938
    def makeVersionDifference(self, derived_series=None, changed_parent=False,
 
939
                              changed_child=False, status=None):
 
940
        """Create a `DistroSeriesDifference` between package versions.
 
941
 
 
942
        The differing package will exist in both the parent series and in the
 
943
        child.
 
944
 
 
945
        :param derived_series: Optional `DistroSeries` that the difference is
 
946
            for.  If not given, one will be created.
 
947
        :param changed_parent: Whether the difference should show a change in
 
948
            the parent's version of the package.
 
949
        :param changed_child: Whether the difference should show a change in
 
950
            the child's version of the package.
 
951
        :param status: Optional status for the `DistroSeriesDifference`.  If
 
952
            not given, defaults to `NEEDS_ATTENTION`.
 
953
        """
 
954
        if status is None:
 
955
            status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION
 
956
        base_version = "1.%d" % self.factory.getUniqueInteger()
 
957
        versions = dict.fromkeys(('base', 'parent', 'derived'), base_version)
 
958
        if changed_parent:
 
959
            versions['parent'] += "-%s" % self.factory.getUniqueString()
 
960
        if changed_child:
 
961
            versions['derived'] += "-%s" % self.factory.getUniqueString()
 
962
        return self.factory.makeDistroSeriesDifference(
 
963
            derived_series=derived_series, versions=versions, status=status,
 
964
            set_base_version=True)
905
965
 
906
966
    def test_getForDistroSeries_default(self):
907
967
        # By default all differences needing attention for the given
918
978
    def test_getForDistroSeries_filters_by_distroseries(self):
919
979
        # Differences for other series are not included.
920
980
        derived_series = self.makeDerivedSeries()
921
 
        diffs = self.makeDiffsForDistroSeries(derived_series)
 
981
        self.makeDiffsForDistroSeries(derived_series)
922
982
        diff_for_other_series = self.factory.makeDistroSeriesDifference()
923
983
 
924
984
        result = getUtility(IDistroSeriesDifferenceSource).getForDistroSeries(
935
995
            derived_series,
936
996
            DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES)
937
997
 
 
998
        self.assertContentEqual(diffs['unique'], result)
 
999
 
938
1000
    def test_getForDistroSeries_filters_by_status(self):
939
1001
        # A single status can be used to filter results.
940
1002
        derived_series = self.makeDerivedSeries()
976
1038
            sorted(names),
977
1039
            [result.source_package_name.name for result in results])
978
1040
 
979
 
    def test_getByDistroSeriesAndName(self):
 
1041
    def test_getForDistroSeries_filters_by_parent(self):
 
1042
        # The differences can be filtered by parent series.
 
1043
        dsp = self.factory.makeDistroSeriesParent()
 
1044
        derived_series = dsp.derived_series
 
1045
        parent_series = dsp.parent_series
 
1046
 
 
1047
        # Add another parent to this series.
 
1048
        parent_series2 = self.factory.makeDistroSeriesParent(
 
1049
            derived_series=derived_series).parent_series
 
1050
 
 
1051
        diffs = self.makeDiffsForDistroSeries(
 
1052
            derived_series, parent_series=parent_series)
 
1053
        diffs2 = self.makeDiffsForDistroSeries(
 
1054
            derived_series, parent_series=parent_series2)
 
1055
 
 
1056
        results = getUtility(
 
1057
            IDistroSeriesDifferenceSource).getForDistroSeries(
 
1058
                derived_series, parent_series=parent_series)
 
1059
        results2 = getUtility(
 
1060
            IDistroSeriesDifferenceSource).getForDistroSeries(
 
1061
                derived_series, parent_series=parent_series2)
 
1062
 
 
1063
        self.assertContentEqual(diffs['normal'], results)
 
1064
        self.assertContentEqual(diffs2['normal'], results2)
 
1065
 
 
1066
    def test_getByDistroSeriesNameAndParentSeries(self):
980
1067
        # An individual difference is obtained using the name.
981
1068
        ds_diff = self.factory.makeDistroSeriesDifference(
982
1069
            source_package_name_str='fooname')
983
1070
 
984
1071
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
985
 
        result = dsd_source.getByDistroSeriesAndName(
986
 
            ds_diff.derived_series, 'fooname')
 
1072
        result = dsd_source.getByDistroSeriesNameAndParentSeries(
 
1073
            ds_diff.derived_series, 'fooname', ds_diff.parent_series)
987
1074
 
988
1075
        self.assertEqual(ds_diff, result)
989
1076
 
 
1077
    def test_getSimpleUpgrades_finds_simple_update(self):
 
1078
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1079
        dsd = self.makeVersionDifference(changed_parent=True)
 
1080
        self.assertEqual(dsd.base_version, dsd.source_version)
 
1081
        self.assertContentEqual(
 
1082
            [dsd], dsd_source.getSimpleUpgrades(dsd.derived_series))
 
1083
 
 
1084
    def test_getSimpleUpgrades_ignores_hidden_differences(self):
 
1085
        invisible_statuses = [
 
1086
            DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT,
 
1087
            DistroSeriesDifferenceStatus.BLACKLISTED_ALWAYS,
 
1088
            DistroSeriesDifferenceStatus.RESOLVED,
 
1089
            ]
 
1090
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1091
        series = self.makeDerivedSeries()
 
1092
        for status in invisible_statuses:
 
1093
            self.makeVersionDifference(
 
1094
                derived_series=series, changed_parent=True, status=status)
 
1095
        self.assertContentEqual([], dsd_source.getSimpleUpgrades(series))
 
1096
 
 
1097
    def test_getSimpleUpgrades_ignores_other_distroseries(self):
 
1098
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1099
        self.makeVersionDifference(changed_parent=True)
 
1100
        self.assertContentEqual(
 
1101
            [], dsd_source.getSimpleUpgrades(self.factory.makeDistroSeries()))
 
1102
 
 
1103
    def test_getSimpleUpgrades_ignores_packages_changed_in_child(self):
 
1104
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1105
        dsd = self.makeVersionDifference(
 
1106
            changed_parent=True, changed_child=True)
 
1107
        self.assertContentEqual(
 
1108
            [], dsd_source.getSimpleUpgrades(dsd.derived_series))
 
1109
 
 
1110
    def test_getSimpleUpgrades_ignores_packages_not_updated_in_parent(self):
 
1111
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1112
        dsd = self.makeVersionDifference(changed_parent=False)
 
1113
        self.assertContentEqual(
 
1114
            [], dsd_source.getSimpleUpgrades(dsd.derived_series))
 
1115
 
 
1116
    def test_getSimpleUpgrades_ignores_packages_unique_to_child(self):
 
1117
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1118
        diff_type = DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES
 
1119
        dsd = self.factory.makeDistroSeriesDifference(
 
1120
            difference_type=diff_type)
 
1121
        self.assertContentEqual(
 
1122
            [], dsd_source.getSimpleUpgrades(dsd.derived_series))
 
1123
 
 
1124
    def test_getSimpleUpgrades_ignores_packages_missing_from_child(self):
 
1125
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1126
        diff_type = DistroSeriesDifferenceType.MISSING_FROM_DERIVED_SERIES
 
1127
        dsd = self.factory.makeDistroSeriesDifference(
 
1128
            difference_type=diff_type)
 
1129
        self.assertContentEqual(
 
1130
            [], dsd_source.getSimpleUpgrades(dsd.derived_series))
 
1131
 
 
1132
    def test_collateDifferencesByParentArchive(self):
 
1133
        dsp1 = self.factory.makeDistroSeriesParent()
 
1134
        dsp2 = self.factory.makeDistroSeriesParent()
 
1135
        differences = [
 
1136
            self.factory.makeDistroSeriesDifference(dsp1.derived_series),
 
1137
            self.factory.makeDistroSeriesDifference(dsp2.derived_series),
 
1138
            self.factory.makeDistroSeriesDifference(dsp1.derived_series),
 
1139
            self.factory.makeDistroSeriesDifference(dsp2.derived_series),
 
1140
            ]
 
1141
        dsd_source = getUtility(IDistroSeriesDifferenceSource)
 
1142
        observed = (
 
1143
            dsd_source.collateDifferencesByParentArchive(differences))
 
1144
        expected = {
 
1145
            dsp1.parent_series.main_archive: differences[0::2],
 
1146
            dsp2.parent_series.main_archive: differences[1::2],
 
1147
            }
 
1148
        self.assertEqual(observed, expected)
 
1149
 
990
1150
 
991
1151
class TestMostRecentComments(TestCaseWithFactory):
992
1152
 
993
1153
    layer = DatabaseFunctionalLayer
994
1154
 
995
1155
    def test_most_recent_comments(self):
996
 
        derived_series = self.factory.makeDistroSeries(
997
 
            previous_series=self.factory.makeDistroSeries())
 
1156
        dsp = self.factory.makeDistroSeriesParent()
998
1157
        dsds = set(
999
1158
            self.factory.makeDistroSeriesDifference(
1000
 
                derived_series=derived_series) for index in xrange(5))
 
1159
                derived_series=dsp.derived_series) for index in xrange(5))
1001
1160
        expected_comments = set()
1002
1161
        for dsd in dsds:
1003
1162
            # Add a couple of comments.
1028
1187
        return dsd
1029
1188
 
1030
1189
    def test_simple(self):
1031
 
        derived_series = self.factory.makeDistroSeries(
1032
 
            previous_series=self.factory.makeDistroSeries())
 
1190
        dsp = self.factory.makeDistroSeriesParent()
 
1191
        derived_series = dsp.derived_series
1033
1192
        dsds = [
1034
1193
            self.create_difference(derived_series),
1035
1194
            self.create_difference(derived_series),
1058
1217
            parent_source_pubs_by_spn_id_found)
1059
1218
 
1060
1219
    def test_statuses(self):
1061
 
        derived_series = self.factory.makeDistroSeries(
1062
 
            previous_series=self.factory.makeDistroSeries())
 
1220
        dsp = self.factory.makeDistroSeriesParent()
 
1221
        derived_series = dsp.derived_series
1063
1222
        dsd = self.create_difference(derived_series)
1064
1223
        # Change the derived source publication to DELETED.
1065
1224
        removeSecurityProxy(dsd.source_pub).status = (
1080
1239
        # When match_version is True, the version of the publications (well,
1081
1240
        # the release) must exactly match those recorded on the
1082
1241
        # DistroSeriesDifference.
1083
 
        derived_series = self.factory.makeDistroSeries(
1084
 
            previous_series=self.factory.makeDistroSeries())
 
1242
        dsp = self.factory.makeDistroSeriesParent()
 
1243
        derived_series = dsp.derived_series
1085
1244
        dsd = self.create_difference(derived_series)
1086
1245
        # Modify the release version.
1087
1246
        removeSecurityProxy(