Merge "Bazel: Add support for toolchain_java11"
diff --git a/Documentation/dev-roles.txt b/Documentation/dev-roles.txt
index d8f3d38..3278b5a 100644
--- a/Documentation/dev-roles.txt
+++ b/Documentation/dev-roles.txt
@@ -253,6 +253,11 @@
responsibilities and live up to the promise of answering incoming
requests in a timely manner.
+Community members may submit new items under the
+link:https://bugs.chromium.org/p/gerrit/issues/list?q=component:ESC[ESC component]
+in the issue tracker, or add that component to existing items, to raise them to
+the attention of ESC members.
+
link:#maintainer[Maintainers] can become steering committee member by
election, or by being appointed by Google (only for the seats that
belong to Google).
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index ea63d73..4279764 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -522,7 +522,9 @@
cfg.setInt("sshd", null, "commandStartThreads", 1);
cfg.setInt("receive", null, "threadPoolSize", 1);
cfg.setInt("index", null, "threads", 1);
- cfg.setBoolean("index", null, "reindexAfterRefUpdate", false);
+ if (cfg.getString("index", null, "reindexAfterRefUpdate") == null) {
+ cfg.setBoolean("index", null, "reindexAfterRefUpdate", false);
+ }
}
private static Injector createTestInjector(Daemon daemon) throws Exception {
diff --git a/java/com/google/gerrit/extensions/api/projects/ProjectApi.java b/java/com/google/gerrit/extensions/api/projects/ProjectApi.java
index 3d70996..c6d9dee 100644
--- a/java/com/google/gerrit/extensions/api/projects/ProjectApi.java
+++ b/java/com/google/gerrit/extensions/api/projects/ProjectApi.java
@@ -201,6 +201,9 @@
*/
void index(boolean indexChildren) throws RestApiException;
+ /** Reindexes all changes of the project. */
+ void indexChanges() throws RestApiException;
+
/**
* A default implementation which allows source compatibility when adding new methods to the
* interface.
@@ -370,5 +373,10 @@
public void index(boolean indexChildren) throws RestApiException {
throw new NotImplementedException();
}
+
+ @Override
+ public void indexChanges() throws RestApiException {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/java/com/google/gerrit/extensions/events/ChangeIndexedListener.java b/java/com/google/gerrit/extensions/events/ChangeIndexedListener.java
index 8dd64ed..64bc022 100644
--- a/java/com/google/gerrit/extensions/events/ChangeIndexedListener.java
+++ b/java/com/google/gerrit/extensions/events/ChangeIndexedListener.java
@@ -20,6 +20,21 @@
@ExtensionPoint
public interface ChangeIndexedListener {
/**
+ * Invoked when a change is scheduled for indexing.
+ *
+ * @param projectName project containing the change
+ * @param id id of the change that was scheduled for indexing
+ */
+ default void onChangeScheduledForIndexing(String projectName, int id) {}
+
+ /**
+ * Invoked when a change is scheduled for deletion from indexing.
+ *
+ * @param id id of the change that was scheduled for deletion from indexing
+ */
+ default void onChangeScheduledForDeletionFromIndex(int id) {}
+
+ /**
* Invoked when a change is indexed.
*
* @param projectName project containing the change
diff --git a/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java b/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
index dc968f6..1ac905d 100644
--- a/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
@@ -43,6 +43,7 @@
import com.google.gerrit.extensions.api.projects.TagApi;
import com.google.gerrit.extensions.api.projects.TagInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.IdString;
@@ -69,6 +70,7 @@
import com.google.gerrit.server.restapi.project.GetHead;
import com.google.gerrit.server.restapi.project.GetParent;
import com.google.gerrit.server.restapi.project.Index;
+import com.google.gerrit.server.restapi.project.IndexChanges;
import com.google.gerrit.server.restapi.project.ListBranches;
import com.google.gerrit.server.restapi.project.ListDashboards;
import com.google.gerrit.server.restapi.project.ListTags;
@@ -124,6 +126,7 @@
private final GetParent getParent;
private final SetParent setParent;
private final Index index;
+ private final IndexChanges indexChanges;
@AssistedInject
ProjectApiImpl(
@@ -158,6 +161,7 @@
GetParent getParent,
SetParent setParent,
Index index,
+ IndexChanges indexChanges,
@Assisted ProjectResource project) {
this(
permissionBackend,
@@ -192,6 +196,7 @@
getParent,
setParent,
index,
+ indexChanges,
null);
}
@@ -228,6 +233,7 @@
GetParent getParent,
SetParent setParent,
Index index,
+ IndexChanges indexChanges,
@Assisted String name) {
this(
permissionBackend,
@@ -262,6 +268,7 @@
getParent,
setParent,
index,
+ indexChanges,
name);
}
@@ -298,6 +305,7 @@
GetParent getParent,
SetParent setParent,
Index index,
+ IndexChanges indexChanges,
String name) {
this.permissionBackend = permissionBackend;
this.createProject = createProject;
@@ -332,6 +340,7 @@
this.setParent = setParent;
this.name = name;
this.index = index;
+ this.indexChanges = indexChanges;
}
@Override
@@ -648,6 +657,15 @@
}
}
+ @Override
+ public void indexChanges() throws RestApiException {
+ try {
+ indexChanges.apply(checkExists(), new Input());
+ } catch (Exception e) {
+ throw asRestApiException("Cannot index changes", e);
+ }
+ }
+
private ProjectResource checkExists() throws ResourceNotFoundException {
if (project == null) {
throw new ResourceNotFoundException(name);
diff --git a/java/com/google/gerrit/server/index/change/ChangeIndexer.java b/java/com/google/gerrit/server/index/change/ChangeIndexer.java
index 07bd963..4a1180c 100644
--- a/java/com/google/gerrit/server/index/change/ChangeIndexer.java
+++ b/java/com/google/gerrit/server/index/change/ChangeIndexer.java
@@ -31,7 +31,9 @@
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
+import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.plugincontext.PluginSetContext;
+import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
@@ -67,6 +69,7 @@
@Nullable private final ChangeIndexCollection indexes;
@Nullable private final ChangeIndex index;
private final ChangeData.Factory changeDataFactory;
+ private final ChangeNotes.Factory notesFactory;
private final ThreadLocalRequestContext context;
private final ListeningExecutorService batchExecutor;
private final ListeningExecutorService executor;
@@ -83,6 +86,7 @@
ChangeIndexer(
@GerritServerConfig Config cfg,
ChangeData.Factory changeDataFactory,
+ ChangeNotes.Factory notesFactory,
ThreadLocalRequestContext context,
PluginSetContext<ChangeIndexedListener> indexedListeners,
StalenessChecker stalenessChecker,
@@ -91,6 +95,7 @@
@Assisted ChangeIndex index) {
this.executor = executor;
this.changeDataFactory = changeDataFactory;
+ this.notesFactory = notesFactory;
this.context = context;
this.indexedListeners = indexedListeners;
this.stalenessChecker = stalenessChecker;
@@ -104,6 +109,7 @@
ChangeIndexer(
@GerritServerConfig Config cfg,
ChangeData.Factory changeDataFactory,
+ ChangeNotes.Factory notesFactory,
ThreadLocalRequestContext context,
PluginSetContext<ChangeIndexedListener> indexedListeners,
StalenessChecker stalenessChecker,
@@ -112,6 +118,7 @@
@Assisted ChangeIndexCollection indexes) {
this.executor = executor;
this.changeDataFactory = changeDataFactory;
+ this.notesFactory = notesFactory;
this.context = context;
this.indexedListeners = indexedListeners;
this.stalenessChecker = stalenessChecker;
@@ -134,6 +141,7 @@
public ListenableFuture<?> indexAsync(Project.NameKey project, Change.Id id) {
IndexTask task = new IndexTask(project, id);
if (queuedIndexTasks.add(task)) {
+ fireChangeScheduledForIndexingEvent(project.get(), id.get());
return submit(task);
}
return Futures.immediateFuture(null);
@@ -159,6 +167,11 @@
* @param cd change to index.
*/
public void index(ChangeData cd) {
+ fireChangeScheduledForIndexingEvent(cd.project().get(), cd.getId().get());
+ doIndex(cd);
+ }
+
+ private void doIndex(ChangeData cd) {
indexImpl(cd);
// Always double-check whether the change might be stale immediately after
@@ -199,10 +212,18 @@
fireChangeIndexedEvent(cd.project().get(), cd.getId().get());
}
+ private void fireChangeScheduledForIndexingEvent(String projectName, int id) {
+ indexedListeners.runEach(l -> l.onChangeScheduledForIndexing(projectName, id));
+ }
+
private void fireChangeIndexedEvent(String projectName, int id) {
indexedListeners.runEach(l -> l.onChangeIndexed(projectName, id));
}
+ private void fireChangeScheduledForDeletionFromIndexEvent(int id) {
+ indexedListeners.runEach(l -> l.onChangeScheduledForDeletionFromIndex(id));
+ }
+
private void fireChangeDeletedFromIndexEvent(int id) {
indexedListeners.runEach(l -> l.onChangeDeleted(id));
}
@@ -233,6 +254,7 @@
* @return future for the deleting task.
*/
public ListenableFuture<?> deleteAsync(Change.Id id) {
+ fireChangeScheduledForDeletionFromIndexEvent(id.get());
return submit(new DeleteTask(id));
}
@@ -242,6 +264,11 @@
* @param id change ID to delete.
*/
public void delete(Change.Id id) {
+ fireChangeScheduledForDeletionFromIndexEvent(id.get());
+ doDelete(id);
+ }
+
+ private void doDelete(Change.Id id) {
new DeleteTask(id).call();
}
@@ -332,8 +359,12 @@
@Override
public Void callImpl() throws Exception {
remove();
- ChangeData cd = changeDataFactory.create(project, id);
- index(cd);
+ try {
+ ChangeNotes changeNotes = notesFactory.createChecked(project, id);
+ doIndex(changeDataFactory.create(changeNotes));
+ } catch (NoSuchChangeException e) {
+ doDelete(id);
+ }
return null;
}
diff --git a/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java b/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
index 21579d2..c429158 100644
--- a/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
+++ b/java/com/google/gerrit/server/index/change/ReindexAfterRefUpdate.java
@@ -17,7 +17,6 @@
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static com.google.gerrit.server.query.change.ChangeData.asChanges;
-import com.google.common.base.Objects;
import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
@@ -34,20 +33,14 @@
import com.google.gerrit.server.git.QueueProvider.QueueType;
import com.google.gerrit.server.index.IndexExecutor;
import com.google.gerrit.server.index.account.AccountIndexer;
-import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.gerrit.server.util.RequestContext;
import com.google.inject.Inject;
import com.google.inject.Provider;
-import java.io.IOException;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import org.eclipse.jgit.lib.Config;
@@ -58,15 +51,12 @@
private final Provider<InternalChangeQuery> queryProvider;
private final ChangeIndexer.Factory indexerFactory;
private final ChangeIndexCollection indexes;
- private final ChangeNotes.Factory notesFactory;
private final AllUsersName allUsersName;
private final AccountCache accountCache;
private final Provider<AccountIndexer> indexer;
private final ListeningExecutorService executor;
private final boolean enabled;
- private final Set<Index> queuedIndexTasks = Collections.newSetFromMap(new ConcurrentHashMap<>());
-
@Inject
ReindexAfterRefUpdate(
@GerritServerConfig Config cfg,
@@ -74,7 +64,6 @@
Provider<InternalChangeQuery> queryProvider,
ChangeIndexer.Factory indexerFactory,
ChangeIndexCollection indexes,
- ChangeNotes.Factory notesFactory,
AllUsersName allUsersName,
AccountCache accountCache,
Provider<AccountIndexer> indexer,
@@ -83,7 +72,6 @@
this.queryProvider = queryProvider;
this.indexerFactory = indexerFactory;
this.indexes = indexes;
- this.notesFactory = notesFactory;
this.allUsersName = allUsersName;
this.accountCache = accountCache;
this.indexer = indexer;
@@ -113,12 +101,9 @@
@Override
public void onSuccess(List<Change> changes) {
for (Change c : changes) {
- Index task = new Index(event, c.getId());
- if (queuedIndexTasks.add(task)) {
- // Don't retry indefinitely; if this fails changes may be stale.
- @SuppressWarnings("unused")
- Future<?> possiblyIgnoredError = executor.submit(task);
- }
+ @SuppressWarnings("unused")
+ Future<?> possiblyIgnoredError =
+ indexerFactory.create(executor, indexes).indexAsync(c.getProject(), c.getId());
}
}
@@ -178,51 +163,4 @@
@Override
protected void remove() {}
}
-
- private class Index extends Task<Void> {
- private final Change.Id id;
-
- Index(Event event, Change.Id id) {
- super(event);
- this.id = id;
- }
-
- @Override
- protected Void impl(RequestContext ctx) throws IOException {
- // Reload change, as some time may have passed since GetChanges.
- remove();
- try {
- Change c =
- notesFactory.createChecked(Project.nameKey(event.getProjectName()), id).getChange();
- indexerFactory.create(executor, indexes).index(c);
- } catch (NoSuchChangeException e) {
- indexerFactory.create(executor, indexes).delete(id);
- }
- return null;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(Index.class, id.get());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof Index)) {
- return false;
- }
- Index other = (Index) obj;
- return id.get() == other.id.get();
- }
-
- @Override
- public String toString() {
- return "Index change " + id.get() + " of project " + event.getProjectName();
- }
-
- @Override
- protected void remove() {
- queuedIndexTasks.remove(this);
- }
- }
}
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 53940a7..cf72874 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -1396,10 +1396,10 @@
Optional<ChangeData> result =
idx.get(id, IndexedChangeQuery.createOptions(indexConfig, 0, 1, ImmutableSet.of()));
- assertThat(result.isPresent()).isTrue();
+ assertThat(result).isPresent();
gApi.changes().id(changeId).delete();
result = idx.get(id, IndexedChangeQuery.createOptions(indexConfig, 0, 1, ImmutableSet.of()));
- assertThat(result.isPresent()).isFalse();
+ assertThat(result).isEmpty();
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
index a9c7d99..e3796c4 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
@@ -24,6 +24,9 @@
import static com.google.gerrit.server.project.ProjectState.OVERRIDDEN_BY_PARENT;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toSet;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -47,6 +50,7 @@
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.extensions.events.ChangeIndexedListener;
import com.google.gerrit.extensions.events.ProjectIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
@@ -54,6 +58,7 @@
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
+import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.group.SystemGroupBackend;
@@ -79,6 +84,7 @@
private static final String JIRA_MATCH = "(jira\\\\s+#?)(\\\\d+)";
@Inject private DynamicSet<ProjectIndexedListener> projectIndexedListeners;
+ @Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
@Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@@ -473,6 +479,26 @@
}
@Test
+ public void reindexChangesOfProject() throws Exception {
+ Change.Id changeId1 = createChange().getChange().getId();
+ Change.Id changeId2 = createChange().getChange().getId();
+
+ ChangeIndexedListener changeIndexedListener = mock(ChangeIndexedListener.class);
+ RegistrationHandle registrationHandle =
+ changeIndexedListeners.add("gerrit", changeIndexedListener);
+ try {
+ gApi.projects().name(project.get()).indexChanges();
+
+ verify(changeIndexedListener, times(1))
+ .onChangeScheduledForIndexing(project.get(), changeId1.get());
+ verify(changeIndexedListener, times(1))
+ .onChangeScheduledForIndexing(project.get(), changeId2.get());
+ } finally {
+ registrationHandle.remove();
+ }
+ }
+
+ @Test
public void maxObjectSizeIsNotSetByDefault() throws Exception {
ConfigInfo info = getConfig();
assertThat(info.maxObjectSizeLimit.value).isNull();
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
index 5892536..49fd781 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
@@ -61,7 +62,7 @@
Optional<FieldBundle> result =
i.getRaw(project, QueryOptions.create(indexConfig, 0, 1, FIELDS));
- assertThat(result.isPresent()).isTrue();
+ assertThat(result).isPresent();
Iterable<byte[]> refState = result.get().getValue(ProjectField.REF_STATE);
assertThat(refState).isNotEmpty();
diff --git a/javatests/com/google/gerrit/acceptance/pgm/BUILD b/javatests/com/google/gerrit/acceptance/pgm/BUILD
index d15c6ce..57b93f6 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/BUILD
+++ b/javatests/com/google/gerrit/acceptance/pgm/BUILD
@@ -30,7 +30,7 @@
"pgm",
"no_windows",
],
- vm_args = ["-Xmx512m"],
+ vm_args = ["-Xmx1024m"],
deps = [
":util",
"//java/com/google/gerrit/elasticsearch",
diff --git a/javatests/com/google/gerrit/acceptance/pgm/InitIT.java b/javatests/com/google/gerrit/acceptance/pgm/InitIT.java
index a573e35..aba0684 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/InitIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/InitIT.java
@@ -14,7 +14,7 @@
package com.google.gerrit.acceptance.pgm;
-import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.NoHttpd;
@@ -43,9 +43,9 @@
QueryOptions opts =
QueryOptions.create(IndexConfig.createDefault(), 0, 1, ImmutableSet.of("name"));
Optional<ProjectData> allProjectsData = projectIndex.getSearchIndex().get(allProjects, opts);
- assertThat(allProjectsData.isPresent()).isTrue();
+ assertThat(allProjectsData).isPresent();
Optional<ProjectData> allUsersData = projectIndex.getSearchIndex().get(allUsers, opts);
- assertThat(allUsersData.isPresent()).isTrue();
+ assertThat(allUsersData).isPresent();
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index c2df9ca..a756c97 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -32,6 +32,10 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.EMPTY_TREE_ID;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -39,6 +43,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
@@ -60,6 +65,7 @@
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.common.LabelInfo;
+import com.google.gerrit.extensions.events.ChangeIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.extensions.restapi.AuthException;
@@ -125,6 +131,7 @@
@Inject private ApprovalsUtil approvalsUtil;
@Inject private DynamicSet<OnSubmitValidationListener> onSubmitValidationListeners;
+ @Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
@Inject private IdentifiedUser.GenericFactory userFactory;
@Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@@ -1210,6 +1217,63 @@
}
}
+ @Test
+ @GerritConfig(name = "index.reindexAfterRefUpdate", value = "true")
+ public void submitSchedulesOpenChangesOfSameBranchForReindexing() throws Throwable {
+ // Create a merged change.
+ PushOneCommit push =
+ pushFactory.create(admin.newIdent(), testRepo, "Merged Change", "foo.txt", "foo");
+ PushOneCommit.Result mergedChange = push.to("refs/for/master");
+ mergedChange.assertOkStatus();
+ approve(mergedChange.getChangeId());
+ submit(mergedChange.getChangeId());
+
+ // Create some open changes.
+ PushOneCommit.Result change1 = createChange();
+ PushOneCommit.Result change2 = createChange();
+ PushOneCommit.Result change3 = createChange();
+
+ // Create a branch with one open change.
+ BranchInput in = new BranchInput();
+ in.revision = projectOperations.project(project).getHead("master").name();
+ gApi.projects().name(project.get()).branch("dev").create(in);
+ PushOneCommit.Result changeOtherBranch = createChange("refs/for/dev");
+
+ ChangeIndexedListener changeIndexedListener = mock(ChangeIndexedListener.class);
+ RegistrationHandle registrationHandle =
+ changeIndexedListeners.add("gerrit", changeIndexedListener);
+ try {
+ // submit a change, this should trigger asynchronous reindexing of the open changes on the
+ // same branch
+ approve(change1.getChangeId());
+ submit(change1.getChangeId());
+ assertThat(gApi.changes().id(change1.getChangeId()).get().status)
+ .isEqualTo(ChangeStatus.MERGED);
+
+ // on submit the change that is submitted gets reindexed synchronously
+ verify(changeIndexedListener, atLeast(1))
+ .onChangeScheduledForIndexing(project.get(), change1.getChange().getId().get());
+ verify(changeIndexedListener, atLeast(1))
+ .onChangeIndexed(project.get(), change1.getChange().getId().get());
+
+ // the open changes on the same branch get reindexed asynchronously
+ verify(changeIndexedListener, times(1))
+ .onChangeScheduledForIndexing(project.get(), change2.getChange().getId().get());
+ verify(changeIndexedListener, times(1))
+ .onChangeScheduledForIndexing(project.get(), change3.getChange().getId().get());
+
+ // merged changes don't get reindexed
+ verify(changeIndexedListener, times(0))
+ .onChangeScheduledForIndexing(project.get(), mergedChange.getChange().getId().get());
+
+ // open changes on other branches don't get reindexed
+ verify(changeIndexedListener, times(0))
+ .onChangeScheduledForIndexing(project.get(), changeOtherBranch.getChange().getId().get());
+ } finally {
+ registrationHandle.remove();
+ }
+ }
+
private void assertSubmitter(PushOneCommit.Result change) throws Throwable {
ChangeInfo info = get(change.getChangeId(), ListChangesOption.MESSAGES);
assertThat(info.messages).isNotNull();
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
index 8ddfa45..a55f17e 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
@@ -15,6 +15,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
@@ -362,8 +363,8 @@
parseCommitMessageRange(commitBefore);
Optional<ChangeNoteUtil.CommitMessageRange> rangeAfter =
parseCommitMessageRange(commitAfter);
- assertThat(rangeBefore.isPresent()).isTrue();
- assertThat(rangeAfter.isPresent()).isTrue();
+ assertThat(rangeBefore).isPresent();
+ assertThat(rangeAfter).isPresent();
String subjectBefore =
decode(
diff --git a/javatests/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java b/javatests/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
index 6e14635..5531709 100644
--- a/javatests/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
@@ -15,6 +15,10 @@
package com.google.gerrit.acceptance.server.mail;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -37,16 +41,17 @@
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
-import org.easymock.EasyMock;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
public class MailProcessorIT extends AbstractMailIT {
@Inject private MailProcessor mailProcessor;
@Inject private AccountOperations accountOperations;
- @Inject private CommentValidator mockCommentValidator;
@Inject private TestCommentHelper testCommentHelper;
+ private static final CommentValidator mockCommentValidator = mock(CommentValidator.class);
+
private static final String COMMENT_TEXT = "The comment text";
@Override
@@ -54,7 +59,6 @@
return new FactoryModule() {
@Override
public void configure() {
- CommentValidator mockCommentValidator = EasyMock.createMock(CommentValidator.class);
bind(CommentValidator.class)
.annotatedWith(Exports.named(mockCommentValidator.getClass()))
.toInstance(mockCommentValidator);
@@ -63,13 +67,15 @@
};
}
+ @BeforeClass
+ public static void setUpMock() {
+ // Let the mock comment validator accept all comments during test setup.
+ when(mockCommentValidator.validateComments(any())).thenReturn(ImmutableList.of());
+ }
+
@Before
public void setUp() {
- // Let the mock comment validator accept all comments during test setup.
- EasyMock.reset(mockCommentValidator);
- EasyMock.expect(mockCommentValidator.validateComments(EasyMock.anyObject()))
- .andReturn(ImmutableList.of());
- EasyMock.replay(mockCommentValidator);
+ clearInvocations(mockCommentValidator);
}
@Test
@@ -268,16 +274,7 @@
MailProcessingUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
- EasyMock.reset(mockCommentValidator);
- CommentForValidation commentForValidation =
- CommentForValidation.create(CommentForValidation.CommentType.CHANGE_MESSAGE, COMMENT_TEXT);
- EasyMock.expect(
- mockCommentValidator.validateComments(
- ImmutableList.of(
- CommentForValidation.create(
- CommentForValidation.CommentType.CHANGE_MESSAGE, COMMENT_TEXT))))
- .andReturn(ImmutableList.of(commentForValidation.failValidation("Oh no!")));
- EasyMock.replay(mockCommentValidator);
+ setupFailValidation(CommentForValidation.CommentType.CHANGE_MESSAGE);
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(getChangeUrl(changeInfo) + "/1", COMMENT_TEXT, null, null, null);
@@ -290,7 +287,6 @@
assertNotifyTo(user);
Message message = sender.nextMessage();
assertThat(message.body()).contains("rejected one or more comments");
- EasyMock.verify(mockCommentValidator);
}
@Test
@@ -302,16 +298,7 @@
MailProcessingUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
- EasyMock.reset(mockCommentValidator);
- CommentForValidation commentForValidation =
- CommentForValidation.create(CommentForValidation.CommentType.CHANGE_MESSAGE, COMMENT_TEXT);
- EasyMock.expect(
- mockCommentValidator.validateComments(
- ImmutableList.of(
- CommentForValidation.create(
- CommentForValidation.CommentType.INLINE_COMMENT, COMMENT_TEXT))))
- .andReturn(ImmutableList.of(commentForValidation.failValidation("Oh no!")));
- EasyMock.replay(mockCommentValidator);
+ setupFailValidation(CommentForValidation.CommentType.INLINE_COMMENT);
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(getChangeUrl(changeInfo) + "/1", null, COMMENT_TEXT, null, null);
@@ -324,7 +311,6 @@
assertNotifyTo(user);
Message message = sender.nextMessage();
assertThat(message.body()).contains("rejected one or more comments");
- EasyMock.verify(mockCommentValidator);
}
@Test
@@ -336,16 +322,7 @@
MailProcessingUtil.rfcDateformatter.format(
ZonedDateTime.ofInstant(comments.get(0).updated.toInstant(), ZoneId.of("UTC")));
- EasyMock.reset(mockCommentValidator);
- CommentForValidation commentForValidation =
- CommentForValidation.create(CommentForValidation.CommentType.CHANGE_MESSAGE, COMMENT_TEXT);
- EasyMock.expect(
- mockCommentValidator.validateComments(
- ImmutableList.of(
- CommentForValidation.create(
- CommentForValidation.CommentType.FILE_COMMENT, COMMENT_TEXT))))
- .andReturn(ImmutableList.of(commentForValidation.failValidation("Oh no!")));
- EasyMock.replay(mockCommentValidator);
+ setupFailValidation(CommentForValidation.CommentType.FILE_COMMENT);
MailMessage.Builder b = messageBuilderWithDefaultFields();
String txt = newPlaintextBody(getChangeUrl(changeInfo) + "/1", null, null, COMMENT_TEXT, null);
@@ -358,10 +335,17 @@
assertNotifyTo(user);
Message message = sender.nextMessage();
assertThat(message.body()).contains("rejected one or more comments");
- EasyMock.verify(mockCommentValidator);
}
private String getChangeUrl(ChangeInfo changeInfo) {
return canonicalWebUrl.get() + "c/" + changeInfo.project + "/+/" + changeInfo._number;
}
+
+ private void setupFailValidation(CommentForValidation.CommentType type) {
+ CommentForValidation commentForValidation = CommentForValidation.create(type, COMMENT_TEXT);
+
+ when(mockCommentValidator.validateComments(
+ ImmutableList.of(CommentForValidation.create(type, COMMENT_TEXT))))
+ .thenReturn(ImmutableList.of(commentForValidation.failValidation("Oh no!")));
+ }
}
diff --git a/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java b/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
index 4f47927..0ad2010 100644
--- a/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.server.quota;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
@@ -104,7 +105,7 @@
assertThrows(
NullPointerException.class,
() -> quotaBackend.user(identifiedAdmin).requestToken("testGroup"));
- assertThat(exception).isEqualTo(thrown);
+ assertThat(thrown).isEqualTo(exception);
verify(quotaEnforcerA);
}
@@ -136,7 +137,7 @@
OptionalLong tokens =
quotaBackend.user(identifiedAdmin).availableTokens("testGroup").availableTokens();
- assertThat(tokens.isPresent()).isTrue();
+ assertThat(tokens).isPresent();
assertThat(tokens.getAsLong()).isEqualTo(10L);
}
@@ -151,7 +152,7 @@
OptionalLong tokens =
quotaBackend.user(identifiedAdmin).availableTokens("testGroup").availableTokens();
- assertThat(tokens.isPresent()).isTrue();
+ assertThat(tokens).isPresent();
assertThat(tokens.getAsLong()).isEqualTo(20L);
}
}
diff --git a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
index 7a1cf51..ee75153 100644
--- a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
+++ b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
@@ -15,6 +15,9 @@
package com.google.gerrit.server.extensions.webui;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -35,7 +38,6 @@
import java.util.Collection;
import java.util.Map;
import java.util.Set;
-import org.easymock.EasyMock;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.junit.Test;
@@ -131,9 +133,7 @@
// Set up the Mock to expect a call of bulkEvaluateTest to only contain cond{1,2} since cond3
// needs to be identified as duplicate and not called out explicitly.
- PermissionBackend permissionBackendMock = EasyMock.createMock(PermissionBackend.class);
- permissionBackendMock.bulkEvaluateTest(ImmutableSet.of(cond1, cond2));
- EasyMock.replay(permissionBackendMock);
+ PermissionBackend permissionBackendMock = mock(PermissionBackend.class);
UiActions.evaluatePermissionBackendConditions(
permissionBackendMock, ImmutableList.of(cond1, cond2, cond3));
@@ -142,6 +142,8 @@
// the value of cond1 and issues no additional call to PermissionBackend.
forProject.disallowValueQueries();
+ verify(permissionBackendMock, only()).bulkEvaluateTest(ImmutableSet.of(cond1, cond2));
+
// Assert the values of all conditions
assertThat(cond1.value()).isFalse();
assertThat(cond2.value()).isTrue();
diff --git a/javatests/com/google/gerrit/server/project/GroupListTest.java b/javatests/com/google/gerrit/server/project/GroupListTest.java
index 5ccefa0..7d6a2c3 100644
--- a/javatests/com/google/gerrit/server/project/GroupListTest.java
+++ b/javatests/com/google/gerrit/server/project/GroupListTest.java
@@ -14,16 +14,14 @@
package com.google.gerrit.server.project;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -48,8 +46,7 @@
@Before
public void setup() throws IOException {
- ValidationError.Sink sink = createNiceMock(ValidationError.Sink.class);
- replay(sink);
+ ValidationError.Sink sink = mock(ValidationError.Sink.class);
groupList = GroupList.parse(PROJECT, TEXT, sink);
}
@@ -97,12 +94,9 @@
@Test
public void validationError() throws Exception {
- ValidationError.Sink sink = createMock(ValidationError.Sink.class);
- sink.error(anyObject(ValidationError.class));
- expectLastCall().times(2);
- replay(sink);
+ ValidationError.Sink sink = mock(ValidationError.Sink.class);
groupList = GroupList.parse(PROJECT, TEXT.replace("\t", " "), sink);
- verify(sink);
+ verify(sink, times(2)).error(any(ValidationError.class));
}
@Test
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index b0555ca..20f3bb9 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -2115,6 +2115,12 @@
gApi.changes().id(change1.getChangeId()).current().review(ReviewInput.approve());
gApi.changes().id(change1.getChangeId()).current().submit();
+ // If a change gets submitted, the remaining open changes get reindexed asynchronously to update
+ // their mergeability information. If the further assertions in this test are done before the
+ // asynchronous reindex completed they fail because the mergeability information in the index
+ // was not updated yet. To avoid this flakiness we index change2 synchronously here.
+ gApi.changes().id(change2.getChangeId()).index();
+
assertQuery("status:open conflicts:" + change2.getId().get());
assertQuery("status:open is:mergeable");
assertQuery("status:open -is:mergeable", change2);
diff --git a/javatests/com/google/gerrit/server/rules/BUILD b/javatests/com/google/gerrit/server/rules/BUILD
index 62d9a79..2545431 100644
--- a/javatests/com/google/gerrit/server/rules/BUILD
+++ b/javatests/com/google/gerrit/server/rules/BUILD
@@ -15,6 +15,7 @@
"//lib:guava",
"//lib/guice",
"//lib/jgit/org.eclipse.jgit:jgit",
+ "//lib/mockito",
"//lib/prolog:runtime",
"//lib/truth",
"//prolog:gerrit-prolog-common",
diff --git a/javatests/com/google/gerrit/server/rules/GerritCommonTest.java b/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
index be0b8e7..9d7afbc 100644
--- a/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
+++ b/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
@@ -16,7 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import static org.easymock.EasyMock.expect;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.server.project.testing.TestLabels;
@@ -31,7 +32,6 @@
import java.io.PushbackReader;
import java.io.StringReader;
import java.util.Arrays;
-import org.easymock.EasyMock;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
@@ -60,9 +60,8 @@
protected void setUpEnvironment(PrologEnvironment env) throws Exception {
LabelTypes labelTypes =
new LabelTypes(Arrays.asList(TestLabels.codeReview(), TestLabels.verified()));
- ChangeData cd = EasyMock.createMock(ChangeData.class);
- expect(cd.getLabelTypes()).andStubReturn(labelTypes);
- EasyMock.replay(cd);
+ ChangeData cd = mock(ChangeData.class);
+ when(cd.getLabelTypes()).thenReturn(labelTypes);
env.set(StoredValues.CHANGE_DATA, cd);
}
diff --git a/plugins/replication b/plugins/replication
index f1e84b0..5a3519e 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit f1e84b0738b60d89d8bd710e58ebba4eac61b770
+Subproject commit 5a3519e6e1733e2515900866b8db9ca98ba9da7e
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
index 6962121..a019388 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
@@ -83,16 +83,11 @@
};
GrDiffBuilder.ContextButtonType = {
- STEP: 'step',
+ ABOVE: 'above',
+ BELOW: 'below',
ALL: 'all',
};
- const ContextPlacement = {
- LAST: 'last',
- FIRST: 'first',
- MIDDLE: 'middle',
- };
-
const PARTIAL_CONTEXT_AMOUNT = 10;
/**
@@ -236,53 +231,40 @@
group => { return group.element; });
};
- /**
- * @param {!Array<!Object>} contextGroups (!Array<!GrDiffGroup>)
- */
- GrDiffBuilder.prototype._getContextControlPlacementFor = function(
- contextGroups) {
- const firstContextGroup = contextGroups[0];
- const lastContextGroup = contextGroups[contextGroups.length - 1];
- const firstLines = firstContextGroup.lines;
- const lastLines = lastContextGroup.lines;
- const firstContextInFile = firstLines.length && firstLines[0].firstInFile;
- const lastContextInFile = lastLines.length &&
- lastLines[lastLines.length - 1].lastInFile;
- if (firstContextInFile && !lastContextInFile) {
- return ContextPlacement.FIRST;
- } else if (lastContextInFile && !firstContextInFile) {
- return ContextPlacement.LAST;
- }
- return ContextPlacement.MIDDLE;
- };
-
GrDiffBuilder.prototype._createContextControl = function(section, line) {
- const contextGroups = line.contextGroups;
- if (!contextGroups) return null;
- const numLines = contextGroups[contextGroups.length - 1].lineRange.left.end
- - contextGroups[0].lineRange.left.start + 1;
+ if (!line.contextGroups) return null;
+
+ const numLines =
+ line.contextGroups[line.contextGroups.length - 1].lineRange.left.end -
+ line.contextGroups[0].lineRange.left.start + 1;
+
if (numLines === 0) return null;
- const contextPlacement = this._getContextControlPlacementFor(contextGroups);
- const isStepBidirectional = (contextPlacement === ContextPlacement.MIDDLE);
- const minimalForStepExpansion = isStepBidirectional ?
- PARTIAL_CONTEXT_AMOUNT * 2 : PARTIAL_CONTEXT_AMOUNT;
- const showStepExpansion = numLines > minimalForStepExpansion;
-
const td = this._createElement('td');
- if (showStepExpansion) {
+ const showPartialLinks = numLines > PARTIAL_CONTEXT_AMOUNT;
+
+ if (showPartialLinks) {
td.appendChild(this._createContextButton(
- GrDiffBuilder.ContextButtonType.STEP, section, line,
- numLines, contextPlacement));
+ GrDiffBuilder.ContextButtonType.ABOVE, section, line, numLines));
+ td.appendChild(document.createTextNode(' - '));
}
+
td.appendChild(this._createContextButton(
GrDiffBuilder.ContextButtonType.ALL, section, line, numLines));
+ if (showPartialLinks) {
+ td.appendChild(document.createTextNode(' - '));
+ td.appendChild(this._createContextButton(
+ GrDiffBuilder.ContextButtonType.BELOW, section, line, numLines));
+ }
+
return td;
};
GrDiffBuilder.prototype._createContextButton = function(type, section, line,
- numLines, contextPlacement) {
+ numLines) {
+ const context = PARTIAL_CONTEXT_AMOUNT;
+
const button = this._createElement('gr-button', 'showContext');
button.setAttribute('link', true);
button.setAttribute('no-uppercase', true);
@@ -294,14 +276,14 @@
text = 'Show ' + numLines + ' common line';
if (numLines > 1) { text += 's'; }
groups.push(...line.contextGroups);
- } else if (type === GrDiffBuilder.ContextButtonType.STEP) {
- const linesToShowAbove = contextPlacement === ContextPlacement.FIRST ?
- 0 : PARTIAL_CONTEXT_AMOUNT;
- const linesToShowBelow = contextPlacement === ContextPlacement.LAST ?
- 0 : PARTIAL_CONTEXT_AMOUNT;
- text = '+' + PARTIAL_CONTEXT_AMOUNT + ' Lines';
- groups = GrDiffGroup.hideInContextControl(
- line.contextGroups, linesToShowAbove, numLines - linesToShowBelow);
+ } else if (type === GrDiffBuilder.ContextButtonType.ABOVE) {
+ text = '+' + context + '↑';
+ groups = GrDiffGroup.hideInContextControl(line.contextGroups,
+ context, numLines);
+ } else if (type === GrDiffBuilder.ContextButtonType.BELOW) {
+ text = '+' + context + '↓';
+ groups = GrDiffGroup.hideInContextControl(line.contextGroups,
+ 0, numLines - context);
}
Polymer.dom(button).textContent = text;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
index 49fdc06..b917845 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
@@ -89,92 +89,44 @@
assert.isTrue(node.classList.contains('classes'));
});
- function assertContextControl(buttons, expectedButtons) {
- const actualButtonLabels = buttons.map(
- b => Polymer.dom(b).textContent);
- assert.deepEqual(actualButtonLabels, expectedButtons);
- }
-
- function createContextControl({numLines,
- firstInFile, lastInFile,
- expectStepExpansion}) {
+ test('context control buttons', () => {
+ // Create 10 lines.
const lines = [];
- for (let i = 0; i < numLines; i++) {
+ for (let i = 0; i < 10; i++) {
const line = new GrDiffLine(GrDiffLine.Type.BOTH);
line.beforeNumber = i + 1;
line.afterNumber = i + 1;
line.text = 'lorem upsum';
lines.push(line);
}
- lines[0].firstInFile = !!firstInFile;
- lines[lines.length - 1].lastInFile = !!lastInFile;
+
const contextLine = {
contextGroups: [new GrDiffGroup(GrDiffGroup.Type.BOTH, lines)],
};
+
const section = {};
- const td = builder._createContextControl(section, contextLine);
- return [...td.querySelectorAll('gr-button.showContext')];
- }
-
- function getGroupsAfterExpanding(button) {
- let newGroups;
- button.addEventListener('tap', e => { newGroups = e.detail.groups; });
- MockInteractions.tap(button);
- return newGroups;
- }
-
- test('context control buttons in the middle of the file', () => {
- // Does not include +10 buttons when there are fewer than 21 lines.
- let buttons = createContextControl({numLines: 20});
- assertContextControl(buttons, ['Show 20 common lines']);
-
- // Includes +10 buttons when there are at least 21 lines.
- buttons = createContextControl({numLines: 21});
- assertContextControl(buttons, ['+10 Lines', 'Show 21 common lines']);
-
- // When clicked with 22 Lines expands in both directions with remaining context in the middle.
-
- buttons = createContextControl({numLines: 22});
- assertContextControl(buttons, ['+10 Lines', 'Show 22 common lines']);
- const newGroupTypes = getGroupsAfterExpanding(buttons[0]).map(g => g.type);
- assert.deepEqual(newGroupTypes,
- [GrDiffLine.Type.BOTH, GrDiffLine.Type.CONTEXT_CONTROL,
- GrDiffLine.Type.BOTH]);
- });
-
- test('context control buttons in the beginning of the file', () => {
// Does not include +10 buttons when there are fewer than 11 lines.
- let buttons = createContextControl({numLines: 10, firstInFile: true});
- assertContextControl(buttons, ['Show 10 common lines']);
+ let td = builder._createContextControl(section, contextLine);
+ let buttons = td.querySelectorAll('gr-button.showContext');
- // Includes +10 button when there are at least 11 lines.
- buttons = createContextControl({numLines: 11, firstInFile: true});
- assertContextControl(buttons, ['+10 Lines', 'Show 11 common lines']);
+ assert.equal(buttons.length, 1);
+ assert.equal(Polymer.dom(buttons[0]).textContent, 'Show 10 common lines');
- // When clicked with 12 Lines expands only up and remaining context in the beginning of the file.
- buttons = createContextControl({numLines: 12, firstInFile: true});
- assertContextControl(buttons, ['+10 Lines', 'Show 12 common lines']);
- const newGroupTypes = getGroupsAfterExpanding(buttons[0]).map(g => g.type);
- assert.deepEqual(newGroupTypes,
- [GrDiffLine.Type.CONTEXT_CONTROL, GrDiffLine.Type.BOTH]);
- });
+ // Add another line.
+ const line = new GrDiffLine(GrDiffLine.Type.BOTH);
+ line.text = 'lorem upsum';
+ line.beforeNumber = 11;
+ line.afterNumber = 11;
+ contextLine.contextGroups[0].addLine(line);
- test('context control buttons in the end of the file', () => {
- // Does not include +10 buttons when there are fewer than 11 lines.
- let buttons = createContextControl({numLines: 10, lastInFile: true});
- assertContextControl(buttons, ['Show 10 common lines']);
+ // Includes +10 buttons when there are at least 11 lines.
+ td = builder._createContextControl(section, contextLine);
+ buttons = td.querySelectorAll('gr-button.showContext');
- // Includes +10 button when there are at least 11 lines.
- buttons = createContextControl({numLines: 11, lastInFile: true});
- assertContextControl(buttons, ['+10 Lines', 'Show 11 common lines']);
-
- // When clicked with 12 Lines expands only up and remaining context in the beginning of the file.
- buttons = createContextControl({numLines: 12, lastInFile: true});
- assertContextControl(buttons, ['+10 Lines', 'Show 12 common lines']);
- // When clicked with 12 Lines expands only down and remaining context in the end of the file.
- const newGroupTypes = getGroupsAfterExpanding(buttons[0]).map(g => g.type);
- assert.deepEqual(newGroupTypes, [GrDiffLine.Type.BOTH,
- GrDiffLine.Type.CONTEXT_CONTROL]);
+ assert.equal(buttons.length, 3);
+ assert.equal(Polymer.dom(buttons[0]).textContent, '+10↑');
+ assert.equal(Polymer.dom(buttons[1]).textContent, 'Show 11 common lines');
+ assert.equal(Polymer.dom(buttons[2]).textContent, '+10↓');
});
test('newlines 1', () => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
index 65d81bf..104c0c2 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
@@ -305,6 +305,7 @@
// Stub the network calls into requests that never resolve.
sandbox.stub(element, '_getDiff', () => new Promise(() => {}));
+ element.patchRange = {};
element.reload();
assert.isTrue(cancelStub.called);
@@ -368,6 +369,7 @@
(changeNum, basePatchNum, patchNum, path, onErr) => {
onErr(error);
});
+ element.patchRange = {};
return element.reload().then(() => {
assert.isTrue(onErrStub.calledOnce);
});
@@ -725,6 +727,7 @@
test('delegates cancel()', () => {
const stub = sandbox.stub(element.$.diff, 'cancel');
+ element.patchRange = {};
element.reload();
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
@@ -1243,9 +1246,11 @@
const l = document.createElement('div');
l.setAttribute('comment-side', 'left');
+ l.setAttribute('line-num', 'FILE');
const r = document.createElement('div');
r.setAttribute('comment-side', 'right');
+ r.setAttribute('line-num', 'FILE');
const threadEls = [l, r];
assert.deepEqual(element._filterThreadElsForLocation(threadEls, line),
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
index d1c58b2..d4b4e2b 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
@@ -66,6 +66,7 @@
ADDED: 'edit_b',
REMOVED: 'edit_a',
};
+
/**
* The maximum size for an addition or removal chunk before it is broken down
* into a series of chunks that are this size at most.
@@ -268,8 +269,7 @@
right: this._linesRight(chunk).length,
},
groups: [this._chunkToGroup(
- chunk, state.lineNums.left + 1, state.lineNums.right + 1,
- /* firstInFile */ false, /* lastInFile */ false)],
+ chunk, state.lineNums.left + 1, state.lineNums.right + 1)],
newChunkIndex: state.chunkIndex + 1,
};
}
@@ -321,13 +321,10 @@
const lineCount = collapsibleChunks.reduce(
(sum, chunk) => sum + this._commonChunkLength(chunk), 0);
- const firstChunk = state.chunkIndex === 0;
- const lastChunk = state.chunkIndex === chunks.length - 1;
let groups = this._chunksToGroups(
collapsibleChunks,
state.lineNums.left + 1,
- state.lineNums.right + 1,
- firstChunk, lastChunk);
+ state.lineNums.right + 1);
if (this.context !== WHOLE_FILE) {
const hiddenStart = state.chunkIndex === 0 ? 0 : this.context;
@@ -360,17 +357,11 @@
* @param {!Array<!Object>} chunks
* @param {number} offsetLeft
* @param {number} offsetRight
- * @param {boolean} firstProcessed
- * @param {boolean} lastProcessed
* @return {!Array<!Object>} (GrDiffGroup)
*/
- _chunksToGroups(chunks, offsetLeft, offsetRight, firstProcessed,
- lastProcessed) {
- return chunks.map((chunk, index) => {
- const firstInFile = firstProcessed && index === 0;
- const lastInFile = lastProcessed && index === chunks.length - 1;
- const group = this._chunkToGroup(chunk, offsetLeft,
- offsetRight, firstInFile, lastInFile);
+ _chunksToGroups(chunks, offsetLeft, offsetRight) {
+ return chunks.map(chunk => {
+ const group = this._chunkToGroup(chunk, offsetLeft, offsetRight);
const chunkLength = this._commonChunkLength(chunk);
offsetLeft += chunkLength;
offsetRight += chunkLength;
@@ -384,10 +375,9 @@
* @param {number} offsetRight
* @return {!Object} (GrDiffGroup)
*/
- _chunkToGroup(chunk, offsetLeft, offsetRight, firstInFile, lastInFile) {
+ _chunkToGroup(chunk, offsetLeft, offsetRight) {
const type = chunk.ab ? GrDiffGroup.Type.BOTH : GrDiffGroup.Type.DELTA;
- const lines = this._linesFromChunk(chunk, offsetLeft, offsetRight,
- firstInFile, lastInFile);
+ const lines = this._linesFromChunk(chunk, offsetLeft, offsetRight);
const group = new GrDiffGroup(type, lines);
group.keyLocation = chunk.keyLocation;
group.dueToRebase = chunk.due_to_rebase;
@@ -395,30 +385,25 @@
return group;
},
- _linesFromChunk(chunk, offsetLeft, offsetRight, firstInFile, lastInFile) {
- let lines = [];
+ _linesFromChunk(chunk, offsetLeft, offsetRight) {
if (chunk.ab) {
- lines = chunk.ab.map((row, i) => this._lineFromRow(
+ return chunk.ab.map((row, i) => this._lineFromRow(
GrDiffLine.Type.BOTH, offsetLeft, offsetRight, row, i));
- } else {
- if (chunk.a) {
- // Avoiding a.push(...b) because that causes callstack overflows for
- // large b, which can occur when large files are added removed.
- lines = lines.concat(this._linesFromRows(
- GrDiffLine.Type.REMOVE, chunk.a, offsetLeft,
- chunk[DiffHighlights.REMOVED]));
- }
- if (chunk.b) {
- // Avoiding a.push(...b) because that causes callstack overflows for
- // large b, which can occur when large files are added removed.
- lines = lines.concat(this._linesFromRows(
- GrDiffLine.Type.ADD, chunk.b, offsetRight,
- chunk[DiffHighlights.ADDED]));
- }
}
- if (lines.length > 0) {
- lines[0].firstInFile = firstInFile;
- lines[lines.length - 1].lastInFile = lastInFile;
+ let lines = [];
+ if (chunk.a) {
+ // Avoiding a.push(...b) because that causes callstack overflows for
+ // large b, which can occur when large files are added removed.
+ lines = lines.concat(this._linesFromRows(
+ GrDiffLine.Type.REMOVE, chunk.a, offsetLeft,
+ chunk[DiffHighlights.REMOVED]));
+ }
+ if (chunk.b) {
+ // Avoiding a.push(...b) because that causes callstack overflows for
+ // large b, which can occur when large files are added removed.
+ lines = lines.concat(this._linesFromRows(
+ GrDiffLine.Type.ADD, chunk.b, offsetRight,
+ chunk[DiffHighlights.ADDED]));
}
return lines;
},
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.js
index 49d583f..b64385d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-line.js
@@ -44,12 +44,6 @@
this.contextGroups = null;
this.text = '';
-
- /** @type {boolean} */
- this.firstInFile = false;
-
- /** @type {boolean} */
- this.lastInFile = false;
}
GrDiffLine.Type = {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
index a9755ce..bc8af9d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
@@ -187,8 +187,6 @@
}
.contextControl gr-button {
display: inline-block;
- margin-left: 1em;
- margin-right: 1em;
text-decoration: none;
--gr-button: {
color: var(--diff-context-control-color);
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index 6cdac42..f5a64dc 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -111,8 +111,7 @@
'diff/gr-diff-cursor/gr-diff-cursor_test.html',
'diff/gr-diff-highlight/gr-annotation_test.html',
'diff/gr-diff-highlight/gr-diff-highlight_test.html',
- // TODO: uncomment file & fix tests. The file was missed in this list for a long time.
- // 'diff/gr-diff-host/gr-diff-host_test.html',
+ 'diff/gr-diff-host/gr-diff-host_test.html',
'diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html',
'diff/gr-diff-processor/gr-diff-processor_test.html',
'diff/gr-diff-selection/gr-diff-selection_test.html',