예제 #1
0
 def test_handles_output(self):
     spawner, process = self._makeSpawnerAndProcess()
     stdout_handler = FakeMethod()
     spawner.start("ls", stdout_handler=stdout_handler)
     write_and_flush(process.stdout_sink, "readme.txt\n")
     spawner.communicate()
     self.assertEqual([("readme.txt\n", )], stdout_handler.extract_args())
    def test_handleUnpushedBranch_mails_branch_owner(self):
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        branch_owner = self.factory.makePerson(email=email)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))
        exporter._sendMail = FakeMethod()

        self.becomeDbUser('translationstobranch')

        exporter._exportToBranches([productseries])

        self.assertEqual(1, exporter._sendMail.call_count)
        (sender, recipients, subject,
         text), kwargs = (exporter._sendMail.calls[-1])
        self.assertIn(config.canonical.noreply_from_address, sender)
        self.assertIn(email, recipients)
        self.assertEqual("Launchpad: translations branch has not been set up.",
                         subject)

        self.assertIn("problem with translations branch synchronization", text)
        self.assertIn(productseries.title, text)
        self.assertIn(productseries.translations_branch.bzr_identity, text)
        self.assertIn('bzr push lp://', text)
예제 #3
0
    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)
예제 #4
0
    def setUp(self):
        super(TestStoreChannelsWidget, self).setUp()
        field = List(__name__="channels", title="Store channels")
        self.context = self.factory.makeSnap()
        field = field.bind(self.context)
        request = LaunchpadTestRequest()
        self.widget = StoreChannelsWidget(field, None, request)

        # setup fake store client response for available channels/risks
        self.risks = [
            {
                "name": "stable",
                "display_name": "Stable"
            },
            {
                "name": "candidate",
                "display_name": "Candidate"
            },
            {
                "name": "beta",
                "display_name": "Beta"
            },
            {
                "name": "edge",
                "display_name": "Edge"
            },
        ]
        snap_store_client = FakeMethod()
        snap_store_client.listChannels = FakeMethod(result=self.risks)
        self.useFixture(ZopeUtilityFixture(snap_store_client,
                                           ISnapStoreClient))
 def test_handles_output(self):
     spawner, process = self._makeSpawnerAndProcess()
     stdout_handler = FakeMethod()
     spawner.start("ls", stdout_handler=stdout_handler)
     write_and_flush(process.stdout_sink, "readme.txt\n")
     spawner.communicate()
     self.assertEqual([("readme.txt\n", )], stdout_handler.extract_args())
 def test_handles_error_output(self):
     spawner, process = self._makeSpawnerAndProcess()
     stderr_handler = FakeMethod()
     spawner.start("ls", stderr_handler=stderr_handler)
     write_and_flush(process.stderr_sink, "File not found.\n")
     spawner.communicate()
     self.assertEqual(
         [("File not found.\n", )], stderr_handler.extract_args())
 def test_handles_output_before_completion(self):
     spawner, process = self._makeSpawnerAndProcess(returncode=0)
     handler = FakeMethod()
     spawner.start(
         "hello", stdout_handler=handler, completion_handler=handler)
     write_and_flush(process.stdout_sink, "Hello\n")
     spawner.complete()
     self.assertEqual([("Hello\n", ), (0, )], handler.extract_args())
예제 #8
0
 def test_handles_error_output(self):
     spawner, process = self._makeSpawnerAndProcess()
     stderr_handler = FakeMethod()
     spawner.start("ls", stderr_handler=stderr_handler)
     write_and_flush(process.stderr_sink, "File not found.\n")
     spawner.communicate()
     self.assertEqual([("File not found.\n", )],
                      stderr_handler.extract_args())
예제 #9
0
 def test_handles_output_before_completion(self):
     spawner, process = self._makeSpawnerAndProcess(returncode=0)
     handler = FakeMethod()
     spawner.start("hello",
                   stdout_handler=handler,
                   completion_handler=handler)
     write_and_flush(process.stdout_sink, "Hello\n")
     spawner.complete()
     self.assertEqual([("Hello\n", ), (0, )], handler.extract_args())
