def test_non_virtual_ppa_dispatch(self): # When the BinaryPackageBuildBehaviour dispatches PPA builds to # non-virtual builders, it stores the chroot on the server and # requests a binary package build, lying to say that the archive # purpose is "PRIMARY" because this ensures that the package mangling # tools will run over the built packages. archive = self.factory.makeArchive(virtualized=False) slave = OkSlave() builder = self.factory.makeBuilder(virtualized=False) builder.setCleanStatus(BuilderCleanStatus.CLEAN) vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() yield interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehaviour(bq, builder, slave), BufferLogger()) yield self.assertExpectedInteraction(slave.call_log, builder, build, lf, archive, ArchivePurpose.PRIMARY, 'universe')
def test_private_source_dispatch(self): archive = self.factory.makeArchive(private=True) slave = OkSlave() builder = self.factory.makeBuilder() builder.setCleanStatus(BuilderCleanStatus.CLEAN) vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) sprf = build.source_package_release.addFile( self.factory.makeLibraryFileAlias(db_only=True), filetype=SourcePackageFileType.ORIG_TARBALL) sprf_url = ( 'http://private-ppa.launchpad.dev/%s/%s/ubuntu/pool/%s/%s' % (archive.owner.name, archive.name, poolify(build.source_package_release.sourcepackagename.name, 'main'), sprf.libraryfile.filename)) lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() yield interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehaviour(bq, builder, slave), BufferLogger()) yield self.assertExpectedInteraction( slave.call_log, builder, build, lf, archive, ArchivePurpose.PPA, extra_uploads=[(sprf_url, 'buildd', 'sekrit')], filemap_names=[sprf.libraryfile.filename])
def test_non_virtual_ppa_dispatch_with_primary_ancestry(self): # If there is a primary component override, it is honoured for # non-virtual PPA builds too. archive = self.factory.makeArchive(virtualized=False) slave = OkSlave() builder = self.factory.makeBuilder(virtualized=False) builder.setCleanStatus(BuilderCleanStatus.CLEAN) vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) self.factory.makeSourcePackagePublishingHistory( distroseries=build.distro_series, archive=archive.distribution.main_archive, sourcepackagename=build.source_package_release.sourcepackagename, component='main') lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() yield interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehaviour(bq, builder, slave), BufferLogger()) yield self.assertExpectedInteraction(slave.call_log, builder, build, lf, archive, ArchivePurpose.PRIMARY, 'main')
def test_scan_aborts_lost_slave_with_job(self): # SlaveScanner.scan uses BuilderInteractor.rescueIfLost to abort # slaves that don't have the expected job. slave = BuildingSlave('nontrivial') bq = FakeBuildQueue() # Instrument updateBuild. interactor = BuilderInteractor() interactor.updateBuild = FakeMethod() scanner = SlaveScanner('mock', MockBuilderFactory(MockBuilder(), bq), BufferLogger(), interactor_factory=FakeMethod(interactor), slave_factory=FakeMethod(slave), behavior_factory=FakeMethod(TrivialBehavior())) # XXX: checkCancellation needs more than a FakeBuildQueue. scanner.checkCancellation = FakeMethod(defer.succeed(False)) # A single scan will call status(), notice that the slave is # lost, abort() the slave, then reset() the job without calling # updateBuild(). yield scanner.scan() self.assertEqual(['status', 'abort'], slave.call_log) self.assertEqual(0, interactor.updateBuild.call_count) self.assertEqual(1, bq.reset.call_count)
def setUp(self): super(TestHandleStatusMixin, self).setUp() self.factory = LaunchpadObjectFactory() self.build = self.makeBuild() # For the moment, we require a builder for the build so that # handleStatus_OK can get a reference to the slave. self.builder = self.factory.makeBuilder() self.build.buildqueue_record.markAsBuilding(self.builder) self.slave = WaitingSlave('BuildStatus.OK') self.slave.valid_file_hashes.append('test_file_hash') self.interactor = BuilderInteractor() self.behaviour = self.interactor.getBuildBehaviour( self.build.buildqueue_record, self.builder, self.slave) # We overwrite the buildmaster root to use a temp directory. tempdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, tempdir) self.upload_root = tempdir tmp_builddmaster_root = """ [builddmaster] root: %s """ % self.upload_root config.push('tmp_builddmaster_root', tmp_builddmaster_root) # We stub out our builds getUploaderCommand() method so # we can check whether it was called as well as # verifySuccessfulUpload(). removeSecurityProxy( self.build).verifySuccessfulUpload = FakeMethod(result=True)
def test_virtual_ppa_dispatch(self): # Make sure the builder slave gets reset before a build is # dispatched to it. archive = self.factory.makeArchive(virtualized=True) slave = OkSlave() builder = self.factory.makeBuilder(virtualized=True, vm_host="foohost") vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() d = interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehavior(bq, builder, slave), BufferLogger()) def check_build(ignored): # We expect the first call to the slave to be a resume call, # followed by the rest of the usual calls we expect. expected_resume_call = slave.call_log.pop(0) self.assertEqual('resume', expected_resume_call) self.assertExpectedInteraction(ignored, slave.call_log, builder, build, lf, archive, ArchivePurpose.PPA) return d.addCallback(check_build)
def setUp(self): super(TestBinaryBuildPackageBehaviourBuildCollection, self).setUp() switch_dbuser('testadmin') self.builder = self.factory.makeBuilder() self.interactor = BuilderInteractor() self.build = self.factory.makeBinaryPackageBuild( builder=self.builder, pocket=PackagePublishingPocket.RELEASE) lf = self.factory.makeLibraryFileAlias() transaction.commit() self.build.distro_arch_series.addOrUpdateChroot(lf) self.candidate = self.build.queueBuild() self.candidate.markAsBuilding(self.builder) # This is required so that uploaded files from the buildd don't # hang around between test runs. self.addCleanup(self._cleanup)
def test_virtual_ppa_dispatch(self): archive = self.factory.makeArchive(virtualized=True) slave = OkSlave() builder = self.factory.makeBuilder(virtualized=True, vm_host="foohost") builder.setCleanStatus(BuilderCleanStatus.CLEAN) vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() yield interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehaviour(bq, builder, slave), BufferLogger()) yield self.assertExpectedInteraction(slave.call_log, builder, build, lf, archive, ArchivePurpose.PPA)
def test_partner_dispatch_no_publishing_history(self): archive = self.factory.makeArchive(virtualized=False, purpose=ArchivePurpose.PARTNER) slave = OkSlave() builder = self.factory.makeBuilder(virtualized=False) vitals = extract_vitals_from_db(builder) build = self.factory.makeBinaryPackageBuild(builder=builder, archive=archive) lf = self.factory.makeLibraryFileAlias() transaction.commit() build.distro_arch_series.addOrUpdateChroot(lf) bq = build.queueBuild() bq.markAsBuilding(builder) interactor = BuilderInteractor() d = interactor._startBuild( bq, vitals, builder, slave, interactor.getBuildBehavior(bq, builder, slave), BufferLogger()) d.addCallback(self.assertExpectedInteraction, slave.call_log, builder, build, lf, archive, ArchivePurpose.PARTNER) return d
def test_scan_aborts_lost_slave_when_idle(self): # SlaveScanner.scan uses BuilderInteractor.rescueIfLost to abort # slaves that aren't meant to have a job. slave = BuildingSlave() # Instrument updateBuild. interactor = BuilderInteractor() interactor.updateBuild = FakeMethod() scanner = SlaveScanner('mock', MockBuilderFactory(MockBuilder(), None), BufferLogger(), interactor_factory=FakeMethod(interactor), slave_factory=FakeMethod(slave), behavior_factory=FakeMethod(None)) # A single scan will call status(), notice that the slave is # lost, abort() the slave, then reset() the job without calling # updateBuild(). yield scanner.scan() self.assertEqual(['status', 'abort'], slave.call_log) self.assertEqual(0, interactor.updateBuild.call_count)
def test_scan_with_job(self): # SlaveScanner.scan calls updateBuild() when a job is building. slave = BuildingSlave('trivial') bq = FakeBuildQueue() # Instrument updateBuild. interactor = BuilderInteractor() interactor.updateBuild = FakeMethod() scanner = SlaveScanner('mock', MockBuilderFactory(MockBuilder(), bq), BufferLogger(), interactor_factory=FakeMethod(interactor), slave_factory=FakeMethod(slave), behavior_factory=FakeMethod(TrivialBehavior())) # XXX: checkCancellation needs more than a FakeBuildQueue. scanner.checkCancellation = FakeMethod(defer.succeed(False)) yield scanner.scan() self.assertEqual(['status'], slave.call_log) self.assertEqual(1, interactor.updateBuild.call_count) self.assertEqual(0, bq.reset.call_count)
def _assessFailureCounts(self, fail_notes): # Helper for assessFailureCounts boilerplate. return assessFailureCounts(BufferLogger(), extract_vitals_from_db(self.builder), self.builder, self.slave, BuilderInteractor(), Exception(fail_notes))
def setUp(self): super(TestCancellationChecking, self).setUp() builder_name = BOB_THE_BUILDER_NAME self.builder = getUtility(IBuilderSet)[builder_name] self.builder.virtualized = True self.interactor = BuilderInteractor()
def test_resetOrFail_nonvirtual(self): builder = MockBuilder(virtualized=False, builderok=True) vitals = extract_vitals_from_db(builder) yield BuilderInteractor().resetOrFail( vitals, None, builder, DevNullLogger(), Exception()) self.assertFalse(builder.builderok)