@Test
  public void prepopulatedFields() throws Exception {
    assume().that(notesMigration.enabled()).isFalse();
    TestRepository<Repo> repo = createProject("repo");
    Change change = newChange(repo, null, null, null, null).insert();

    db = new DisabledReviewDb();
    requestContext.setContext(newRequestContext(userId));
    // Use QueryProcessor directly instead of API so we get ChangeDatas back.
    List<ChangeData> cds =
        queryProcessor.queryChanges(queryBuilder.parse(change.getId().toString())).changes();
    assertThat(cds).hasSize(1);

    ChangeData cd = cds.get(0);
    cd.change();
    cd.patchSets();
    cd.currentApprovals();
    cd.changedLines();
    cd.reviewedBy();

    // TODO(dborowitz): Swap out GitRepositoryManager somehow? Will probably be
    // necessary for notedb anyway.
    cd.isMergeable();

    // Don't use ExpectedException since that wouldn't distinguish between
    // failures here and on the previous calls.
    try {
      cd.messages();
    } catch (AssertionError e) {
      assertThat(e.getMessage()).isEqualTo(DisabledReviewDb.MESSAGE);
    }
  }
  @Test
  public void byCommentBy() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change1 = newChange(repo, null, null, null, null).insert();
    Change change2 = newChange(repo, null, null, null, null).insert();

    int user2 =
        accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId().get();

    ReviewInput input = new ReviewInput();
    input.message = "toplevel";
    ReviewInput.CommentInput comment = new ReviewInput.CommentInput();
    comment.line = 1;
    comment.message = "inline";
    input.comments =
        ImmutableMap.<String, List<ReviewInput.CommentInput>>of(
            Patch.COMMIT_MSG, ImmutableList.<ReviewInput.CommentInput>of(comment));
    gApi.changes().id(change1.getId().get()).current().review(input);

    input = new ReviewInput();
    input.message = "toplevel";
    gApi.changes().id(change2.getId().get()).current().review(input);

    assertQuery("commentby:" + userId.get(), change2, change1);
    assertQuery("commentby:" + user2);
  }
  private Iterable<ChangeData> byCommitsOnBranchNotMergedFromDatabase(
      Repository repo, ReviewDb db, Branch.NameKey branch, List<String> hashes)
      throws OrmException, IOException {
    Set<Change.Id> changeIds = Sets.newHashSetWithExpectedSize(hashes.size());
    String lastPrefix = null;
    for (Ref ref : repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES).values()) {
      String r = ref.getName();
      if ((lastPrefix != null && r.startsWith(lastPrefix))
          || !hashes.contains(ref.getObjectId().name())) {
        continue;
      }
      Change.Id id = Change.Id.fromRef(r);
      if (id == null) {
        continue;
      }
      if (changeIds.add(id)) {
        lastPrefix = r.substring(0, r.lastIndexOf('/'));
      }
    }

    List<ChangeData> cds = new ArrayList<>(hashes.size());
    for (Change c : db.changes().get(changeIds)) {
      if (c.getDest().equals(branch) && c.getStatus() != Change.Status.MERGED) {
        cds.add(changeDataFactory.create(db, c));
      }
    }
    return cds;
  }
  @Test
  public void limit() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change last = null;
    int n = 5;
    for (int i = 0; i < n; i++) {
      last = newChange(repo, null, null, null, null).insert();
    }

    for (int i = 1; i <= n + 2; i++) {
      int expectedSize;
      Boolean expectedMoreChanges;
      if (i < n) {
        expectedSize = i;
        expectedMoreChanges = true;
      } else {
        expectedSize = n;
        expectedMoreChanges = null;
      }
      String q = "status:new limit:" + i;
      List<ChangeInfo> results = newQuery(q).get();
      assertThat(results).named(q).hasSize(expectedSize);
      assertThat(results.get(results.size() - 1)._moreChanges)
          .named(q)
          .isEqualTo(expectedMoreChanges);
      assertThat(results.get(0)._number).isEqualTo(last.getId().get());
    }
  }
  private static ChangeKind getChangeKindInternal(
      ChangeKindCache cache,
      ReviewDb db,
      Change change,
      PatchSet patch,
      ChangeData.Factory changeDataFactory,
      ProjectCache projectCache,
      GitRepositoryManager repoManager) {
    Repository repo = null;
    // TODO - dborowitz: add NEW_CHANGE type for default.
    ChangeKind kind = ChangeKind.REWORK;
    // Trivial case: if we're on the first patch, we don't need to open
    // the repository.
    if (patch.getId().get() > 1) {
      try {
        ProjectState projectState = projectCache.checkedGet(change.getProject());

        repo = repoManager.openRepository(change.getProject());

        ChangeData cd = changeDataFactory.create(db, change);
        Collection<PatchSet> patchSetCollection = cd.patches();
        PatchSet priorPs = patch;
        for (PatchSet ps : patchSetCollection) {
          if (ps.getId().get() < patch.getId().get()
              && (ps.getId().get() > priorPs.getId().get() || priorPs == patch)) {
            // We only want the previous patch set, so walk until the last one
            priorPs = ps;
          }
        }

        // If we still think the previous patch is the current patch,
        // we only have one patch set.  Return the default.
        // This can happen if a user creates a draft, uploads a second patch,
        // and deletes the draft.
        if (priorPs != patch) {
          kind =
              cache.getChangeKind(
                  projectState,
                  repo,
                  ObjectId.fromString(priorPs.getRevision().get()),
                  ObjectId.fromString(patch.getRevision().get()));
        }
      } catch (IOException | OrmException e) {
        // Do nothing; assume we have a complex change
        log.warn(
            "Unable to get change kind for patchSet "
                + patch.getPatchSetId()
                + "of change "
                + change.getChangeId(),
            e);
      } finally {
        if (repo != null) {
          repo.close();
        }
      }
    }
    return kind;
  }
 synchronized Set<Change> addAll(Collection<Change> changes, boolean force) {
   Set<Change> r = Sets.newLinkedHashSetWithExpectedSize(changes.size());
   for (Change c : changes) {
     if (force ? forcePending.add(c.getId()) : pending.add(c.getId())) {
       r.add(c);
     }
   }
   return r;
 }
