def testCreateUpdateEmptyRevision(self):
        conduit = phlsys_conduit.Conduit(
            self.test_data.TEST_URI, self.test_data.PHAB.user, self.test_data.PHAB.certificate
        )
        author = phldef_conduit.ALICE.user
        with phlsys_conduit.act_as_user_context(conduit, author):
            revision_id = phlcon_differential.create_empty_revision(conduit)

        revision_list = phlcon_differential.query(conduit, [revision_id])
        self.assertEqual(len(revision_list), 1)

        with phlsys_conduit.act_as_user_context(conduit, author):
            phlcon_differential.update_revision_empty(conduit, revision_id)
 def test_B_AcceptedPersistsWhenUpdated(self):
     conduit = self.phabConduit
     author = phldef_conduit.ALICE.user
     reviewer = phldef_conduit.BOB.user
     with phlsys_conduit.act_as_user_context(conduit, author):
         revision = phlcon_differential.create_empty_revision(conduit)
     with phlsys_conduit.act_as_user_context(conduit, reviewer):
         phlcon_differential.create_comment(conduit, revision, action=phlcon_differential.Action.accept)
     with phlsys_conduit.act_as_user_context(conduit, author):
         phlcon_differential.update_revision_empty(conduit, revision)
     self.assertEqual(
         phlcon_differential.get_revision_status(conduit, revision), phlcon_differential.ReviewStates.accepted
     )
Beispiel #3
0
    def testCreateUpdateEmptyRevision(self):
        conduit = phlsys_conduit.Conduit(
            self.test_data.TEST_URI,
            self.test_data.PHAB.user,
            self.test_data.PHAB.certificate)
        author = phldef_conduit.ALICE.user
        with phlsys_conduit.act_as_user_context(conduit, author):
            revision_id = phlcon_differential.create_empty_revision(conduit)

        revision_list = phlcon_differential.query(conduit, [revision_id])
        self.assertEqual(len(revision_list), 1)

        with phlsys_conduit.act_as_user_context(conduit, author):
            phlcon_differential.update_revision_empty(conduit, revision_id)
Beispiel #4
0
 def test_B_AcceptedPersistsWhenUpdated(self):
     conduit = self.phabConduit
     author = phldef_conduit.ALICE.user
     reviewer = phldef_conduit.BOB.user
     with phlsys_conduit.act_as_user_context(conduit, author):
         revision = phlcon_differential.create_empty_revision(conduit)
     with phlsys_conduit.act_as_user_context(conduit, reviewer):
         phlcon_differential.create_comment(
             conduit,
             revision,
             action=phlcon_differential.Action.accept)
     with phlsys_conduit.act_as_user_context(conduit, author):
         phlcon_differential.update_revision_empty(conduit, revision)
     self.assertEqual(
         phlcon_differential.get_revision_status(conduit, revision),
         phlcon_differential.ReviewStates.accepted)
    def update_revision(self, revisionid, raw_diff, message):
        """Update an existing Differential revision with a new diff.

        :revisionid: id of the Differential revision to update
        :raw_diff: raw output string from e.g. 'git diff master...'
        :message: string message to annotate the update event with
        :returns: None

        """
        # do some sanity checks before committing to the expensive operation
        # of storing a diff in Differential
        status = self._reviewstate_cache.get_status(revisionid)
        if status == phlcon_differential.ReviewStates.closed:
            raise abdt_exception.AbdUserException(
                "can't update a closed revision")

        author_user = self._get_author_user(revisionid)
        with phlsys_conduit.act_as_user_context(self._conduit, author_user):
            diffid = phlcon_differential.create_raw_diff(
                self._conduit, raw_diff).id
            try:
                phlcon_differential.update_revision(
                    self._conduit, revisionid, diffid, [], message)
            except phlcon_differential.UpdateClosedRevisionError:
                raise abdt_exception.AbdUserException(
                    "CONDUIT: can't update a closed revision")
        self._log(
            'conduit-updaterev',
            'updated {} as {}'.format(revisionid, author_user))
