← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~james-w/launchpad/no-more-sampledata-2 into lp:launchpad/devel

 

James Westby has proposed merging lp:~james-w/launchpad/no-more-sampledata-2 into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


Hi,

Apologies for the bumper branch. Very small changes snowballed
very quickly.

This branch moves SoyuzTestPublisher to back on to the
factory, as a precursor to moving it away from sampledata.

It now runs pretty much the same code inside the factory as it
was running before, and now SoyuzTestPublisher is just a layer
on top of the factory with some conveniences for complex
tests.

The major change is that there are now lots more proxied objects
in soyuz tests, so most of the changes are fallout from that.
There's a lot of removeSecurityProxy involved there, as most of
the problems we in test setup code that is reaching around the
interface to do test set up. I'm not entirely happy that we have
to do that, they should be able to come in by the front door, but
fixing all of that would be too much for one branch.

There's also a bit of having the tests specify the parameters
for the creation of objects where they will assert something
based on that parameter. I didn't do that across the board though.

Plus there are a few drive-by fixes and cleanups as always.

Breakdown of the changes, as not all are immediately obvious. It's perhaps
best to review in reverse order of the changes listed here (odd that bzr
diff gave me the files in roughly reverse order).

lib/lp/archivepublisher/tests/test_dominator.py - just making the values explicit.

lib/lp/archivepublisher/tests/test_publisher.py, lib/lp/soyuz/scripts/tests/test_publishdistro.py, lib/lp/soyuz/tests/test_publishing_top_level_api.py - using sync() from SQLObject, which isn't
on the interface.

lib/lp/archiveuploader/tests/nascentupload-ddebs.txt - getPubSource now creates a user, which
requires the extra setup that only used to be done later.

lib/lp/soyuz/configure.zcml - specifying a permission for isAutoSyncUpload to actually
get the object to pass verifyObject.

lib/lp/soyuz/doc/archive-files.txt - setting a value that could be set at creation time
if there were an appropriate way to do that. It's just set up though, so this has the
same effect.

lib/lp/soyuz/doc/packageupload-lookups.txt - Using rSP to ensure that the repr is
what is expected.

lib/lp/soyuz/doc/publishing.txt - changing purpose of an archive or parent series aren't normally allowed. New archives/series could be created instead. Changing the published
component isn't possible, but you could republish in the new component.

lib/lp/soyuz/doc/sourcepackagerelease.txt - deletion is protected, but this is just test
cleanup, so we don't care.

lib/lp/soyuz/interfaces/binarypackagename.py, lib/lp/soyuz/model/binarypackagename.py -
unused parts of the interface that aren't implemented (properly) on the concrete class, so I 
removed them.

lib/lp/soyuz/scripts/tests/test_changeoverride.py - specifying values and changing the
version of a publication, which isn't normally allowed.

lib/lp/soyuz/scripts/tests/test_copypackage.py - various instances of bypassing the
interface for test setup.

lib/lp/soyuz/scripts/tests/test_ppa_apache_log_parser.py - correcting a copy paste comment.

lib/lp/soyuz/tests/test_binarypackagebuild.py - the proxy stops you concatenating lists, so
listify each of them.

lib/lp/soyuz/tests/test_publish_archive_indexes.py - specify all the tested values. Also
a case of forcing invalid data in to a field. I also deleted some copy paste comments
that made no sense in the context.

lib/lp/soyuz/tests/test_publishing.py - the big one, using the factory and lp.testing.sampledata rather than creating objects itself, then a whole bunch of fixes
from the fallout of this due to the proxy.

lib/lp/testing/factory.py - some fixes and additions to support the transition. Plus a
change to give distroseries and distributions less generic names, which made some test
failures easier to understand.

lib/lp/testing/matchers.py - a new matcher to help with...

lib/lp/testing/tests/test_factory.py - the tests for the changes to the factory.

lib/lp/testing/tests/test_matchers.py - the tests for the new matcher.

Thanks,

James

-- 
https://code.launchpad.net/~james-w/launchpad/no-more-sampledata-2/+merge/31887
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~james-w/launchpad/no-more-sampledata-2 into lp:launchpad/devel.
=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
--- lib/lp/archivepublisher/tests/test_dominator.py	2010-07-22 11:59:40 +0000
+++ lib/lp/archivepublisher/tests/test_dominator.py	2010-08-05 20:36:49 +0000
@@ -21,10 +21,10 @@
     def createSourceAndBinaries(self, version):
         """Create a source and binaries with the given version."""
         source = self.getPubSource(
-            version=version,
+            version=version, sourcename="foo",
             status=PackagePublishingStatus.PUBLISHED)
         binaries = self.getPubBinaries(
-            pub_source=source,
+            pub_source=source, version=version, binaryname="foo-bin",
             status=PackagePublishingStatus.PUBLISHED)
         return (source, binaries)
 

=== modified file 'lib/lp/archivepublisher/tests/test_publisher.py'
--- lib/lp/archivepublisher/tests/test_publisher.py	2010-07-22 08:19:27 +0000
+++ lib/lp/archivepublisher/tests/test_publisher.py	2010-08-05 20:36:49 +0000
@@ -83,7 +83,7 @@
         publisher.A_publish(False)
         self.layer.txn.commit()
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertDirtyPocketsContents(
             [('breezy-autotest', 'RELEASE')], publisher.dirty_pockets)
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
@@ -226,8 +226,8 @@
         publisher.A_publish(force_publishing=False)
         self.layer.txn.commit()
 
-        pub_source.sync()
-        pub_source2.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertDirtyPocketsContents(
             [('hoary-test', 'RELEASE')], publisher.dirty_pockets)
         self.assertEqual(pub_source2.status,
@@ -259,8 +259,8 @@
         publisher.A_publish(force_publishing=False)
         self.layer.txn.commit()
 
-        pub_source.sync()
-        pub_source2.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertDirtyPocketsContents(
             [('breezy-autotest', 'UPDATES')], publisher.dirty_pockets)
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
@@ -360,7 +360,7 @@
         publisher.A_publish(False)
         self.layer.txn.commit()
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertDirtyPocketsContents(
             [('breezy-autotest', 'RELEASE')], publisher.dirty_pockets)
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)

=== modified file 'lib/lp/archiveuploader/tests/nascentupload-ddebs.txt'
--- lib/lp/archiveuploader/tests/nascentupload-ddebs.txt	2009-10-11 05:25:10 +0000
+++ lib/lp/archiveuploader/tests/nascentupload-ddebs.txt	2010-08-05 20:36:49 +0000
@@ -16,6 +16,8 @@
 
     >>> from lp.soyuz.tests.test_publishing import (
     ...     SoyuzTestPublisher)
+    >>> from canonical.config import config
+    >>> from canonical.testing import LaunchpadZopelessLayer
 
     >>> test_publisher = SoyuzTestPublisher()
 
@@ -26,17 +28,12 @@
 
     >>> unused = test_publisher.setUpDefaultDistroSeries(hoary)
 
+    >>> LaunchpadZopelessLayer.txn.commit()
+    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
+
     >>> source_ancestry = test_publisher.getPubSource(
     ...     sourcename='debug', version='0.99')
 
-We need a slightly different database setup for creating binaries.
-
-    >>> from canonical.config import config
-    >>> from canonical.testing import LaunchpadZopelessLayer
-
-    >>> LaunchpadZopelessLayer.txn.commit()
-    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
-
     >>> binary_ancestry = test_publisher.getPubBinaries(
     ...     binaryname='debug-bin', pub_source=source_ancestry)
 

=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml	2010-06-30 17:35:36 +0000
+++ lib/lp/soyuz/configure.zcml	2010-08-05 20:36:49 +0000
@@ -188,7 +188,8 @@
                 displayversion
                 is_delayed_copy
                 isPPA
-                components"/>
+                components
+                isAutoSyncUpload"/>
         <require
             permission="launchpad.Edit"
             attributes="

=== modified file 'lib/lp/soyuz/doc/archive-files.txt'
--- lib/lp/soyuz/doc/archive-files.txt	2010-05-11 07:09:18 +0000
+++ lib/lp/soyuz/doc/archive-files.txt	2010-08-05 20:36:49 +0000
@@ -145,7 +145,7 @@
 
     >>> diff_name = 'test-pkg_1.0_1.1.diff.gz'
     >>> diff = test_publisher.addMockFile(diff_name)
-    >>> package_diff.diff_content = diff
+    >>> removeSecurityProxy(package_diff).diff_content = diff
 
     >>> diff == cprov.archive.getFileByName(diff_name)
     True

=== modified file 'lib/lp/soyuz/doc/packageupload-lookups.txt'
--- lib/lp/soyuz/doc/packageupload-lookups.txt	2010-03-06 04:57:40 +0000
+++ lib/lp/soyuz/doc/packageupload-lookups.txt	2010-08-05 20:36:49 +0000
@@ -98,6 +98,7 @@
     # Create a testing source and its binaries in
     # ubuntutest/breezy-autotest/i386.
     >>> from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
+    >>> from zope.security.proxy import removeSecurityProxy
     >>> login('foo.bar@xxxxxxxxxxxxx')
     >>> test_publisher = SoyuzTestPublisher()
     >>> test_publisher.prepareBreezyAutotest()
@@ -112,7 +113,7 @@
 The `SourcePackageRelease` 'package_upload' and 'upload_changesfile'
 
     >>> original_source_upload = source.sourcepackagerelease.package_upload
-    >>> print original_source_upload
+    >>> print removeSecurityProxy(original_source_upload)
     <PackageUpload ...>
 
     >>> source_changesfile = source.sourcepackagerelease.upload_changesfile

=== modified file 'lib/lp/soyuz/doc/publishing.txt'
--- lib/lp/soyuz/doc/publishing.txt	2010-07-12 03:14:42 +0000
+++ lib/lp/soyuz/doc/publishing.txt	2010-08-05 20:36:49 +0000
@@ -2,10 +2,11 @@
 SourcePackagePublishingHistory
 ==============================
 
-This class provides public access to publishing records via a SQL view.
+This class provides public access to publishing records.
 
-    >>> from canonical.launchpad.database import SourcePackagePublishingHistory
-    >>> from canonical.launchpad.database import BinaryPackagePublishingHistory
+    >>> from lp.soyuz.model.publishing import (
+    ...     BinaryPackagePublishingHistory, SourcePackagePublishingHistory)
+    >>> from zope.security.proxy import removeSecurityProxy
 
 Select a publishing record from the sampledata (pmount is a
 interesting one):