Example #7
0
  private void updateChangeStatus(OpenBranch ob, List<ChangeData> submitted, IdentifiedUser caller)
      throws ResourceConflictException {
    List<Change.Id> problemChanges = new ArrayList<>(submitted.size());
    logDebug("Updating change status for {} changes", submitted.size());

    for (ChangeData cd : submitted) {
      Change.Id id = cd.getId();
      try {
        Change c = cd.change();
        CodeReviewCommit commit = commits.get(id);
        CommitMergeStatus s = commit != null ? commit.getStatusCode() : null;
        logDebug("Status of change {} ({}) on {}: {}", id, commit.name(), c.getDest(), s);
        checkState(s != null, "status not set for change %s; expected to previously fail fast", id);
        setApproval(cd, caller);

        ObjectId mergeResultRev =
            ob.mergeTip != null ? ob.mergeTip.getMergeResults().get(commit) : null;
        String txt = s.getMessage();

        // The change notes must be forcefully reloaded so that the SUBMIT
        // approval that we added earlier is visible
        commit.notes().reload();
        if (s == CommitMergeStatus.CLEAN_MERGE) {
          setMerged(c, message(c, txt + getByAccountName(commit)), mergeResultRev);
        } else if (s == CommitMergeStatus.CLEAN_REBASE || s == CommitMergeStatus.CLEAN_PICK) {
          setMerged(
              c,
              message(c, txt + " as " + commit.name() + getByAccountName(commit)),
              mergeResultRev);
        } else if (s == CommitMergeStatus.ALREADY_MERGED) {
          setMerged(c, null, mergeResultRev);
        } else {
          throw new IllegalStateException(
              "unexpected status "
                  + s
                  + " for change "
                  + c.getId()
                  + "; expected to previously fail fast");
        }
      } catch (OrmException | IOException err) {
        logWarn("Error updating change status for " + id, err);
        problemChanges.add(id);
      }
    }

    if (problemChanges.isEmpty()) {
      return;
    }
    StringBuilder msg = new StringBuilder("Error updating status of change");
    if (problemChanges.size() == 1) {
      msg.append(' ').append(problemChanges.iterator().next());
    } else {
      msg.append('s').append(Joiner.on(", ").join(problemChanges));
    }
    throw new ResourceConflictException(msg.toString());
  }
  @Test
  public void byId() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change1 = newChange(repo, null, null, null, null).insert();
    Change change2 = newChange(repo, null, null, null, null).insert();

    assertQuery("12345");
    assertQuery(change1.getId().get(), change1);
    assertQuery(change2.getId().get(), change2);
  }
  @Test
  public void byKey() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change = newChange(repo, null, null, null, null).insert();
    String key = change.getKey().get();

    assertQuery("I0000000000000000000000000000000000000000");
    for (int i = 0; i <= 36; i++) {
      String q = key.substring(0, 41 - i);
      assertQuery(q, change);
    }
  }