Beispiel #6
0
 def test_can_act_as_user(self):
     test_data = phldef_conduit
     conduit = phlsys_conduit.Conduit(test_data.TEST_URI,
                                      test_data.PHAB.user,
                                      test_data.PHAB.certificate)
     with phlsys_conduit.act_as_user_context(conduit, test_data.ALICE.user):
         conduit("differential.query")
def createDifferentialReview(
        conduit, user, parsed, gitContext, review_branch, rawDiff):
    clone = gitContext.clone
    phlgit_checkout.new_branch_force_based_on(
        clone, review_branch.branch, review_branch.remote_branch)

    with phlsys_conduit.act_as_user_context(conduit, user):
        print "- creating diff"
        diffid = phlcon_differential.create_raw_diff(conduit, rawDiff).id

        print "- creating revision"
        review = phlcon_differential.create_revision(
            conduit, diffid, parsed.fields)
        print "- created " + str(review.revisionid)

        workingBranch = abdt_naming.makeWorkingBranchName(
            abdt_naming.WB_STATUS_OK,
            review_branch.description,
            review_branch.base,
            review.revisionid)

        print "- pushing working branch: " + workingBranch
        phlgit_push.push_asymmetrical(
            clone, review_branch.branch, workingBranch, gitContext.remote)

    print "- commenting on " + str(review.revisionid)
    commenter = abdcmnt_commenter.Commenter(conduit, review.revisionid)
    commenter.createdReview(review_branch.branch, review_branch.base)

    return review.revisionid
 def test_can_act_as_user(self):
     test_data = phldef_conduit
     conduit = phlsys_conduit.Conduit(
         test_data.TEST_URI,
         test_data.PHAB.user,
         test_data.PHAB.certificate)
     with phlsys_conduit.act_as_user_context(conduit, test_data.ALICE.user):
         conduit.call("differential.query")
    def close_revision(self, revisionid):
        """Set an existing Differential revision to 'closed'.

        :revisionid: id of the Differential revision to close
        :returns: None

        """
        author_user = self._get_author_user(revisionid)
        with phlsys_conduit.act_as_user_context(self._conduit, author_user):
            phlcon_differential.close(self._conduit, revisionid)
    def create_empty_revision_as_user(self, username):
        """Return the id of a newly created empty revision as 'username'.

        :username: username for the author of the revision
        :returns: id of created revision

        """
        with phlsys_conduit.act_as_user_context(self._conduit, username):
            revision = phlcon_differential.create_empty_revision(self._conduit)
        return revision
    def test_C_CantUpdateClosedReviews(self):
        conduit = self.phabConduit
        author = phldef_conduit.ALICE.user
        reviewer = phldef_conduit.BOB.user
        with phlsys_conduit.act_as_user_context(conduit, author):
            revision = phlcon_differential.create_empty_revision(conduit)
        with phlsys_conduit.act_as_user_context(conduit, reviewer):
            phlcon_differential.create_comment(conduit, revision, action=phlcon_differential.Action.accept)
        with phlsys_conduit.act_as_user_context(conduit, author):
            phlcon_differential.create_comment(conduit, revision, action=phlcon_differential.Action.close)
            self.assertRaises(
                phlcon_differential.UpdateClosedRevisionError,
                phlcon_differential.update_revision_empty,
                conduit,
                revision,
            )

            # expect that we can close a closed revision without errors
            phlcon_differential.close(conduit, revision)