예제 #10
0
class FakeUploadPolicy:
    def __init__(self, spph):
        self.distroseries = spph.distroseries
        self.archive = spph.distroseries.main_archive
        self.pocket = spph.pocket
        self.redirect_warning = None

    setDistroSeriesAndPocket = FakeMethod()
    validateUploadType = FakeMethod()
    checkUpload = FakeMethod()
예제 #11
0
 def test_createIndexes_marks_index_creation_complete(self):
     # createIndexes calls markIndexCreationComplete for the suite.
     distro = self.makeDistroWithPublishDirectory()
     series = self.factory.makeDistroSeries(distribution=distro)
     script = self.makeScript(distro)
     script.markIndexCreationComplete = FakeMethod()
     script.runPublishDistro = FakeMethod()
     suite = get_a_suite(series)
     script.createIndexes(distro, [suite])
     self.assertEqual([((distro, suite), {})],
                      script.markIndexCreationComplete.calls)
예제 #12
0
 def test_correct_opal_signing_command_executed_no_keys(self):
     # Check that calling signOpal() will generate no commands when
     # no keys are present.
     self.setUpOpalKeys(create=False)
     fake_call = FakeMethod(result=0)
     self.useFixture(MonkeyPatch("subprocess.call", fake_call))
     upload = SigningUpload()
     upload.generateOpalKeys = FakeMethod()
     upload.setTargetDirectory(self.archive, "test_1.0_amd64.tar.gz",
                               "distroseries")
     upload.signOpal('t.opal')
     self.assertEqual(0, fake_call.call_count)
     self.assertEqual(0, upload.generateOpalKeys.call_count)
    def test_commit_uses_getBzrCommitterID(self):
        # commit() passes self.getBzrCommitterID() to bzr as the
        # committer.
        bzr_id = self.factory.getUniqueString()
        self.committer.getBzrCommitterID = FakeMethod(result=bzr_id)
        fake_commit = FakeMethod()
        self.committer.transform_preview.commit = fake_commit

        self.committer.writeFile('x', b'y')
        self.committer.commit('')

        commit_args, commit_kwargs = fake_commit.calls[-1]
        self.assertEqual(bzr_id, commit_kwargs['committer'])
예제 #14
0
    def process(self):
        self.tarfile.close()
        self.buffer.close()
        upload = UefiUpload()
        upload.signUefi = FakeMethod()
        upload.signKmod = FakeMethod()
        # Under no circumstances is it safe to execute actual commands.
        fake_call = FakeMethod(result=0)
        self.useFixture(MonkeyPatch("subprocess.call", fake_call))
        upload.process(self.archive, self.path, self.suite)
        self.assertEqual(0, fake_call.call_count)

        return upload
예제 #15
0
    def test_handles_multiple_processes(self):
        spawner = CommandSpawner()
        handler = FakeMethod()

        first_process = FakeProcess(returncode=1)
        instrument_spawn(spawner, first_process)
        spawner.start(["/bin/echo", "1"], completion_handler=handler)

        second_process = FakeProcess(returncode=2)
        instrument_spawn(spawner, second_process)
        spawner.start(["/bin/echo", "2"], completion_handler=handler)

        spawner.complete()
        self.assertContentEqual([(1, ), (2, )], handler.extract_args())
    def test_handles_multiple_processes(self):
        spawner = CommandSpawner()
        handler = FakeMethod()

        first_process = FakeProcess(returncode=1)
        instrument_spawn(spawner, first_process)
        spawner.start(["/bin/echo", "1"], completion_handler=handler)

        second_process = FakeProcess(returncode=2)
        instrument_spawn(spawner, second_process)
        spawner.start(["/bin/echo", "2"], completion_handler=handler)

        spawner.complete()
        self.assertContentEqual([(1, ), (2, )], handler.extract_args())
예제 #17
0
class FakeChangesFile:
    def __init__(self, spph, file_path):
        self.files = []
        self.filepath = file_path
        self.filename = os.path.basename(file_path)
        self.architectures = ['i386']
        self.suite_name = '-'.join([spph.distroseries.name, spph.pocket.name])
        self.raw_content = open(file_path).read()
        self.signingkey = None

    parseChanges = FakeMethod([])
    checkFileName = FakeMethod([])
    processAddresses = FakeMethod([])
    processFiles = FakeMethod([])
    verify = FakeMethod([UploadError("Deliberately broken")])