Example #10
0
 private ChangeMessage message(Change c, String body) {
   String uuid;
   try {
     uuid = ChangeUtil.messageUUID(db);
   } catch (OrmException e) {
     return null;
   }
   ChangeMessage m =
       new ChangeMessage(
           new ChangeMessage.Key(c.getId(), uuid), null, TimeUtil.nowTs(), c.currentPatchSetId());
   m.setMessage(body);
   return m;
 }
Example #11
0
 private void matchChange(Set<Change.Id> matched, Change change) {
   try {
     if (change != null
         && inProject(change)
         && changeControlFactory.controlFor(change, userProvider.get()).isVisible(db)) {
       matched.add(change.getId());
     }
   } catch (NoSuchChangeException e) {
     // Ignore this change.
   } catch (OrmException e) {
     log.warn("Error reading change " + change.getId(), e);
   }
 }
 protected Change newPatchSet(TestRepository<Repo> repo, Change c) throws Exception {
   // Add a new file so the patch set is not a trivial rebase, to avoid default
   // Code-Review label copying.
   int n = c.currentPatchSetId().get() + 1;
   RevCommit commit =
       repo.parseBody(repo.commit().message("message").add("file" + n, "contents " + n).create());
   ChangeControl ctl = changeControlFactory.controlFor(c.getId(), user);
   return patchSetFactory
       .create(repo.getRepository(), repo.getRevWalk(), ctl, commit)
       .setSendMail(false)
       .setRunHooks(false)
       .setValidatePolicy(ValidatePolicy.NONE)
       .insert();
 }
  @Test
  public void byTopic() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins1 = newChange(repo, null, null, null, null);
    Change change1 = ins1.getChange();
    change1.setTopic("feature1");
    ins1.insert();

    ChangeInserter ins2 = newChange(repo, null, null, null, null);
    Change change2 = ins2.getChange();
    change2.setTopic("feature2");
    ins2.insert();

    ChangeInserter ins3 = newChange(repo, null, null, null, null);
    Change change3 = ins3.getChange();
    change3.setTopic("Cherrypick-feature2");
    ins3.insert();

    ChangeInserter ins4 = newChange(repo, null, null, null, null);
    Change change4 = ins4.getChange();
    change4.setTopic("feature2-fixup");
    ins4.insert();

    Change change5 = newChange(repo, null, null, null, null).insert();

    assertQuery("intopic:foo");
    assertQuery("intopic:feature1", change1);
    assertQuery("intopic:feature2", change4, change3, change2);
    assertQuery("topic:feature2", change2);
    assertQuery("intopic:feature2", change4, change3, change2);
    assertQuery("intopic:fixup", change4);
    assertQuery("topic:\"\"", change5);
    assertQuery("intopic:\"\"", change5);
  }
  private List<Change> setUpHashtagChanges() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change1 = newChange(repo, null, null, null, null).insert();
    Change change2 = newChange(repo, null, null, null, null).insert();

    HashtagsInput in = new HashtagsInput();
    in.add = ImmutableSet.of("foo");
    gApi.changes().id(change1.getId().get()).setHashtags(in);

    in.add = ImmutableSet.of("foo", "bar", "a tag");
    gApi.changes().id(change2.getId().get()).setHashtags(in);

    return ImmutableList.of(change1, change2);
  }
  private void postAdd(Change change, PostResult result) throws OrmException, EmailException {
    if (result.reviewers.isEmpty()) {
      return;
    }

    // Execute hook for added reviewers
    //
    PatchSet patchSet = db.get().patchSets().get(change.currentPatchSetId());
    for (AccountInfo info : result.reviewers) {
      Account account = accountCache.get(info._id).getAccount();
      hooks.doReviewerAddedHook(change, account, patchSet, db.get());
    }

    // Email the reviewers
    //
    // The user knows they added themselves, don't bother emailing them.
    List<Account.Id> added = Lists.newArrayListWithCapacity(result.reviewers.size());
    for (AccountInfo info : result.reviewers) {
      if (!info._id.equals(currentUser.getAccountId())) {
        added.add(info._id);
      }
    }
    if (!added.isEmpty()) {
      AddReviewerSender cm;

      cm = addReviewerSenderFactory.create(change);
      cm.setFrom(currentUser.getAccountId());
      cm.addReviewers(added);
      cm.send();
    }
  }
  /**
   * Evaluate the submit rules.
   *
   * @return List of {@link SubmitRecord} objects returned from the evaluated rules, including any
   *     errors.
   */
  public List<SubmitRecord> evaluate() {
    Change c = control.getChange();
    if (!allowClosed && c.getStatus().isClosed()) {
      SubmitRecord rec = new SubmitRecord();
      rec.status = SubmitRecord.Status.CLOSED;
      return Collections.singletonList(rec);
    }
    if (!allowDraft) {
      if (c.getStatus() == Change.Status.DRAFT) {
        return cannotSubmitDraft();
      }
      try {
        initPatchSet();
      } catch (OrmException e) {
        return ruleError("Error looking up patch set " + control.getChange().currentPatchSetId());
      }
      if (patchSet.isDraft()) {
        return cannotSubmitDraft();
      }
    }

    List<Term> results;
    try {
      results =
          evaluateImpl(
              "locate_submit_rule",
              "can_submit",
              "locate_submit_filter",
              "filter_submit_results",
              control.getUser());
    } catch (RuleEvalException e) {
      return ruleError(e.getMessage(), e);
    }

    if (results.isEmpty()) {
      // This should never occur. A well written submit rule will always produce
      // at least one result informing the caller of the labels that are
      // required for this change to be submittable. Each label will indicate
      // whether or not that is actually possible given the permissions.
      return ruleError(
          String.format(
              "Submit rule '%s' for change %s of %s has " + "no solution.",
              getSubmitRuleName(), cd.getId(), getProjectName()));
    }

    return resultsToSubmitRecord(getSubmitRule(), results);
  }
