~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/soyuz/tests/test_publishing.py

[r=rockstar][ui=none] Fix the merge conflicts between devel and
        db-devel

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
import shutil
10
10
from StringIO import StringIO
11
11
import tempfile
12
 
import unittest
13
12
 
14
13
import pytz
15
14
from zope.component import getUtility
44
43
from lp.soyuz.interfaces.queue import PackageUploadStatus
45
44
from canonical.launchpad.scripts import FakeLogger
46
45
from lp.testing import TestCaseWithFactory
47
 
from lp.testing.factory import LaunchpadObjectFactory
 
46
from lp.testing.factory import (
 
47
    LaunchpadObjectFactory, remove_security_proxy_and_shout_at_engineer)
48
48
from lp.testing.fakemethod import FakeMethod
49
49
 
50
50
 
146
146
            PackageUploadStatus.DONE: 'setDone',
147
147
            PackageUploadStatus.ACCEPTED: 'setAccepted',
148
148
            }
149
 
        method = getattr(package_upload, status_to_method[upload_status])
 
149
        naked_package_upload = remove_security_proxy_and_shout_at_engineer(
 
150
            package_upload)
 
151
        method = getattr(
 
152
            naked_package_upload, status_to_method[upload_status])
150
153
        method()
151
154
 
152
155
        return package_upload
222
225
            changes_file_name=changes_file_name,
223
226
            changes_file_content=changes_file_content,
224
227
            upload_status=upload_status)
225
 
        package_upload.addSource(spr)
 
228
        naked_package_upload = remove_security_proxy_and_shout_at_engineer(
 
229
            package_upload)
 
230
        naked_package_upload.addSource(spr)
226
231
 
227
232
        if filename is None:
228
233
            filename = "%s_%s.dsc" % (sourcename, version)
458
463
        return source
459
464
 
460
465
 
461
 
class TestNativePublishingBase(unittest.TestCase, SoyuzTestPublisher):
 
466
class TestNativePublishingBase(TestCaseWithFactory, SoyuzTestPublisher):
462
467
    layer = LaunchpadZopelessLayer
463
468
    dbuser = config.archivepublisher.dbuser
464
469
 
465
470
    def __init__(self, methodName='runTest'):
466
 
        unittest.TestCase.__init__(self, methodName=methodName)
 
471
        super(TestNativePublishingBase, self).__init__(methodName=methodName)
467
472
        SoyuzTestPublisher.__init__(self)
468
473
 
469
474
    def setUp(self):
470
475
        """Setup a pool dir, the librarian, and instantiate the DiskPool."""
 
476
        super(TestNativePublishingBase, self).setUp()
471
477
        self.layer.switchDbUser(config.archivepublisher.dbuser)
472
478
        self.prepareBreezyAutotest()
473
479
        self.config = Config(self.ubuntutest)
481
487
 
482
488
    def tearDown(self):
483
489
        """Tear down blows the pool dir away."""
 
490
        super(TestNativePublishingBase, self).tearDown()
484
491
        shutil.rmtree(self.config.distroroot)
485
492
 
486
493
    def getPubSource(self, *args, **kwargs):
503
510
        self.layer.commit()
504
511
        return binaries
505
512
 
506
 
    def checkSourcePublication(self, source, status):
507
 
        """Assert the source publications has the given status.
508
 
 
509
 
        Retrieve an up-to-date record corresponding to the given publication,
510
 
        check and return it.
511
 
        """
512
 
        fresh_source = SourcePackagePublishingHistory.get(source.id)
513
 
        self.assertEqual(
514
 
            fresh_source.status, status, "%s is not %s (%s)" % (
515
 
            fresh_source.displayname, status.name, source.status.name))
516
 
        return fresh_source
517
 
 
518
 
    def checkBinaryPublication(self, binary, status):
519
 
        """Assert the binary publication has the given status.
520
 
 
521
 
        Retrieve an up-to-date record corresponding to the given publication,
522
 
        check and return it.
523
 
        """
524
 
        fresh_binary = BinaryPackagePublishingHistory.get(binary.id)
