Fix ref state for starred changes to be in All-Users
This was a bug in I622dbbb3, which accidentally referenced the starred
change ref in the project repo. Add tests that hopefully should make
this kind of thing easier to spot.
Change-Id: If908c6ea7bbe99be113b6b0c87b5be311ed7547c
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
index 1672eea..1d376d5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -971,7 +971,7 @@
input.editRefs().values().forEach(
r -> result.add(RefState.of(r).toByteArray(project)));
input.starRefs().values().forEach(
- r -> result.add(RefState.of(r.ref()).toByteArray(project)));
+ r -> result.add(RefState.of(r.ref()).toByteArray(args.allUsers)));
if (PrimaryStorage.of(input.change()) == PrimaryStorage.NOTE_DB) {
ChangeNotes notes = input.notes();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/StalenessChecker.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/StalenessChecker.java
index 0c3d89c..7c841c5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/change/StalenessChecker.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/change/StalenessChecker.java
@@ -62,7 +62,7 @@
private static final Logger log =
LoggerFactory.getLogger(StalenessChecker.class);
- private final ImmutableSet<String> FIELDS = ImmutableSet.of(
+ public static final ImmutableSet<String> FIELDS = ImmutableSet.of(
ChangeField.CHANGE.getName(),
ChangeField.REF_STATE.getName(),
ChangeField.REF_STATE_PATTERN.getName());
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index d22e7a8..5e5a047 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -21,6 +21,7 @@
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.stream.Collectors.toList;
import com.google.common.base.MoreObjects;
import com.google.common.collect.FluentIterable;
@@ -38,6 +39,7 @@
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput;
import com.google.gerrit.extensions.api.changes.StarsInput;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -54,6 +56,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.Sequences;
@@ -66,10 +69,15 @@
import com.google.gerrit.server.edit.ChangeEditModifier;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.validators.CommitValidators;
+import com.google.gerrit.server.index.IndexConfig;
+import com.google.gerrit.server.index.QueryOptions;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndexCollection;
import com.google.gerrit.server.index.change.ChangeIndexer;
+import com.google.gerrit.server.index.change.IndexedChangeQuery;
+import com.google.gerrit.server.index.change.StalenessChecker;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.notedb.NoteDbChangeState;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.RequestContext;
@@ -100,6 +108,7 @@
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -125,6 +134,7 @@
@Inject protected ChangeEditModifier changeEditModifier;
@Inject protected ChangeIndexCollection indexes;
@Inject protected ChangeIndexer indexer;
+ @Inject protected IndexConfig indexConfig;
@Inject protected InMemoryDatabase schemaFactory;
@Inject protected InMemoryRepositoryManager repoManager;
@Inject protected InternalChangeQuery internalChangeQuery;
@@ -1638,6 +1648,97 @@
assertQuery("has:edit");
}
+ @Test
+ public void refStateFields() throws Exception {
+ Account.Id user = createAccount("user");
+ Project.NameKey project = new Project.NameKey("repo");
+ TestRepository<Repo> repo = createProject(project.get());
+ String path = "file";
+ RevCommit commit = repo.parseBody(
+ repo.commit().message("one").add(path, "contents").create());
+ Change change = insert(repo, newChangeForCommit(repo, commit));
+ Change.Id id = change.getId();
+ int c = id.get();
+ PatchSet ps = db.patchSets().get(change.currentPatchSetId());
+ requestContext.setContext(newRequestContext(user));
+
+ // Ensure one of each type of supported ref is present for the change. If
+ // any more refs are added, update this test to reflect them.
+
+ // Edit
+ assertThat(changeEditModifier.createEdit(change, ps))
+ .isEqualTo(RefUpdate.Result.NEW);
+
+ // Star
+ gApi.accounts()
+ .self()
+ .starChange(change.getId().toString());
+
+ if (notesMigration.readChanges()) {
+ // Robot comment.
+ ReviewInput rin = new ReviewInput();
+ RobotCommentInput rcin = new RobotCommentInput();
+ rcin.robotId = "happyRobot";
+ rcin.robotRunId = "1";
+ rcin.line = 1;
+ rcin.message = "nit: trailing whitespace";
+ rcin.path = path;
+ rin.robotComments = ImmutableMap.of(path, ImmutableList.of(rcin));
+ gApi.changes().id(c).current().review(rin);
+ }
+
+ // Draft.
+ DraftInput din = new DraftInput();
+ din.path = path;
+ din.line = 1;
+ din.message = "draft";
+ gApi.changes().id(c).current().createDraft(din);
+
+ if (notesMigration.readChanges()) {
+ // Force NoteDb primary.
+ change = ReviewDbUtil.unwrapDb(db).changes().get(id);
+ change.setNoteDbState(NoteDbChangeState.NOTE_DB_PRIMARY_STATE);
+ ReviewDbUtil.unwrapDb(db).changes().update(Collections.singleton(change));
+ indexer.index(db, change);
+ }
+
+ QueryOptions opts = IndexedChangeQuery.createOptions(
+ indexConfig, 0, 1, StalenessChecker.FIELDS);
+ ChangeData cd = indexes.getSearchIndex().get(id, opts).get();
+
+ String cs = RefNames.shard(c);
+ int u = user.get();
+ String us = RefNames.shard(u);
+
+ List<String> expectedStates = Lists.newArrayList(
+ "repo:refs/users/" + us + "/edit-" + c + "/1",
+ "All-Users:refs/starred-changes/" + cs + "/" + u);
+ if (notesMigration.readChanges()) {
+ expectedStates.add("repo:refs/changes/" + cs + "/meta");
+ expectedStates.add("repo:refs/changes/" + cs + "/robot-comments");
+ expectedStates.add("All-Users:refs/draft-comments/" + cs + "/" + u);
+ }
+ assertThat(
+ cd.getRefStates().stream()
+ .map(String::new)
+ // Omit SHA-1, we're just concerned with the project/ref names.
+ .map(s -> s.substring(0, s.lastIndexOf(':')))
+ .collect(toList()))
+ .containsExactlyElementsIn(expectedStates);
+
+ List<String> expectedPatterns = Lists.newArrayList(
+ "repo:refs/users/*/edit-" + c + "/*");
+ if (notesMigration.readChanges()) {
+ expectedPatterns.add("All-Users:refs/starred-changes/" + cs + "/*");
+ expectedPatterns.add("All-Users:refs/draft-comments/" + cs + "/*");
+ }
+ assertThat(
+ cd.getRefStatePatterns().stream()
+ .map(String::new)
+ .collect(toList()))
+ .containsExactlyElementsIn(expectedPatterns);
+ }
+
protected ChangeInserter newChange(TestRepository<Repo> repo)
throws Exception {
return newChange(repo, null, null, null, null);