Example #17
0
 private boolean inProject(Change change) {
   if (projectControl != null) {
     return projectControl.getProject().getNameKey().equals(change.getProject());
   } else {
     // No --project option, so they want every project.
     return true;
   }
 }
  @Test
  public void explicitVisibleTo() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change1 = newChange(repo, null, null, userId.get(), null).insert();
    ChangeInserter ins2 = newChange(repo, null, null, userId.get(), null);
    Change change2 = ins2.getChange();
    change2.setStatus(Change.Status.DRAFT);
    ins2.insert();

    String q = "project:repo";
    assertQuery(q, change2, change1);

    // Second user cannot see first user's drafts.
    Account.Id user2 =
        accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId();
    assertQuery(q + " visibleto:" + user2.get(), change1);
  }
  @Test
  public void byStatus() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins1 = newChange(repo, null, null, null, null);
    Change change1 = ins1.getChange();
    change1.setStatus(Change.Status.NEW);
    ins1.insert();
    ChangeInserter ins2 = newChange(repo, null, null, null, null);
    Change change2 = ins2.getChange();
    change2.setStatus(Change.Status.MERGED);
    ins2.insert();

    assertQuery("status:new", change1);
    assertQuery("status:NEW", change1);
    assertQuery("is:new", change1);
    assertQuery("status:merged", change2);
    assertQuery("is:merged", change2);
  }
