Merge branch 'stable-3.5' into stable-3.6
* stable-3.5:
test: Simplify SSL setup
Add 8.9.* to supported versions
test: Always enable SSL for ES containers
Bump testcontainers to 1.19.7
Remove unused build var
test: Add assert for closing indexes
test: Use the 'withTag' helper to get DockerImageName
Include an 'Accept' header for Content-Type in requests
Add a debug log while insert/replace change index operation
Release-Notes: skip
Change-Id: I1426e2fd38b21d64c81804560b96b34a07ccd466
diff --git a/BUILD b/BUILD
index 94ce436..858c03a 100644
--- a/BUILD
+++ b/BUILD
@@ -53,8 +53,6 @@
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",
@@ -64,6 +62,20 @@
SUFFIX = "sTest.java"
+ABSTRACT_ELASTICSEARCH_TESTS = {i: "Elastic*Query" + i.capitalize() + SUFFIX for i in TYPES}
+
+[java_library(
+ name = "abstract_elasticsearch_query_%ss_test" % name,
+ testonly = True,
+ srcs = glob(["src/test/java/com/google/gerrit/elasticsearch/" + src]),
+ visibility = ["//visibility:public"],
+ deps = ELASTICSEARCH_DEPS + PLUGIN_TEST_DEPS + [
+ QUERY_TESTS_DEP % name,
+ ":elasticsearch_test_utils",
+ ":index-elasticsearch__plugin",
+ ],
+) for name, src in ABSTRACT_ELASTICSEARCH_TESTS.items()]
+
ELASTICSEARCH_TESTS_V7 = {i: "ElasticV7Query" + i.capitalize() + SUFFIX for i in TYPES}
[junit_tests(
@@ -79,9 +91,29 @@
QUERY_TESTS_DEP % name,
":elasticsearch_test_utils",
":index-elasticsearch__plugin",
+ ":abstract_elasticsearch_query_%ss_test" % name,
],
) for name, src in ELASTICSEARCH_TESTS_V7.items()]
+ELASTICSEARCH_TESTS_V8 = {i: "ElasticV8Query" + i.capitalize() + SUFFIX for i in TYPES}
+
+[junit_tests(
+ name = "elasticsearch_query_%ss_test_V8" % name,
+ size = "enormous",
+ srcs = ["src/test/java/com/google/gerrit/elasticsearch/" + src],
+ tags = [
+ "docker",
+ "elastic",
+ "exclusive",
+ ],
+ deps = ELASTICSEARCH_DEPS + PLUGIN_TEST_DEPS + [
+ QUERY_TESTS_DEP % name,
+ ":elasticsearch_test_utils",
+ ":index-elasticsearch__plugin",
+ ":abstract_elasticsearch_query_%ss_test" % name,
+ ],
+) for name, src in ELASTICSEARCH_TESTS_V8.items()]
+
junit_tests(
name = "index-elasticsearch_tests",
size = "small",
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 7ab2c29..72549a8 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -8,19 +8,19 @@
)
# Ensure artifacts compatibility by selecting them from the Bill Of Materials
- # https://search.maven.org/artifact/org.testcontainers/testcontainers/1.17.5/pom
- TESTCONTAINERS_VERSION = "1.17.5"
+ # https://search.maven.org/artifact/org.testcontainers/testcontainers/1.19.7/pom
+ TESTCONTAINERS_VERSION = "1.19.7"
maven_jar(
name = "testcontainers",
artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION,
- sha1 = "7c5ad975fb789ecd09b1ee5f72907f48a300bc61",
+ sha1 = "2dd7b1497fc444755582b0efc88636c4d299601f",
)
maven_jar(
name = "testcontainers-elasticsearch",
artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
- sha1 = "060895f2fc6640ab4a6c383bc98c5c39ef644fbb",
+ sha1 = "8cd9f4ae67c9299143eb718541ff544b66273283",
)
maven_jar(
@@ -29,36 +29,36 @@
sha1 = "92edc22a9ab2f3e17c9bf700aaee377d50e8b530",
)
- DOCKER_JAVA_VERS = "3.2.13"
+ DOCKER_JAVA_VERS = "3.3.6"
maven_jar(
name = "docker-java-api",
artifact = "com.github.docker-java:docker-java-api:" + DOCKER_JAVA_VERS,
- sha1 = "5817ef8f770cb7e740d590090bf352df9491f3c1",
+ sha1 = "8e152880bfe595c81a25501e21a6d7b1d4df97be",
)
maven_jar(
name = "docker-java-transport",
artifact = "com.github.docker-java:docker-java-transport:" + DOCKER_JAVA_VERS,
- sha1 = "e9d308d1822181a9d48c99739f5eca014ec89199",
+ sha1 = "0d536d16a297f9139b833955390a3d581e336e67",
)
maven_jar(
name = "docker-java-transport-zerodep",
artifact = "com.github.docker-java:docker-java-transport-zerodep:" + DOCKER_JAVA_VERS,
- sha1 = "4cbc2c09d6c264767a39624066987ed4a152bc68",
+ sha1 = "c9cde0239ce03376f6dfd0465bd461853af22196",
)
# Match version used in docker-java-transport
- # https://search.maven.org/artifact/com.github.docker-java/docker-java-transport/3.2.12/pom
+ # https://search.maven.org/artifact/com.github.docker-java/docker-java-transport/3.3.6/pom
maven_jar(
name = "jna",
- artifact = "net.java.dev.jna:jna:5.8.0",
- sha1 = "3551d8d827e54858214107541d3aff9c615cb615",
+ artifact = "net.java.dev.jna:jna:5.13.0",
+ sha1 = "1200e7ebeedbe0d10062093f32925a912020e747",
)
# Match jackson.version from docker-java
- # https://search.maven.org/artifact/com.github.docker-java/docker-java-parent/3.2.12/pom
+ # https://search.maven.org/artifact/com.github.docker-java/docker-java-parent/3.3.6/pom
maven_jar(
name = "jackson-annotations",
artifact = "com.fasterxml.jackson.core:jackson-annotations:2.10.3",
diff --git a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 482868c..58a53b1 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -278,9 +278,9 @@
protected boolean hasErrors(Response response) {
try {
- String contentType = response.getEntity().getContentType().getValue();
+ ContentType contentType = ContentType.get(response.getEntity());
Preconditions.checkState(
- contentType.equals(ContentType.APPLICATION_JSON.toString()),
+ contentType.toString().equalsIgnoreCase(ContentType.APPLICATION_JSON.toString()),
String.format("Expected %s, but was: %s", ContentType.APPLICATION_JSON, contentType));
String responseStr = EntityUtils.toString(response.getEntity());
JsonObject responseJson = (JsonObject) new JsonParser().parse(responseStr);
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index 8504e16..b6121e8 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -17,6 +17,7 @@
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableSet;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.elasticsearch.ElasticMapping.Mapping;
import com.google.gerrit.elasticsearch.bulk.BulkRequest;
import com.google.gerrit.elasticsearch.bulk.IndexRequest;
@@ -52,6 +53,8 @@
/** Secondary index implementation using Elasticsearch. */
class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
implements ChangeIndex {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
static class ChangeMapping {
final Mapping changes;
final Mapping openChanges;
@@ -99,6 +102,17 @@
BulkRequest bulk =
new IndexRequest(getId(cd), indexName).add(new UpdateRequest<>(schema, cd, skipFields));
+ if (logger.atFine().isEnabled()) {
+ String metaRevision = null;
+ try {
+ metaRevision = cd.metaRevisionOrThrow().name();
+ } catch (Exception ignored) {
+ }
+ logger.atFine().log(
+ "Indexing: change: %s, status: %s, meta revision: %s",
+ cd.change().currentPatchSetId(), cd.change().getStatus(), metaRevision);
+ }
+
String uri = getURI(BULK);
Response response = postRequestWithRefreshParam(uri, bulk);
int statusCode = response.getStatusLine().getStatusCode();
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
index b41f365..9caa14d 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
@@ -22,14 +22,17 @@
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
+import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
+import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
@@ -129,6 +132,8 @@
private RestClient build() {
RestClientBuilder builder = RestClient.builder(cfg.getHosts());
+ builder.setDefaultHeaders(
+ new Header[] {new BasicHeader("Accept", ContentType.APPLICATION_JSON.toString())});
setConfiguredTimeouts(builder);
setConfiguredCredentialsIfAny(builder);
return builder.build();
@@ -150,8 +155,13 @@
credentialsProvider.setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(username, password));
builder.setHttpClientConfigCallback(
- (HttpAsyncClientBuilder httpClientBuilder) ->
- httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
+ (HttpAsyncClientBuilder httpClientBuilder) -> {
+ httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+ configureHttpClientBuilder(httpClientBuilder);
+ return httpClientBuilder;
+ });
}
}
+
+ protected void configureHttpClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {}
}
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java
index dffdf3e..2fad786 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java
@@ -18,7 +18,8 @@
import java.util.regex.Pattern;
public enum ElasticVersion {
- V7_16("7.16.*");
+ V7_16("7.16.*"),
+ V8_9("8.9.*");
private final String version;
private final Pattern pattern;
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java
new file mode 100644
index 0000000..ce16b2e
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryAccountsTest.java
@@ -0,0 +1,78 @@
+// Copyright (C) 2024 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.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.server.query.account.AbstractQueryAccountsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Injector;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public abstract class ElasticAbstractQueryAccountsTest extends AbstractQueryAccountsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return ElasticTestUtils.createConfig();
+ }
+
+ @ConfigSuite.Config
+ public static Config searchAfterPaginationType() {
+ Config config = defaultConfig();
+ config.setString("index", null, "paginationType", "SEARCH_AFTER");
+ return config;
+ }
+
+ private static ElasticContainer container;
+ private static CloseableHttpAsyncClient client;
+
+ protected static void startIndexService(ElasticVersion elasticVersion) {
+ container = ElasticContainer.createAndStart(elasticVersion);
+ client = ElasticTestUtils.createHttpAsyncClient(container);
+ client.start();
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testErrorResponseFromAccountIndex() throws Exception {
+ gApi.accounts().self().index();
+
+ ElasticTestUtils.closeIndex(client, container, testName);
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> gApi.accounts().self().index());
+ assertThat(thrown).hasMessageThat().contains("Failed to replace account");
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java
new file mode 100644
index 0000000..d37e626
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryChangesTest.java
@@ -0,0 +1,95 @@
+// Copyright (C) 2024 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.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.exceptions.StorageException;
+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;
+import com.google.inject.Injector;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+public abstract class ElasticAbstractQueryChangesTest extends AbstractQueryChangesTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return ElasticTestUtils.createConfig();
+ }
+
+ @ConfigSuite.Config
+ public static Config searchAfterPaginationType() {
+ Config config = defaultConfig();
+ config.setString("index", null, "paginationType", "SEARCH_AFTER");
+ return config;
+ }
+
+ private static ElasticContainer container;
+ private static CloseableHttpAsyncClient client;
+
+ protected static void startIndexService(ElasticVersion elasticVersion) {
+ container = ElasticContainer.createAndStart(elasticVersion);
+ client = ElasticTestUtils.createHttpAsyncClient(container);
+ 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).
+ ElasticTestUtils.closeIndex(client, container, testName);
+ }
+
+ @Override
+ protected void initAfterLifecycleStart() throws Exception {
+ super.initAfterLifecycleStart();
+ ElasticTestUtils.createAllIndexes(injector);
+ }
+
+ @Override
+ protected Injector createInjector() {
+ return ElasticTestUtils.createInjector(config, testName, container);
+ }
+
+ @Test
+ public void testErrorResponseFromChangeIndex() throws Exception {
+ TestRepository<InMemoryRepositoryManager.Repo> repo = createProject("repo");
+ Change c = insert(repo, newChangeWithStatus(repo, Change.Status.NEW));
+ gApi.changes().id(c.getChangeId()).index();
+
+ ElasticTestUtils.closeIndex(client, container, testName);
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> gApi.changes().id(c.getChangeId()).index());
+ assertThat(thrown).hasMessageThat().contains("Failed to reindex change");
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java
new file mode 100644
index 0000000..f449bca
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryGroupsTest.java
@@ -0,0 +1,79 @@
+// Copyright (C) 2024 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.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.extensions.api.groups.GroupApi;
+import com.google.gerrit.server.query.group.AbstractQueryGroupsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Injector;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public abstract class ElasticAbstractQueryGroupsTest extends AbstractQueryGroupsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return ElasticTestUtils.createConfig();
+ }
+
+ @ConfigSuite.Config
+ public static Config searchAfterPaginationType() {
+ Config config = defaultConfig();
+ config.setString("index", null, "paginationType", "SEARCH_AFTER");
+ return config;
+ }
+
+ private static ElasticContainer container;
+ private static CloseableHttpAsyncClient client;
+
+ protected static void startIndexService(ElasticVersion elasticVersion) {
+ container = ElasticContainer.createAndStart(elasticVersion);
+ client = ElasticTestUtils.createHttpAsyncClient(container);
+ client.start();
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testErrorResponseFromGroupIndex() throws Exception {
+ GroupApi group = gApi.groups().create("test");
+ group.index();
+
+ ElasticTestUtils.closeIndex(client, container, testName);
+ StorageException thrown = assertThrows(StorageException.class, () -> group.index());
+ assertThat(thrown).hasMessageThat().contains("Failed to replace group");
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java
new file mode 100644
index 0000000..5f4847c
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticAbstractQueryProjectsTest.java
@@ -0,0 +1,79 @@
+// Copyright (C) 2024 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.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.extensions.api.projects.ProjectApi;
+import com.google.gerrit.server.query.project.AbstractQueryProjectsTest;
+import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Injector;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.eclipse.jgit.lib.Config;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public abstract class ElasticAbstractQueryProjectsTest extends AbstractQueryProjectsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return ElasticTestUtils.createConfig();
+ }
+
+ @ConfigSuite.Config
+ public static Config searchAfterPaginationType() {
+ Config config = defaultConfig();
+ config.setString("index", null, "paginationType", "SEARCH_AFTER");
+ return config;
+ }
+
+ private static ElasticContainer container;
+ private static CloseableHttpAsyncClient client;
+
+ protected static void startIndexService(ElasticVersion elasticVersion) {
+ container = ElasticContainer.createAndStart(elasticVersion);
+ client = ElasticTestUtils.createHttpAsyncClient(container);
+ client.start();
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testErrorResponseFromProjectIndex() throws Exception {
+ ProjectApi project = gApi.projects().create("test");
+ project.index(false);
+
+ ElasticTestUtils.closeIndex(client, container, testName);
+ StorageException thrown = assertThrows(StorageException.class, () -> project.index(false));
+ assertThat(thrown).hasMessageThat().contains("Failed to replace project");
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java
index 86b1bac..a65e57c 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -15,11 +15,13 @@
package com.google.gerrit.elasticsearch;
import com.google.common.flogger.FluentLogger;
+import java.nio.file.Path;
import org.apache.http.HttpHost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.ContainerLaunchException;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
+import org.testcontainers.images.builder.Transferable;
import org.testcontainers.utility.DockerImageName;
/* Helper class for running ES integration tests in docker container */
@@ -30,6 +32,51 @@
public static ElasticContainer createAndStart(ElasticVersion version) {
ElasticContainer container = new ElasticContainer(version);
try {
+ Path certs = Path.of("/usr/share/elasticsearch/config/certs");
+ String customizedCertPath = certs.resolve("http_ca_customized.crt").toString();
+ String sslKeyPath = certs.resolve("elasticsearch.key").toString();
+ String sslCrtPath = certs.resolve("elasticsearch.crt").toString();
+ container =
+ (ElasticContainer)
+ container
+ .withPassword(ElasticsearchContainer.ELASTICSEARCH_DEFAULT_PASSWORD)
+ .withEnv("xpack.security.enabled", "true")
+ .withEnv("xpack.security.http.ssl.enabled", "true")
+ .withEnv("xpack.security.http.ssl.key", sslKeyPath)
+ .withEnv("xpack.security.http.ssl.certificate", sslCrtPath)
+ .withEnv("xpack.security.http.ssl.certificate_authorities", customizedCertPath)
+ // Create our own cert so that the gerrit-ci docker hostname
+ // matches the certificate subject. Otherwise we get an error like:
+ // Host name '10.0.1.1' does not match the certificate subject provided by the
+ // peer (CN=4932da9bab1d)
+ .withCopyToContainer(
+ Transferable.of(
+ "#!/bin/bash\n"
+ + "mkdir -p "
+ + certs.toString()
+ + ";"
+ + "openssl req -x509 -newkey rsa:4096 -keyout "
+ + sslKeyPath
+ + " -out "
+ + sslCrtPath
+ + " -days 365 -nodes -subj \"/CN="
+ + container.getHost()
+ + "\";"
+ + "openssl x509 -outform der -in "
+ + sslCrtPath
+ + " -out "
+ + customizedCertPath
+ + "; chown -R elasticsearch "
+ + certs.toString(),
+ 555),
+ "/usr/share/elasticsearch/generate-certs.sh")
+ // because we need to generate the certificates before Elasticsearch starts, the
+ // entry command has to be adjusted accordingly
+ .withCommand(
+ "sh",
+ "-c",
+ "/usr/share/elasticsearch/generate-certs.sh && /usr/local/bin/docker-entrypoint.sh")
+ .withCertPath(customizedCertPath);
container.start();
} catch (ContainerLaunchException e) {
logger.atSevere().log(
@@ -39,16 +86,20 @@
return container;
}
- private static String getImageName(ElasticVersion version) {
+ private static DockerImageName getImageName(ElasticVersion version) {
+ DockerImageName image = DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch");
switch (version) {
case V7_16:
- return "docker.elastic.co/elasticsearch/elasticsearch:7.16.2";
+ return image.withTag("7.16.2");
+ case V8_9:
+ return image.withTag("8.9.2");
}
throw new IllegalStateException("No tests for version: " + version.name());
}
private ElasticContainer(ElasticVersion version) {
- super(DockerImageName.parse(getImageName(version)));
+ super(getImageName(version));
+ withEnv("action.destructive_requires_name", "false");
}
@Override
@@ -57,6 +108,7 @@
}
public HttpHost getHttpHost() {
- return new HttpHost(getContainerIpAddress(), getMappedPort(ELASTICSEARCH_DEFAULT_PORT));
+ String protocol = caCertAsBytes().isPresent() ? "https://" : "http://";
+ return HttpHost.create(protocol + getHttpHostAddress());
}
}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticContainerRestClientProvider.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainerRestClientProvider.java
new file mode 100644
index 0000000..5b8ad40
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticContainerRestClientProvider.java
@@ -0,0 +1,37 @@
+// Copyright (C) 2024 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.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+
+@Singleton
+class ElasticContainerRestClientProvider extends ElasticRestClientProvider {
+ private final ElasticContainer container;
+
+ @Inject
+ ElasticContainerRestClientProvider(ElasticConfiguration cfg, ElasticContainer container) {
+ super(cfg);
+ this.container = container;
+ }
+
+ @Override
+ protected void configureHttpClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {
+ if (container.caCertAsBytes().isPresent()) {
+ httpClientBuilder.setSSLContext(container.createSslContextFromCa());
+ }
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java
index f5ba9db..a280ba5 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticTestUtils.java
@@ -14,32 +14,49 @@
package com.google.gerrit.elasticsearch;
+import static com.google.common.truth.Truth.assertWithMessage;
import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.testcontainers.elasticsearch.ElasticsearchContainer.ELASTICSEARCH_DEFAULT_PASSWORD;
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.AbstractModule;
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.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.apache.http.util.EntityUtils;
import org.eclipse.jgit.lib.Config;
public final class ElasticTestUtils {
+ private static final String ELASTIC_USERNAME = "elastic";
+ private static final String ELASTIC_PASSWORD = ELASTICSEARCH_DEFAULT_PASSWORD;
+
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, "server", container.getHttpHost().toURI());
config.setString("elasticsearch", null, "prefix", prefix);
config.setInt("index", null, "maxLimit", 10000);
+ if (container.caCertAsBytes().isPresent()) {
+ config.setString("elasticsearch", null, "username", ELASTIC_USERNAME);
+ config.setString("elasticsearch", null, "password", ELASTIC_PASSWORD);
+ }
}
public static void createAllIndexes(Injector injector) {
@@ -76,6 +93,20 @@
"com.google.gerrit.elasticsearch.ElasticIndexModule");
}
+ public static class ElasticContainerTestModule extends AbstractModule {
+ private final ElasticContainer container;
+
+ ElasticContainerTestModule(ElasticContainer container) {
+ this.container = container;
+ }
+
+ @Override
+ protected void configure() {
+ bind(ElasticRestClientProvider.class).to(ElasticContainerRestClientProvider.class);
+ bind(ElasticContainer.class).toInstance(container);
+ }
+ }
+
public static Injector createInjector(
Config config, GerritTestName testName, ElasticContainer container) {
Config elasticsearchConfig = new Config(config);
@@ -83,23 +114,42 @@
InMemoryModule.setDefaults(elasticsearchConfig);
String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix);
- return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
+ return Guice.createInjector(
+ new ElasticContainerTestModule(container), new InMemoryModule(elasticsearchConfig));
+ }
+
+ public static CloseableHttpAsyncClient createHttpAsyncClient(ElasticContainer container) {
+ HttpAsyncClientBuilder builder = HttpAsyncClients.custom();
+ if (container.caCertAsBytes().isPresent()) {
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(
+ AuthScope.ANY, new UsernamePasswordCredentials(ELASTIC_USERNAME, ELASTIC_PASSWORD));
+ builder
+ .setSSLContext(container.createSslContextFromCa())
+ .setDefaultCredentialsProvider(credentialsProvider);
+ }
+ return builder.build();
}
public static void closeIndex(
CloseableHttpAsyncClient client, ElasticContainer container, GerritTestName testName)
throws Exception {
- 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);
+ HttpResponse response =
+ client
+ .execute(
+ new HttpPost(
+ String.format(
+ "%s/%s*/_close",
+ container.getHttpHost().toURI(), testName.getSanitizedMethodName())),
+ HttpClientContext.create(),
+ null)
+ .get(5, MINUTES);
+ int statusCode = response.getStatusLine().getStatusCode();
+ assertWithMessage(
+ "response status code should be %s, but was %s. Full response was %s",
+ HttpStatus.SC_OK, statusCode, EntityUtils.toString(response.getEntity()))
+ .that(statusCode)
+ .isEqualTo(HttpStatus.SC_OK);
}
private ElasticTestUtils() {
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
index 7f6a585..a9c8361 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -14,68 +14,11 @@
package com.google.gerrit.elasticsearch;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.server.query.account.AbstractQueryAccountsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.inject.Injector;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClients;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Test;
-public class ElasticV7QueryAccountsTest extends AbstractQueryAccountsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return ElasticTestUtils.createConfig();
- }
-
- @ConfigSuite.Config
- public static Config searchAfterPaginationType() {
- Config config = defaultConfig();
- config.setString("index", null, "paginationType", "SEARCH_AFTER");
- return config;
- }
-
- private static ElasticContainer container;
- private static CloseableHttpAsyncClient client;
-
+public class ElasticV7QueryAccountsTest extends ElasticAbstractQueryAccountsTest {
@BeforeClass
public static void startIndexService() {
- container = ElasticContainer.createAndStart(ElasticVersion.V7_16);
- client = HttpAsyncClients.createDefault();
- client.start();
- }
-
- @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);
- }
-
- @Test
- public void testErrorResponseFromAccountIndex() throws Exception {
- gApi.accounts().self().index();
-
- ElasticTestUtils.closeIndex(client, container, testName);
- StorageException thrown =
- assertThrows(StorageException.class, () -> gApi.accounts().self().index());
- assertThat(thrown).hasMessageThat().contains("Failed to replace account");
+ startIndexService(ElasticVersion.V7_16);
}
}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
index 9160b9e..9961987 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -14,85 +14,11 @@
package com.google.gerrit.elasticsearch;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.exceptions.StorageException;
-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;
-import com.google.inject.Injector;
-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();
- }
-
- @ConfigSuite.Config
- public static Config searchAfterPaginationType() {
- Config config = defaultConfig();
- config.setString("index", null, "paginationType", "SEARCH_AFTER");
- return config;
- }
-
- private static ElasticContainer container;
- private static CloseableHttpAsyncClient client;
-
+public class ElasticV7QueryChangesTest extends ElasticAbstractQueryChangesTest {
@BeforeClass
public static void startIndexService() {
- container = ElasticContainer.createAndStart(ElasticVersion.V7_16);
- 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).
- ElasticTestUtils.closeIndex(client, container, testName);
- }
-
- @Override
- protected void initAfterLifecycleStart() throws Exception {
- super.initAfterLifecycleStart();
- ElasticTestUtils.createAllIndexes(injector);
- }
-
- @Override
- protected Injector createInjector() {
- return ElasticTestUtils.createInjector(config, testName, container);
- }
-
- @Test
- public void testErrorResponseFromChangeIndex() throws Exception {
- TestRepository<InMemoryRepositoryManager.Repo> repo = createProject("repo");
- Change c = insert(repo, newChangeWithStatus(repo, Change.Status.NEW));
- gApi.changes().id(c.getChangeId()).index();
-
- ElasticTestUtils.closeIndex(client, container, testName);
- StorageException thrown =
- assertThrows(StorageException.class, () -> gApi.changes().id(c.getChangeId()).index());
- assertThat(thrown).hasMessageThat().contains("Failed to reindex change");
+ startIndexService(ElasticVersion.V7_16);
}
}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
index 271ee19..9a48181 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -14,69 +14,11 @@
package com.google.gerrit.elasticsearch;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.extensions.api.groups.GroupApi;
-import com.google.gerrit.server.query.group.AbstractQueryGroupsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.inject.Injector;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClients;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Test;
-public class ElasticV7QueryGroupsTest extends AbstractQueryGroupsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return ElasticTestUtils.createConfig();
- }
-
- @ConfigSuite.Config
- public static Config searchAfterPaginationType() {
- Config config = defaultConfig();
- config.setString("index", null, "paginationType", "SEARCH_AFTER");
- return config;
- }
-
- private static ElasticContainer container;
- private static CloseableHttpAsyncClient client;
-
+public class ElasticV7QueryGroupsTest extends ElasticAbstractQueryGroupsTest {
@BeforeClass
public static void startIndexService() {
- container = ElasticContainer.createAndStart(ElasticVersion.V7_16);
- client = HttpAsyncClients.createDefault();
- client.start();
- }
-
- @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);
- }
-
- @Test
- public void testErrorResponseFromGroupIndex() throws Exception {
- GroupApi group = gApi.groups().create("test");
- group.index();
-
- ElasticTestUtils.closeIndex(client, container, testName);
- StorageException thrown = assertThrows(StorageException.class, () -> group.index());
- assertThat(thrown).hasMessageThat().contains("Failed to replace group");
+ startIndexService(ElasticVersion.V7_16);
}
}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
index 38eef22..f37bbff 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -14,69 +14,11 @@
package com.google.gerrit.elasticsearch;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.extensions.api.projects.ProjectApi;
-import com.google.gerrit.server.query.project.AbstractQueryProjectsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.inject.Injector;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClients;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Test;
-public class ElasticV7QueryProjectsTest extends AbstractQueryProjectsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return ElasticTestUtils.createConfig();
- }
-
- @ConfigSuite.Config
- public static Config searchAfterPaginationType() {
- Config config = defaultConfig();
- config.setString("index", null, "paginationType", "SEARCH_AFTER");
- return config;
- }
-
- private static ElasticContainer container;
- private static CloseableHttpAsyncClient client;
-
+public class ElasticV7QueryProjectsTest extends ElasticAbstractQueryProjectsTest {
@BeforeClass
public static void startIndexService() {
- container = ElasticContainer.createAndStart(ElasticVersion.V7_16);
- client = HttpAsyncClients.createDefault();
- client.start();
- }
-
- @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);
- }
-
- @Test
- public void testErrorResponseFromProjectIndex() throws Exception {
- ProjectApi project = gApi.projects().create("test");
- project.index(false);
-
- ElasticTestUtils.closeIndex(client, container, testName);
- StorageException thrown = assertThrows(StorageException.class, () -> project.index(false));
- assertThat(thrown).hasMessageThat().contains("Failed to replace project");
+ startIndexService(ElasticVersion.V7_16);
}
}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryAccountsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryAccountsTest.java
new file mode 100644
index 0000000..b1ef2e5
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryAccountsTest.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 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.junit.BeforeClass;
+
+public class ElasticV8QueryAccountsTest extends ElasticAbstractQueryAccountsTest {
+ @BeforeClass
+ public static void startIndexService() {
+ startIndexService(ElasticVersion.V8_9);
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryChangesTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryChangesTest.java
new file mode 100644
index 0000000..a9a220d
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryChangesTest.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 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.junit.BeforeClass;
+
+public class ElasticV8QueryChangesTest extends ElasticAbstractQueryChangesTest {
+ @BeforeClass
+ public static void startIndexService() {
+ startIndexService(ElasticVersion.V8_9);
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryGroupsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryGroupsTest.java
new file mode 100644
index 0000000..37a204d
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryGroupsTest.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 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.junit.BeforeClass;
+
+public class ElasticV8QueryGroupsTest extends ElasticAbstractQueryGroupsTest {
+ @BeforeClass
+ public static void startIndexService() {
+ startIndexService(ElasticVersion.V8_9);
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryProjectsTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryProjectsTest.java
new file mode 100644
index 0000000..ace5767
--- /dev/null
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticV8QueryProjectsTest.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 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.junit.BeforeClass;
+
+public class ElasticV8QueryProjectsTest extends ElasticAbstractQueryProjectsTest {
+ @BeforeClass
+ public static void startIndexService() {
+ startIndexService(ElasticVersion.V8_9);
+ }
+}
diff --git a/src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java
index ea7782b..b750466 100644
--- a/src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java
+++ b/src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java
@@ -24,6 +24,10 @@
public void supportedVersion() throws Exception {
assertThat(ElasticVersion.forVersion("7.16.0")).isEqualTo(ElasticVersion.V7_16);
assertThat(ElasticVersion.forVersion("7.16.1")).isEqualTo(ElasticVersion.V7_16);
+
+ assertThat(ElasticVersion.forVersion("8.9.0")).isEqualTo(ElasticVersion.V8_9);
+ assertThat(ElasticVersion.forVersion("8.9.1")).isEqualTo(ElasticVersion.V8_9);
+ assertThat(ElasticVersion.forVersion("8.9.2")).isEqualTo(ElasticVersion.V8_9);
}
@Test