def land(conduit, wb, gitContext, branch):
    clone = gitContext.clone
    print "landing " + wb.remote_branch + " onto " + wb.remote_base
    name, email, user = abdt_conduitgit.getPrimaryNameEmailAndUserFromBranch(
        clone, conduit, wb.remote_base, wb.remote_branch)
    d = phlcon_differential
    with phlsys_conduit.act_as_user_context(conduit, user):
        phlgit_checkout.new_branch_force_based_on(
            clone, wb.base, wb.remote_base)

        # compose the commit message
        message = d.get_commit_message(conduit, wb.id)

        try:
            with phlsys_fs.nostd():
                squashMessage = phlgit_merge.squash(
                    clone,
                    wb.remote_branch,
                    message,
                    name + " <" + email + ">")
        except phlsys_subprocess.CalledProcessError as e:
            clone.call("reset", "--hard")  # fix the working copy
            raise abdt_exception.LandingException(
                '\n' + e.stdout, branch, wb.base)

        print "- pushing " + wb.remote_base
        phlgit_push.push(clone, wb.base, gitContext.remote)
        print "- deleting " + wb.branch
        phlgit_push.delete(clone, wb.branch, gitContext.remote)
        print "- deleting " + branch
        phlgit_push.delete(clone, branch, gitContext.remote)

    print "- commenting on revision " + str(wb.id)
    commenter = abdcmnt_commenter.Commenter(conduit, wb.id)
    commenter.landedReview(branch, wb.base, squashMessage)

    authorPHID = d.query(conduit, [wb.id])[0].authorPHID
    authorUser = phlcon_user.query_usernames_from_phids(
        conduit, [authorPHID])[0]
    # TODO: there's a potential race condition on the author here
    with phlsys_conduit.act_as_user_context(conduit, authorUser):
        d.close(conduit, wb.id)
def processUpdatedBranch(
        mailer, conduit, gitContext, review_branch, working_branch):
    abdte = abdt_exception
    if working_branch is None:
        print "create review for " + review_branch.branch
        tryCreateReview(
            mailer, conduit, gitContext, review_branch, mail_on_fail=True)
    else:
        commenter = abdcmnt_commenter.Commenter(conduit, working_branch.id)
        if abdt_naming.isStatusBadPreReview(working_branch):
            hasChanged = not phlgit_branch.is_identical(
                gitContext.clone,
                review_branch.remote_branch,
                working_branch.remote_branch)
            print "try again to create review for " + review_branch.branch
            phlgit_push.delete(
                gitContext.clone,
                working_branch.branch,
                gitContext.remote)
            tryCreateReview(
                mailer,
                conduit,
                gitContext,
                review_branch,
                mail_on_fail=hasChanged)
        else:
            print "update review for " + review_branch.branch
            revision = phlcon_differential.query(
                conduit, [working_branch.id])[0]
            author_user = phlcon_user.query_usernames_from_phids(
                conduit, [revision.authorPHID])[0]
            try:
                updateReview(
                    conduit,
                    gitContext,
                    review_branch,
                    working_branch,
                    author_user)
            except abdte.LandingException as e:
                print "landing exception"
                abdt_workingbranch.pushBadLand(
                    gitContext, review_branch, working_branch)
                commenter.exception(e)
                with phlsys_conduit.act_as_user_context(conduit, author_user):
                    phlcon_differential.create_comment(
                        conduit,
                        working_branch.id,
                        action=phlcon_differential.Action.rethink)
            except abdte.AbdUserException as e:
                print "user exception"
                abdt_workingbranch.pushBadInReview(
                    gitContext, review_branch, working_branch)
                commenter.exception(e)
