예제 #1
0
 def test_triggers_webhooks(self):
     # Jobs trigger any relevant webhooks when they're enabled.
     self.useFixture(FeatureFixture({'code.git.webhooks.enabled': 'on'}))
     repository = self.factory.makeGitRepository()
     self.factory.makeGitRefs(
         repository, paths=['refs/heads/master', 'refs/tags/1.0'])
     hook = self.factory.makeWebhook(
         target=repository, event_types=['git:push:0.1'])
     job = GitRefScanJob.create(repository)
     paths = ('refs/heads/master', 'refs/tags/2.0')
     self.useFixture(GitHostingFixture(refs=self.makeFakeRefs(paths)))
     with dbuser('branchscanner'):
         JobRunner([job]).runAll()
     delivery = hook.deliveries.one()
     sha1 = lambda s: hashlib.sha1(s).hexdigest()
     self.assertThat(
         delivery,
         MatchesStructure(
             event_type=Equals('git:push:0.1'),
             payload=MatchesDict({
                 'git_repository': Equals('/' + repository.unique_name),
                 'git_repository_path': Equals(repository.unique_name),
                 'ref_changes': Equals({
                     'refs/tags/1.0': {
                         'old': {'commit_sha1': sha1('refs/tags/1.0')},
                         'new': None},
                     'refs/tags/2.0': {
                         'old': None,
                         'new': {'commit_sha1': sha1('refs/tags/2.0')}},
                 })})))
     with dbuser(config.IWebhookDeliveryJobSource.dbuser):
         self.assertEqual(
             "<WebhookDeliveryJob for webhook %d on %r>" % (
                 hook.id, hook.target),
             repr(delivery))
예제 #2
0
 def test_local(self):
     [ref] = self.factory.makeGitRefs()
     hosting_fixture = self.useFixture(GitHostingFixture(blob=b"foo"))
     self.assertEqual(b"foo", ref.getBlob("dir/file"))
     self.assertEqual([((ref.repository.getInternalPath(), "dir/file"), {
         "rev": ref.path
     })], hosting_fixture.getBlob.calls)
예제 #3
0
    def createExampleGitMerge(self):
        """Create an example Git-based merge scenario.

        The actual diff work is done in turnip, and we have no turnip
        fixture as yet, so for the moment we just install a fake hosting
        client that will return a plausible-looking diff.
        """
        bmp = self.factory.makeBranchMergeProposalForGit()
        source_sha1 = bmp.source_git_ref.commit_sha1
        target_sha1 = bmp.target_git_ref.commit_sha1
        patch = dedent("""\
            diff --git a/foo b/foo
            index %s..%s 100644
            --- a/foo
            +++ b/foo
            @@ -1,2 +1,7 @@
            +<<<<<<< foo
             c
            +=======
            +d
            +>>>>>>> foo
             a
            +b
            """) % (target_sha1[:7], source_sha1[:7])
        self.hosting_fixture = self.useFixture(GitHostingFixture(merge_diff={
            "patch": patch,
            "conflicts": ["foo"],
            }))
        return bmp, source_sha1, target_sha1, patch
예제 #4
0
 def test_git_to_git_import(self):
     # The repository page for a git-to-git-imported repository contains
     # a summary of the import details.
     self.useFixture(GitHostingFixture())
     code_import = self.factory.makeCodeImport(
         rcs_type=RevisionControlSystems.GIT,
         target_rcs_type=TargetRevisionControlSystems.GIT)
     self.assertImportDetailsDisplayed(
         code_import, 'git-import-details',
         'This repository is an import of the Git repository')
예제 #5
0
 def test_logs_bad_ref_info(self):
     repository = self.factory.makeGitRepository()
     job = GitRefScanJob.create(repository)
     self.useFixture(GitHostingFixture(refs={"refs/heads/master": {}}))
     expected_message = (
         'Unconvertible ref refs/heads/master {}: '
         'ref info does not contain "object" key')
     with self.expectedLog(expected_message):
         with dbuser("branchscanner"):
             JobRunner([job]).runAll()
     self.assertEqual([], list(repository.refs))
예제 #6
0
 def test_git_to_git_import_same_details(self):
     self.useFixture(GitHostingFixture())
     code_import = self.factory.makeProductCodeImport(
         git_repo_url='git://git.example.com/fooix.git',
         target_rcs_type=TargetRevisionControlSystems.GIT)
     unique_name = code_import.target.unique_name
     user = login_celebrity('vcs_imports')
     code_import.updateFromData(
         {'review_status': CodeImportReviewStatus.FAILING}, user)
     transaction.commit()
     self.assertSameDetailsEmail(
         'git://git.example.com/fooix.git', unique_name)