Example #20
0
  private void setMerged(Change c, ChangeMessage msg, ObjectId mergeResultRev)
      throws OrmException, IOException {
    logDebug("Setting change {} merged", c.getId());
    ChangeUpdate update = null;
    final PatchSetApproval submitter;
    PatchSet merged;
    try {
      db.changes().beginTransaction(c.getId());

      // We must pull the patchset out of commits, because the patchset ID is
      // modified when using the cherry-pick merge strategy.
      CodeReviewCommit commit = commits.get(c.getId());
      PatchSet.Id mergedId = commit.change().currentPatchSetId();
      merged = db.patchSets().get(mergedId);
      c = setMergedPatchSet(c.getId(), mergedId);
      submitter = approvalsUtil.getSubmitter(db, commit.notes(), mergedId);
      ChangeControl control = commit.getControl();
      update = updateFactory.create(control, c.getLastUpdatedOn());

      // TODO(yyonas): we need to be able to change the author of the message
      // is not the person for whom the change was made. addMergedMessage
      // did this in the past.
      if (msg != null) {
        cmUtil.addChangeMessage(db, update, msg);
      }
      db.commit();

    } finally {
      db.rollback();
    }
    update.commit();
    indexer.index(db, c);

    try {
      mergedSenderFactory
          .create(c.getId(), submitter != null ? submitter.getAccountId() : null)
          .sendAsync();
    } catch (Exception e) {
      log.error("Cannot email merged notification for " + c.getId(), e);
    }
    if (submitter != null && mergeResultRev != null) {
      try {
        hooks.doChangeMergedHook(
            c,
            accountCache.get(submitter.getAccountId()).getAccount(),
            merged,
            db,
            mergeResultRev.name());
      } catch (OrmException ex) {
        logError("Cannot run hook for submitted patch set " + c.getId(), ex);
      }
    }
  }
  @Test
  public void byLabel() throws Exception {
    accountManager.authenticate(AuthRequest.forUser("anotheruser"));
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins = newChange(repo, null, null, null, null);
    Change change = ins.insert();

    gApi.changes()
        .id(change.getId().get())
        .current()
        .review(new ReviewInput().label("Code-Review", 1));

    assertQuery("label:Code-Review=-2");
    assertQuery("label:Code-Review-2");
    assertQuery("label:Code-Review=-1");
    assertQuery("label:Code-Review-1");
    assertQuery("label:Code-Review=0");
    assertQuery("label:Code-Review=+1", change);
    assertQuery("label:Code-Review=1", change);
    assertQuery("label:Code-Review+1", change);
    assertQuery("label:Code-Review=+2");
    assertQuery("label:Code-Review=2");
    assertQuery("label:Code-Review+2");

    assertQuery("label:Code-Review>=0", change);
    assertQuery("label:Code-Review>0", change);
    assertQuery("label:Code-Review>=1", change);
    assertQuery("label:Code-Review>1");
    assertQuery("label:Code-Review>=2");

    assertQuery("label: Code-Review<=2", change);
    assertQuery("label: Code-Review<2", change);
    assertQuery("label: Code-Review<=1", change);
    assertQuery("label:Code-Review<1");
    assertQuery("label:Code-Review<=0");

    assertQuery("label:Code-Review=+1,anotheruser");
    assertQuery("label:Code-Review=+1,user", change);
    assertQuery("label:Code-Review=+1,user=user", change);
    assertQuery("label:Code-Review=+1,Administrators", change);
    assertQuery("label:Code-Review=+1,group=Administrators", change);
  }
  @Test
  public void byComment() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins = newChange(repo, null, null, null, null);
    Change change = ins.insert();

    ReviewInput input = new ReviewInput();
    input.message = "toplevel";
    ReviewInput.CommentInput comment = new ReviewInput.CommentInput();
    comment.line = 1;
    comment.message = "inline";
    input.comments =
        ImmutableMap.<String, List<ReviewInput.CommentInput>>of(
            Patch.COMMIT_MSG, ImmutableList.<ReviewInput.CommentInput>of(comment));
    gApi.changes().id(change.getId().get()).current().review(input);

    assertQuery("comment:foo");
    assertQuery("comment:toplevel", change);
    assertQuery("comment:inline", change);
  }