@@ -173,7 +174,7 @@
 FULLY_BUILT.
 
     >>> from lp.soyuz.interfaces.archive import ArchivePurpose
-    >>> spph.archive.purpose = ArchivePurpose.COPY
+    >>> removeSecurityProxy(spph.archive).purpose = ArchivePurpose.COPY
     >>> build_status_summary = spph.getStatusSummaryForBuilds()
     >>> print_build_status_summary(build_status_summary)
     FULLYBUILT
@@ -181,7 +182,7 @@
     i386 build of abc 666 in ubuntutest breezy-autotest RELEASE
 
     # Just set the purpose back before continuing on.
-    >>> spph.archive.purpose = ArchivePurpose.PRIMARY
+    >>> removeSecurityProxy(spph.archive).purpose = ArchivePurpose.PRIMARY
 
 If one of the builds becomes published, it will not appear in the summary:
 
@@ -779,8 +780,8 @@
 This simulates a rebuild in of the same source in a more recent
 distroseries, like rebuilding SRUs for constant sources.
 
-    >>> breezy_autotest.parent_series = None
-    >>> hoary_test.parent_series = breezy_autotest
+    >>> removeSecurityProxy(breezy_autotest).parent_series = None
+    >>> removeSecurityProxy(hoary_test).parent_series = breezy_autotest
 
     >>> ppa_source.createMissingBuilds()
     []
@@ -791,8 +792,8 @@
 Now, let's check the opposite, as if the copy was from a more recent
 distroseries to a older one, like a backport rebuild.
 
-    >>> breezy_autotest.parent_series = hoary_test
-    >>> hoary_test.parent_series = None
+    >>> removeSecurityProxy(breezy_autotest).parent_series = hoary_test
+    >>> removeSecurityProxy(hoary_test).parent_series = None
 
     >>> ppa_source.createMissingBuilds()
     []
@@ -1330,7 +1331,6 @@
 
     >>> diff_file = getUtility(ILibraryFileAliasSet)[1]
 
-    >>> from zope.security.proxy import removeSecurityProxy
     >>> naked_diff = removeSecurityProxy(pmount_diff)
     >>> naked_diff.diff_content = diff_file
     >>> flush_database_updates()
@@ -1877,7 +1877,8 @@
 It works in the same way for binaries.
 
     >>> multiverse = getUtility(IComponentSet)['multiverse']
-    >>> test_binary.binarypackagerelease.component = multiverse
+    >>> naked_bpr = removeSecurityProxy(test_binary.binarypackagerelease)
+    >>> naked_bpr.component = multiverse
 
     >>> print test_binary.component.name
     universe

=== modified file 'lib/lp/soyuz/doc/sourcepackagerelease.txt'
--- lib/lp/soyuz/doc/sourcepackagerelease.txt	2010-05-19 15:39:52 +0000
+++ lib/lp/soyuz/doc/sourcepackagerelease.txt	2010-08-05 20:36:49 +0000
@@ -196,10 +196,10 @@
 
   >>> new_spr = hoary.createUploadedSourcePackageRelease(
   ...     arg_name, version, arg_maintainer,
-  ...     builddepends, builddependsindep, archhintlist, arg_comp, arg_creator,
-  ...     arg_urgency, changelog, changelog_entry, dsc, arg_key, arg_sect,
-  ...     dsc_maintainer_rfc822, dsc_standards_version, dsc_format,
-  ...     dsc_binaries, archive, copyright=copyright,
+  ...     builddepends, builddependsindep, archhintlist, arg_comp,
+  ...     arg_creator, arg_urgency, changelog, changelog_entry, dsc,
+  ...     arg_key, arg_sect, dsc_maintainer_rfc822, dsc_standards_version,
+  ...     dsc_format, dsc_binaries, archive, copyright=copyright,
   ...     build_conflicts=None, build_conflicts_indep=None,
   ...     source_package_recipe_build=arg_recipebuild)
 
@@ -349,7 +349,8 @@
 private PPA, it gets deleted from that private PPA.  At this point the
 package is still public:
 
-    >>> private_publication.requestDeletion(cprov)
+    >>> from zope.security.proxy import removeSecurityProxy
+    >>> removeSecurityProxy(private_publication).requestDeletion(cprov)
     >>> transaction.commit()
     >>> login('no-priv@xxxxxxxxxxxxx')
     >>> check_permission('launchpad.View', test_sourcepackagerelease)

=== modified file 'lib/lp/soyuz/interfaces/binarypackagename.py'
--- lib/lp/soyuz/interfaces/binarypackagename.py	2010-01-12 19:02:09 +0000
+++ lib/lp/soyuz/interfaces/binarypackagename.py	2010-08-05 20:36:49 +0000
@@ -14,7 +14,7 @@
     ]
 
 from zope.schema import Int, TextLine
-from zope.interface import Interface, Attribute
+from zope.interface import Interface
 
 from canonical.launchpad import _
 from canonical.launchpad.validators.name import name_validator
@@ -26,11 +26,6 @@
     name = TextLine(title=_('Valid Binary package name'),
                     required=True, constraint=name_validator)
 
-    binarypackages = Attribute('binarypackages')
-
-    def nameSelector(sourcepackage=None, selected=None):
-        """Return browser-ready HTML to select a Binary Package Name"""
-
     def __unicode__():
         """Return the name"""
 

=== modified file 'lib/lp/soyuz/model/binarypackagename.py'
--- lib/lp/soyuz/model/binarypackagename.py	2010-08-02 02:13:52 +0000
+++ lib/lp/soyuz/model/binarypackagename.py	2010-08-05 20:36:49 +0000
@@ -8,7 +8,7 @@
     'BinaryPackageName',
     'BinaryPackageNameSet',
     'BinaryPackageNameVocabulary',
-    'getBinaryPackageDescriptions'
+    'getBinaryPackageDescriptions',
 ]
 
 # Zope imports
@@ -17,7 +17,7 @@
 
 # SQLObject/SQLBase
 from sqlobject import (
-    SQLObjectNotFound, StringCol, SQLMultipleJoin, CONTAINSSTRING)
+    SQLObjectNotFound, StringCol, CONTAINSSTRING)
 
 from storm.store import EmptyResultSet
 
@@ -39,10 +39,6 @@
     name = StringCol(dbName='name', notNull=True, unique=True,
                      alternateID=True)
 
-    binarypackages = SQLMultipleJoin(
-        'BinaryPackage', joinColumn='binarypackagename'
-        )
-
     def __unicode__(self):
         return self.name
 
@@ -125,6 +121,7 @@
 
     Builds descriptions based on releases of that binary package name.
     """
+
     def getTermsWithDescriptions(self, results):
         # Prefill the descriptions dictionary with the latest
         # description uploaded for that package name.
@@ -165,11 +162,10 @@
 
     for release in releases:
         binarypackagename = release.binarypackagename.name
-        if not descriptions.has_key(binarypackagename):
+        if binarypackagename in descriptions:
             description = release.description.strip().replace("\n", " ")
             if len(description) > max_title_length:
                 description = (release.description[:max_title_length]
                               + "...")
             descriptions[binarypackagename] = description
     return descriptions
-

=== modified file 'lib/lp/soyuz/scripts/tests/test_changeoverride.py'
--- lib/lp/soyuz/scripts/tests/test_changeoverride.py	2010-07-20 12:06:36 +0000
+++ lib/lp/soyuz/scripts/tests/test_changeoverride.py	2010-08-05 20:36:49 +0000
@@ -8,13 +8,15 @@
 import unittest
 
 from zope.component import getUtility
+from zope.security.proxy import removeSecurityProxy
 
 from lp.soyuz.interfaces.component import IComponentSet
 from lp.registry.interfaces.distribution import IDistributionSet
 from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.pocket import PackagePublishingPocket
-from lp.soyuz.interfaces.publishing import PackagePublishingPriority
+from lp.soyuz.interfaces.publishing import (
+    PackagePublishingPriority, PackagePublishingStatus)
 from lp.soyuz.interfaces.section import ISectionSet
 from canonical.launchpad.scripts import FakeLogger
 from lp.soyuz.scripts.changeoverride import (
@@ -252,18 +254,25 @@
          * 'boingo-data' binaries PENDING in warty i386 & hppa.
         """
         source = self.test_publisher.getPubSource(
-            sourcename="boingo", version='1.0', distroseries=self.warty)
+            sourcename="boingo", version='1.0', distroseries=self.warty,
+            component="main", section="base",
+            status=PackagePublishingStatus.PENDING)
 
         binaries = self.test_publisher.getPubBinaries(
-            'boingo-bin', pub_source=source, distroseries=self.warty)
+            'boingo-bin', pub_source=source, distroseries=self.warty,
+            version="1.0", component="main", section="base",
+            priority=PackagePublishingPriority.STANDARD,
+            status=PackagePublishingStatus.PENDING)
 
         build = binaries[0].binarypackagerelease.build
         other_binary = self.test_publisher.uploadBinaryForBuild(
             build, 'boingo-data')