예제 #7
0
 def test_run(self):
     # Running a job to reclaim space sends a request to the hosting
     # service.
     hosting_fixture = self.useFixture(GitHostingFixture())
     name = "/~owner/+git/gone"
     path = "1"
     job = ReclaimGitRepositorySpaceJob.create(name, path)
     self.makeJobReady(job)
     [job] = list(ReclaimGitRepositorySpaceJob.iterReady())
     with dbuser("branchscanner"):
         JobRunner([job]).runAll()
     self.assertEqual([(path,)], hosting_fixture.delete.extract_args())
예제 #8
0
 def setUp(self):
     super(TestGitRefGetCommits, self).setUp()
     [self.ref] = self.factory.makeGitRefs()
     self.authors = [self.factory.makePerson() for _ in range(2)]
     with admin_logged_in():
         self.author_emails = [
             author.preferredemail.email for author in self.authors
         ]
     self.dates = [
         datetime(2015, 1, 1, 0, 0, 0, tzinfo=pytz.UTC),
         datetime(2015, 1, 2, 0, 0, 0, tzinfo=pytz.UTC),
     ]
     self.sha1_tip = unicode(hashlib.sha1("tip").hexdigest())
     self.sha1_root = unicode(hashlib.sha1("root").hexdigest())
     self.log = [
         {
             "sha1": self.sha1_tip,
             "message": "tip",
             "author": {
                 "name": self.authors[0].display_name,
                 "email": self.author_emails[0],
                 "time": int(seconds_since_epoch(self.dates[1])),
             },
             "committer": {
                 "name": self.authors[1].display_name,
                 "email": self.author_emails[1],
                 "time": int(seconds_since_epoch(self.dates[1])),
             },
             "parents": [self.sha1_root],
             "tree": unicode(hashlib.sha1("").hexdigest()),
         },
         {
             "sha1": self.sha1_root,
             "message": "root",
             "author": {
                 "name": self.authors[1].display_name,
                 "email": self.author_emails[1],
                 "time": int(seconds_since_epoch(self.dates[0])),
             },
             "committer": {
                 "name": self.authors[0].display_name,
                 "email": self.author_emails[0],
                 "time": int(seconds_since_epoch(self.dates[0])),
             },
             "parents": [],
             "tree": unicode(hashlib.sha1("").hexdigest()),
         },
     ]
     self.hosting_fixture = self.useFixture(GitHostingFixture(log=self.log))
예제 #9
0
 def test_run(self):
     # Ensure the job scans the repository.
     repository = self.factory.makeGitRepository()
     job = GitRefScanJob.create(repository)
     paths = ("refs/heads/master", "refs/tags/1.0")
     author = repository.owner
     author_date_start = datetime(2015, 1, 1, tzinfo=pytz.UTC)
     author_date_gen = time_counter(author_date_start, timedelta(days=1))
     self.useFixture(GitHostingFixture(
         refs=self.makeFakeRefs(paths),
         commits=self.makeFakeCommits(author, author_date_gen, paths)))
     with dbuser("branchscanner"):
         JobRunner([job]).runAll()
     self.assertRefsMatch(repository.refs, repository, paths)
     self.assertEqual("refs/heads/master", repository.default_branch)
예제 #10
0
 def test_skips_code_import(self):
     self.useFixture(GitHostingFixture())
     person = self.factory.makePerson()
     team = self.factory.makeTeam(members=[person])
     code_imports = [
         self.factory.makeCodeImport(registrant=person,
                                     target_rcs_type=target_rcs_type,
                                     owner=team)
         for target_rcs_type in (TargetRevisionControlSystems.BZR,
                                 TargetRevisionControlSystems.GIT)
     ]
     person_id = person.id
     account_id = person.account.id
     script = self.makeScript([six.ensure_str(person.name)])
     with dbuser('launchpad'):
         self.runScript(script)
     self.assertRemoved(account_id, person_id)
     self.assertEqual(person, code_imports[0].registrant)
     self.assertEqual(person, code_imports[1].registrant)