Example #23
0
 protected boolean isVisibleTo(Change change, CurrentUser user) throws OrmException {
   if (change == null) {
     return false;
   }
   ProjectState pe = projectCache.get(change.getProject());
   if (pe == null) {
     return false;
   }
   ProjectControl pc = pe.controlFor(user);
   ReviewDb db = dbProvider.get();
   return pc.controlFor(db, change).isVisible(db);
 }
  @Test
  public void updatedOrderWithSubMinuteResolution() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins1 = newChange(repo, null, null, null, null);
    Change change1 = ins1.insert();
    Change change2 = newChange(repo, null, null, null, null).insert();

    assertThat(lastUpdatedMs(change1)).isLessThan(lastUpdatedMs(change2));

    assertQuery("status:new", change2, change1);

    gApi.changes().id(change1.getId().get()).current().review(new ReviewInput());
    change1 = db.changes().get(change1.getId());

    assertThat(lastUpdatedMs(change1)).isGreaterThan(lastUpdatedMs(change2));
    assertThat(lastUpdatedMs(change1) - lastUpdatedMs(change2))
        .isLessThan(MILLISECONDS.convert(1, MINUTES));

    // change1 moved to the top.
    assertQuery("status:new", change1, change2);
  }
  @Test
  public void byStatusClosed() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins1 = newChange(repo, null, null, null, null);
    Change change1 = ins1.getChange();
    change1.setStatus(Change.Status.MERGED);
    ins1.insert();
    ChangeInserter ins2 = newChange(repo, null, null, null, null);
    Change change2 = ins2.getChange();
    change2.setStatus(Change.Status.ABANDONED);
    ins2.insert();
    ChangeInserter ins3 = newChange(repo, null, null, null, null);
    Change change3 = ins3.getChange();
    change3.setStatus(Change.Status.NEW);
    ins3.insert();

    Change[] expected = new Change[] {change2, change1};
    assertQuery("status:closed", expected);
    assertQuery("status:CLOSED", expected);
    assertQuery("status:c", expected);
    assertQuery("status:cl", expected);
    assertQuery("status:clo", expected);
    assertQuery("status:clos", expected);
    assertQuery("status:close", expected);
    assertQuery("status:closed", expected);
    assertQuery("is:closed", expected);
  }
  @Test
  public void byStatusOpen() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    ChangeInserter ins1 = newChange(repo, null, null, null, null);
    Change change1 = ins1.getChange();
    change1.setStatus(Change.Status.NEW);
    ins1.insert();
    ChangeInserter ins2 = newChange(repo, null, null, null, null);
    Change change2 = ins2.getChange();
    change2.setStatus(Change.Status.DRAFT);
    ins2.insert();
    ChangeInserter ins3 = newChange(repo, null, null, null, null);
    Change change3 = ins3.getChange();
    change3.setStatus(Change.Status.MERGED);
    ins3.insert();

    Change[] expected = new Change[] {change2, change1};
    assertQuery("status:open", expected);
    assertQuery("status:OPEN", expected);
    assertQuery("status:o", expected);
    assertQuery("status:op", expected);
    assertQuery("status:ope", expected);
    assertQuery("status:pending", expected);
    assertQuery("status:PENDING", expected);
    assertQuery("status:p", expected);
    assertQuery("status:pe", expected);
    assertQuery("status:pen", expected);
    assertQuery("is:open", expected);
  }
  @Test
  public void byTriplet() throws Exception {
    TestRepository<Repo> repo = createProject("repo");
    Change change = newChange(repo, null, null, null, "branch").insert();
    String k = change.getKey().get();

    assertQuery("repo~branch~" + k, change);
    assertQuery("change:repo~branch~" + k, change);
    assertQuery("repo~refs/heads/branch~" + k, change);
    assertQuery("change:repo~refs/heads/branch~" + k, change);
    assertQuery("repo~branch~" + k.substring(0, 10), change);
    assertQuery("change:repo~branch~" + k.substring(0, 10), change);

    assertQuery("foo~bar");
    assertBadQuery("change:foo~bar");
    assertQuery("otherrepo~branch~" + k);
    assertQuery("change:otherrepo~branch~" + k);
    assertQuery("repo~otherbranch~" + k);
    assertQuery("change:repo~otherbranch~" + k);
    assertQuery("repo~branch~I0000000000000000000000000000000000000000");
    assertQuery("change:repo~branch~I0000000000000000000000000000000000000000");
  }