-        other_binary.version = '0.9'
+        removeSecurityProxy(other_binary).version = '0.9'
         binaries.extend(
             self.test_publisher.publishBinaryInArchive(
-                other_binary, source.archive))
+                other_binary, source.archive, section="base",
+                priority=PackagePublishingPriority.STANDARD,
+                status=PackagePublishingStatus.PENDING))
 
     def test_changeoverride_operations(self):
         """Check if `IArchivePublisher.changeOverride` is wrapped correctly.

=== modified file 'lib/lp/soyuz/scripts/tests/test_copypackage.py'
--- lib/lp/soyuz/scripts/tests/test_copypackage.py	2010-07-20 12:06:36 +0000
+++ lib/lp/soyuz/scripts/tests/test_copypackage.py	2010-08-05 20:36:49 +0000
@@ -683,7 +683,7 @@
         utc = pytz.timezone('UTC')
         old_date = datetime.datetime(1970, 1, 1, tzinfo=utc)
         a_binary_file = binaries[0].binarypackagerelease.files[0]
-        a_binary_file.libraryfile.expires = old_date
+        removeSecurityProxy(a_binary_file.libraryfile).expires = old_date
 
         # Now source-only copies are allowed.
         copy_checker = CopyChecker(archive, include_binaries=False)
@@ -714,7 +714,7 @@
         expire = datetime.datetime.now(utc) + datetime.timedelta(days=365)
 
         a_source_file = source.sourcepackagerelease.files[0]
-        a_source_file.libraryfile.expires = expire
+        removeSecurityProxy(a_source_file.libraryfile).expires = expire
 
         copy_checker = CopyChecker(archive, include_binaries=False)
         self.assertRaisesWithContent(
@@ -1065,7 +1065,7 @@
         # something else.
         source = self.createDelayedCopyContext()
         contrib = getUtility(IComponentSet).new('contrib')
-        source.sourcepackagerelease.component = contrib
+        removeSecurityProxy(source.sourcepackagerelease).component = contrib
         [build] = source.getBuilds()
         [binary] = build.binarypackages
         binary.override(component=contrib)
@@ -1089,7 +1089,7 @@
         # something else.
         source = self.createDelayedCopyContext()
         contrib = getUtility(IComponentSet).new('contrib')
-        source.sourcepackagerelease.component = contrib
+        removeSecurityProxy(source.sourcepackagerelease).component = contrib
         [build] = source.getBuilds()
         [binary] = build.binarypackages
         binary.override(component=contrib)
@@ -2265,7 +2265,8 @@
 
         # Override the copied binarypackagerelease to 'universe'.
         for binary in ppa_binaries:
-            binary.binarypackagerelease.component = universe
+            removeSecurityProxy(binary.binarypackagerelease).component = (
+                universe)
 
         self.layer.txn.commit()
 
@@ -2365,7 +2366,8 @@
                 distroseries=warty, archive=archive, pocket=pocket,
                 changes_file_content=changes_file_content,
                 status=PackagePublishingStatus.PUBLISHED)
-            source.sourcepackagerelease.changelog_entry = (
+            naked_spr = removeSecurityProxy(source.sourcepackagerelease)
+            naked_spr.changelog_entry = (
                 "Required for close_bugs_for_sourcepublication")
             binaries = test_publisher.getPubBinaries(
                 pub_source=source, distroseries=warty, archive=archive,

=== modified file 'lib/lp/soyuz/scripts/tests/test_ppa_apache_log_parser.py'
--- lib/lp/soyuz/scripts/tests/test_ppa_apache_log_parser.py	2010-07-20 12:06:36 +0000
+++ lib/lp/soyuz/scripts/tests/test_ppa_apache_log_parser.py	2010-08-05 20:36:49 +0000
@@ -40,8 +40,8 @@
         self.assertIs(None, get_ppa_file_key('/foo'))
 
     def test_get_ppa_file_key_ignores_non_binary_path(self):
-        # A path with extra path segments returns None, to indicate that
-        # it should be ignored.
+        # A path pointing to a file not from a binary package returns
+        # None to indicate that it should be ignored.
         self.assertIs(None, get_ppa_file_key(
             '/cprov/ppa/ubuntu/pool/main/f/foo/foo_1.2.3-4.dsc'))
 

=== modified file 'lib/lp/soyuz/scripts/tests/test_publishdistro.py'
--- lib/lp/soyuz/scripts/tests/test_publishdistro.py	2010-03-09 07:29:18 +0000
+++ lib/lp/soyuz/scripts/tests/test_publishdistro.py	2010-08-05 20:36:49 +0000
@@ -72,7 +72,7 @@
 
         rc, out, err = self.runPublishDistroScript()
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(0, rc, "Publisher failed with:\n%s\n%s" % (out, err))
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
 
@@ -88,7 +88,7 @@
         pub_source = self.getPubSource(filecontent='foo')
         self.layer.txn.commit()
         self.runPublishDistro()
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
 
         random_person = getUtility(IPersonSet).getByName('name16')
         pub_source.requestDeletion(random_person)
@@ -96,7 +96,7 @@
         self.assertTrue(pub_source.scheduleddeletiondate is None,
             "pub_source.scheduleddeletiondate should not be set, and it is.")
         self.runPublishDistro()
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertTrue(pub_source.scheduleddeletiondate is not None,
             "pub_source.scheduleddeletiondate should be set, and it's not.")
 
@@ -123,8 +123,8 @@
 
         self.runPublishDistro(['-s', 'hoary-test'])
 
-        pub_source.sync()
-        pub_source2.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PENDING)
         self.assertEqual(
             pub_source2.status, PackagePublishingStatus.PUBLISHED)
@@ -212,9 +212,9 @@
 
         self.runPublishDistro(['--ppa'])
 
-        pub_source.sync()
-        pub_source2.sync()
-        pub_source3.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_source2).sync()
+        removeSecurityProxy(pub_source3).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PENDING)
         self.assertEqual(
             pub_source2.status, PackagePublishingStatus.PUBLISHED)
@@ -246,21 +246,21 @@
             private=True, distribution=ubuntutest)
 
         # Publish something to the private PPA:
-        pub_source =  self.getPubSource(
+        pub_source = self.getPubSource(
             sourcename='baz', filecontent='baz', archive=private_ppa)
         self.layer.txn.commit()
 
         # Try a plain PPA run, to ensure the private one is NOT published.
         self.runPublishDistro(['--ppa'])
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PENDING)
 
         # Now publish the private PPAs and make sure they are really
         # published.
         self.runPublishDistro(['--private-ppa'])
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
 
     def testPublishPrimaryDebug(self):
@@ -289,7 +289,7 @@
         self.prepareBreezyAutotest()
         pub_binaries = self.getPubBinaries(format=BinaryPackageFormat.DDEB)
         for binary in pub_binaries:
-            binary.archive = debug_archive
+            removeSecurityProxy(binary).archive = debug_archive
 
         # Commit setup changes, so the script can operate on them.
         self.layer.txn.commit()
@@ -330,7 +330,7 @@
         removeSecurityProxy(copy_archive).publish = True
 
         # Publish something.
-        pub_source =  self.getPubSource(
+        pub_source = self.getPubSource(
             sourcename='baz', filecontent='baz', archive=copy_archive)
 
         # Try a plain PPA run, to ensure the copy archive is not published.

=== modified file 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
--- lib/lp/soyuz/tests/test_binarypackagebuild.py	2010-07-21 07:45:50 +0000
+++ lib/lp/soyuz/tests/test_binarypackagebuild.py	2010-08-05 20:36:49 +0000
@@ -322,18 +322,18 @@
         self.sources = []
         gedit_src_hist = self.publisher.getPubSource(
             sourcename="gedit", status=PackagePublishingStatus.PUBLISHED)
-        self.builds += gedit_src_hist.createMissingBuilds()
+        self.builds += list(gedit_src_hist.createMissingBuilds())
         self.sources.append(gedit_src_hist)
 
         firefox_src_hist = self.publisher.getPubSource(
             sourcename="firefox", status=PackagePublishingStatus.PUBLISHED)
-        self.builds += firefox_src_hist.createMissingBuilds()
+        self.builds += list(firefox_src_hist.createMissingBuilds())
         self.sources.append(firefox_src_hist)
 
         gtg_src_hist = self.publisher.getPubSource(
             sourcename="getting-things-gnome",
             status=PackagePublishingStatus.PUBLISHED)
-        self.builds += gtg_src_hist.createMissingBuilds()
+        self.builds += list(gtg_src_hist.createMissingBuilds())
         self.sources.append(gtg_src_hist)
 
 

=== modified file 'lib/lp/soyuz/tests/test_publish_archive_indexes.py'
--- lib/lp/soyuz/tests/test_publish_archive_indexes.py	2010-07-20 12:06:36 +0000
+++ lib/lp/soyuz/tests/test_publish_archive_indexes.py	2010-08-05 20:36:49 +0000
@@ -8,6 +8,10 @@
 import tempfile
 import unittest
 
+from zope.security.proxy import removeSecurityProxy
+
+from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
+from lp.soyuz.interfaces.publishing import PackagePublishingPriority
 from lp.soyuz.tests.test_publishing import TestNativePublishingBase
 
 
@@ -31,8 +35,14 @@
         the package in question.
         """
         pub_source = self.getPubSource(
+            sourcename='foo', dsc_binaries='foo-bin',
+            version='666', section='base',
             builddepends='fooish', builddependsindep='pyfoo',
-            build_conflicts='bar', build_conflicts_indep='pybar')
+            build_conflicts='bar', build_conflicts_indep='pybar',
+            dsc_maintainer_rfc822='Foo Bar <foo@xxxxxxx>',
+            architecturehintlist='all', dsc_standards_version='3.6.2',
+            dsc_format='1.0', filename='foo_666.dsc',
+            filecontent='I do not care about sources.')
 
         self.assertEqual(
             [u'Package: foo',
@@ -52,16 +62,29 @@
              u' 5913c3ad52c14a62e6ae7eef51f9ef42 28 foo_666.dsc'],
             pub_source.getIndexStanza().splitlines())
 
+    def getPubSourceForBinary(self):
+        return self.getPubSource(
+            sourcename='foo', dsc_maintainer_rfc822='Foo Bar <foo@xxxxxxx>')
+
     def testBinaryStanza(self):
         """Check just-created binary publication Index stanza.
 
         See also testSourceStanza, it must present something similar for
         binary packages.
         """
