Merge "RestCollection: Allow throwing any RestApiException from list() method"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 4bfd2a4..3f97120 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2994,10 +2994,13 @@
=== Section elasticsearch
WARNING: The Elasticsearch support has only been tested with Elasticsearch
-version 2.4.x. Support for other versions is not guaranteed.
+versions 2.4, 5.6 and 6.2. Support for other versions is not guaranteed.
-Open and closed changes are indexed in a single index, separated
-into types `open_changes` and `closed_changes` respectively.
+Open and closed changes are indexed in a single index, separated into types
+`open_changes` and `closed_changes` respectively, if using Elasticsearch
+versions 2.4 or 5.6. Open and closed changes are merged into the default `_doc`
+type otherwise. The latter is also used for accounts and groups indices starting
+with Elasticsearch 6.2.
[[elasticsearch.prefix]]elasticsearch.prefix::
+
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index fea2f8c..055ebcb 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -274,6 +274,15 @@
* server
* ssh
+[[elasticsearch]]
+=== Elasticsearch
+
+Successfully running the elasticsearch tests may require setting the local
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html[virtual memory].
+
+Bazel link:https://github.com/bazelbuild/bazel/issues/3476[does not currently make container failures visible],
+if any.
+
== Dependencies
Dependency JARs are normally downloaded as needed, but you can
@@ -382,16 +391,6 @@
details. Users should watch the cache sizes and clean them manually if
necessary.
-Due to the `--experimental_strict_action_env` option used in `bazelrc`
-it is possible that some commands required by the build are not found
-on the PATH, causing the build to fail. In this case the PATH used in
-the build can be overridden with the `--action_env=PATH` directive in
-the user's `~/.bazelrc` file, for example:
-
-----
- build --action_env=PATH=/usr/local/opt/coreutils/libexec/gnubin/:/usr/local/bin/:/usr/bin/
-----
-
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index ac7be2c..8d1b2d8 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -5809,7 +5809,8 @@
The name of the target branch. +
The `refs/heads/` prefix is omitted.
|`subject` ||
-The subject of the change (header line of the commit message).
+The commit message of the change. Comment lines (beginning with `#`) will
+be removed.
|`topic` |optional|The topic to which this change belongs.
|`status` |optional, default to `NEW`|
The status of the change (only `NEW` accepted here).
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 453712a..0ccd820 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -25,6 +25,7 @@
import com.google.common.collect.Lists;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.CharStreams;
+import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
import com.google.gerrit.elasticsearch.builders.QueryBuilder;
import com.google.gerrit.elasticsearch.builders.SearchSourceBuilder;
import com.google.gerrit.elasticsearch.bulk.DeleteRequest;
@@ -75,6 +76,7 @@
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
protected static final String BULK = "_bulk";
+ protected static final String MAPPINGS = "mappings";
protected static final String ORDER = "order";
protected static final String SEARCH = "_search";
@@ -105,6 +107,7 @@
private final SitePaths sitePaths;
private final String indexNameRaw;
+ protected final String type;
protected final ElasticRestClientProvider client;
protected final String indexName;
protected final Gson gson;
@@ -123,6 +126,7 @@
this.indexName = cfg.getIndexName(indexName, schema.getVersion());
this.indexNameRaw = indexName;
this.client = client;
+ this.type = client.adapter().getType(indexName);
}
@Override
@@ -142,7 +146,7 @@
@Override
public void delete(K id) throws IOException {
- String uri = getURI(indexNameRaw, BULK);
+ String uri = getURI(type, BULK);
Response response = postRequest(getDeleteActions(id), uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
@@ -181,8 +185,20 @@
protected abstract String getId(V v);
+ protected String getMappingsForSingleType(String candidateType, MappingProperties properties) {
+ return getMappingsFor(client.adapter().getType(candidateType), properties);
+ }
+
+ protected String getMappingsFor(String type, MappingProperties properties) {
+ JsonObject mappingType = new JsonObject();
+ mappingType.add(type, gson.toJsonTree(properties));
+ JsonObject mappings = new JsonObject();
+ mappings.add(MAPPINGS, gson.toJsonTree(mappingType));
+ return gson.toJson(mappings);
+ }
+
protected String delete(String type, K id) {
- return new DeleteRequest(id.toString(), indexName, type).toString();
+ return new DeleteRequest(id.toString(), indexName, type, client.adapter()).toString();
}
protected abstract V fromDocument(JsonObject doc, Set<String> fields);
diff --git a/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
index c212a8b..58f4fb9 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
@@ -16,7 +16,6 @@
import static com.google.gerrit.server.index.account.AccountField.ID;
-import com.google.common.collect.ImmutableMap;
import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
import com.google.gerrit.elasticsearch.bulk.BulkRequest;
import com.google.gerrit.elasticsearch.bulk.IndexRequest;
@@ -76,9 +75,10 @@
@Override
public void replace(AccountState as) throws IOException {
BulkRequest bulk =
- new IndexRequest(getId(as), indexName, ACCOUNTS).add(new UpdateRequest<>(schema, as));
+ new IndexRequest(getId(as), indexName, type, client.adapter())
+ .add(new UpdateRequest<>(schema, as));
- String uri = getURI(ACCOUNTS, BULK);
+ String uri = getURI(type, BULK);
Response response = postRequest(bulk, uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
@@ -99,13 +99,12 @@
@Override
protected String getDeleteActions(Account.Id a) {
- return delete(ACCOUNTS, a);
+ return delete(type, a);
}
@Override
protected String getMappings() {
- ImmutableMap<String, AccountMapping> mappings = ImmutableMap.of("mappings", mapping);
- return gson.toJson(mappings);
+ return getMappingsForSingleType(ACCOUNTS, mapping.accounts);
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index ccf15d7..1ec8d2b 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -76,11 +76,13 @@
class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
implements ChangeIndex {
static class ChangeMapping {
+ MappingProperties changes;
MappingProperties openChanges;
MappingProperties closedChanges;
ChangeMapping(Schema<ChangeData> schema, ElasticQueryAdapter adapter) {
MappingProperties mapping = ElasticMapping.createMapping(schema, adapter);
+ this.changes = mapping;
this.openChanges = mapping;
this.closedChanges = mapping;
}
@@ -127,12 +129,15 @@
throw new IOException(e);
}
+ ElasticQueryAdapter adapter = client.adapter();
BulkRequest bulk =
- new IndexRequest(getId(cd), indexName, insertIndex)
- .add(new UpdateRequest<>(schema, cd))
- .add(new DeleteRequest(cd.getId().toString(), indexName, deleteIndex));
+ new IndexRequest(getId(cd), indexName, adapter.getType(insertIndex), adapter)
+ .add(new UpdateRequest<>(schema, cd));
+ if (!adapter.usePostV5Type()) {
+ bulk.add(new DeleteRequest(cd.getId().toString(), indexName, deleteIndex, adapter));
+ }
- String uri = getURI(CHANGES, BULK);
+ String uri = getURI(type, BULK);
Response response = postRequest(bulk, uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
@@ -147,11 +152,18 @@
throws QueryParseException {
Set<Change.Status> statuses = ChangeIndexRewriter.getPossibleStatus(p);
List<String> indexes = Lists.newArrayListWithCapacity(2);
- if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
- indexes.add(OPEN_CHANGES);
- }
- if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
- indexes.add(CLOSED_CHANGES);
+ if (client.adapter().usePostV5Type()) {
+ if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()
+ || !Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
+ indexes.add(ElasticQueryAdapter.POST_V5_TYPE);
+ }
+ } else {
+ if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
+ indexes.add(OPEN_CHANGES);
+ }
+ if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
+ indexes.add(CLOSED_CHANGES);
+ }
}
QueryOptions filteredOpts = opts.filterFields(IndexUtils::changeFields);
@@ -175,12 +187,18 @@
@Override
protected String getDeleteActions(Id c) {
+ if (client.adapter().usePostV5Type()) {
+ return delete(ElasticQueryAdapter.POST_V5_TYPE, c);
+ }
return delete(OPEN_CHANGES, c) + delete(CLOSED_CHANGES, c);
}
@Override
protected String getMappings() {
- return gson.toJson(ImmutableMap.of("mappings", mapping));
+ if (client.adapter().usePostV5Type()) {
+ return getMappingsFor(ElasticQueryAdapter.POST_V5_TYPE, mapping.changes);
+ }
+ return gson.toJson(ImmutableMap.of(MAPPINGS, mapping));
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java b/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
index d2de01e..cf1a4ed 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
@@ -14,7 +14,6 @@
package com.google.gerrit.elasticsearch;
-import com.google.common.collect.ImmutableMap;
import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
import com.google.gerrit.elasticsearch.bulk.BulkRequest;
import com.google.gerrit.elasticsearch.bulk.IndexRequest;
@@ -74,9 +73,10 @@
@Override
public void replace(InternalGroup group) throws IOException {
BulkRequest bulk =
- new IndexRequest(getId(group), indexName, GROUPS).add(new UpdateRequest<>(schema, group));
+ new IndexRequest(getId(group), indexName, type, client.adapter())
+ .add(new UpdateRequest<>(schema, group));
- String uri = getURI(GROUPS, BULK);
+ String uri = getURI(type, BULK);
Response response = postRequest(bulk, uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
@@ -96,13 +96,12 @@
@Override
protected String getDeleteActions(AccountGroup.UUID g) {
- return delete(GROUPS, g);
+ return delete(type, g);
}
@Override
protected String getMappings() {
- ImmutableMap<String, GroupMapping> mappings = ImmutableMap.of("mappings", mapping);
- return gson.toJson(mappings);
+ return getMappingsForSingleType(GROUPS, mapping.groups);
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java b/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
index dfb1c5d..623f62c 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
@@ -14,7 +14,6 @@
package com.google.gerrit.elasticsearch;
-import com.google.common.collect.ImmutableMap;
import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
import com.google.gerrit.elasticsearch.bulk.BulkRequest;
import com.google.gerrit.elasticsearch.bulk.IndexRequest;
@@ -74,10 +73,10 @@
@Override
public void replace(ProjectData projectState) throws IOException {
BulkRequest bulk =
- new IndexRequest(projectState.getProject().getName(), indexName, PROJECTS)
+ new IndexRequest(projectState.getProject().getName(), indexName, type, client.adapter())
.add(new UpdateRequest<>(schema, projectState));
- String uri = getURI(PROJECTS, BULK);
+ String uri = getURI(type, BULK);
Response response = postRequest(bulk, uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
@@ -92,19 +91,17 @@
public DataSource<ProjectData> getSource(Predicate<ProjectData> p, QueryOptions opts)
throws QueryParseException {
JsonArray sortArray = getSortArray(ProjectField.NAME.getName());
- return new ElasticQuerySource(
- p, opts.filterFields(IndexUtils::projectFields), PROJECTS, sortArray);
+ return new ElasticQuerySource(p, opts.filterFields(IndexUtils::projectFields), type, sortArray);
}
@Override
protected String getDeleteActions(Project.NameKey nameKey) {
- return delete(PROJECTS, nameKey);
+ return delete(type, nameKey);
}
@Override
protected String getMappings() {
- ImmutableMap<String, ProjectMapping> mappings = ImmutableMap.of("mappings", mapping);
- return gson.toJson(mappings);
+ return getMappingsForSingleType(PROJECTS, mapping.projects);
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
index b6cbf2f..3201289 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
@@ -17,7 +17,11 @@
import com.google.gson.JsonObject;
public class ElasticQueryAdapter {
+ static final String POST_V5_TYPE = "_doc";
+
private final boolean ignoreUnmapped;
+ private final boolean usePostV5Type;
+
private final String searchFilteringName;
private final String indicesExistParam;
private final String exactFieldType;
@@ -27,6 +31,8 @@
ElasticQueryAdapter(ElasticVersion version) {
this.ignoreUnmapped = version == ElasticVersion.V2_4;
+ this.usePostV5Type = version == ElasticVersion.V6_2;
+
switch (version) {
case V5_6:
case V6_2:
@@ -55,6 +61,12 @@
}
}
+ public void setType(JsonObject properties, String type) {
+ if (!usePostV5Type) {
+ properties.addProperty("_type", type);
+ }
+ }
+
public String searchFilteringName() {
return searchFilteringName;
}
@@ -78,4 +90,12 @@
String rawFieldsKey() {
return rawFieldsKey;
}
+
+ boolean usePostV5Type() {
+ return usePostV5Type;
+ }
+
+ String getType(String preV6Type) {
+ return usePostV5Type() ? POST_V5_TYPE : preV6Type;
+ }
}
diff --git a/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java b/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
index c7757b2..7392d09 100644
--- a/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
+++ b/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
@@ -14,6 +14,7 @@
package com.google.gerrit.elasticsearch.bulk;
+import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
import com.google.gson.JsonObject;
abstract class ActionRequest extends BulkRequest {
@@ -22,12 +23,15 @@
private final String id;
private final String index;
private final String type;
+ private final ElasticQueryAdapter adapter;
- protected ActionRequest(String action, String id, String index, String type) {
+ protected ActionRequest(
+ String action, String id, String index, String type, ElasticQueryAdapter adapter) {
this.action = action;
this.id = id;
this.index = index;
this.type = type;
+ this.adapter = adapter;
}
@Override
@@ -35,7 +39,7 @@
JsonObject properties = new JsonObject();
properties.addProperty("_id", id);
properties.addProperty("_index", index);
- properties.addProperty("_type", type);
+ adapter.setType(properties, type);
JsonObject jsonAction = new JsonObject();
jsonAction.add(action, properties);
diff --git a/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java b/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
index 7d549ca..570d5a0 100644
--- a/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
+++ b/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
@@ -14,9 +14,11 @@
package com.google.gerrit.elasticsearch.bulk;
+import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
+
public class DeleteRequest extends ActionRequest {
- public DeleteRequest(String id, String index, String type) {
- super("delete", id, index, type);
+ public DeleteRequest(String id, String index, String type, ElasticQueryAdapter adapter) {
+ super("delete", id, index, type, adapter);
}
}
diff --git a/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java b/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
index b131501..c571a0e 100644
--- a/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
+++ b/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
@@ -14,9 +14,11 @@
package com.google.gerrit.elasticsearch.bulk;
+import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
+
public class IndexRequest extends ActionRequest {
- public IndexRequest(String id, String index, String type) {
- super("index", id, index, type);
+ public IndexRequest(String id, String index, String type, ElasticQueryAdapter adapter) {
+ super("index", id, index, type, adapter);
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/CreateChange.java b/java/com/google/gerrit/server/restapi/change/CreateChange.java
index 9f86e46..73669a1 100644
--- a/java/com/google/gerrit/server/restapi/change/CreateChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateChange.java
@@ -171,7 +171,8 @@
throw new BadRequestException("branch must be non-empty");
}
- if (Strings.isNullOrEmpty(input.subject)) {
+ String subject = clean(Strings.nullToEmpty(input.subject));
+ if (Strings.isNullOrEmpty(subject)) {
throw new BadRequestException("commit message must be non-empty");
}
@@ -264,7 +265,7 @@
GeneralPreferencesInfo info = accountState.getGeneralPreferences();
// Add a Change-Id line if there isn't already one
- String commitMessage = input.subject;
+ String commitMessage = subject;
if (ChangeIdUtil.indexOfChangeId(commitMessage, "\n") == -1) {
ObjectId treeId = mergeTip == null ? emptyTreeId(oi) : mergeTip.getTree();
ObjectId id = ChangeIdUtil.computeChangeId(treeId, mergeTip, author, author, commitMessage);
@@ -388,4 +389,16 @@
private static ObjectId emptyTreeId(ObjectInserter inserter) throws IOException {
return inserter.insert(new TreeFormatter());
}
+
+ /**
+ * Remove comment lines from a commit message.
+ *
+ * <p>Based on {@link org.eclipse.jgit.util.ChangeIdUtil#clean}.
+ *
+ * @param msg
+ * @return message without comment lines, possibly empty.
+ */
+ private String clean(String msg) {
+ return msg.replaceAll("(?m)^#.*$\n?", "").trim();
+ }
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
index 3e9b90c..c723082 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
@@ -117,6 +117,13 @@
}
@Test
+ public void createNewChange_InvalidCommentInCommitMessage() throws Exception {
+ ChangeInput ci = newChangeInput(ChangeStatus.NEW);
+ ci.subject = "#12345 Test";
+ assertCreateFails(ci, BadRequestException.class, "commit message must be non-empty");
+ }
+
+ @Test
public void createNewChange() throws Exception {
ChangeInfo info = assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
assertThat(info.revisions.get(info.currentRevision).commit.message)
@@ -124,6 +131,15 @@
}
@Test
+ public void createNewChangeWithCommentsInCommitMessage() throws Exception {
+ ChangeInput ci = newChangeInput(ChangeStatus.NEW);
+ ci.subject += "\n# Comment line";
+ ChangeInfo info = gApi.changes().create(ci).get();
+ assertThat(info.revisions.get(info.currentRevision).commit.message)
+ .doesNotContain("# Comment line");
+ }
+
+ @Test
public void createNewChangeWithChangeId() throws Exception {
ChangeInput ci = newChangeInput(ChangeStatus.NEW);
String changeId = "I1234000000000000000000000000000000000000";
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index a7a23c3..c78f7c0 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -47,7 +47,7 @@
case V5_6:
return "elasticsearch:5.6.9-alpine";
case V6_2:
- return "docker.elastic.co/elasticsearch/elasticsearch:6.2.4";
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
new file mode 100644
index 0000000..db710f6
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+import com.google.gerrit.server.query.account.AbstractQueryAccountsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.InMemoryModule;
+import com.google.gerrit.testing.IndexConfig;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class ElasticV6QueryAccountsTest extends AbstractQueryAccountsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V6_2);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @Override
+ protected void initAfterLifecycleStart() throws Exception {
+ super.initAfterLifecycleStart();
+ ElasticTestUtils.createAllIndexes(injector);
+ }
+
+ @Override
+ protected Injector createInjector() {
+ Config elasticsearchConfig = new Config(config);
+ InMemoryModule.setDefaults(elasticsearchConfig);
+ String indicesPrefix = testName();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
new file mode 100644
index 0000000..043de4e
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.InMemoryModule;
+import com.google.gerrit.testing.IndexConfig;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class ElasticV6QueryChangesTest extends AbstractQueryChangesTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V6_2);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @Override
+ protected void initAfterLifecycleStart() throws Exception {
+ super.initAfterLifecycleStart();
+ ElasticTestUtils.createAllIndexes(injector);
+ }
+
+ @Override
+ protected Injector createInjector() {
+ Config elasticsearchConfig = new Config(config);
+ InMemoryModule.setDefaults(elasticsearchConfig);
+ String indicesPrefix = testName();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
new file mode 100644
index 0000000..b126c9d
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+import com.google.gerrit.server.query.group.AbstractQueryGroupsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.InMemoryModule;
+import com.google.gerrit.testing.IndexConfig;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class ElasticV6QueryGroupsTest extends AbstractQueryGroupsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V6_2);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @Override
+ protected void initAfterLifecycleStart() throws Exception {
+ super.initAfterLifecycleStart();
+ ElasticTestUtils.createAllIndexes(injector);
+ }
+
+ @Override
+ protected Injector createInjector() {
+ Config elasticsearchConfig = new Config(config);
+ InMemoryModule.setDefaults(elasticsearchConfig);
+ String indicesPrefix = testName();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
new file mode 100644
index 0000000..eaaf0c8
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+import com.google.gerrit.server.query.project.AbstractQueryProjectsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.InMemoryModule;
+import com.google.gerrit.testing.IndexConfig;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class ElasticV6QueryProjectsTest extends AbstractQueryProjectsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V6_2);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @Override
+ protected void initAfterLifecycleStart() throws Exception {
+ super.initAfterLifecycleStart();
+ ElasticTestUtils.createAllIndexes(injector);
+ }
+
+ @Override
+ protected Injector createInjector() {
+ Config elasticsearchConfig = new Config(config);
+ InMemoryModule.setDefaults(elasticsearchConfig);
+ String indicesPrefix = testName();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 2582d3c..c5ba182 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -831,7 +831,6 @@
_updateDiffCursor() {
const diffElements = Polymer.dom(this.root).querySelectorAll('gr-diff');
-
// Overwrite the cursor's list of diffs:
this.$.diffCursor.splice(
...['diffs', 0, this.$.diffCursor.diffs.length].concat(diffElements));
@@ -922,25 +921,26 @@
this._expandedFilePaths.indexOf(diff.path) === -1);
this._clearCollapsedDiffs(collapsedDiffs);
- if (!record) { return; }
+ if (!record) { return; } // Happens after "Collapse all" clicked.
this.filesExpanded = this._computeExpandedFiles(
this._expandedFilePaths.length, this._files.length);
// Find the paths introduced by the new index splices:
const newPaths = record.indexSplices
- .map(splice => {
- return splice.object.slice(splice.index,
- splice.index + splice.addedCount);
- })
- .reduce((acc, paths) => { return acc.concat(paths); }, []);
-
- this.$.reporting.time(EXPAND_ALL_TIMING_LABEL);
+ .map(splice => splice.object.slice(
+ splice.index, splice.index + splice.addedCount))
+ .reduce((acc, paths) => acc.concat(paths), []);
// Required so that the newly created diff view is included in this.diffs.
Polymer.dom.flush();
- this._renderInOrder(newPaths, this.diffs, newPaths.length);
+ this.$.reporting.time(EXPAND_ALL_TIMING_LABEL);
+
+ if (newPaths.length) {
+ this._renderInOrder(newPaths, this.diffs, newPaths.length);
+ }
+
this._updateDiffCursor();
this.$.diffCursor.handleDiffUpdate();
},
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index 0289449..277d005 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -883,7 +883,7 @@
flushAsynchronousOperations();
assert.equal(element.$$('iron-icon').icon, 'gr-icons:expand-more');
- assert.equal(renderSpy.callCount, 2);
+ assert.equal(renderSpy.callCount, 1);
assert.notInclude(element._expandedFilePaths, path);
assert.equal(collapseStub.lastCall.args[0].length, 1);
});
diff --git a/tools/bazel.rc b/tools/bazel.rc
index 8f158e9..7230cf3 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -2,4 +2,5 @@
build --disk_cache=~/.gerritcodereview/bazel-cache/cas
build --repository_cache=~/.gerritcodereview/bazel-cache/repository
build --experimental_strict_action_env
+build --action_env=PATH
test --build_tests_only
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
index 8ef8b7b..23f88df 100644
--- a/tools/bzl/plugin.bzl
+++ b/tools/bzl/plugin.bzl
@@ -28,6 +28,7 @@
gwt_module = [],
resources = [],
manifest_entries = [],
+ dir_name = None,
target_suffix = "",
**kwargs):
native.java_library(
@@ -43,6 +44,9 @@
if gwt_module:
static_jars = [':%s-static' % name]
+ if not dir_name:
+ dir_name = name
+
native.java_binary(
name = '%s__non_stamped' % name,
deploy_manifest_lines = manifest_entries + ["Gerrit-ApiType: plugin"],
@@ -88,7 +92,7 @@
stamp = 1,
srcs = ['%s__non_stamped_deploy.jar' % name],
cmd = " && ".join([
- "GEN_VERSION=$$(cat bazel-out/stable-status.txt | grep -w STABLE_BUILD_%s_LABEL | cut -d ' ' -f 2)" % name.upper(),
+ "GEN_VERSION=$$(cat bazel-out/stable-status.txt | grep -w STABLE_BUILD_%s_LABEL | cut -d ' ' -f 2)" % dir_name.upper(),
"cd $$TMP",
"unzip -q $$ROOT/$<",
"echo \"Implementation-Version: $$GEN_VERSION\n$$(cat META-INF/MANIFEST.MF)\" > META-INF/MANIFEST.MF",