예제 #18
0
    def test_failed_index_creation_is_not_marked_complete(self):
        # If index creation fails, it is not marked as having been
        # completed.  The next run will retry.
        class Boom(Exception):
            """Simulated failure."""

        series = self.factory.makeDistroSeries()
        script = self.makeScript(series.distribution)
        script.markIndexCreationComplete = FakeMethod()
        script.runPublishDistro = FakeMethod(failure=Boom("Sorry!"))
        try:
            script.createIndexes(series.distribution, [get_a_suite(series)])
        except:
            pass
        self.assertEqual([], script.markIndexCreationComplete.calls)
예제 #19
0
 def test_correct_opal_keygen_command_executed(self):
     # Check that calling generateOpalKeys() will generate the
     # expected command.
     self.setUpPPA()
     self.setUpOpalKeys(create=False)
     fake_call = FakeMethod(result=0)
     self.useFixture(MonkeyPatch("subprocess.call", fake_call))
     upload = SigningUpload()
     upload.setTargetDirectory(self.archive, "test_1.0_amd64.tar.gz",
                               "distroseries")
     upload.generateOpalKeys()
     self.assertEqual(2, fake_call.call_count)
     # Assert the actual command matches.
     args = fake_call.calls[0][0][0]
     # Sanitise the keygen tmp file.
     if args[11].endswith('.keygen'):
         args[11] = 'XXX.keygen'
     expected_cmd = [
         'openssl', 'req', '-new', '-nodes', '-utf8', '-sha512', '-days',
         '3650', '-batch', '-x509', '-config', 'XXX.keygen', '-outform',
         'PEM', '-out', self.opal_pem, '-keyout', self.opal_pem
     ]
     self.assertEqual(expected_cmd, args)
     args = fake_call.calls[1][0][0]
     expected_cmd = [
         'openssl', 'x509', '-in', self.opal_pem, '-outform', 'DER', '-out',
         self.opal_x509
     ]
     self.assertEqual(expected_cmd, args)
class FakeScript(LaunchpadScript):
    """A dummy script that only records which feature controller is active."""

    observed_feature_controller = object()

    def __init__(self, name):
        super(FakeScript, self).__init__(name=name, test_args=[])

    def main(self):
        self.observed_feature_controller = get_relevant_feature_controller()

    # Shortcut some underpinnings of LaunchpadScript.run that we can't
    # afford to have happen in tests.
    _init_zca = FakeMethod()
    _init_db = FakeMethod()
    record_activity = FakeMethod()
예제 #21
0
 def test_prepareFreshSeries_copies_custom_uploads(self):
     distro = self.makeDistroWithPublishDirectory()
     old_series = self.factory.makeDistroSeries(distribution=distro,
                                                status=SeriesStatus.CURRENT)
     new_series = self.factory.makeDistroSeries(distribution=distro,
                                                previous_series=old_series,
                                                status=SeriesStatus.FROZEN)
     self.factory.makeDistroArchSeries(distroseries=new_series,
                                       architecturetag='i386')
     custom_upload = self.factory.makeCustomPackageUpload(
         distroseries=old_series,
         custom_type=PackageUploadCustomFormat.DEBIAN_INSTALLER,
         filename='debian-installer-images_1.0-20110805_i386.tar.gz')
     script = self.makeScript(distro)
     script.createIndexes = FakeMethod()
     script.setUp()
     have_fresh_series = script.prepareFreshSeries(distro)
     self.assertTrue(have_fresh_series)
     [copied_upload
      ] = new_series.getPackageUploads(name=u'debian-installer-images',
                                       exact_match=False)
     [copied_custom] = copied_upload.customfiles
     self.assertEqual(
         custom_upload.customfiles[0].libraryfilealias.filename,
         copied_custom.libraryfilealias.filename)