+        pub_source = self.getPubSourceForBinary()
         pub_binaries = self.getPubBinaries(
+            binaryname='foo-bin',
+            priority=PackagePublishingPriority.STANDARD, section="base",
+            installed_size=100, architecturespecific=True,
+            version='666',
             depends='biscuit', recommends='foo-dev', suggests='pyfoo',
             conflicts='old-foo', replaces='old-foo', provides='foo-master',
-            pre_depends='master-foo', enhances='foo-super', breaks='old-foo')
+            pre_depends='master-foo', enhances='foo-super', breaks='old-foo',
+            filecontent='bbbiiinnnaaarrryyy', summary='Foo app is great',
+            format=BinaryPackageFormat.DEB,
+            description='Well ...\nit does nothing, though',
+            pub_source=pub_source)
         pub_binary = pub_binaries[0]
         self.assertEqual(
             [u'Package: foo-bin',
@@ -114,8 +137,15 @@
             "Normal\nNormal"
             "\n.\n.\n."
             "\n %s" % ('x' * 100))
+        pub_source = self.getPubSourceForBinary()
         pub_binary = self.getPubBinaries(
-            description=description)[0]
+            description=description, pub_source=pub_source,
+            binaryname='foo-bin',
+            priority=PackagePublishingPriority.STANDARD,
+            section="base", installed_size=100, architecturespecific=False,
+            format=BinaryPackageFormat.DEB,
+            version="666", filecontent="bbbiiinnnaaarrryyy",
+            summary='Foo app is great')[0]
 
         self.assertEqual(
             [u'Package: foo-bin',
@@ -150,8 +180,14 @@
         'utf-8' for disk writing.
         """
         description = u'Using non-ascii as: \xe7\xe3\xe9\xf3'
+        pub_source = self.getPubSourceForBinary()
         pub_binary = self.getPubBinaries(
-            description=description)[0]
+            description=description, pub_source=pub_source,
+            binaryname='foo-bin',
+            priority=PackagePublishingPriority.STANDARD, section="base",
+            installed_size=100, architecturespecific=False,
+            version="666", format=BinaryPackageFormat.DEB,
+            filecontent='bbbiiinnnaaarrryyy', summary='Foo app is great')[0]
 
         self.assertEqual(
             [u'Package: foo-bin',
@@ -200,7 +236,9 @@
 
     def test_getIndexStanza_binary_stanza(self):
         """Check a binary stanza with APT parser."""
-        pub_binary = self.getPubBinaries()[0]
+        pub_binary = self.getPubBinaries(
+            binaryname='foo-bin', summary='Foo app is great',
+            description='Well ...\n it does nothing, though')[0]
 
         parser = self.write_stanza_and_reparse(pub_binary.getIndexStanza())
 
@@ -211,7 +249,8 @@
 
     def test_getIndexStanza_source_stanza(self):
         """Check a source stanza with APT parser."""
-        pub_source = self.getPubSource()
+        pub_source = self.getPubSource(
+            sourcename="foo", dsc_maintainer_rfc822='Foo Bar <foo@xxxxxxx>')
 
         parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
 
@@ -243,12 +282,12 @@
         This test can be removed if the parser is fixed and the corrupt
         data has been cleaned.
         """
-        pub_source = self.getPubSource()
-
         # An example of a corrupt dsc_binaries field. We need to ensure
         # that the corruption is not carried over into the index stanza.
-        pub_source.sourcepackagerelease.dsc_binaries = (
-            'foo_bin,\nbar_bin,\nzed_bin')
+        pub_source = self.getPubSource(
+            sourcename="foo", version="666")
+        naked_spr = removeSecurityProxy(pub_source.sourcepackagerelease)
+        naked_spr.dsc_binaries = "foo_bin,\nbar_bin,\nzed_bin"
 
         parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
 
@@ -278,24 +317,16 @@
         the binary field in the same way that apt_pkg.ParseTagFiles would,
         that it will continue to be written correctly to index files.
         """
-        pub_source = self.getPubSource()
-
-        # An example of a corrupt dsc_binaries field. We need to ensure
-        # that the corruption is not carried over into the index stanza.
-        pub_source.sourcepackagerelease.dsc_binaries = (
-            'foo_bin,\n bar_bin,\n zed_bin')
+        pub_source = self.getPubSource(
+            sourcename='foo', version="666",
+            dsc_binaries='foo_bin,\n bar_bin,\n zed_bin')
 
         parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
 
         self.assertEqual('foo', parser.Section['Package'])
-
-        # Without the fix, this raises a key-error due to apt-pkg not
-        # being able to parse the file.
         self.assertEqual(
             '666', parser.Section['Version'],
             'The Version field should be parsed correctly.')
-
-        # Without the fix, the second binary would not be parsed at all.
         self.assertEqual(
             'foo_bin,\n bar_bin,\n zed_bin', parser.Section['Binary'])
 

=== modified file 'lib/lp/soyuz/tests/test_publishing.py'
--- lib/lp/soyuz/tests/test_publishing.py	2010-08-02 02:13:52 +0000
+++ lib/lp/soyuz/tests/test_publishing.py	2010-08-05 20:36:49 +0000
@@ -16,7 +16,6 @@
 
 from canonical.config import config
 from canonical.database.constants import UTC_NOW
-from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
 from canonical.launchpad.webapp.errorlog import ErrorReportingUtility
 from canonical.testing import (
     DatabaseFunctionalLayer, LaunchpadZopelessLayer)
@@ -31,20 +30,18 @@
 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
 from lp.soyuz.model.processor import ProcessorFamily
 from lp.soyuz.model.publishing import (
-    SourcePackagePublishingHistory, BinaryPackagePublishingHistory)
+    BinaryPackagePublishingHistory)
 from lp.soyuz.interfaces.archive import ArchivePurpose
 from lp.soyuz.interfaces.archivearch import IArchiveArchSet
-from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
 from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFormat
 from lp.soyuz.interfaces.component import IComponentSet
-from lp.soyuz.interfaces.section import ISectionSet
 from lp.soyuz.interfaces.publishing import (
     IPublishingSet, PackagePublishingPriority, PackagePublishingStatus)
 from lp.soyuz.interfaces.queue import PackageUploadStatus
 from canonical.launchpad.scripts import FakeLogger
 from lp.testing import TestCaseWithFactory
-from lp.testing.factory import (
-    LaunchpadObjectFactory, remove_security_proxy_and_shout_at_engineer)
+from lp.testing.factory import LaunchpadObjectFactory
+from lp.testing.sampledata import UBUNTU_DEVELOPER_ADMIN_NAME
 from lp.testing.fakemethod import FakeMethod
 
 
@@ -73,7 +70,8 @@
             distroseries = self.factory.makeDistroRelease()
         self.distroseries = distroseries
         # Set up a person that has a GPG key.
-        self.person = getUtility(IPersonSet).getByName('name16')
+        self.person = getUtility(IPersonSet).getByName(
+            UBUNTU_DEVELOPER_ADMIN_NAME)
         # Make sure the name exists in the database, to make it easier
         # to get packages from distributions and distro series.
         name_set = getUtility(ISourcePackageNameSet)
@@ -127,31 +125,22 @@
 
         Returns a ILibraryFileAlias corresponding to the file uploaded.
         """
-        library_file = getUtility(ILibraryFileAliasSet).create(
-            filename, len(filecontent), StringIO(filecontent),
-            'application/text', restricted=restricted)
-        return library_file
+        return self.factory.makeLibraryFileAlias(
+            filename=filename, content=filecontent, restricted=restricted,
+            content_type='application/text')
 
     def addPackageUpload(self, archive, distroseries,
                          pocket=PackagePublishingPocket.RELEASE,
                          changes_file_name="foo_666_source.changes",
                          changes_file_content="fake changes file content",
                          upload_status=PackageUploadStatus.DONE):
-        signing_key = self.person.gpg_keys[0]
-        package_upload = distroseries.createQueueEntry(
-            pocket, changes_file_name, changes_file_content, archive,
-            signing_key)
-
-        status_to_method = {
-            PackageUploadStatus.DONE: 'setDone',
-            PackageUploadStatus.ACCEPTED: 'setAccepted',
-            }
-        naked_package_upload = remove_security_proxy_and_shout_at_engineer(
-            package_upload)
-        method = getattr(
-            naked_package_upload, status_to_method[upload_status])
-        method()
-
+        person = self.factory.makePerson()
+        signing_key = self.factory.makeGPGKey(person)
+        package_upload = self.factory.makePackageUpload(
+            archive=archive, distroseries=distroseries, pocket=pocket,
+            changes_filename=changes_file_name,
+            changes_file_content=changes_file_content,
+            signing_key=signing_key, status=upload_status)
         return package_upload
 
     def getPubSource(self, sourcename=None, version='666', component='main',
@@ -177,26 +166,35 @@
         """
         if sourcename is None:
             sourcename = self.default_package_name
-        spn = getUtility(ISourcePackageNameSet).getOrCreateByName(sourcename)
-
-        component = getUtility(IComponentSet)[component]
-        section = getUtility(ISectionSet)[section]
+        spn = self.factory.getOrMakeSourcePackageName(name=sourcename)
+        component = self.factory.makeComponent(name=component)
 
         if distroseries is None:
             distroseries = self.distroseries
         if archive is None:
             archive = distroseries.main_archive
-        if maintainer is None:
-            maintainer = self.person
         if creator is None:
-            creator = self.person
-
-        spr = distroseries.createUploadedSourcePackageRelease(
+            creator = self.factory.makePerson()
+            self.factory.makeGPGKey(creator)
+
+        changes_file_name = "%s_%s_source.changes" % (sourcename, version)
+        if spr_only:
+            upload_status = PackageUploadStatus.ACCEPTED
+        else:
+            upload_status = PackageUploadStatus.DONE
+        package_upload = self.addPackageUpload(
+            archive, distroseries, pocket,
+            changes_file_name=changes_file_name,
+            changes_file_content=changes_file_content,
+            upload_status=upload_status)
+
+        spr = self.factory.makeSourcePackageRelease(
+            distroseries=distroseries,
             sourcepackagename=spn,
             maintainer=maintainer,
             creator=creator,
             component=component,
-            section=section,
+            section_name=section,
             urgency=urgency,
             version=version,
             builddepends=builddepends,
@@ -204,30 +202,15 @@
             build_conflicts=build_conflicts,
             build_conflicts_indep=build_conflicts_indep,
             architecturehintlist=architecturehintlist,
-            changelog=None,
-            changelog_entry=None,
-            dsc=None,
-            copyright='placeholder ...',
-            dscsigningkey=self.person.gpg_keys[0],
+            dscsigningkey=creator.gpg_keys[0],
             dsc_maintainer_rfc822=dsc_maintainer_rfc822,
             dsc_standards_version=dsc_standards_version,
             dsc_format=dsc_format,
             dsc_binaries=dsc_binaries,
-            archive=archive, dateuploaded=date_uploaded)
-
-        changes_file_name = "%s_%s_source.changes" % (sourcename, version)
-        if spr_only:
-            upload_status = PackageUploadStatus.ACCEPTED
-        else:
-            upload_status = PackageUploadStatus.DONE
-        package_upload = self.addPackageUpload(
-            archive, distroseries, pocket,
-            changes_file_name=changes_file_name,
-            changes_file_content=changes_file_content,
-            upload_status=upload_status)
-        naked_package_upload = remove_security_proxy_and_shout_at_engineer(
-            package_upload)
-        naked_package_upload.addSource(spr)
+            archive=archive,
+            date_uploaded=date_uploaded,
+            )
+        removeSecurityProxy(package_upload).addSource(spr)
 
         if filename is None:
             filename = "%s_%s.dsc" % (sourcename, version)
@@ -238,24 +221,18 @@
         if spr_only:
             return spr
 
-        if status == PackagePublishingStatus.PUBLISHED:
-            datepublished = UTC_NOW
-        else:
-            datepublished = None
-
-        spph = SourcePackagePublishingHistory(
+        spph = self.factory.makeSourcePackagePublishingHistory(
             distroseries=distroseries,
             sourcepackagerelease=spr,
             component=spr.component,
-            section=spr.section,
+            section_name=spr.section.name,
             status=status,
-            datecreated=date_uploaded,
+            date_uploaded=date_uploaded,
             dateremoved=dateremoved,
-            datepublished=datepublished,
             scheduleddeletiondate=scheduleddeletiondate,
             pocket=pocket,
-            archive=archive)
-
+            archive=archive,
+            )
         return spph
 
     def getPubBinaries(self, binaryname='foo-bin', summary='Foo app is great',
@@ -275,7 +252,10 @@
                        version='666',
                        architecturespecific=False,
                        builder=None,
-                       component='main'):
+                       component='main',
+                       section='base',
+                       priority=PackagePublishingPriority.STANDARD,
+                       installed_size=100):
         """Return a list of binary publishing records."""
         if distroseries is None:
             distroseries = self.distroseries
@@ -305,10 +285,11 @@
             binarypackagerelease = self.uploadBinaryForBuild(
                 build, binaryname, filecontent, summary, description,
                 shlibdep, depends, recommends, suggests, conflicts, replaces,
-                provides, pre_depends, enhances, breaks, format)
+                provides, pre_depends, enhances, breaks, format,
+                installed_size=installed_size)
             pub_binaries = self.publishBinaryInArchive(
                 binarypackagerelease, archive, status, pocket,
-                scheduleddeletiondate, dateremoved)
+                scheduleddeletiondate, dateremoved, section, priority)
             published_binaries.extend(pub_binaries)
             package_upload = self.addPackageUpload(
                 archive, distroseries, pocket,
@@ -326,20 +307,18 @@
         summary="summary", description="description", shlibdep=None,
         depends=None, recommends=None, suggests=None, conflicts=None,
         replaces=None, provides=None, pre_depends=None, enhances=None,
-        breaks=None, format=BinaryPackageFormat.DEB):
+        breaks=None, format=BinaryPackageFormat.DEB, installed_size=None):
         """Return the corresponding `BinaryPackageRelease`."""
         sourcepackagerelease = build.source_package_release
         distroarchseries = build.distro_arch_series
         architecturespecific = (
             not sourcepackagerelease.architecturehintlist == 'all')
 
-        binarypackagename = getUtility(
-            IBinaryPackageNameSet).getOrCreateByName(binaryname)
+        binarypackagename = self.factory.getOrMakeBinaryPackageName(
+            name=binaryname)
 
-        binarypackagerelease = build.createBinaryPackageRelease(
-            version=sourcepackagerelease.version,
-            component=sourcepackagerelease.component,
-            section=sourcepackagerelease.section,
+        binarypackagerelease = self.factory.makeBinaryPackageRelease(
+            build=build,
             binarypackagename=binarypackagename,
             summary=summary,
             description=description,
@@ -354,10 +333,11 @@
             enhances=enhances,
             breaks=breaks,
             essential=False,
-            installedsize=100,
             architecturespecific=architecturespecific,
             binpackageformat=format,
-            priority=PackagePublishingPriority.STANDARD)
+            priority=PackagePublishingPriority.STANDARD,
+            installed_size=installed_size,
+            )
 
         # Create the corresponding binary file.
         if architecturespecific:
@@ -395,7 +375,8 @@
         self, binarypackagerelease, archive,
         status=PackagePublishingStatus.PENDING,
         pocket=PackagePublishingPocket.RELEASE,
-        scheduleddeletiondate=None, dateremoved=None):
+        scheduleddeletiondate=None, dateremoved=None, section=None,
+        priority=None):
         """Return the corresponding BinaryPackagePublishingHistory."""
         distroarchseries = binarypackagerelease.build.distro_arch_series
 
@@ -407,20 +388,17 @@
 
         pub_binaries = []
         for arch in archs:
-            pub = BinaryPackagePublishingHistory(
+            pub = self.factory.makeBinaryPackagePublishingHistory(
                 distroarchseries=arch,
                 binarypackagerelease=binarypackagerelease,
-                component=binarypackagerelease.component,
-                section=binarypackagerelease.section,
-                priority=binarypackagerelease.priority,
                 status=status,
                 scheduleddeletiondate=scheduleddeletiondate,
                 dateremoved=dateremoved,
-                datecreated=UTC_NOW,
                 pocket=pocket,
-                archive=archive)
-            if status == PackagePublishingStatus.PUBLISHED:
-                pub.datepublished = UTC_NOW
+                archive=archive,
+                section_name=section,
+                priority=priority,
+                )
             pub_binaries.append(pub)
 
         return pub_binaries
@@ -540,7 +518,8 @@
         for pub in pubs:
             self.checkPastDate(pub.datesuperseded)
             if supersededby is not None:
-                if isinstance(pub, BinaryPackagePublishingHistory):
+                if isinstance(
+                    removeSecurityProxy(pub), BinaryPackagePublishingHistory):
                     dominant = supersededby.binarypackagerelease.build
                 else:
                     dominant = supersededby.sourcepackagerelease
@@ -611,7 +590,7 @@
         self.layer.commit()
 
         foo_name = "%s/main/f/foo/foo_666.dsc" % self.pool_dir
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(
             pub_source.status, PackagePublishingStatus.PUBLISHED)
         self.assertEqual(open(foo_name).read().strip(), 'foo is happy')
@@ -623,7 +602,7 @@
         pub_source2.publish(self.disk_pool, self.logger)
         self.layer.commit()
 
-        pub_source2.sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertEqual(
             pub_source2.status, PackagePublishingStatus.PENDING)
         self.assertEqual(open(foo_name).read().strip(), 'foo is happy')
@@ -640,7 +619,7 @@
         self.layer.commit()
         bar_name = "%s/main/b/bar/bar_666.dsc" % self.pool_dir
         self.assertEqual(open(bar_name).read().strip(), 'bar is good')
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(
             pub_source.status, PackagePublishingStatus.PUBLISHED)
 
@@ -648,7 +627,7 @@
             sourcename='bar', filecontent='bar is good')
         pub_source2.publish(self.disk_pool, self.logger)
         self.layer.commit()
-        pub_source2.sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertEqual(
             pub_source2.status, PackagePublishingStatus.PUBLISHED)
 
@@ -668,8 +647,8 @@
         pub_source2.publish(self.disk_pool, self.logger)
         self.layer.commit()
 
-        pub_source.sync()
-        pub_source2.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_source2).sync()
         self.assertEqual(
             pub_source.status, PackagePublishingStatus.PUBLISHED)
         self.assertEqual(
@@ -688,7 +667,7 @@
         pub_source3.publish(self.disk_pool, self.logger)
         self.layer.commit()
 
-        pub_source3.sync()
+        removeSecurityProxy(pub_source3).sync()
         self.assertEqual(
             pub_source3.status, PackagePublishingStatus.PENDING)
 
@@ -709,7 +688,7 @@
         pub_source.publish(test_disk_pool, self.logger)
         self.layer.commit()
 
-        pub_source.sync()
+        removeSecurityProxy(pub_source).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
         self.assertEqual(pub_source.sourcepackagerelease.upload_archive,
                          cprov.archive)
@@ -795,7 +774,7 @@
 
         # Adjust the source package release original component.
         universe = getUtility(IComponentSet)['universe']
-        source.sourcepackagerelease.component = universe
+        removeSecurityProxy(source.sourcepackagerelease).component = universe
 
         self.copyAndCheck(source, source.distroseries, 'universe')
 
@@ -905,8 +884,9 @@
         """
         available_archs = [self.sparc_distroarch, self.avr_distroarch]
         pubrec = self.getPubSource(architecturehintlist='any')
+        naked_pubrec = removeSecurityProxy(pubrec)
         self.assertEquals([self.sparc_distroarch],
-            pubrec._getAllowedArchitectures(available_archs))
+            naked_pubrec._getAllowedArchitectures(available_archs))
 
     def test__getAllowedArchitectures_restricted_override(self):
         """Test _getAllowedArchitectures honors overrides of restricted archs.
@@ -917,8 +897,9 @@
         available_archs = [self.sparc_distroarch, self.avr_distroarch]
         getUtility(IArchiveArchSet).new(self.archive, self.avr_family)
         pubrec = self.getPubSource(architecturehintlist='any')
+        naked_pubrec = removeSecurityProxy(pubrec)
         self.assertEquals([self.sparc_distroarch, self.avr_distroarch],
-            pubrec._getAllowedArchitectures(available_archs))
+            naked_pubrec._getAllowedArchitectures(available_archs))
 
     def test_createMissingBuilds_restricts_any(self):
         """createMissingBuilds() should limit builds targeted at 'any'

=== modified file 'lib/lp/soyuz/tests/test_publishing_top_level_api.py'
--- lib/lp/soyuz/tests/test_publishing_top_level_api.py	2010-07-20 12:06:36 +0000
+++ lib/lp/soyuz/tests/test_publishing_top_level_api.py	2010-08-05 20:36:49 +0000
@@ -3,6 +3,8 @@
 
 """Test top-level publication API in Soyuz."""
 
+from zope.security.proxy import removeSecurityProxy
+
 from lp.soyuz.tests.test_publishing import TestNativePublishingBase
 
 from lp.registry.interfaces.series import SeriesStatus
@@ -109,8 +111,8 @@
         self._publish(pocket=pocket)
 
         # source and binary PUBLISHED in database.
-        pub_source.sync()
-        pub_bin.sync()
+        removeSecurityProxy(pub_source).sync()
+        removeSecurityProxy(pub_bin).sync()
         self.assertEqual(pub_source.status, PackagePublishingStatus.PUBLISHED)
         self.assertEqual(pub_bin.status, PackagePublishingStatus.PUBLISHED)
 

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2010-08-04 00:47:20 +0000
+++ lib/lp/testing/factory.py	2010-08-05 20:36:49 +0000
@@ -143,6 +143,7 @@
 from lp.soyuz.interfaces.archive import (
     default_name_by_purpose, IArchiveSet, ArchivePurpose)
 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
+from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
 from lp.soyuz.interfaces.binarypackagerelease import (
     BinaryPackageFileType, BinaryPackageFormat)
 from lp.soyuz.interfaces.component import IComponentSet
@@ -150,9 +151,8 @@
 from lp.soyuz.interfaces.processor import IProcessorFamilySet
 from lp.soyuz.interfaces.publishing import (
     IPublishingSet, PackagePublishingPriority, PackagePublishingStatus)
+from lp.soyuz.interfaces.queue import PackageUploadStatus
 from lp.soyuz.interfaces.section import ISectionSet
-from lp.soyuz.model.binarypackagename import BinaryPackageName
-from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
 from lp.soyuz.model.files import BinaryPackageFile, SourcePackageReleaseFile
 from lp.soyuz.model.processor import ProcessorFamilySet
 from lp.testing import (
@@ -1671,9 +1671,9 @@
                          members=None, title=None):
         """Make a new distribution."""
         if name is None:
-            name = self.getUniqueString()
+            name = self.getUniqueString(prefix="distribution")
         if displayname is None:
-            displayname = self.getUniqueString()
+            displayname = name.capitalize()
         if title is None:
             title = self.getUniqueString()
         description = self.getUniqueString()
@@ -1694,7 +1694,7 @@
         if distribution is None:
             distribution = self.makeDistribution()
         if name is None:
-            name = self.getUniqueString()
+            name = self.getUniqueString(prefix="distroseries")
         if displayname is None:
             displayname = name.capitalize()
         if version is None:
@@ -2267,6 +2267,35 @@
     def getAnySourcePackageUrgency(self):
         return SourcePackageUrgency.MEDIUM
 
+    def makePackageUpload(self, distroseries=None, archive=None,
+                          pocket=None, changes_filename=None,
+                          changes_file_content=None,
+                          signing_key=None, status=None):
+        if archive is None:
+            archive = self.makeArchive()
+        if distroseries is None:
+            distroseries = self.makeDistroSeries(
+                distribution=archive.distribution)
+        if changes_filename is None:
+            changes_filename = self.getUniqueString("changesfilename")
+        if changes_file_content is None:
+            changes_file_content = self.getUniqueString("changesfilecontent")
+        if pocket is None:
+            pocket = PackagePublishingPocket.RELEASE
+        package_upload = distroseries.createQueueEntry(
+            pocket, changes_filename, changes_file_content, archive,
+            signing_key=signing_key)
+        if status is not None:
+            status_to_method = {
+                PackageUploadStatus.DONE: 'setDone',
+                PackageUploadStatus.ACCEPTED: 'setAccepted',
+                }
+            naked_package_upload = removeSecurityProxy(package_upload)
+            method = getattr(
+                naked_package_upload, status_to_method[status])
+            method()
+        return package_upload
+
     def makeSourcePackageRelease(self, archive=None, sourcepackagename=None,
                                  distroseries=None, maintainer=None,
                                  creator=None, component=None,
@@ -2313,9 +2342,10 @@
         if maintainer is None:
             maintainer = self.makePerson()
 
-        maintainer_email = '%s <%s>' % (
-            maintainer.displayname,
-            maintainer.preferredemail.email)
+        if dsc_maintainer_rfc822 is None:
+            dsc_maintainer_rfc822 = '%s <%s>' % (
+                maintainer.displayname,
+                maintainer.preferredemail.email)
 
         if creator is None:
             creator = self.makePerson()
@@ -2341,7 +2371,7 @@
             dsc=None,
             copyright=self.getUniqueString(),
             dscsigningkey=dscsigningkey,
-            dsc_maintainer_rfc822=maintainer_email,
+            dsc_maintainer_rfc822=dsc_maintainer_rfc822,
             dsc_standards_version=dsc_standards_version,
             dsc_format=dsc_format,
             dsc_binaries=dsc_binaries,
@@ -2481,6 +2511,8 @@
         naked_spph.datecreated = date_uploaded
         naked_spph.dateremoved = dateremoved
         naked_spph.scheduleddeletiondate = scheduleddeletiondate
+        if status == PackagePublishingStatus.PUBLISHED:
+            naked_spph.datepublished = UTC_NOW
         return spph
 
     def makeBinaryPackagePublishingHistory(self, binarypackagerelease=None,
@@ -2529,12 +2561,25 @@
         naked_bpph.dateremoved = dateremoved
         naked_bpph.scheduleddeletiondate = scheduleddeletiondate
         naked_bpph.priority = priority
+        if status == PackagePublishingStatus.PUBLISHED:
+            naked_bpph.datepublished = UTC_NOW
         return bpph
 
     def makeBinaryPackageName(self, name=None):
+        """Make an `IBinaryPackageName`."""
         if name is None:
             name = self.getUniqueString("binarypackage")
-        return BinaryPackageName(name=name)
+        return getUtility(IBinaryPackageNameSet).new(name)
+
+    def getOrMakeBinaryPackageName(self, name=None):
+        """Get an existing `IBinaryPackageName` or make a new one.
+
+        This method encapsulates getOrCreateByName so that tests can be kept
+        free of the getUtility(IBinaryPackageNameSet) noise.
+        """
+        if name is None:
+            return self.makeBinaryPackageName()
+        return getUtility(IBinaryPackageNameSet).getOrCreateByName(name)
 
     def makeBinaryPackageFile(self, binarypackagerelease=None,
                               library_file=None, filetype=None):
@@ -2553,32 +2598,44 @@
                                  binpackageformat=None, component=None,
                                  section_name=None, priority=None,
                                  architecturespecific=False,
-                                 summary=None, description=None):
+                                 summary=None, description=None,
+                                 shlibdeps=None, depends=None,
+                                 recommends=None, suggests=None,
+                                 conflicts=None, replaces=None,
+                                 provides=None, pre_depends=None,
+                                 enhances=None, breaks=None,
+                                 essential=False, installed_size=None):
         """Make a `BinaryPackageRelease`."""
+        if build is None:
+            build = self.makeBinaryPackageBuild()
         if binarypackagename is None:
             binarypackagename = self.makeBinaryPackageName()
         if version is None:
-            version = self.getUniqueString("version")
-        if build is None:
-            build = self.makeBinaryPackageBuild()
+            version = build.source_package_release.version
         if binpackageformat is None:
             binpackageformat = BinaryPackageFormat.DEB
         if component is None:
-            component = self.makeComponent()
-        section = self.makeSection(name=section_name)
+            component = build.source_package_release.component
+        section = build.source_package_release.section
         if priority is None:
             priority = PackagePublishingPriority.OPTIONAL
         if summary is None:
             summary = self.getUniqueString("summary")
         if description is None:
             description = self.getUniqueString("description")
-        return ProxyFactory(
-            BinaryPackageRelease(
+        if installed_size is None:
+            installed_size = self.getUniqueInteger()
+        return build.createBinaryPackageRelease(
                 binarypackagename=binarypackagename, version=version,
-                build=build, binpackageformat=binpackageformat,
+                binpackageformat=binpackageformat,
                 component=component, section=section, priority=priority,
                 summary=summary, description=description,
-                architecturespecific=architecturespecific))
+                architecturespecific=architecturespecific,
+                shlibdeps=shlibdeps, depends=depends, recommends=recommends,
+                suggests=suggests, conflicts=conflicts, replaces=replaces,
+                provides=provides, pre_depends=pre_depends,
+                enhances=enhances, breaks=breaks, essential=essential,
+                installedsize=installed_size)
 
     def makeSection(self, name=None):
         """Make a `Section`."""

=== modified file 'lib/lp/testing/matchers.py'
--- lib/lp/testing/matchers.py	2010-08-02 20:56:25 +0000
+++ lib/lp/testing/matchers.py	2010-08-05 20:36:49 +0000
@@ -3,12 +3,14 @@
 
 __metaclass__ = type
 __all__ = [
+    'DoesNotCorrectlyProvide',
     'DoesNotProvide',
-    'DoesNotCorrectlyProvide',
+    'DoesNotStartWith',
     'IsNotProxied',
     'IsProxied',
     'Provides',
     'ProvidesAndIsProxied',
+    'StartsWith',
     ]
 
 from zope.interface.verify import verifyObject
@@ -133,3 +135,39 @@
         if mismatch is not None:
             return mismatch
         return IsProxied().match(matchee)
+
+
+class DoesNotStartWith(Mismatch):
+
+    def __init__(self, matchee, expected):
+        """Create a DoesNotStartWith Mismatch.
+
+        :param matchee: the string that did not match.
+        :param expected: the string that `matchee` was expected to start
+            with.
+        """
+        self.matchee = matchee
+        self.expected = expected
+
+    def describe(self):
+        return "'%s' does not start with '%s'." % (
+            self.matchee, self.expected)
+
+
+class StartsWith(Matcher):
+    """Checks whether one string starts with another."""
+
+    def __init__(self, expected):
+        """Create a StartsWith Matcher.
+
+        :param expected: the string that matchees should start with.
+        """
+        self.expected = expected
+
+    def __str__(self):
+        return "Starts with '%s'." % self.expected
+
+    def match(self, matchee):
+        if not matchee.startswith(self.expected):
+            return DoesNotStartWith(matchee, self.expected)
+        return None

=== modified file 'lib/lp/testing/tests/test_factory.py'
--- lib/lp/testing/tests/test_factory.py	2010-08-03 01:28:16 +0000
+++ lib/lp/testing/tests/test_factory.py	2010-08-05 20:36:49 +0000
@@ -17,26 +17,46 @@
     DatabaseFunctionalLayer, LaunchpadZopelessLayer)
 from lp.buildmaster.interfaces.buildbase import BuildStatus
 from lp.code.enums import CodeImportReviewStatus
+from lp.registry.interfaces.distribution import IDistribution
+from lp.registry.interfaces.distroseries import IDistroSeries
 from lp.registry.interfaces.sourcepackage import SourcePackageFileType
 from lp.registry.interfaces.suitesourcepackage import ISuiteSourcePackage
 from lp.services.worlddata.interfaces.language import ILanguage
 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuild
+from lp.soyuz.interfaces.binarypackagename import IBinaryPackageName
 from lp.soyuz.interfaces.binarypackagerelease import (
     BinaryPackageFileType, IBinaryPackageRelease)
 from lp.soyuz.interfaces.files import (
     IBinaryPackageFile, ISourcePackageReleaseFile)
 from lp.soyuz.interfaces.publishing import (
     IBinaryPackagePublishingHistory, ISourcePackagePublishingHistory,
-    PackagePublishingPriority, PackagePublishingStatus)
+    PackagePublishingPriority, PackagePublishingPocket,
+    PackagePublishingStatus)
+from lp.soyuz.interfaces.queue import IPackageUpload, PackageUploadStatus
+from lp.soyuz.interfaces.sourcepackagerelease import ISourcePackageRelease
 from lp.testing import TestCaseWithFactory
 from lp.testing.factory import is_security_proxied_or_harmless