525
 
        self.assertEqual(
526
 
            fresh_binary.status, status, "%s is not %s (%s)" % (
527
 
            fresh_binary.displayname, status.name, fresh_binary.status.name))
528
 
        return fresh_binary
529
 
 
530
 
    def checkBinaryPublications(self, binaries, status):
531
 
        """Assert the binary publications have the given status.
532
 
 
533
 
        See `checkBinaryPublication`.
534
 
        """
535
 
        fresh_binaries = []
536
 
        for bin in binaries:
537
 
            bin = self.checkBinaryPublication(bin, status)
538
 
            fresh_binaries.append(bin)
539
 
        return fresh_binaries
540
 
 
541
 
    def checkPublications(self, source, binaries, status):
542
 
        """Assert source and binary publications have in the given status.
543
 
 
544
 
        See `checkSourcePublication` and `checkBinaryPublications`.
545
 
        """
546
 
        self.checkSourcePublication(source, status)
547
 
        self.checkBinaryPublications(binaries, status)
 
513
    def checkPublication(self, pub, status):
 
514
        """Assert the publication has the given status."""
 
515
        self.assertEqual(
 
516
            pub.status, status, "%s is not %s (%s)" % (
 
517
            pub.displayname, status.name, pub.status.name))
 
518
 
 
519
    def checkPublications(self, pubs, status):
 
520
        """Assert the given publications have the given status.
 
521
 
 
522
        See `checkPublication`.
 
523
        """
 
524
        for pub in pubs:
 
525
            self.checkPublication(pub, status)
548
526
 
549
527
    def checkPastDate(self, date, lag=None):
550
528
        """Assert given date is older than 'now'.
558
536
            limit = limit + lag
559
537
        self.assertTrue(date < limit, "%s >= %s" % (date, limit))
560
538
 
 
539
    def checkSuperseded(self, pubs, supersededby=None):
 
540
        self.checkPublications(pubs, PackagePublishingStatus.SUPERSEDED)
 
541
        for pub in pubs:
 
542
            self.checkPastDate(pub.datesuperseded)
 
543
            if supersededby is not None:
 
544
                if isinstance(pub, BinaryPackagePublishingHistory):
 
545
                    dominant = supersededby.binarypackagerelease.build
 
546
                else:
 
547
                    dominant = supersededby.sourcepackagerelease
 
548
                self.assertEquals(dominant, pub.supersededby)
 
549
            else:
 
550
                self.assertIs(None, pub.supersededby)
 
551
 
561
552
 
562
553
class TestNativePublishing(TestNativePublishingBase):
563
554
 
816
807
 
817
808
        # Adjust the binary package release original component.
818
809
        universe = getUtility(IComponentSet)['universe']
819
 
        from zope.security.proxy import removeSecurityProxy
820
810
        removeSecurityProxy(binary.binarypackagerelease).component = universe
821
811
 
822
812
        self.copyAndCheck(
1026
1016
        record = self.publishing_set.getByIdAndArchive(
1027
1017
            binary_publishing.id, wrong_archive, source=False)
1028
1018
        self.assertEqual(None, record)
 
1019
 
 
1020
 
 
1021
class TestSourceDomination(TestNativePublishingBase):
 
1022
    """Test SourcePackagePublishingHistory.supersede() operates correctly."""
 
1023
 
 
1024
    def testSupersede(self):
 
1025
        """Check that supersede() without arguments works."""
 
1026
        source = self.getPubSource()
 
1027
        source.supersede()
 
1028
        self.checkSuperseded([source])
 
1029
 
 
1030
    def testSupersedeWithDominant(self):
 
1031
        """Check that supersede() with a dominant publication works."""
 
1032
        source = self.getPubSource()
 
1033
        super_source = self.getPubSource()
 
1034
        source.supersede(super_source)
 
1035
        self.checkSuperseded([source], super_source)
 
1036
 
 
1037
    def testSupersedingSupersededSourceFails(self):
 
1038
        """Check that supersede() fails with a superseded source.
 
1039
 
 
1040
        Sources should not be superseded twice. If a second attempt is made,
 
1041
        the Dominator's lookups are buggy.
 