예제 #22
0
    def test_fail_to_resume_slave_resets_job(self):
        # If an attempt to resume and dispatch a slave fails, it should
        # reset the job via job.reset()

        # Make a slave with a failing resume() method.
        slave = OkSlave()
        slave.resume = lambda: deferLater(reactor, 0, defer.fail,
                                          Failure(('out', 'err', 1)))

        # Reset sampledata builder.
        builder = removeSecurityProxy(
            getUtility(IBuilderSet)[BOB_THE_BUILDER_NAME])
        self._resetBuilder(builder)
        self.assertEqual(0, builder.failure_count)
        self.patch(BuilderSlave, 'makeBuilderSlave', FakeMethod(slave))
        builder.vm_host = "fake_vm_host"

        scanner = self._getScanner()

        # Get the next job that will be dispatched.
        job = removeSecurityProxy(builder._findBuildCandidate())
        job.virtualized = True
        builder.virtualized = True
        transaction.commit()
        yield scanner.singleCycle()

        # The failure_count will have been incremented on the builder, we
        # can check that to see that a dispatch attempt did indeed occur.
        self.assertEqual(1, builder.failure_count)
        # There should also be no builder set on the job.
        self.assertIsNone(job.builder)
        build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(job)
        self.assertEqual(build.status, BuildStatus.NEEDSBUILD)
예제 #23
0
 def test_countCalls(self):
     # A FakeMethod counts the number of times it's been invoked.
     func = FakeMethod()
     for count in range(3):
         self.assertEqual(count, func.call_count)
         func()
         self.assertEqual(count + 1, func.call_count)
예제 #24
0
    def test_multiple_parents_do_not_close_bugs(self):
        # The initialization does not close the bugs on the copied
        # publications (and thus does not try to access the bug table).
        parent1, parent2 = self.setUpParents(packages1={'p1': '0.1-1'},
                                             packages2={'p2': '2.1'})
        child = self.factory.makeDistroSeries()
        switch_dbuser('initializedistroseries')

        # Patch close_bugs_for_sourcepublication to be able to record if
        # the method has been called.
        fakeCloseBugs = FakeMethod()
        from lp.soyuz.scripts import packagecopier as packagecopier_module
        self.patch(packagecopier_module, 'close_bugs_for_sourcepublication',
                   fakeCloseBugs)

        child = self._fullInitialize([parent1, parent2], child=child)
        # Make sure the initialization was successful.
        self.assertBinPackagesAndVersions(child, [(u'p1', u'0.1-1'),
                                                  (u'p2', u'2.1')])
        # Assert that close_bugs_for_sourcepublication has not been
        # called.
        self.assertEqual(0, fakeCloseBugs.call_count)
        # Switch back to launchpad_main to be able to cleanup the
        # feature flags.
        switch_dbuser('launchpad_main')
예제 #25
0
    def test_scan_skipped_if_builderfactory_stale(self):
        # singleCycle does nothing if the BuilderFactory's update
        # timestamp is older than the end of the previous scan. This
        # prevents eg. a scan after a dispatch from failing to notice
        # that a build has been dispatched.
        pbf = PrefetchedBuilderFactory()
        pbf.update()
        scanner = self._getScanner(builder_factory=pbf)
        fake_scan = FakeMethod()

        def _fake_scan():
            fake_scan()
            return defer.succeed(None)

        scanner.scan = _fake_scan
        self.assertEqual(0, fake_scan.call_count)

        # An initial cycle triggers a scan.
        yield scanner.singleCycle()
        self.assertEqual(1, fake_scan.call_count)

        # But a subsequent cycle without updating BuilderFactory's data
        # is a no-op.
        yield scanner.singleCycle()
        self.assertEqual(1, fake_scan.call_count)

        # Updating the BuilderFactory causes scans to resume.
        pbf.update()
        yield scanner.singleCycle()
        self.assertEqual(2, fake_scan.call_count)
    def test_reportApprovalConflict_sets_error_output_just_once(self):
        # Repeated occurrence of the same approval conflict will not
        # result in repeated setting of error_output.
        series = self.factory.makeProductSeries()
        domain = self.factory.getUniqueString()
        templates = [
            self.factory.makePOTemplate(productseries=series,
                                        translation_domain=domain)
            for counter in range(3)
        ]
        entry = removeSecurityProxy(
            self.factory.makeTranslationImportQueueEntry())

        entry.reportApprovalConflict(domain, len(templates), templates)
        original_error = entry.error_output
        transaction.commit()

        # Try reporting the conflict again, with the templates
        # reshuffled to see if reportApprovalConflict can be fooled into
        # thinking it's a different error.  Make as sure as we can that
        # entry.error_output is not modified.
        slave_entry = ISlaveStore(entry).get(TranslationImportQueueEntry,
                                             entry.id)
        slave_entry.setErrorOutput = FakeMethod()
        slave_entry.reportApprovalConflict(domain, len(templates),
                                           reversed(templates))
        self.assertEqual(original_error, slave_entry.error_output)
        self.assertIn(domain, original_error)
        self.assertEqual(0, slave_entry.setErrorOutput.call_count)