-from lp.testing.matchers import IsProxied, Provides, ProvidesAndIsProxied
+from lp.testing.matchers import (
+    IsProxied, Provides, ProvidesAndIsProxied, StartsWith)
 
 
 class TestFactory(TestCaseWithFactory):
 
     layer = DatabaseFunctionalLayer
 
+    # getOrMakeBinaryPackageName
+    def test_getOrMakeBinaryPackageName_returns_proxied_IBPN(self):
+        binarypackagename = self.factory.getOrMakeBinaryPackageName()
+        self.assertThat(
+            binarypackagename, ProvidesAndIsProxied(IBinaryPackageName))
+
+    def test_getOrMakeBinaryPackageName_returns_existing_name(self):
+        binarypackagename1 = self.factory.getOrMakeBinaryPackageName(
+            name="foo")
+        binarypackagename2 = self.factory.getOrMakeBinaryPackageName(
+            name="foo")
+        self.assertEqual(binarypackagename1, binarypackagename2)
+
     # loginAsAnyone
     def test_loginAsAnyone(self):
         # Login as anyone logs you in as any user.
@@ -71,6 +91,12 @@
             status=BuildStatus.FULLYBUILT)
         self.assertEqual(BuildStatus.FULLYBUILT, bpb.status)
 
+    # makeBinaryPackageName
+    def test_makeBinaryPackageName_returns_proxied_IBinaryPackageName(self):
+        binarypackagename = self.factory.makeBinaryPackageName()
+        self.assertThat(
+            binarypackagename, ProvidesAndIsProxied(IBinaryPackageName))
+
     # makeBinaryPackagePublishingHistory
     def test_makeBinaryPackagePublishingHistory_returns_IBPPH(self):
         bpph = self.factory.makeBinaryPackagePublishingHistory()