1042
        """
 
1043
        source = self.getPubSource()
 
1044
        super_source = self.getPubSource()
 
1045
        source.supersede(super_source)
 
1046
        self.checkSuperseded([source], super_source)
 
1047
 
 
1048
        # Manually set a date in the past, so we can confirm that
 
1049
        # the second supersede() fails properly.
 
1050
        source.datesuperseded = datetime.datetime(
 
1051
            2006, 12, 25, tzinfo=pytz.timezone("UTC"))
 
1052
        super_date = source.datesuperseded
 
1053
 
 
1054
        self.assertRaises(AssertionError, source.supersede, super_source)
 
1055
        self.checkSuperseded([source], super_source)
 
1056
        self.assertEquals(super_date, source.datesuperseded)
 
1057
 
 
1058
 
 
1059
class TestBinaryDomination(TestNativePublishingBase):
 
1060
    """Test BinaryPackagePublishingHistory.supersede() operates correctly."""
 
1061
 
 
1062
    def testSupersede(self):
 
1063
        """Check that supersede() without arguments works."""
 
1064
        bins = self.getPubBinaries(architecturespecific=True)
 
1065
        bins[0].supersede()
 
1066
        self.checkSuperseded([bins[0]])
 
1067
        self.checkPublication(bins[1], PackagePublishingStatus.PENDING)
 
1068
 
 
1069
    def testSupersedeWithDominant(self):
 
1070
        """Check that supersede() with a dominant publication works."""
 
1071
        bins = self.getPubBinaries(architecturespecific=True)
 
1072
        super_bins = self.getPubBinaries(architecturespecific=True)
 
1073
        bins[0].supersede(super_bins[0])
 
1074
        self.checkSuperseded([bins[0]], super_bins[0])
 
1075
        self.checkPublication(bins[1], PackagePublishingStatus.PENDING)
 
1076
 
 
1077
    def testSupersedesArchIndepBinariesAtomically(self):
 
1078
        """Check that supersede() supersedes arch-indep binaries atomically.
 
1079
 
 
1080
        Architecture-independent binaries should be removed from all
 