예제 #27
0
 def process(self):
     self.archive.close()
     self.buffer.close()
     upload = UefiUpload()
     upload.sign = FakeMethod()
     upload.process(self.pubconf, self.path, self.suite)
     return upload
예제 #28
0
    def _assertFailureCounting(self, builder_count, job_count,
                               expected_builder_count, expected_job_count):
        # If scan() fails with an exception, failure_counts should be
        # incremented.  What we do with the results of the failure
        # counts is tested below separately, this test just makes sure that
        # scan() is setting the counts.
        def failing_scan():
            return defer.fail(Exception("fake exception"))

        scanner = self._getScanner()
        scanner.scan = failing_scan
        from lp.buildmaster import manager as manager_module
        self.patch(manager_module, 'assessFailureCounts', FakeMethod())
        builder = getUtility(IBuilderSet)[scanner.builder_name]

        builder.failure_count = builder_count
        naked_job = removeSecurityProxy(builder.currentjob.specific_job)
        naked_job.build.failure_count = job_count
        # The _scanFailed() calls abort, so make sure our existing
        # failure counts are persisted.
        transaction.commit()

        # singleCycle() calls scan() which is our fake one that throws an
        # exception.
        yield scanner.singleCycle()

        # Failure counts should be updated, and the assessment method
        # should have been called.  The actual behaviour is tested below
        # in TestFailureAssessments.
        self.assertEqual(expected_builder_count, builder.failure_count)
        self.assertEqual(expected_job_count,
                         builder.currentjob.specific_job.build.failure_count)
        self.assertEqual(1, manager_module.assessFailureCounts.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)
예제 #30
0
    def test_publish_recovers_working_dists_on_ctrl_C(self):
        # If the user hits ctrl-C while publishing, the publish method
        # recovers its working directory.
        failure = KeyboardInterrupt("Ctrl-C!")

        script = self.makeScript()
        script.publishDistroUploads = FakeMethod(failure=failure)
        script.recoverArchiveWorkingDir = FakeMethod()
        script.setUp()

        try:
            script.publish(script.distributions[0])
        except KeyboardInterrupt:
            pass

        self.assertEqual(1, script.recoverArchiveWorkingDir.call_count)
 def test_run(self):
     _, _, job = self.makeJob()
     method = FakeMethod()
     removeSecurityProxy(job).attachTranslationFiles = method
     transaction.commit()
     _, job.run()
     self.assertEqual(method.call_count, 1)
예제 #32
0
 def test_security_run_publishes_only_security_updates(self):
     script = self.makeScript(extra_args=['--security-only'])
     script.publish = FakeMethod()
     script.main()
     self.assertEqual(1, script.publish.call_count)
     args, kwargs = script.publish.calls[0]
     self.assertEqual({'security_only': True}, kwargs)
예제 #33
0
 def test_takeArguments(self):
     # A FakeMethod invocation accepts any arguments it gets.
     func = FakeMethod()
     func()
     func(1)
     func(2, kwarg=3)
     self.assertEqual(3, func.call_count)
예제 #34
0
 def test_does_not_call_completion_handler_twice(self):
     spawner, process = self._makeSpawnerAndProcess(returncode=0)
     completion_handler = FakeMethod()
     spawner.start("echo", completion_handler=completion_handler)
     spawner.complete()
     spawner.complete()
     self.assertEqual(1, completion_handler.call_count)