@@ -110,11 +136,153 @@
             priority=PackagePublishingPriority.EXTRA)
         self.assertEquals(PackagePublishingPriority.EXTRA, bpph.priority)
 
+    def test_makeBinaryPackagePublishingHistory_sets_datecreated(self):
+        bpph = self.factory.makeBinaryPackagePublishingHistory()
+        self.assertNotEqual(None, bpph.datecreated)
+
+    def test_makeBinaryPackagePublishingHistory_sets_datepub_PENDING(self):
+        bpph = self.factory.makeBinaryPackagePublishingHistory(
+            status=PackagePublishingStatus.PENDING)
+        self.assertEqual(None, bpph.datepublished)
+
+    def test_makeBinaryPackagePublishingHistory_sets_datepub_PUBLISHED(self):
+        bpph = self.factory.makeBinaryPackagePublishingHistory(
+            status=PackagePublishingStatus.PUBLISHED)
+        self.assertNotEqual(None, bpph.datepublished)
+
     # makeBinaryPackageRelease
     def test_makeBinaryPackageRelease_returns_IBinaryPackageRelease(self):
         bpr = self.factory.makeBinaryPackageRelease()
         self.assertThat(bpr, ProvidesAndIsProxied(IBinaryPackageRelease))
 
+    def test_makeBinaryPackageRelease_uses_build(self):
+        build = self.factory.makeBinaryPackageBuild()
+        bpr = self.factory.makeBinaryPackageRelease(build=build)
+        self.assertEqual(build, bpr.build)
+
+    def test_makeBinaryPackageRelease_uses_build_version(self):
+        build = self.factory.makeBinaryPackageBuild()
+        bpr = self.factory.makeBinaryPackageRelease(build=build)
+        self.assertEqual(
+            build.source_package_release.version, bpr.version)
+
+    def test_makeBinaryPackageRelease_uses_build_component(self):
+        build = self.factory.makeBinaryPackageBuild()
+        bpr = self.factory.makeBinaryPackageRelease(build=build)
+        self.assertEqual(
+            build.source_package_release.component, bpr.component)
+
+    def test_makeBinaryPackageRelease_uses_build_section(self):
+        build = self.factory.makeBinaryPackageBuild()
+        bpr = self.factory.makeBinaryPackageRelease(build=build)
+        self.assertEqual(
+            build.source_package_release.section, bpr.section)
+
+    def test_makeBinaryPackageRelease_matches_build_version(self):
+        bpr = self.factory.makeBinaryPackageRelease()
+        self.assertEqual(
+            bpr.build.source_package_release.version, bpr.version)
+
+    def test_makeBinaryPackageRelease_matches_build_component(self):
+        bpr = self.factory.makeBinaryPackageRelease()
+        self.assertEqual(
+            bpr.build.source_package_release.component, bpr.component)
+
+    def test_makeBinaryPackageRelease_matches_build_section(self):
+        bpr = self.factory.makeBinaryPackageRelease()
+        self.assertEqual(
+            bpr.build.source_package_release.section, bpr.section)
+
+    def test_makeBinaryPackageRelease_uses_shlibdeps(self):
+        bpr = self.factory.makeBinaryPackageRelease(shlibdeps="foo bar")
+        self.assertEqual("foo bar", bpr.shlibdeps)
+
+    def test_makeBinaryPackageRelease_allows_None_shlibdeps(self):
+        bpr = self.factory.makeBinaryPackageRelease(shlibdeps=None)
+        self.assertEqual(None, bpr.shlibdeps)
+
+    def test_makeBinaryPackageRelease_uses_depends(self):
+        bpr = self.factory.makeBinaryPackageRelease(depends="apt | bzr")
+        self.assertEqual("apt | bzr", bpr.depends)
+
+    def test_makeBinaryPackageRelease_allows_None_depends(self):
+        bpr = self.factory.makeBinaryPackageRelease(depends=None)
+        self.assertEqual(None, bpr.depends)
+
+    def test_makeBinaryPackageRelease_uses_recommends(self):
+        bpr = self.factory.makeBinaryPackageRelease(recommends="ssss")
+        self.assertEqual("ssss", bpr.recommends)
+
+    def test_makeBinaryPackageRelease_allows_None_recommends(self):
+        bpr = self.factory.makeBinaryPackageRelease(recommends=None)
+        self.assertEqual(None, bpr.recommends)
+
+    def test_makeBinaryPackageRelease_uses_suggests(self):
+        bpr = self.factory.makeBinaryPackageRelease(suggests="ssss")
+        self.assertEqual("ssss", bpr.suggests)
+
+    def test_makeBinaryPackageRelease_allows_None_suggests(self):
+        bpr = self.factory.makeBinaryPackageRelease(suggests=None)
+        self.assertEqual(None, bpr.suggests)
+
+    def test_makeBinaryPackageRelease_uses_conflicts(self):
+        bpr = self.factory.makeBinaryPackageRelease(conflicts="ssss")
+        self.assertEqual("ssss", bpr.conflicts)
+
+    def test_makeBinaryPackageRelease_allows_None_conflicts(self):
+        bpr = self.factory.makeBinaryPackageRelease(conflicts=None)
+        self.assertEqual(None, bpr.conflicts)
+
+    def test_makeBinaryPackageRelease_uses_replaces(self):
+        bpr = self.factory.makeBinaryPackageRelease(replaces="ssss")
+        self.assertEqual("ssss", bpr.replaces)
+
+    def test_makeBinaryPackageRelease_allows_None_replaces(self):
+        bpr = self.factory.makeBinaryPackageRelease(replaces=None)
+        self.assertEqual(None, bpr.replaces)
+
+    def test_makeBinaryPackageRelease_uses_provides(self):
+        bpr = self.factory.makeBinaryPackageRelease(provides="ssss")
+        self.assertEqual("ssss", bpr.provides)
+
+    def test_makeBinaryPackageRelease_allows_None_provides(self):
+        bpr = self.factory.makeBinaryPackageRelease(provides=None)
+        self.assertEqual(None, bpr.provides)
+
+    def test_makeBinaryPackageRelease_uses_pre_depends(self):
+        bpr = self.factory.makeBinaryPackageRelease(pre_depends="ssss")
+        self.assertEqual("ssss", bpr.pre_depends)
+
+    def test_makeBinaryPackageRelease_allows_None_pre_depends(self):
+        bpr = self.factory.makeBinaryPackageRelease(pre_depends=None)
+        self.assertEqual(None, bpr.pre_depends)
+
+    def test_makeBinaryPackageRelease_uses_enhances(self):
+        bpr = self.factory.makeBinaryPackageRelease(enhances="ssss")
+        self.assertEqual("ssss", bpr.enhances)
+
+    def test_makeBinaryPackageRelease_allows_None_enhances(self):
+        bpr = self.factory.makeBinaryPackageRelease(enhances=None)
+        self.assertEqual(None, bpr.enhances)
+
+    def test_makeBinaryPackageRelease_uses_breaks(self):
+        bpr = self.factory.makeBinaryPackageRelease(breaks="ssss")
+        self.assertEqual("ssss", bpr.breaks)
+
+    def test_makeBinaryPackageRelease_allows_None_breaks(self):
+        bpr = self.factory.makeBinaryPackageRelease(breaks=None)
+        self.assertEqual(None, bpr.breaks)
+
+    def test_makeBinaryPackageRelease_uses_essential(self):
+        bpr = self.factory.makeBinaryPackageRelease(essential=True)
+        self.assertEqual(True, bpr.essential)
+        bpr = self.factory.makeBinaryPackageRelease(essential=False)
+        self.assertEqual(False, bpr.essential)
+
+    def test_makeBinaryPackageRelease_uses_installed_size(self):
+        bpr = self.factory.makeBinaryPackageRelease(installed_size=110)
+        self.assertEqual(110, bpr.installedsize)
+
     # makeCodeImport
     def test_makeCodeImportNoStatus(self):
         # If makeCodeImport is not given a review status, it defaults to NEW.
