Merge branch 'stable-3.6' * stable-3.6: Remove dependency on //java/com/google/gerrit/proto Restore dockerized integration tests Adapt Bazel build and deps to latest stable-3.5 Adapt to the latest Index interface in stable-3.5 Also adapt account and change index implementation to removal of support for legacy numeric type done in: I6a040f55cc. Change-Id: I360f99595aec8430de593318eff5c403fe5a9040
diff --git a/BUILD b/BUILD index 06352ab..4750354 100644 --- a/BUILD +++ b/BUILD
@@ -1,6 +1,5 @@ load("@rules_java//java:defs.bzl", "java_library") load("//tools/bzl:junit.bzl", "junit_tests") -load("//javatests/com/google/gerrit/acceptance:tests.bzl", "acceptance_tests") load( "//tools/bzl:plugin.bzl", "PLUGIN_DEPS", @@ -8,72 +7,54 @@ "gerrit_plugin", ) -gerrit_plugin ( +gerrit_plugin( name = "index-elasticsearch", srcs = glob(["src/main/java/**/*.java"]), deps = [ - "//java/com/google/gerrit/common:annotations", - "//java/com/google/gerrit/entities", - "//java/com/google/gerrit/exceptions", - "//java/com/google/gerrit/extensions:api", - "//java/com/google/gerrit/index", - "//java/com/google/gerrit/index:query_exception", - "//java/com/google/gerrit/index/project", - "//java/com/google/gerrit/lifecycle", - "//java/com/google/gerrit/proto", - "//java/com/google/gerrit/server", - "//lib:gson", - "//lib:guava", - "//lib:jgit", - "//lib:protobuf", - "//lib/commons:lang", "@elasticsearch-rest-client//jar", - "//lib/flogger:api", - "//lib/guice", - "//lib/guice:guice-assistedinject", "@httpasyncclient//jar", - "//lib/httpcomponents:httpclient", - "//lib/httpcomponents:httpcore", "@httpcore-nio//jar", "@jackson-core//jar", ], ) +ELASTICSEARCH_DEPS = [ + "@docker-java-api//jar", + "@docker-java-transport//jar", + "@duct-tape//jar", + "@httpasyncclient//jar", + "@jackson-annotations//jar", + "@jackson-core//jar", + "@jna//jar", + "@testcontainers-elasticsearch//jar", + "@testcontainers//jar", +] + java_library( - name = "elasticsearch_test_utils", + name = "index-elasticsearch__plugin_test_deps", testonly = True, srcs = [], visibility = ["//visibility:public"], - deps = [ - "//java/com/google/gerrit/index", - "//lib:guava", - "//lib:jgit", - "//lib:junit", - "//lib/guice", - "//lib/httpcomponents:httpcore", - "//lib/jackson:jackson-annotations", - "//lib/testcontainers", - "//lib/testcontainers:docker-java-api", - "//lib/testcontainers:docker-java-transport", - "@testcontainers-elasticsearch//jar", + exports = ELASTICSEARCH_DEPS, +) + +java_library( + name = "elasticsearch_test_utils", + testonly = True, + srcs = glob( + ["src/test/java/**/*.java"], + exclude = ["src/test/java/**/*Test.java"], + ), + visibility = ["//visibility:public"], + deps = ELASTICSEARCH_DEPS + PLUGIN_DEPS + PLUGIN_TEST_DEPS + [ ":index-elasticsearch__plugin", ], ) -ELASTICSEARCH_DEPS = [ - ":elasticsearch_test_utils", - "//java/com/google/gerrit/testing:gerrit-test-util", - "//lib/guice", - "//lib:jgit", -] - -HTTP_TEST_DEPS = [ - "@httpasyncclient//jar", - "//lib/httpcomponents:httpclient", -] - QUERY_TESTS_DEP = "//javatests/com/google/gerrit/server/query/%s:abstract_query_tests" +ACCOUNT_QUERY_TESTS_DEP = "//javatests/com/google/gerrit/server/query/account:abstract_query_tests" + TYPES = [ "account", "change", @@ -85,26 +66,30 @@ ELASTICSEARCH_TESTS_V7 = {i: "ElasticV7Query" + i.capitalize() + SUFFIX for i in TYPES} -ELASTICSEARCH_TAGS = [ - "docker", - "elastic", -] +[junit_tests( + name = "elasticsearch_query_%ss_test_V7" % name, + size = "enormous", + srcs = ["src/test/java/com/google/gerrit/elasticsearch/" + src], + tags = [ + "docker", + "elastic", + ], + deps = ELASTICSEARCH_DEPS + PLUGIN_TEST_DEPS + [ + QUERY_TESTS_DEP % name, + ":elasticsearch_test_utils", + ":index-elasticsearch__plugin", + ], +) for name, src in ELASTICSEARCH_TESTS_V7.items()] junit_tests( name = "index-elasticsearch_tests", size = "small", srcs = glob( ["src/test/java/**/*Test.java"], - exclude = ["Elastic*Query*" + SUFFIX], + exclude = ["src/test/java/**/Elastic*Query*" + SUFFIX], ), tags = ["elastic"], - deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [ - "//java/com/google/gerrit/testing:gerrit-test-util", - "//lib:guava", - "//lib:jgit", - "//lib/guice", - "//lib/httpcomponents:httpcore", - "//lib/truth", - ":elasticsearch_test_utils", + deps = PLUGIN_TEST_DEPS + [ + ":index-elasticsearch__plugin", ], )
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl index b863175..fc1420c 100644 --- a/external_plugin_deps.bzl +++ b/external_plugin_deps.bzl
@@ -5,6 +5,12 @@ # Ensure artifacts compatibility by selecting them from the Bill Of Materials # https://search.maven.org/artifact/net.openhft/chronicle-bom/2.20.191/pom def external_plugin_deps(): + maven_jar( + name = "testcontainers", + artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION, + sha1 = "95c6cfde71c2209f0c29cb14e432471e0b111880", + ) + # When upgrading elasticsearch-rest-client, also upgrade httpcore-nio # and httpasyncclient as necessary in tools/nongoogle.bzl. Consider # also the other org.apache.httpcomponents dependencies in @@ -21,6 +27,38 @@ sha1 = "595e3a50f59cd3c1d281ca6c1bc4037e277a1353", ) + maven_jar( + name = "duct-tape", + artifact = "org.rnorth.duct-tape:duct-tape:1.0.8", + sha1 = "92edc22a9ab2f3e17c9bf700aaee377d50e8b530", + ) + + maven_jar( + name = "visible-assertions", + artifact = "org.rnorth.visible-assertions:visible-assertions:2.1.2", + sha1 = "20d31a578030ec8e941888537267d3123c2ad1c1", + ) + + maven_jar( + name = "jna", + artifact = "net.java.dev.jna:jna:5.5.0", + sha1 = "0e0845217c4907822403912ad6828d8e0b256208", + ) + + DOCKER_JAVA_VERS = "3.2.8" + + maven_jar( + name = "docker-java-api", + artifact = "com.github.docker-java:docker-java-api:" + DOCKER_JAVA_VERS, + sha1 = "4ac22a72d546a9f3523cd4b5fabffa77c4a6ec7c", + ) + + maven_jar( + name = "docker-java-transport", + artifact = "com.github.docker-java:docker-java-transport:" + DOCKER_JAVA_VERS, + sha1 = "c3b5598c67d0a5e2e780bf48f520da26b9915eab", + ) + # elasticsearch-rest-client explicitly depends on this version maven_jar( name = "httpasyncclient", @@ -42,8 +80,13 @@ ) maven_jar( + name = "jackson-annotations", + artifact = "com.fasterxml.jackson.core:jackson-annotations:2.10.3", + sha1 = "0f63b3b1da563767d04d2e4d3fc1ae0cdeffebe7", + ) + + maven_jar( name = "httpasyncclient", artifact = "org.apache.httpcomponents:httpasyncclient:4.1.4", sha1 = "f3a3240681faae3fa46b573a4c7e50cec9db0d86", ) -
diff --git a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java index 562464d..90ce18b 100644 --- a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java +++ b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -152,6 +152,11 @@ } @Override + public void insert(V obj) { + replace(obj); + } + + @Override public Schema<V> getSchema() { return schema; }
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java index 8967789..beb57bd 100644 --- a/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java +++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
@@ -91,15 +91,12 @@ @Override public DataSource<AccountState> getSource(Predicate<AccountState> p, QueryOptions opts) throws QueryParseException { + boolean useLegacyNumericFields = schema.hasField(AccountField.ID); JsonArray sortArray = getSortArray( - schema.useLegacyNumericFields() - ? AccountField.ID.getName() - : AccountField.ID_STR.getName()); + useLegacyNumericFields ? AccountField.ID.getName() : AccountField.ID_STR.getName()); return new ElasticQuerySource( - p, - opts.filterFields(o -> IndexUtils.accountFields(o, schema.useLegacyNumericFields())), - sortArray); + p, opts.filterFields(o -> IndexUtils.accountFields(o, useLegacyNumericFields)), sortArray); } @Override @@ -129,7 +126,7 @@ source .getAsJsonObject() .get( - schema.useLegacyNumericFields() + schema.hasField(AccountField.ID) ? AccountField.ID.getName() : AccountField.ID_STR.getName()) .getAsInt());
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java index 7d4e0c7..83be597 100644 --- a/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java +++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -69,7 +69,6 @@ private final ChangeMapping mapping; private final ChangeData.Factory changeDataFactory; private final Schema<ChangeData> schema; - private final FieldDef<ChangeData, ?> idField; private final ImmutableSet<String> skipFields; @Inject @@ -84,8 +83,6 @@ this.changeDataFactory = changeDataFactory; this.schema = schema; this.mapping = new ChangeMapping(schema, client.adapter()); - this.idField = - this.schema.useLegacyNumericFields() ? ChangeField.LEGACY_ID : ChangeField.LEGACY_ID_STR; this.skipFields = MergeabilityComputationBehavior.fromConfig(gerritConfig).includeInIndex() ? ImmutableSet.of() @@ -110,8 +107,7 @@ @Override public DataSource<ChangeData> getSource(Predicate<ChangeData> p, QueryOptions opts) throws QueryParseException { - QueryOptions filteredOpts = - opts.filterFields(o -> IndexUtils.changeFields(o, schema.useLegacyNumericFields())); + QueryOptions filteredOpts = opts.filterFields(o -> IndexUtils.changeFields(o)); return new ElasticQuerySource(p, filteredOpts, getSortArray()); } @@ -122,7 +118,7 @@ JsonArray sortArray = new JsonArray(); addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray); addNamedElement(ChangeField.MERGED_ON.getName(), getMergedOnSortOptions(), sortArray); - addNamedElement(idField.getName(), properties, sortArray); + addNamedElement(ChangeField.LEGACY_ID_STR.getName(), properties, sortArray); return sortArray; } @@ -160,7 +156,7 @@ JsonElement c = source.get(ChangeField.CHANGE.getName()); if (c == null) { - int id = source.get(idField.getName()).getAsInt(); + int id = source.get(ChangeField.LEGACY_ID_STR.getName()).getAsInt(); // IndexUtils#changeFields ensures either CHANGE or PROJECT is always present. String projectName = requireNonNull(source.get(ChangeField.PROJECT.getName()).getAsString()); return changeDataFactory.create(Project.nameKey(projectName), Change.id(id));
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java index 40ac603..9fc070a 100644 --- a/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java +++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
@@ -29,7 +29,6 @@ import com.google.gerrit.index.query.QueryParseException; import com.google.gerrit.index.query.RegexPredicate; import com.google.gerrit.index.query.TimestampRangePredicate; -import java.time.Instant; public class ElasticQueryBuilder { @@ -119,9 +118,8 @@ } private <T> QueryBuilder notTimestamp(TimestampRangePredicate<T> r) throws QueryParseException { - if (r.getMinTimestamp().getTime() == 0) { - return QueryBuilders.rangeQuery(r.getField().getName()) - .gt(Instant.ofEpochMilli(r.getMaxTimestamp().getTime())); + if (r.getMinTimestamp().toEpochMilli() == 0) { + return QueryBuilders.rangeQuery(r.getField().getName()).gt(r.getMaxTimestamp()); } throw new QueryParseException("cannot negate: " + r); } @@ -129,15 +127,14 @@ private <T> QueryBuilder timestampQuery(IndexPredicate<T> p) throws QueryParseException { if (p instanceof TimestampRangePredicate) { TimestampRangePredicate<T> r = (TimestampRangePredicate<T>) p; - if (r.getMaxTimestamp().getTime() == Long.MAX_VALUE) { + if (r.getMaxTimestamp().toEpochMilli() == Long.MAX_VALUE) { // The time range only has the start value, search from the start to the max supported value // Long.MAX_VALUE - return QueryBuilders.rangeQuery(r.getField().getName()) - .gte(Instant.ofEpochMilli(r.getMinTimestamp().getTime())); + return QueryBuilders.rangeQuery(r.getField().getName()).gte(r.getMinTimestamp()); } return QueryBuilders.rangeQuery(r.getField().getName()) - .gte(Instant.ofEpochMilli(r.getMinTimestamp().getTime())) - .lte(Instant.ofEpochMilli(r.getMaxTimestamp().getTime())); + .gte(r.getMinTimestamp()) + .lte(r.getMaxTimestamp()); } throw new QueryParseException("not a timestamp: " + p); }
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md index b6f6e51..1720f52 100644 --- a/src/main/resources/Documentation/build.md +++ b/src/main/resources/Documentation/build.md
@@ -34,4 +34,20 @@ ```sh bazelisk test plugins/index-elasticsearch/... -``` \ No newline at end of file +``` + +This project can be imported into the Eclipse IDE. +Add the plugin name to the `CUSTOM_PLUGINS` and to the +`CUSTOM_PLUGINS_TEST_DEPS` set in Gerrit core in +`tools/bzl/plugins.bzl`, and execute: + +``` + ./tools/eclipse/project.py +``` + +More information about Bazel can be found in the [Gerrit +documentation](../../../Documentation/dev-bazel.html). + +[Back to @PLUGIN@ documentation index][index] + +[index]: index.html
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java new file mode 100644 index 0000000..503852b --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -0,0 +1,59 @@ +// 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 org.apache.http.HttpHost; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.elasticsearch.ElasticsearchContainer; +import org.testcontainers.utility.DockerImageName; + +/* Helper class for running ES integration tests in docker container */ +public class ElasticContainer extends ElasticsearchContainer { + private static final int ELASTICSEARCH_DEFAULT_PORT = 9200; + + public static ElasticContainer createAndStart(ElasticVersion version) { + ElasticContainer container = new ElasticContainer(version); + container.start(); + return container; + } + + private static String getImageName(ElasticVersion version) { + switch (version) { + case V7_6: + return "blacktop/elasticsearch:7.6.2"; + case V7_7: + return "blacktop/elasticsearch:7.7.1"; + case V7_8: + return "blacktop/elasticsearch:7.8.1"; + } + throw new IllegalStateException("No tests for version: " + version.name()); + } + + private ElasticContainer(ElasticVersion version) { + super( + DockerImageName.parse(getImageName(version)) + .asCompatibleSubstituteFor("docker.elastic.co/elasticsearch/elasticsearch")); + } + + @Override + protected Logger logger() { + return LoggerFactory.getLogger("org.testcontainers"); + } + + public HttpHost getHttpHost() { + return new HttpHost(getContainerIpAddress(), getMappedPort(ELASTICSEARCH_DEFAULT_PORT)); + } +}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java new file mode 100644 index 0000000..c3ca595 --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java
@@ -0,0 +1,87 @@ +// Copyright (C) 2016 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.index.IndexDefinition; +import com.google.gerrit.server.LibModuleType; +import com.google.gerrit.testing.GerritTestName; +import com.google.gerrit.testing.InMemoryModule; +import com.google.gerrit.testing.IndexConfig; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import java.util.Collection; +import java.util.UUID; +import org.eclipse.jgit.lib.Config; + +public final class ElasticTestUtils { + public static void configure(Config config, ElasticContainer container, String prefix) { + String hostname = container.getHttpHost().getHostName(); + int port = container.getHttpHost().getPort(); + config.setString("index", null, "type", "elasticsearch"); + config.setString("elasticsearch", null, "server", "http://" + hostname + ":" + port); + config.setString("elasticsearch", null, "prefix", prefix); + config.setInt("index", null, "maxLimit", 10000); + } + + public static void createAllIndexes(Injector injector) { + Collection<IndexDefinition<?, ?, ?>> indexDefs = + injector.getInstance(Key.get(new TypeLiteral<Collection<IndexDefinition<?, ?, ?>>>() {})); + for (IndexDefinition<?, ?, ?> indexDef : indexDefs) { + indexDef.getIndexCollection().getSearchIndex().deleteAll(); + } + } + + public static Config getConfig(ElasticVersion version) { + ElasticContainer container = ElasticContainer.createAndStart(version); + String indicesPrefix = UUID.randomUUID().toString(); + Config cfg = new Config(); + configure(cfg, container, indicesPrefix); + return cfg; + } + + public static Config createConfig() { + Config cfg = IndexConfig.create(); + + // For some reason enabling the staleness checker increases the flakiness of the Elasticsearch + // tests. Hence disable the staleness checker. + cfg.setBoolean("index", null, "autoReindexIfStale", false); + + return cfg; + } + + public static void configureElasticModule(Config elasticsearchConfig) { + elasticsearchConfig.setString( + "index", + null, + "install" + LibModuleType.INDEX_MODULE_TYPE.getConfigKey(), + "com.google.gerrit.elasticsearch.ElasticIndexModule"); + } + + public static Injector createInjector( + Config config, GerritTestName testName, ElasticContainer container) { + Config elasticsearchConfig = new Config(config); + ElasticTestUtils.configureElasticModule(elasticsearchConfig); + InMemoryModule.setDefaults(elasticsearchConfig); + String indicesPrefix = testName.getSanitizedMethodName(); + ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix); + return Guice.createInjector(new InMemoryModule(elasticsearchConfig)); + } + + private ElasticTestUtils() { + // hide default constructor + } +}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java new file mode 100644 index 0000000..4ee5a16 --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -0,0 +1,57 @@ +// 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.server.query.account.AbstractQueryAccountsTest; +import com.google.gerrit.testing.ConfigSuite; +import com.google.inject.Injector; +import org.eclipse.jgit.lib.Config; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public class ElasticV7QueryAccountsTest extends AbstractQueryAccountsTest { + @ConfigSuite.Default + public static Config defaultConfig() { + return ElasticTestUtils.createConfig(); + } + + private static ElasticContainer container; + + @BeforeClass + public static void startIndexService() { + if (container == null) { + // Only start Elasticsearch once + container = ElasticContainer.createAndStart(ElasticVersion.V7_8); + } + } + + @AfterClass + public static void stopElasticsearchServer() { + if (container != null) { + container.stop(); + } + } + + @Override + protected void initAfterLifecycleStart() throws Exception { + super.initAfterLifecycleStart(); + ElasticTestUtils.createAllIndexes(injector); + } + + @Override + protected Injector createInjector() { + return ElasticTestUtils.createInjector(config, testName, container); + } +}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java new file mode 100644 index 0000000..d704e40 --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -0,0 +1,141 @@ +// 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 static com.google.common.truth.TruthJUnit.assume; +import static java.util.concurrent.TimeUnit.MINUTES; + +import com.google.gerrit.entities.Change; +import com.google.gerrit.server.change.ChangeInserter; +import com.google.gerrit.server.index.change.ChangeField; +import com.google.gerrit.server.query.change.AbstractQueryChangesTest; +import com.google.gerrit.testing.ConfigSuite; +import com.google.gerrit.testing.GerritTestName; +import com.google.gerrit.testing.InMemoryRepositoryManager.Repo; +import com.google.inject.Injector; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; +import org.apache.http.impl.nio.client.HttpAsyncClients; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.Config; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; + +public class ElasticV7QueryChangesTest extends AbstractQueryChangesTest { + @ConfigSuite.Default + public static Config defaultConfig() { + return ElasticTestUtils.createConfig(); + } + + private static ElasticContainer container; + private static CloseableHttpAsyncClient client; + + @BeforeClass + public static void startIndexService() { + if (container == null) { + // Only start Elasticsearch once + container = ElasticContainer.createAndStart(ElasticVersion.V7_8); + client = HttpAsyncClients.createDefault(); + client.start(); + } + } + + @AfterClass + public static void stopElasticsearchServer() { + if (container != null) { + container.stop(); + } + } + + @Rule public final GerritTestName testName = new GerritTestName(); + + @After + public void closeIndex() throws Exception { + // Close the index after each test to prevent exceeding Elasticsearch's + // shard limit (see Issue 10120). + client + .execute( + new HttpPost( + String.format( + "http://%s:%d/%s*/_close", + container.getHttpHost().getHostName(), + container.getHttpHost().getPort(), + testName.getSanitizedMethodName())), + HttpClientContext.create(), + null) + .get(5, MINUTES); + } + + @Override + protected void initAfterLifecycleStart() throws Exception { + super.initAfterLifecycleStart(); + ElasticTestUtils.createAllIndexes(injector); + } + + @Test + @Override + // TODO(davido): overrides byTopic() method to adjust to ES behaviour for + // "prefixtopic" predicate. This should be fixed in a follow-up change. + public void byTopic() throws Exception { + + TestRepository<Repo> repo = createProject("repo"); + ChangeInserter ins1 = newChangeWithTopic(repo, "feature1"); + Change change1 = insert(repo, ins1); + + ChangeInserter ins2 = newChangeWithTopic(repo, "feature2"); + Change change2 = insert(repo, ins2); + + ChangeInserter ins3 = newChangeWithTopic(repo, "Cherrypick-feature2"); + Change change3 = insert(repo, ins3); + + ChangeInserter ins4 = newChangeWithTopic(repo, "feature2-fixup"); + Change change4 = insert(repo, ins4); + + ChangeInserter ins5 = newChangeWithTopic(repo, "https://gerrit.local"); + Change change5 = insert(repo, ins5); + + ChangeInserter ins6 = newChangeWithTopic(repo, "git_gerrit_training"); + Change change6 = insert(repo, ins6); + + Change change_no_topic = insert(repo, newChange(repo)); + + assertQuery("intopic:foo"); + assertQuery("intopic:feature1", change1); + assertQuery("intopic:feature2", change4, change3, change2); + assertQuery("topic:feature2", change2); + assertQuery("intopic:feature2", change4, change3, change2); + assertQuery("intopic:fixup", change4); + assertQuery("intopic:gerrit", change6, change5); + assertQuery("topic:\"\"", change_no_topic); + assertQuery("intopic:\"\"", change_no_topic); + + assume().that(getSchema().hasField(ChangeField.PREFIX_TOPIC)).isTrue(); + // change3 is considered by ES in prefixtopic:feature query, see + // https://www.elastic.co/guide/en/elasticsearch/reference/8.2/query-dsl-match-query-phrase-prefix.html + // assertQuery("prefixtopic:feature", change4, change2, change1); + assertQuery("prefixtopic:feature", change4, change3, change2, change1); + assertQuery("prefixtopic:Cher", change3); + assertQuery("prefixtopic:feature22"); + } + + @Override + protected Injector createInjector() { + return ElasticTestUtils.createInjector(config, testName, container); + } +}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java new file mode 100644 index 0000000..649c0bc --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -0,0 +1,57 @@ +// 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.server.query.group.AbstractQueryGroupsTest; +import com.google.gerrit.testing.ConfigSuite; +import com.google.inject.Injector; +import org.eclipse.jgit.lib.Config; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public class ElasticV7QueryGroupsTest extends AbstractQueryGroupsTest { + @ConfigSuite.Default + public static Config defaultConfig() { + return ElasticTestUtils.createConfig(); + } + + private static ElasticContainer container; + + @BeforeClass + public static void startIndexService() { + if (container == null) { + // Only start Elasticsearch once + container = ElasticContainer.createAndStart(ElasticVersion.V7_8); + } + } + + @AfterClass + public static void stopElasticsearchServer() { + if (container != null) { + container.stop(); + } + } + + @Override + protected void initAfterLifecycleStart() throws Exception { + super.initAfterLifecycleStart(); + ElasticTestUtils.createAllIndexes(injector); + } + + @Override + protected Injector createInjector() { + return ElasticTestUtils.createInjector(config, testName, container); + } +}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java new file mode 100644 index 0000000..d3b3d44 --- /dev/null +++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -0,0 +1,57 @@ +// 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.server.query.project.AbstractQueryProjectsTest; +import com.google.gerrit.testing.ConfigSuite; +import com.google.inject.Injector; +import org.eclipse.jgit.lib.Config; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public class ElasticV7QueryProjectsTest extends AbstractQueryProjectsTest { + @ConfigSuite.Default + public static Config defaultConfig() { + return ElasticTestUtils.createConfig(); + } + + private static ElasticContainer container; + + @BeforeClass + public static void startIndexService() { + if (container == null) { + // Only start Elasticsearch once + container = ElasticContainer.createAndStart(ElasticVersion.V7_8); + } + } + + @AfterClass + public static void stopElasticsearchServer() { + if (container != null) { + container.stop(); + } + } + + @Override + protected void initAfterLifecycleStart() throws Exception { + super.initAfterLifecycleStart(); + ElasticTestUtils.createAllIndexes(injector); + } + + @Override + protected Injector createInjector() { + return ElasticTestUtils.createInjector(config, testName, container); + } +}