def updateInReview(conduit, wb, gitContext, review_branch, author):
    remoteBranch = review_branch.remote_branch
    clone = gitContext.clone

    print "updateInReview"

    print "- creating diff"
    rawDiff = phlgit_diff.raw_diff_range(
        clone, wb.remote_base, remoteBranch, _DIFF_CONTEXT_LINES)
    if not rawDiff:
        raise abdt_exception.AbdUserException(
            "no difference from " + wb.base + " to " + wb.branch)

    # if the diff is too big then regen with less context
    # used_less_context = False
    if len(rawDiff) >= MAX_DIFF_SIZE:
        # used_less_context = True
        rawDiff = phlgit_diff.raw_diff_range(
            clone, wb.remote_base, remoteBranch, _LESS_DIFF_CONTEXT_LINES)

    # if the diff is still too big then regen with no context
    # used_no_context = False
    if len(rawDiff) >= MAX_DIFF_SIZE:
        # used_no_context = True
        rawDiff = phlgit_diff.raw_diff_range(
            clone, wb.remote_base, remoteBranch)

    # if the diff is still too big then error
    if len(rawDiff) >= MAX_DIFF_SIZE:
        raise abdt_exception.LargeDiffException(
            "diff too big", len(rawDiff), MAX_DIFF_SIZE)

    d = phlcon_differential
    used_default_test_plan = False
    with phlsys_conduit.act_as_user_context(conduit, author):
        print "- updating revision " + str(wb.id)
        diffid = d.create_raw_diff(conduit, rawDiff).id
        d.update_revision(
            conduit, wb.id, diffid, [], "update")

    wb = abdt_workingbranch.pushStatus(
        gitContext,
        review_branch,
        wb,
        abdt_naming.WB_STATUS_OK)

    print "- commenting on revision " + str(wb.id)
    commenter = abdcmnt_commenter.Commenter(conduit, wb.id)
    commenter.updatedReview(review_branch.branch)
    if used_default_test_plan:
        commenter.usedDefaultTestPlan(wb.branch, _DEFAULT_TEST_PLAN)

    return wb
    def commandeer_revision_as_user(self, revisionid, username):
        """Change the author of a revision to the specified 'username'.

        :revisionid: id of the Differential revision to claim
        :username: username for the author of the revision
        :returns: None

        """
        with phlsys_conduit.act_as_user_context(self._conduit, username):
            phlcon_differential.create_comment(
                self._conduit,
                revisionid,
                action=phlcon_differential.Action.claim)
    def accept_revision_as_user(self, revisionid, username):
        """Set an existing Differential revision to 'accepted'.

        :revisionid: id of the Differential revision to accept
        :username: username for the reviewer of the revision
        :returns: None

        """
        with phlsys_conduit.act_as_user_context(self._conduit, username):
            phlcon_differential.create_comment(
                self._conduit,
                revisionid,
                action=phlcon_differential.Action.accept)
    def abandon_revision(self, revisionid):
        """Set an existing Differential revision to 'abandoned'.

        :revisionid: id of the Differential revision to close
        :returns: None

        """
        author_user = self._get_author_user(revisionid)
        with phlsys_conduit.act_as_user_context(self._conduit, author_user):
            phlcon_differential.create_comment(
                self._conduit,
                revisionid,
                action=phlcon_differential.Action.abandon)
    def set_requires_revision(self, revisionid):
        """Set an existing Differential revision to 'requires revision'.

        :revisionid: id of the Differential revision to update
        :returns: None

        """
        author_user = self._get_author_user(revisionid)
        with phlsys_conduit.act_as_user_context(self._conduit, author_user):
            phlcon_differential.create_comment(
                self._conduit,
                revisionid,
                action=phlcon_differential.Action.rethink)