예제 #11
0
 def test_merge_detection_triggers_webhooks(self):
     self.useFixture(FeatureFixture(
         {BRANCH_MERGE_PROPOSAL_WEBHOOKS_FEATURE_FLAG: 'on'}))
     repository = self.factory.makeGitRepository()
     target, source = self.factory.makeGitRefs(
         repository, paths=['refs/heads/target', 'refs/heads/source'])
     bmp = self.factory.makeBranchMergeProposalForGit(
         target_ref=target, source_ref=source)
     hook = self.factory.makeWebhook(
         target=repository, event_types=['merge-proposal:0.1'])
     new_refs = {
         target.path: {'object': {
             'sha1': '0' * 40,
             'type': 'commit',
             }},
         source.path: {'object': {
             'sha1': source.commit_sha1,
             'type': 'commit',
             }},
         }
     new_merges = {source.commit_sha1: '0' * 40}
     self.useFixture(GitHostingFixture(refs=new_refs, merges=new_merges))
     job = GitRefScanJob.create(repository)
     with dbuser('branchscanner'):
         JobRunner([job]).runAll()
     delivery = hook.deliveries.one()
     self.assertThat(
         delivery,
         MatchesStructure(
             event_type=Equals('merge-proposal:0.1'),
             payload=MatchesDict({
                 'merge_proposal': Equals(
                     canonical_url(bmp, force_local_path=True)),
                 'action': Equals('modified'),
                 'old': ContainsDict(
                     {'queue_status': Equals('Work in progress')}),
                 'new': ContainsDict({'queue_status': Equals('Merged')}),
                 })))
     with dbuser(config.IWebhookDeliveryJobSource.dbuser):
         self.assertEqual(
             "<WebhookDeliveryJob for webhook %d on %r>" % (
                 hook.id, hook.target),
             repr(delivery))
예제 #12
0
 def makeTargetGitServer(self):
     """Set up a target Git server that can receive imports."""
     self.target_store = tempfile.mkdtemp()
     self.addCleanup(shutil.rmtree, self.target_store)
     self.target_git_server = GitServer(self.target_store, use_server=True)
     self.target_git_server.start_server()
     self.addCleanup(self.target_git_server.stop_server)
     config_name = self.getUniqueString()
     config_fixture = self.useFixture(
         ConfigFixture(config_name,
                       self.layer.config_fixture.instance_name))
     setting_lines = [
         "[codehosting]",
         "git_browse_root: %s" % self.target_git_server.get_url(""),
         "",
         "[launchpad]",
         "internal_macaroon_secret_key: some-secret",
     ]
     config_fixture.add_section("\n" + "\n".join(setting_lines))
     self.useFixture(ConfigUseFixture(config_name))
     self.useFixture(GitHostingFixture())
예제 #13
0
 def test_local_by_url(self):
     # It's possible (though not encouraged) to retrieve files from
     # self-hosted repositories by URL.
     [ref] = self.factory.makeGitRefs()
     hosting_fixture = self.useFixture(GitHostingFixture(blob=b"foo"))
     https_ref = self.factory.makeGitRefRemote(
         repository_url=ref.repository.git_https_url, path=ref.path)
     anon_ref = self.factory.makeGitRefRemote(repository_url=urlutils.join(
         config.codehosting.git_anon_root, ref.repository.shortened_path),
                                              path=ref.path)
     self.assertEqual(b"foo", https_ref.getBlob("dir/file"))
     self.assertEqual(b"foo", anon_ref.getBlob("dir/file"))
     internal_path = ref.repository.getInternalPath()
     expected_calls = [
         ((internal_path, "dir/file"), {
             "rev": ref.path
         }),
         ((internal_path, "dir/file"), {
             "rev": ref.path
         }),
     ]
     self.assertEqual(expected_calls, hosting_fixture.getBlob.calls)