Example #28
0
 private Multimap<ObjectId, PatchSet.Id> getRevisions(OpenRepo or, Collection<ChangeData> cds)
     throws IntegrationException {
   try {
     List<String> refNames = new ArrayList<>(cds.size());
     for (ChangeData cd : cds) {
       Change c = cd.change();
       if (c != null) {
         refNames.add(c.currentPatchSetId().toRefName());
       }
     }
     Multimap<ObjectId, PatchSet.Id> revisions = HashMultimap.create(cds.size(), 1);
     for (Map.Entry<String, Ref> e :
         or.repo
             .getRefDatabase()
             .exactRef(refNames.toArray(new String[refNames.size()]))
             .entrySet()) {
       revisions.put(e.getValue().getObjectId(), PatchSet.Id.fromRef(e.getKey()));
     }
     return revisions;
   } catch (IOException | OrmException e) {
     throw new IntegrationException("Failed to validate changes", e);
   }
 }
Example #29
0
 public void fire(Change change, PatchSet ps, Account restorer, String reason, Timestamp when) {
   if (!listeners.iterator().hasNext()) {
     return;
   }
   try {
     fire(
         util.changeInfo(change),
         util.revisionInfo(change.getProject(), ps),
         util.accountInfo(restorer),
         reason,
         when);
   } catch (PatchListNotAvailableException | GpgException | IOException | OrmException e) {
     log.error("Couldn't fire event", e);
   }
 }
  @Test
  public void reviewedBy() throws Exception {
    clockStepMs = MILLISECONDS.convert(2, MINUTES);
    TestRepository<Repo> repo = createProject("repo");
    Change change1 = newChange(repo, null, null, null, null).insert();
    Change change2 = newChange(repo, null, null, null, null).insert();
    Change change3 = newChange(repo, null, null, null, null).insert();

    gApi.changes().id(change1.getId().get()).current().review(new ReviewInput().message("comment"));

    Account.Id user2 =
        accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId();
    requestContext.setContext(newRequestContext(user2));

    gApi.changes().id(change2.getId().get()).current().review(new ReviewInput().message("comment"));

    PatchSet.Id ps3_1 = change3.currentPatchSetId();
    change3 = newPatchSet(repo, change3);
    assertThat(change3.currentPatchSetId()).isNotEqualTo(ps3_1);
    // Response to previous patch set still counts as reviewing.
    gApi.changes()
        .id(change3.getId().get())
        .revision(ps3_1.get())
        .review(new ReviewInput().message("comment"));

    List<ChangeInfo> actual;
    actual = assertQuery(newQuery("is:reviewed").withOption(REVIEWED), change3, change2);
    assertThat(actual.get(0).reviewed).isTrue();
    assertThat(actual.get(1).reviewed).isTrue();

    actual = assertQuery(newQuery("-is:reviewed").withOption(REVIEWED), change1);
    assertThat(actual.get(0).reviewed).isNull();

    actual = assertQuery("reviewedby:" + userId.get());

    actual =
        assertQuery(newQuery("reviewedby:" + user2.get()).withOption(REVIEWED), change3, change2);
    assertThat(actual.get(0).reviewed).isTrue();
    assertThat(actual.get(1).reviewed).isTrue();
  }