@@ -129,6 +297,52 @@
         code_import = self.factory.makeCodeImport(review_status=status)
         self.assertEqual(status, code_import.review_status)
 
+    # makeDistribution
+    def test_makeDistribution_returns_IDistribution(self):
+        distribution = self.factory.makeDistribution()
+        self.assertThat(
+            removeSecurityProxy(distribution), Provides(IDistribution))
+
+    def test_makeDistribution_returns_proxy(self):
+        distribution = self.factory.makeDistribution()
+        self.assertThat(distribution, IsProxied())
+
+    def test_makeDistribution_created_name_starts_with_distribution(self):
+        distribution = self.factory.makeDistribution()
+        self.assertThat(distribution.name, StartsWith("distribution"))
+
+    def test_makeDistribution_created_display_name_starts_Distribution(self):
+        distribution = self.factory.makeDistribution()
+        self.assertThat(distribution.displayname, StartsWith("Distribution"))
+
+    # makeDistroRelease
+    def test_makeDistroRelease_returns_IDistroSeries(self):
+        distroseries = self.factory.makeDistroRelease()
+        self.assertThat(
+            removeSecurityProxy(distroseries), Provides(IDistroSeries))
+
+    def test_makeDistroRelease_returns_proxy(self):
+        distroseries = self.factory.makeDistroRelease()
+        self.assertThat(distroseries, IsProxied())
+
+    # makeDistroSeries
+    def test_makeDistroSeries_returns_IDistroSeries(self):
+        distroseries = self.factory.makeDistroSeries()
+        self.assertThat(
+            removeSecurityProxy(distroseries), Provides(IDistroSeries))
+
+    def test_makeDistroSeries_returns_proxy(self):
+        distroseries = self.factory.makeDistroSeries()
+        self.assertThat(distroseries, IsProxied())
+
+    def test_makeDistroSeries_created_name_starts_with_distroseries(self):
+        distroseries = self.factory.makeDistroSeries()
+        self.assertThat(distroseries.name, StartsWith("distroseries"))
+
+    def test_makeDistroSeries_created_display_name_starts_Distroseries(self):
+        distroseries = self.factory.makeDistroSeries()
+        self.assertThat(distroseries.displayname, StartsWith("Distroseries"))
+
     # makeLanguage
     def test_makeLanguage(self):
         # Without parameters, makeLanguage creates a language with code
