You don't need to do these last 5 lines, nor the getPubSource.
Doing more than necessary makes for a fragile test if other parts of the
system change. A better test would be to throw some random files into the
root directory of the archive and then assert that they get deleted when
you call deleteArchive, along with the status change.
> +
> def testPublishPartner(self):
> """Test that a partner package is published to the right place."""
> archive = self.ubuntutest.getArchiveByComponent('partner')
>
> === modified file 'lib/lp/soyuz/scripts/publishdistro.py'
> --- lib/lp/soyuz/scripts/publishdistro.py 2010-02-24 11:53:22 +0000
> +++ lib/lp/soyuz/scripts/publishdistro.py 2010-03-25 20:23:14 +0000
> @@ -16,7 +16,7 @@
> from canonical.database.sqlbase import (
> clear_current_connection_cache, flush_database_updates)
> from lp.soyuz.interfaces.archive import (
> - ArchivePurpose, IArchiveSet, MAIN_ARCHIVE_PURPOSES)
> + ArchivePurpose, ArchiveStatus, IArchiveSet, MAIN_ARCHIVE_PURPOSES)
> from lp.registry.interfaces.distribution import IDistributionSet
> from canonical.launchpad.scripts import logger, logger_options
> from lp.services.scripts.base import LaunchpadScriptFailure
> @@ -191,24 +191,34 @@
> else:
> log.info("Processing %s" % archive.archive_url)
> publisher = getPublisher(archive, allowed_suites, log)
> -
> - try_and_commit("publishing", publisher.A_publish,
> - options.careful or options.careful_publishing)
> - # Flag dirty pockets for any outstanding deletions.
> - publisher.A2_markPocketsWithDeletionsDirty()
> - try_and_commit("dominating", publisher.B_dominate,
> - options.careful or options.careful_domination)
> -
> - # The primary and copy archives use apt-ftparchive to generate the
> - # indexes, everything else uses the newer internal LP code.
> - if archive.purpose in (ArchivePurpose.PRIMARY,
ArchivePurpose.COPY):
> - try_and_commit("doing apt-ftparchive",
publisher.C_doFTPArchive,
> - options.careful or options.careful_apt)
> +
> + # Do we need to delete the archive or publish it?
> + if archive.status == ArchiveStatus.DELETING:
> + if archive.purpose == ArchivePurpose.PPA:
> + # Delete the archive.
> + try_and_commit("publishing", publisher.deleteArchive,
> + options.careful or
options.careful_publishing)
> + else:
> + # Other types of archives do not currently support
deletion.
> + pass
> else:
> - try_and_commit("building indexes", publisher.C_writeIndexes,
> + try_and_commit("publishing", publisher.A_publish,
> + options.careful or options.careful_publishing)
> + # Flag dirty pockets for any outstanding deletions.
> + publisher.A2_markPocketsWithDeletionsDirty()
> + try_and_commit("dominating", publisher.B_dominate,
> + options.careful or options.careful_domination)
> +
> + # The primary and copy archives use apt-ftparchive to generate
the
> + # indexes, everything else uses the newer internal LP code.
> + if archive.purpose in (ArchivePurpose.PRIMARY,
ArchivePurpose.COPY):
> + try_and_commit("doing apt-ftparchive",
publisher.C_doFTPArchive,
> + options.careful or options.careful_apt)
> + else:
> + try_and_commit("building indexes",
publisher.C_writeIndexes,
> + options.careful or options.careful_apt)
> +
> + try_and_commit("doing release files",
publisher.D_writeReleaseFiles,
> options.careful or options.careful_apt)
>
> - try_and_commit("doing release files",
publisher.D_writeReleaseFiles,
> - options.careful or options.careful_apt)
> -
> log.debug("Ciao")
This code has got a subtle bug - it will only process archives marked with
publishing enabled because of the filter just above the context of the diff.
I also think in retrospect it's slightly the wrong approach to take here.
What do you think to adding IArchiveSet.getByStatus()? Then at the end of
the publisher script we can grab a list of archives that are in the
DELETING state and simply call publisher.deleteArchive(). The new method
on IArchiveSet would require a simple new test.
Otherwise, we're nearly there! I have a UI branch that's very close to done.
> === modified file 'lib/lp/ archivepublishe r/publishing. py' archivepublishe r/publishing. py 2010-02-09 00:17:40 +0000 archivepublishe r/publishing. py 2010-03-25 20:23:14 +0000 COMPONENT_ ORDER database. sqlbase import sqlvalues interfaces. pocket import ( ngPocket, pocketsuffix) interfaces. archive import ArchivePurpose interfaces. archive import ArchivePurpose, ArchiveStatus interfaces. binarypackagere lease import ( rmat) interfaces. component import IComponentSet interfaces. publishing import PackagePublishi ngStatus librarian. client import LibrarianClient launchpad. webapp. errorlog import ( tility, ScriptRequest) items() ) self): owner.name, self.archive.name, archiveroot) ) exists( self._config. archiveroot) : rmtree( self._config. archiveroot) archiveroot) [('error- explanation' , message)]) tility( ).raising( sys.exc_ info(), request) archiveroot, self.archive. owner.name, DELETED
> --- lib/lp/
> +++ lib/lp/
> @@ -12,9 +12,11 @@
> import hashlib
> import logging
> import os
> +import shutil
>
> from datetime import datetime
>
> +from storm.store import Store
> from zope.component import getUtility
>
> from lp.archivepublisher import HARDCODED_
> @@ -29,13 +31,15 @@
> from canonical.
> from lp.registry.
> PackagePublishi
> -from lp.soyuz.
> +from lp.soyuz.
> from lp.soyuz.
> BinaryPackageFo
> from lp.soyuz.
> from lp.soyuz.
>
> from canonical.
> +from canonical.
> + ErrorReportingU
>
> suffixpocket = dict((v, k) for (k, v) in pocketsuffix.
>
> @@ -596,3 +600,37 @@
> in_file.close()
>
> out_file.write(" %s % 16d %s\n" % (checksum, length, file_name))
> +
> + def deleteArchive(
> + """Delete the archive.
> +
> + Physically remove the entire archive from disk and set the
archive's
> + status to DELETED.
> +
> + Any errors encountered while removing the archive from disk will
> + be caught and an OOPS report generated.
> + """
> +
> + self.log.info(
> + "Attempting to delete archive '%s/%s' at '%s'." % (
> + self.archive.
> + self._config.
> +
> + # Attempt to rmdir if the path to the root of the archive exists.
> + if os.path.
> + try:
> + shutil.
> + except:
> + message = 'Exception while deleting archive root %s' % (
> + self._config.
> + request = ScriptRequest(
> + ErrorReportingU
> + self.log.error('%s (%s)' % (message, request.oopsid))
> + else:
> + self.log.warning(
> + "Root directory '%s' for archive '%s/%s' does not exist." %
(
> + self._config.
> + self.archive.name))
> +
> + # Set archive's status to DELETED.
> + self.archive.status = ArchiveStatus.
This is all good. I was trying to think of failure scenarios with it but I
think you have them all covered!
> archivepublishe r/tests/ test_publisher. py' archivepublishe r/tests/ test_publisher. py 2010-02-10 00:25:55 archivepublishe r/tests/ test_publisher. py 2010-03-25 20:23:14 database. constants import UTC_NOW launchpad. ftests. keys_for_ tests import gpgkeysdir interfaces. archive import ( interfaces. binarypackagere lease import ( rmat) interfaces. distribution import IDistributionSet f/foo/foo_ 666.dsc" % self.pool_dir l(open( foo_path) .read() .strip( ), 'Hello world') (self): IPersonSet) .getByName( 'ubuntu- team') IArchiveSet) .new( self.ubuntutest , owner=ubuntu_team, ArchivePurpose. PPA) test_archive, None, self.logger) "foo_1. dsc", PackagePublishi ngStatus. PENDING, archive= test_archive) A_publish( False) txn.commit( ) C_writeIndexes( False) D_writeReleaseF iles(False)
> === modified file 'lib/lp/
> --- lib/lp/
+0000
> +++ lib/lp/
+0000
> @@ -26,7 +26,7 @@
> from canonical.
> from canonical.
> from lp.soyuz.
> - ArchivePurpose, IArchiveSet)
> + ArchivePurpose, ArchiveStatus, IArchiveSet)
> from lp.soyuz.
> BinaryPackageFo
> from lp.registry.
> @@ -95,6 +95,31 @@
> foo_path = "%s/main/
> self.assertEqua
>
> + def testDeletingPPA
> + """Test deleting a PPA"""
> + ubuntu_team = getUtility(
> + test_archive = getUtility(
> + distribution=
> + purpose=
> +
> + publisher = getPublisher(
> +
> + pub_source = self.getPubSource(
> + sourcename="foo", filename=
> + filecontent='I am a file.',
> + status=
> +
> + publisher.
> + self.layer.
> + publisher.
> + publisher.
> + pub_source.sync()
You don't need to do these last 5 lines, nor the getPubSource.
Doing more than necessary makes for a fragile test if other parts of the
system change. A better test would be to throw some random files into the
root directory of the archive and then assert that they get deleted when
you call deleteArchive, along with the status change.
> + (os.path. exists( publisher. _config. archiveroot) ) deleteArchive( ) exists( publisher. _config. archiveroot) )
> + self.assertTrue
> + publisher.
> + self.assertTrue(not os.path.
How about assertFalse?
> + self.assertEqua l(test_ archive. status, ArchiveStatus. DELETED)
These are good tests.
> + ner(self) : .getArchiveByCo mponent( 'partner' ) soyuz/scripts/ publishdistro. py' soyuz/scripts/ publishdistro. py 2010-02-24 11:53:22 +0000 soyuz/scripts/ publishdistro. py 2010-03-25 20:23:14 +0000 database. sqlbase import ( connection_ cache, flush_database_ updates) interfaces. archive import ( PURPOSES) PURPOSES) interfaces. distribution import IDistributionSet launchpad. scripts import logger, logger_options scripts. base import LaunchpadScript Failure "Processing %s" % archive. archive_ url) archive, allowed_suites, log) commit( "publishing" , publisher. A_publish, careful_ publishing) A2_markPocketsW ithDeletionsDir ty() commit( "dominating" , publisher. B_dominate, careful_ domination) .PRIMARY, COPY): commit( "doing apt-ftparchive", C_doFTPArchive, careful_ apt) DELETING: commit( "publishing" , publisher. deleteArchive, careful_ publishing) commit( "building indexes", publisher. C_writeIndexes, commit( "publishing" , publisher. A_publish, careful_ publishing) A2_markPocketsW ithDeletionsDir ty() commit( "dominating" , publisher. B_dominate, careful_ domination) .PRIMARY, COPY): commit( "doing apt-ftparchive", C_doFTPArchive, careful_ apt) commit( "building indexes", C_writeIndexes, careful_ apt) commit( "doing release files", D_writeReleaseF iles, careful_ apt) commit( "doing release files", D_writeReleaseF iles, careful_ apt)
> def testPublishPart
> """Test that a partner package is published to the right place."""
> archive = self.ubuntutest
>
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -16,7 +16,7 @@
> from canonical.
> clear_current_
> from lp.soyuz.
> - ArchivePurpose, IArchiveSet, MAIN_ARCHIVE_
> + ArchivePurpose, ArchiveStatus, IArchiveSet, MAIN_ARCHIVE_
> from lp.registry.
> from canonical.
> from lp.services.
> @@ -191,24 +191,34 @@
> else:
> log.info(
> publisher = getPublisher(
> -
> - try_and_
> - options.careful or options.
> - # Flag dirty pockets for any outstanding deletions.
> - publisher.
> - try_and_
> - options.careful or options.
> -
> - # The primary and copy archives use apt-ftparchive to generate the
> - # indexes, everything else uses the newer internal LP code.
> - if archive.purpose in (ArchivePurpose
ArchivePurpose.
> - try_and_
publisher.
> - options.careful or options.
> +
> + # Do we need to delete the archive or publish it?
> + if archive.status == ArchiveStatus.
> + if archive.purpose == ArchivePurpose.PPA:
> + # Delete the archive.
> + try_and_
> + options.careful or
options.
> + else:
> + # Other types of archives do not currently support
deletion.
> + pass
> else:
> - try_and_
> + try_and_
> + options.careful or options.
> + # Flag dirty pockets for any outstanding deletions.
> + publisher.
> + try_and_
> + options.careful or options.
> +
> + # The primary and copy archives use apt-ftparchive to generate
the
> + # indexes, everything else uses the newer internal LP code.
> + if archive.purpose in (ArchivePurpose
ArchivePurpose.
> + try_and_
publisher.
> + options.careful or options.
> + else:
> + try_and_
publisher.
> + options.careful or options.
> +
> + try_and_
publisher.
> options.careful or options.
>
> - try_and_
publisher.
> - options.careful or options.
> -
> log.debug("Ciao")
This code has got a subtle bug - it will only process archives marked with
publishing enabled because of the filter just above the context of the diff.
I also think in retrospect it's slightly the wrong approach to take here. getByStatus( )? Then at the end of deleteArchive( ). The new method
What do you think to adding IArchiveSet.
the publisher script we can grab a list of archives that are in the
DELETING state and simply call publisher.
on IArchiveSet would require a simple new test.
Otherwise, we're nearly there! I have a UI branch that's very close to done.
Cheers
J