예제 #14
0
 def test_run(self):
     # The job requests builds and records the result.
     distroseries, processors = self.makeSeriesAndProcessors(
         ["avr2001", "sparc64", "x32"])
     [git_ref] = self.factory.makeGitRefs()
     snap = self.factory.makeSnap(
         git_ref=git_ref, distroseries=distroseries, processors=processors)
     expected_date_created = get_transaction_timestamp(IStore(snap))
     job = SnapRequestBuildsJob.create(
         snap, snap.registrant, distroseries.main_archive,
         PackagePublishingPocket.RELEASE, {"core": "stable"})
     snapcraft_yaml = dedent("""\
         architectures:
           - build-on: avr2001
           - build-on: x32
         """)
     self.useFixture(GitHostingFixture(blob=snapcraft_yaml))
     with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
         JobRunner([job]).runAll()
     now = get_transaction_timestamp(IStore(snap))
     self.assertEmailQueueLength(0)
     self.assertThat(job, MatchesStructure(
         job=MatchesStructure.byEquality(status=JobStatus.COMPLETED),
         date_created=Equals(expected_date_created),
         date_finished=MatchesAll(
             GreaterThan(expected_date_created), LessThan(now)),
         error_message=Is(None),
         builds=AfterPreprocessing(set, MatchesSetwise(*[
             MatchesStructure(
                 build_request=MatchesStructure.byEquality(id=job.job.id),
                 requester=Equals(snap.registrant),
                 snap=Equals(snap),
                 archive=Equals(distroseries.main_archive),
                 distro_arch_series=Equals(distroseries[arch]),
                 pocket=Equals(PackagePublishingPocket.RELEASE),
                 channels=Equals({"core": "stable"}))
             for arch in ("avr2001", "x32")]))))
예제 #15
0
 def test_run_failed(self):
     # A failed run sets the job status to FAILED and records the error
     # message.
     # The job requests builds and records the result.
     distroseries, processors = self.makeSeriesAndProcessors(
         ["avr2001", "sparc64", "x32"])
     [git_ref] = self.factory.makeGitRefs()
     snap = self.factory.makeSnap(
         git_ref=git_ref, distroseries=distroseries, processors=processors)
     expected_date_created = get_transaction_timestamp(IStore(snap))
     job = SnapRequestBuildsJob.create(
         snap, snap.registrant, distroseries.main_archive,
         PackagePublishingPocket.RELEASE, {"core": "stable"})
     self.useFixture(GitHostingFixture()).getBlob.failure = (
         CannotParseSnapcraftYaml("Nonsense on stilts"))
     with dbuser(config.ISnapRequestBuildsJobSource.dbuser):
         JobRunner([job]).runAll()
     now = get_transaction_timestamp(IStore(snap))
     [notification] = self.assertEmailQueueLength(1)
     self.assertThat(dict(notification), ContainsDict({
         "From": Equals(config.canonical.noreply_from_address),
         "To": Equals(format_address_for_person(snap.registrant)),
         "Subject": Equals(
             "Launchpad error while requesting builds of %s" % snap.name),
         }))
     self.assertEqual(
         "Launchpad encountered an error during the following operation: "
         "requesting builds of %s.  Nonsense on stilts" % snap.name,
         notification.get_payload(decode=True))
     self.assertThat(job, MatchesStructure(
         job=MatchesStructure.byEquality(status=JobStatus.FAILED),
         date_created=Equals(expected_date_created),
         date_finished=MatchesAll(
             GreaterThan(expected_date_created), LessThan(now)),
         error_message=Equals("Nonsense on stilts"),
         builds=AfterPreprocessing(set, MatchesSetwise())))
예제 #16
0
 def test_git_to_git_import(self):
     # Test the email for a new git-to-git import.
     self.useFixture(GitHostingFixture())
     eric = self.factory.makePerson(name='eric')
     fooix = self.factory.makeProduct(name='fooix')
     # Eric needs to be logged in for the mail to be sent.
     login_person(eric)
     self.factory.makeProductCodeImport(
         git_repo_url='git://git.example.com/fooix.git',
         branch_name=u'master', product=fooix, registrant=eric,
         target_rcs_type=TargetRevisionControlSystems.GIT)
     transaction.commit()
     msg = message_from_string(stub.test_emails[0][2])
     self.assertEqual('code-import', msg['X-Launchpad-Notification-Type'])
     self.assertEqual('~eric/fooix/+git/master', msg['X-Launchpad-Branch'])
     self.assertEqual(
         'A new git code import has been requested '
         'by Eric:\n'
         '    http://code.launchpad.dev/~eric/fooix/+git/master\n'
         'from\n'
         '    git://git.example.com/fooix.git\n'
         '\n'
         '-- \nYou are getting this email because you are a member of the '
         'vcs-imports team.\n', msg.get_payload(decode=True))
예제 #17
0
 def test_git_ref_links_to_snaps(self):
     self.useFixture(GitHostingFixture())
     [ref] = self.factory.makeGitRefs()
     self.assertSnapsLink(ref, "2 snap packages", git_ref=ref)
예제 #18
0
 def setUp(self):
     super(TestHasSnapsMenu, self).setUp()
     if self.needs_git_hosting_fixture:
         self.useFixture(GitHostingFixture())