Beispiel #19
0
    def test_C_CantUpdateClosedReviews(self):
        conduit = self.phabConduit
        author = phldef_conduit.ALICE.user
        reviewer = phldef_conduit.BOB.user
        with phlsys_conduit.act_as_user_context(conduit, author):
            revision = phlcon_differential.create_empty_revision(conduit)
        with phlsys_conduit.act_as_user_context(conduit, reviewer):
            phlcon_differential.create_comment(
                conduit,
                revision,
                action=phlcon_differential.Action.accept)
        with phlsys_conduit.act_as_user_context(conduit, author):
            phlcon_differential.create_comment(
                conduit,
                revision,
                action=phlcon_differential.Action.close)
            self.assertRaises(
                phlcon_differential.UpdateClosedRevisionError,
                phlcon_differential.update_revision_empty,
                conduit,
                revision)

            # expect that we can close a closed revision without errors
            phlcon_differential.close(conduit, revision)
    def test_commandeeredUpdate(self):
        self._devCheckoutPushNewBranch("ph-review/commandeeredUpdate/master")
        self._devPushNewFile("NEWFILE")
        self._phabUpdateWithExpectations(total=1, bad=0)

        reviewid = self._getTheOnlyReviewId()
        with phlsys_conduit.act_as_user_context(
                self.conduit,
                phldef_conduit.ALICE.user) as conduit:
            phlcon_differential.create_comment(
                conduit,
                reviewid,
                action=phlcon_differential.Action.claim)

        self._devPushNewFile("NEWFILE2")
        self._phabUpdateWithExpectations(total=1, bad=0)
    def create_revision_as_user(self, raw_diff, fields, username):
        """Return the id of a newly created revision based on specified args.

        See phlcon_differential.MessageFields for some examples of valid input
        for specified 'fields'.

        :raw_diff: raw output string from e.g. 'git diff master...'
        :fields: dict of string attributes, required: 'title' and 'testPlan'
        :username: username for the author of the revision
        :returns: id of created revision

        """
        with phlsys_conduit.act_as_user_context(self._conduit, username):
            diffid = phlcon_differential.create_raw_diff(
                self._conduit, raw_diff).id
            review = phlcon_differential.create_revision(
                self._conduit, diffid, fields)
        return review.revisionid
 def _actOnTheOnlyReview(self, user, action):
     # accept the review
     reviewid = self._getTheOnlyReviewId()
     with phlsys_conduit.act_as_user_context(self.conduit, user):
         phlcon_differential.create_comment(
             self.conduit, reviewid, action=action)
    def test_A_Breathing(self):
        # [ A] can describe a conduit with non-empty string
        self.assertIsInstance(self.conduit.describe(), basestring)
        self.assertGreater(len(self.conduit.describe()), 0)

        # generally exercise all of the conduit methods
        alice = self.test_data.ALICE.user
        bob = self.test_data.BOB.user
        revision = self.conduit.create_empty_revision_as_user(bob)
        self.conduit.create_comment(revision, 'test comment')
        self.conduit.create_comment(
            revision, 'silent test comment', silent=True)
        self.conduit.get_commit_message(revision)
        self.assertFalse(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.set_requires_revision(revision)
        self.assertFalse(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.accept_revision_as_user(revision, alice)
        self._invalidate_cache()
        self.assertTrue(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.set_requires_revision(revision)
        self._invalidate_cache()
        self.assertFalse(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.accept_revision_as_user(revision, alice)

        # check that the review is still accepted after an update
        self._invalidate_cache()
        self.assertTrue(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.update_revision(revision, self.empty_diff, 'update')
        self._invalidate_cache()
        self.assertTrue(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))

        self.conduit.abandon_revision(revision)
        self.conduit.get_commit_message(revision)

        self._invalidate_cache()
        self.assertFalse(self.conduit.is_review_accepted(revision))
        self.assertTrue(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))

        # un-abandon
        with phlsys_conduit.act_as_user_context(self.sys_conduit, bob):
            phlcon_differential.create_comment(
                self.sys_conduit,
                revision,
                action=phlcon_differential.Action.reclaim)

        self._invalidate_cache()
        self.assertFalse(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))

        self.conduit.commandeer_revision_as_user(revision, alice)
        self.conduit.commandeer_revision_as_user(revision, bob)

        # close non-accepted revision
        # self.conduit.set_requires_revision(revision)
        # self.assertFalse(self.conduit.is_review_accepted(revision))
        # self.conduit.close_revision(revision)
        # self.assertFalse(self.conduit.is_review_accepted(revision))

        # close revision
        self.conduit.accept_revision_as_user(revision, alice)
        self._invalidate_cache()
        self.assertTrue(self.conduit.is_review_accepted(revision))
        self.assertFalse(self.conduit.is_review_abandoned(revision))
        self.assertTrue(self.conduit.is_review_recently_updated(revision))
        self.conduit.close_revision(revision)
        self.conduit.get_commit_message(revision)

        # commandeer closed revision
        # self.conduit.commandeer_revision_as_user(revision, alice)

        # update closed revision
        self._invalidate_cache()
        self.assertRaises(
            abdt_exception.AbdUserException,
            self.conduit.update_revision,
            revision,
            self.empty_diff,
            'update')

        # comment on closed revision
        self.conduit.create_comment(revision, 'test comment')