@@ -199,6 +413,27 @@
             scheduleddeletiondate=scheduleddeletiondate)
         self.assertEquals(scheduleddeletiondate, spph.scheduleddeletiondate)
 
+    def test_makeSourcePackagePublishingHistory_datepublished_PENDING(self):
+        spph = self.factory.makeSourcePackagePublishingHistory(
+            status=PackagePublishingStatus.PENDING)
+        self.assertEquals(None, spph.datepublished)
+
+    def test_makeSourcePackagePublishingHistory_datepublished_PUBLISHED(self):
+        spph = self.factory.makeSourcePackagePublishingHistory(
+            status=PackagePublishingStatus.PUBLISHED)
+        self.assertNotEqual(None, spph.datepublished)
+
+    # makeSourcePackageRelease
+    def test_makeSourcePackageRelease_returns_proxied_ISPR(self):
+        spr = self.factory.makeSourcePackageRelease()
+        self.assertThat(spr, ProvidesAndIsProxied(ISourcePackageRelease))
+
+    def test_makeSourcePackageRelease_uses_dsc_maintainer_rfc822(self):
+        maintainer = "James Westby <james.westby@xxxxxxxxxxxxx>"
+        spr = self.factory.makeSourcePackageRelease(
+            dsc_maintainer_rfc822=maintainer)
+        self.assertEqual(maintainer, spr.dsc_maintainer_rfc822)
+
     # makeSuiteSourcePackage
     def test_makeSuiteSourcePackage_returns_ISuiteSourcePackage(self):
         ssp = self.factory.makeSuiteSourcePackage()
@@ -234,6 +469,59 @@
             filetype=BinaryPackageFileType.DDEB)
         self.assertEqual(BinaryPackageFileType.DDEB, bpf.filetype)
 
+    # makePackageUpload
+    def test_makePackageUpload_returns_proxied_IPackageUpload(self):
+        pu = self.factory.makePackageUpload()
+        self.assertThat(pu, ProvidesAndIsProxied(IPackageUpload))
+
+    def test_makePackageUpload_uses_distroseries(self):
+        distroseries = self.factory.makeDistroSeries()
+        pu = self.factory.makePackageUpload(distroseries=distroseries)
+        self.assertEqual(distroseries, pu.distroseries)
+
+    def test_makePackageUpload_uses_archive(self):
+        archive = self.factory.makeArchive()
+        pu = self.factory.makePackageUpload(archive=archive)
+        self.assertEqual(archive, pu.archive)
+
+    def test_makePackageUpload_uses_distribution_of_archive(self):
+        archive = self.factory.makeArchive()
+        pu = self.factory.makePackageUpload(archive=archive)
+        self.assertEqual(archive.distribution, pu.distroseries.distribution)
+
+    def test_makePackageUpload_uses_changes_filename(self):
+        changes_filename = "foo"
+        pu = self.factory.makePackageUpload(changes_filename=changes_filename)
+        self.assertEqual(
+            changes_filename, removeSecurityProxy(pu).changesfile.filename)
+
+    def test_makePackageUpload_uses_pocket(self):
+        pu = self.factory.makePackageUpload(
+            pocket=PackagePublishingPocket.RELEASE)
+        self.assertEqual(PackagePublishingPocket.RELEASE, pu.pocket)
+        pu = self.factory.makePackageUpload(
+            pocket=PackagePublishingPocket.PROPOSED)
+        self.assertEqual(PackagePublishingPocket.PROPOSED, pu.pocket)
+
+    def test_makePackageUpload_uses_signing_key(self):
+        person = self.factory.makePerson()
+        signing_key = self.factory.makeGPGKey(person)
+        pu = self.factory.makePackageUpload(signing_key=signing_key)
+        self.assertEqual(signing_key, pu.signing_key)
+
+    def test_makePackageUpload_allows_None_signing_key(self):
+        pu = self.factory.makePackageUpload(signing_key=None)
+        self.assertEqual(None, pu.signing_key)
+
+    def test_makePackageUpload_sets_status_DONE(self):
+        pu = self.factory.makePackageUpload(status=PackageUploadStatus.DONE)
+        self.assertEqual(PackageUploadStatus.DONE, pu.status)
+
+    def test_makePackageUpload_sets_status_ACCEPTED(self):
+        pu = self.factory.makePackageUpload(
+            status=PackageUploadStatus.ACCEPTED)
+        self.assertEqual(PackageUploadStatus.ACCEPTED, pu.status)
+
     # makeSourcePackageReleaseFile
     def test_makeSourcePackageReleaseFile_returns_ISPRF(self):
         spr_file = self.factory.makeSourcePackageReleaseFile()

=== modified file 'lib/lp/testing/tests/test_matchers.py'
--- lib/lp/testing/tests/test_matchers.py	2010-08-02 19:52:59 +0000
+++ lib/lp/testing/tests/test_matchers.py	2010-08-05 20:36:49 +0000
@@ -11,8 +11,8 @@
 
 from lp.testing import TestCase
 from lp.testing.matchers import (
-    DoesNotCorrectlyProvide, DoesNotProvide, IsNotProxied, IsProxied,
-    Provides, ProvidesAndIsProxied)
+    DoesNotCorrectlyProvide, DoesNotProvide, DoesNotStartWith, IsNotProxied,
+    IsProxied, Provides, ProvidesAndIsProxied, StartsWith)
 
 
 class ITestInterface(Interface):
@@ -89,8 +89,10 @@
         self.assertEqual(ITestInterface, mismatch.interface)
 
     def match_does_not_verify(self):
+
         class BadlyImplementedClass:
             implements(ITestInterface)
+
         obj = BadlyImplementedClass()
         matcher = Provides(ITestInterface)
         return obj, matcher.match(obj)
@@ -155,7 +157,7 @@
 
     def test_match(self):
         obj = ProxyFactory(
-            Implementor(), checker=NamesChecker(names=("doFoo",)))
+            Implementor(), checker=NamesChecker(names=("doFoo", )))
         matcher = ProvidesAndIsProxied(ITestInterface)
         self.assertThat(obj, matcher)
         self.assertEqual(None, matcher.match(obj))
@@ -169,3 +171,36 @@
         obj = ProxyFactory(object(), checker=NamesChecker())
         matcher = ProvidesAndIsProxied(ITestInterface)
         self.assertIsInstance(matcher.match(obj), DoesNotProvide)
+
+
+class DoesNotStartWithTests(TestCase):
+
+    def test_describe(self):
+        mismatch = DoesNotStartWith("foo", "bar")
+        self.assertEqual(
+            "'foo' does not start with 'bar'.", mismatch.describe())
+
+
+class StartsWithTests(TestCase):
+
+    def test_str(self):
+        matcher = StartsWith("bar")
+        self.assertEqual("Starts with 'bar'.", str(matcher))
+
+    def test_match(self):
+        matcher = StartsWith("bar")
+        self.assertIs(None, matcher.match("barf"))
+
+    def test_mismatch_returns_does_not_start_with(self):
+        matcher = StartsWith("bar")
+        self.assertIsInstance(matcher.match("foo"), DoesNotStartWith)
+
+    def test_mismatch_sets_matchee(self):
+        matcher = StartsWith("bar")
+        mismatch = matcher.match("foo")
+        self.assertEqual("foo", mismatch.matchee)
+
+    def test_mismatch_sets_expected(self):
+        matcher = StartsWith("bar")
+        mismatch = matcher.match("foo")
+        self.assertEqual("bar", mismatch.expected)