1081
        architectures when they are superseded on at least one (bug #48760).
 
1082
        """
 
1083
        bins = self.getPubBinaries(architecturespecific=False)
 
1084
        super_bins = self.getPubBinaries(architecturespecific=False)
 
1085
        bins[0].supersede(super_bins[0])
 
1086
        self.checkSuperseded(bins, super_bins[0])
 
1087
 
 
1088
    def testAtomicDominationRespectsOverrides(self):
 
1089
        """Check that atomic domination only covers identical overrides.
 
1090
 
 
1091
        This is important, as otherwise newly-overridden arch-indep binaries
 
1092
        will supersede themselves, and vanish entirely (bug #178102).
 
1093
        """
 
1094
        bins = self.getPubBinaries(architecturespecific=False)
 
1095
 
 
1096
        universe = getUtility(IComponentSet)['universe']
 
1097
        super_bins = []
 
1098
        for bin in bins:
 
1099
            super_bins.append(bin.changeOverride(new_component=universe))
 
1100
 
 
1101
        bins[0].supersede(super_bins[0])
 
1102
        self.checkSuperseded(bins, super_bins[0])
 
1103
        self.checkPublications(super_bins, PackagePublishingStatus.PENDING)
 
1104
 
 
1105
    def testSupersedingSupersededArchSpecificBinaryFails(self):
 
1106
        """Check that supersede() fails with a superseded arch-dep binary.
 
1107
 
 
1108
        Architecture-specific binaries should not normally be superseded
 
1109
        twice. If a second attempt is made, the Dominator's lookups are buggy.
 
1110
        """
 
1111
        bin = self.getPubBinaries(architecturespecific=True)[0]
 
1112
        super_bin = self.getPubBinaries(architecturespecific=True)[0]
 
1113
        bin.supersede(super_bin)
 
1114
 
 
1115
        # Manually set a date in the past, so we can confirm that
 
1116
        # the second supersede() fails properly.
 
1117
        bin.datesuperseded = datetime.datetime(
 
1118
            2006, 12, 25, tzinfo=pytz.timezone("UTC"))
 
1119
        super_date = bin.datesuperseded
 
1120
 
 
1121
        self.assertRaises(AssertionError, bin.supersede, super_bin)
 
1122
        self.checkSuperseded([bin], super_bin)
 
1123
        self.assertEquals(super_date, bin.datesuperseded)
 
1124
 
 
1125
    def testSkipsSupersededArchIndependentBinary(self):
 
1126
        """Check that supersede() skips a superseded arch-indep binary.
 
1127
 
 
1128
        Since all publications of an architecture-independent binary are
 
1129
        superseded atomically, they may be superseded again later. In that
 
1130
        case, we skip the domination, leaving the old date unchanged.
 
1131
        """
 
1132
        bin = self.getPubBinaries(architecturespecific=False)[0]
 
1133
        super_bin = self.getPubBinaries(architecturespecific=False)[0]
 
1134
        bin.supersede(super_bin)
 
1135
        self.checkSuperseded([bin], super_bin)
 
1136
 
 
1137
        # Manually set a date in the past, so we can confirm that
 
1138
        # the second supersede() skips properly.
 
1139
        bin.datesuperseded = datetime.datetime(
 
1140
            2006, 12, 25, tzinfo=pytz.timezone("UTC"))
 
1141
        super_date = bin.datesuperseded
 
1142
 
 
1143
        bin.supersede(super_bin)
 
1144
        self.checkSuperseded([bin], super_bin)
 
1145
        self.assertEquals(super_date, bin.datesuperseded)
 
1146
 
 
1147
 
 
1148
class TestBinaryGetOtherPublications(TestNativePublishingBase):
 
1149
    """Test BinaryPackagePublishingHistory._getOtherPublications() works."""
 
1150
 
 
1151
    def checkOtherPublications(self, this, others):
 
1152
        self.assertEquals(
 
1153
            set(removeSecurityProxy(this)._getOtherPublications()),
 
1154
            set(others))
 
1155
 
 
1156
    def testFindsOtherArchIndepPublications(self):
 
1157
        """Arch-indep publications with the same overrides should be found."""
 
1158
        bins = self.getPubBinaries(architecturespecific=False)
 
1159
        self.checkOtherPublications(bins[0], bins)
 
1160
 
 
1161
    def testDoesntFindArchSpecificPublications(self):
 
1162
        """Arch-dep publications shouldn't be found."""
 
1163
        bins = self.getPubBinaries(architecturespecific=True)
 
1164
        self.checkOtherPublications(bins[0], [bins[0]])
 
1165
 
 
1166
    def testDoesntFindPublicationsInOtherArchives(self):
 
1167
        """Publications in other archives shouldn't be found."""
 
1168
        bins = self.getPubBinaries(architecturespecific=False)
 
1169
        foreign_bins = bins[0].copyTo(
 
1170
            bins[0].distroarchseries.distroseries, bins[0].pocket,
 
1171
            self.factory.makeArchive())
 
1172
        self.checkOtherPublications(bins[0], bins)
 
1173
        self.checkOtherPublications(foreign_bins[0], foreign_bins)
 
1174
 
 
1175
    def testDoesntFindPublicationsWithDifferentOverrides(self):
 
1176
        """Publications with different overrides shouldn't be found."""
 
1177
        bins = self.getPubBinaries(architecturespecific=False)
 
1178
        universe = getUtility(IComponentSet)['universe']
 
1179
        foreign_bin = bins[0].changeOverride(new_component=universe)
 
1180
        self.checkOtherPublications(bins[0], bins)
 
1181
        self.checkOtherPublications(foreign_bin, [foreign_bin])
 
1182
 
 
1183
    def testDoesntFindSupersededPublications(self):
 
1184
        """Superseded publications shouldn't be found."""
 
1185
        bins = self.getPubBinaries(architecturespecific=False)
 
1186
        self.checkOtherPublications(bins[0], bins)
 
1187
        # This will supersede both atomically.
 
1188
        bins[0].supersede()
 
1189
        self.checkOtherPublications(bins[0], [])