Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  ElasticReindexIT: Add tests against Elasticsearch version 5
  Elasticsearch: Add tests for queries against version 5
  MatchQueryBuilder: Don't use deprecated "match" query
  Elasticsearch: Add an adapter to support V5
  Add Bazel version check

Change-Id: I72f7ce2f87061f1799abc1a73f57b93a2859b6b6
This commit is contained in:
David Pursehouse
2018-06-05 11:03:10 +09:00
18 changed files with 358 additions and 52 deletions

View File

@@ -4,6 +4,13 @@ load("//tools/bzl:maven_jar.bzl", "maven_jar", "GERRIT", "MAVEN_LOCAL")
load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION") load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION")
load("//plugins:external_plugin_deps.bzl", "external_plugin_deps") load("//plugins:external_plugin_deps.bzl", "external_plugin_deps")
http_archive(
name = "bazel_skylib",
sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d",
strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"],
)
http_archive( http_archive(
name = "io_bazel_rules_closure", name = "io_bazel_rules_closure",
sha256 = "6691c58a2cd30a86776dd9bb34898b041e37136f2dc7e24cadaeaf599c95c657", sha256 = "6691c58a2cd30a86776dd9bb34898b041e37136f2dc7e24cadaeaf599c95c657",
@@ -20,6 +27,10 @@ http_file(
url = "https://raw.githubusercontent.com/google/closure-compiler/775609aad61e14aef289ebec4bfc09ad88877f9e/contrib/externs/polymer-1.0.js", url = "https://raw.githubusercontent.com/google/closure-compiler/775609aad61e14aef289ebec4bfc09ad88877f9e/contrib/externs/polymer-1.0.js",
) )
load("@bazel_skylib//:lib.bzl", "versions")
versions.check(minimum_bazel_version = "0.7.0")
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories") load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
# Prevent redundant loading of dependencies. # Prevent redundant loading of dependencies.

View File

@@ -50,7 +50,6 @@ import org.elasticsearch.client.Response;
abstract class AbstractElasticIndex<K, V> implements Index<K, V> { abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
protected static final String BULK = "_bulk"; protected static final String BULK = "_bulk";
protected static final String IGNORE_UNMAPPED = "ignore_unmapped";
protected static final String ORDER = "order"; protected static final String ORDER = "order";
protected static final String SEARCH = "_search"; protected static final String SEARCH = "_search";
@@ -80,8 +79,8 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
private final Schema<V> schema; private final Schema<V> schema;
private final SitePaths sitePaths; private final SitePaths sitePaths;
private final String indexNameRaw; private final String indexNameRaw;
private final ElasticRestClientProvider client;
protected final ElasticRestClientProvider client;
protected final String indexName; protected final String indexName;
protected final Gson gson; protected final Gson gson;
protected final ElasticQueryBuilder queryBuilder; protected final ElasticQueryBuilder queryBuilder;
@@ -130,7 +129,8 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
@Override @Override
public void deleteAll() throws IOException { public void deleteAll() throws IOException {
// Delete the index, if it exists. // Delete the index, if it exists.
Response response = client.get().performRequest("HEAD", indexName); String endpoint = indexName + client.adapter().indicesExistParam();
Response response = client.get().performRequest("HEAD", endpoint);
int statusCode = response.getStatusLine().getStatusCode(); int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) { if (statusCode == HttpStatus.SC_OK) {
response = client.get().performRequest("DELETE", indexName); response = client.get().performRequest("DELETE", indexName);
@@ -182,7 +182,7 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
protected JsonArray getSortArray(String idFieldName) { protected JsonArray getSortArray(String idFieldName) {
JsonObject properties = new JsonObject(); JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "asc"); properties.addProperty(ORDER, "asc");
properties.addProperty(IGNORE_UNMAPPED, true); client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray(); JsonArray sortArray = new JsonArray();
addNamedElement(idFieldName, properties, sortArray); addNamedElement(idFieldName, properties, sortArray);

View File

@@ -61,8 +61,8 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
public static class AccountMapping { public static class AccountMapping {
MappingProperties accounts; MappingProperties accounts;
public AccountMapping(Schema<AccountState> schema) { public AccountMapping(Schema<AccountState> schema, ElasticQueryAdapter adapter) {
this.accounts = ElasticMapping.createMapping(schema); this.accounts = ElasticMapping.createMapping(schema, adapter);
} }
} }
@@ -83,7 +83,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
@Assisted Schema<AccountState> schema) { @Assisted Schema<AccountState> schema) {
super(cfg, sitePaths, schema, client, ACCOUNTS); super(cfg, sitePaths, schema, client, ACCOUNTS);
this.accountCache = accountCache; this.accountCache = accountCache;
this.mapping = new AccountMapping(schema); this.mapping = new AccountMapping(schema, client.adapter());
this.schema = schema; this.schema = schema;
} }
@@ -133,7 +133,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
QueryBuilder qb = queryBuilder.toQueryBuilder(p); QueryBuilder qb = queryBuilder.toQueryBuilder(p);
fields = IndexUtils.accountFields(opts); fields = IndexUtils.accountFields(opts);
SearchSourceBuilder searchSource = SearchSourceBuilder searchSource =
new SearchSourceBuilder() new SearchSourceBuilder(client.adapter())
.query(qb) .query(qb)
.from(opts.start()) .from(opts.start())
.size(opts.limit()) .size(opts.limit())

View File

@@ -87,8 +87,8 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
MappingProperties openChanges; MappingProperties openChanges;
MappingProperties closedChanges; MappingProperties closedChanges;
ChangeMapping(Schema<ChangeData> schema) { ChangeMapping(Schema<ChangeData> schema, ElasticQueryAdapter adapter) {
MappingProperties mapping = ElasticMapping.createMapping(schema); MappingProperties mapping = ElasticMapping.createMapping(schema, adapter);
this.openChanges = mapping; this.openChanges = mapping;
this.closedChanges = mapping; this.closedChanges = mapping;
} }
@@ -115,7 +115,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
this.db = db; this.db = db;
this.changeDataFactory = changeDataFactory; this.changeDataFactory = changeDataFactory;
this.schema = schema; this.schema = schema;
mapping = new ChangeMapping(schema); this.mapping = new ChangeMapping(schema, client.adapter());
} }
@Override @Override
@@ -189,7 +189,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
QueryBuilder qb = queryBuilder.toQueryBuilder(p); QueryBuilder qb = queryBuilder.toQueryBuilder(p);
fields = IndexUtils.changeFields(opts); fields = IndexUtils.changeFields(opts);
SearchSourceBuilder searchSource = SearchSourceBuilder searchSource =
new SearchSourceBuilder() new SearchSourceBuilder(client.adapter())
.query(qb) .query(qb)
.from(opts.start()) .from(opts.start())
.size(opts.limit()) .size(opts.limit())
@@ -431,7 +431,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
private JsonArray getSortArray() { private JsonArray getSortArray() {
JsonObject properties = new JsonObject(); JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "desc"); properties.addProperty(ORDER, "desc");
properties.addProperty(IGNORE_UNMAPPED, true); client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray(); JsonArray sortArray = new JsonArray();
addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray); addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray);

View File

@@ -60,8 +60,8 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
static class GroupMapping { static class GroupMapping {
MappingProperties groups; MappingProperties groups;
GroupMapping(Schema<InternalGroup> schema) { GroupMapping(Schema<InternalGroup> schema, ElasticQueryAdapter adapter) {
this.groups = ElasticMapping.createMapping(schema); this.groups = ElasticMapping.createMapping(schema, adapter);
} }
} }
@@ -82,7 +82,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
@Assisted Schema<InternalGroup> schema) { @Assisted Schema<InternalGroup> schema) {
super(cfg, sitePaths, schema, client, GROUPS); super(cfg, sitePaths, schema, client, GROUPS);
this.groupCache = groupCache; this.groupCache = groupCache;
this.mapping = new GroupMapping(schema); this.mapping = new GroupMapping(schema, client.adapter());
this.schema = schema; this.schema = schema;
} }
@@ -132,7 +132,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
QueryBuilder qb = queryBuilder.toQueryBuilder(p); QueryBuilder qb = queryBuilder.toQueryBuilder(p);
fields = IndexUtils.groupFields(opts); fields = IndexUtils.groupFields(opts);
SearchSourceBuilder searchSource = SearchSourceBuilder searchSource =
new SearchSourceBuilder() new SearchSourceBuilder(client.adapter())
.query(qb) .query(qb)
.from(opts.start()) .from(opts.start())
.size(opts.limit()) .size(opts.limit())

View File

@@ -21,13 +21,15 @@ import com.google.gerrit.index.Schema;
import java.util.Map; import java.util.Map;
class ElasticMapping { class ElasticMapping {
static MappingProperties createMapping(Schema<?> schema) { static MappingProperties createMapping(Schema<?> schema, ElasticQueryAdapter adapter) {
ElasticMapping.Builder mapping = new ElasticMapping.Builder(); ElasticMapping.Builder mapping = new ElasticMapping.Builder(adapter);
for (FieldDef<?, ?> field : schema.getFields().values()) { for (FieldDef<?, ?> field : schema.getFields().values()) {
String name = field.getName(); String name = field.getName();
FieldType<?> fieldType = field.getType(); FieldType<?> fieldType = field.getType();
if (fieldType == FieldType.EXACT || fieldType == FieldType.KEYWORD) { if (fieldType == FieldType.EXACT) {
mapping.addExactField(name); mapping.addExactField(name);
} else if (fieldType == FieldType.KEYWORD) {
mapping.addKeywordField(name);
} else if (fieldType == FieldType.TIMESTAMP) { } else if (fieldType == FieldType.TIMESTAMP) {
mapping.addTimestamp(name); mapping.addTimestamp(name);
} else if (fieldType == FieldType.INTEGER } else if (fieldType == FieldType.INTEGER
@@ -46,9 +48,14 @@ class ElasticMapping {
} }
static class Builder { static class Builder {
private final ElasticQueryAdapter adapter;
private final ImmutableMap.Builder<String, FieldProperties> fields = private final ImmutableMap.Builder<String, FieldProperties> fields =
new ImmutableMap.Builder<>(); new ImmutableMap.Builder<>();
Builder(ElasticQueryAdapter adapter) {
this.adapter = adapter;
}
MappingProperties build() { MappingProperties build() {
MappingProperties properties = new MappingProperties(); MappingProperties properties = new MappingProperties();
properties.properties = fields.build(); properties.properties = fields.build();
@@ -56,9 +63,20 @@ class ElasticMapping {
} }
Builder addExactField(String name) { Builder addExactField(String name) {
FieldProperties key = new FieldProperties("string"); FieldProperties key = new FieldProperties(adapter.keywordFieldType());
key.index = "not_analyzed"; key.index = adapter.indexProperty();
FieldProperties properties = new FieldProperties("string"); FieldProperties properties;
properties = new FieldProperties(adapter.stringFieldType());
properties.fields = ImmutableMap.of("key", key);
fields.put(name, properties);
return this;
}
Builder addKeywordField(String name) {
FieldProperties key = new FieldProperties(adapter.keywordFieldType());
key.index = adapter.indexProperty();
FieldProperties properties;
properties = new FieldProperties(adapter.keywordFieldType());
properties.fields = ImmutableMap.of("key", key); properties.fields = ImmutableMap.of("key", key);
fields.put(name, properties); fields.put(name, properties);
return this; return this;
@@ -78,7 +96,7 @@ class ElasticMapping {
} }
Builder addString(String name) { Builder addString(String name) {
fields.put(name, new FieldProperties("string")); fields.put(name, new FieldProperties(adapter.stringFieldType()));
return this; return this;
} }

View File

@@ -0,0 +1,74 @@
// 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.gson.JsonObject;
public class ElasticQueryAdapter {
private final boolean ignoreUnmapped;
private final String searchFilteringName;
private final String indicesExistParam;
private final String keywordFieldType;
private final String stringFieldType;
private final String indexProperty;
ElasticQueryAdapter(ElasticVersion version) {
this.ignoreUnmapped = version == ElasticVersion.V2_4;
switch (version) {
case V5_6:
case V6_2:
this.searchFilteringName = "_source";
this.indicesExistParam = "?allow_no_indices=false";
this.keywordFieldType = "keyword";
this.stringFieldType = "text";
this.indexProperty = "true";
break;
case V2_4:
default:
this.searchFilteringName = "fields";
this.indicesExistParam = "";
this.keywordFieldType = "string";
this.stringFieldType = "string";
this.indexProperty = "not_analyzed";
break;
}
}
void setIgnoreUnmapped(JsonObject properties) {
if (ignoreUnmapped) {
properties.addProperty("ignore_unmapped", true);
}
}
public String searchFilteringName() {
return searchFilteringName;
}
String indicesExistParam() {
return indicesExistParam;
}
String keywordFieldType() {
return keywordFieldType;
}
String stringFieldType() {
return stringFieldType;
}
String indexProperty() {
return indexProperty;
}
}

View File

@@ -44,6 +44,7 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
private final String password; private final String password;
private RestClient client; private RestClient client;
private ElasticQueryAdapter adapter;
@Inject @Inject
ElasticRestClientProvider(ElasticConfiguration cfg) { ElasticRestClientProvider(ElasticConfiguration cfg) {
@@ -69,6 +70,7 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
client = build(); client = build();
ElasticVersion version = getVersion(); ElasticVersion version = getVersion();
log.info("Elasticsearch integration version {}", version); log.info("Elasticsearch integration version {}", version);
adapter = new ElasticQueryAdapter(version);
} }
} }
} }
@@ -89,6 +91,11 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
} }
} }
ElasticQueryAdapter adapter() {
get(); // Make sure we're connected
return adapter;
}
public static class FailedToGetVersion extends ElasticException { public static class FailedToGetVersion extends ElasticException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String MESSAGE = "Failed to get Elasticsearch version"; private static final String MESSAGE = "Failed to get Elasticsearch version";

View File

@@ -27,9 +27,14 @@ class MatchQueryBuilder extends QueryBuilder {
enum Type { enum Type {
/** The text is analyzed and used as a phrase query. */ /** The text is analyzed and used as a phrase query. */
PHRASE, MATCH_PHRASE,
/** The text is analyzed and used in a phrase query, with the last term acting as a prefix. */ /** The text is analyzed and used in a phrase query, with the last term acting as a prefix. */
PHRASE_PREFIX MATCH_PHRASE_PREFIX;
@Override
public String toString() {
return name().toLowerCase(Locale.US);
}
} }
private final String name; private final String name;
@@ -52,14 +57,6 @@ class MatchQueryBuilder extends QueryBuilder {
@Override @Override
protected void doXContent(XContentBuilder builder) throws IOException { protected void doXContent(XContentBuilder builder) throws IOException {
builder.startObject("match"); builder.startObject(type.toString()).field(name, text).endObject();
builder.startObject(name);
builder.field("query", text);
if (type != null) {
builder.field("type", type.toString().toLowerCase(Locale.ENGLISH));
}
builder.endObject();
builder.endObject();
} }
} }

View File

@@ -33,7 +33,7 @@ public abstract class QueryBuilders {
* @param text The query text (to be analyzed). * @param text The query text (to be analyzed).
*/ */
public static MatchQueryBuilder matchPhraseQuery(String name, Object text) { public static MatchQueryBuilder matchPhraseQuery(String name, Object text) {
return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.PHRASE); return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.MATCH_PHRASE);
} }
/** /**
@@ -43,7 +43,7 @@ public abstract class QueryBuilders {
* @param text The query text (to be analyzed). * @param text The query text (to be analyzed).
*/ */
public static MatchQueryBuilder matchPhrasePrefixQuery(String name, Object text) { public static MatchQueryBuilder matchPhrasePrefixQuery(String name, Object text) {
return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.PHRASE_PREFIX); return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.MATCH_PHRASE_PREFIX);
} }
/** /**

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.elasticsearch.builders; package com.google.gerrit.elasticsearch.builders;
import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@@ -23,6 +24,7 @@ import java.util.List;
* <p>A trimmed down and modified version of org.elasticsearch.search.builder.SearchSourceBuilder. * <p>A trimmed down and modified version of org.elasticsearch.search.builder.SearchSourceBuilder.
*/ */
public class SearchSourceBuilder { public class SearchSourceBuilder {
private final ElasticQueryAdapter adapter;
private QuerySourceBuilder querySourceBuilder; private QuerySourceBuilder querySourceBuilder;
@@ -33,7 +35,9 @@ public class SearchSourceBuilder {
private List<String> fieldNames; private List<String> fieldNames;
/** Constructs a new search source builder. */ /** Constructs a new search source builder. */
public SearchSourceBuilder() {} public SearchSourceBuilder(ElasticQueryAdapter adapter) {
this.adapter = adapter;
}
/** Constructs a new search source builder with a search query. */ /** Constructs a new search source builder with a search query. */
public SearchSourceBuilder query(QueryBuilder query) { public SearchSourceBuilder query(QueryBuilder query) {
@@ -95,9 +99,9 @@ public class SearchSourceBuilder {
if (fieldNames != null) { if (fieldNames != null) {
if (fieldNames.size() == 1) { if (fieldNames.size() == 1) {
builder.field("fields", fieldNames.get(0)); builder.field(adapter.searchFilteringName(), fieldNames.get(0));
} else { } else {
builder.startArray("fields"); builder.startArray(adapter.searchFilteringName());
for (String fieldName : fieldNames) { for (String fieldName : fieldNames) {
builder.value(fieldName); builder.value(fieldName);
} }

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.elasticsearch; package com.google.gerrit.elasticsearch;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gerrit.elasticsearch.ElasticVersion;
import java.util.Set; import java.util.Set;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.junit.internal.AssumptionViolatedException; import org.junit.internal.AssumptionViolatedException;

View File

@@ -17,14 +17,11 @@ package com.google.gerrit.elasticsearch;
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo; import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
import com.google.gerrit.server.query.change.AbstractQueryChangesTest; import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testutil.InMemoryModule; import com.google.gerrit.testutil.InMemoryModule;
import com.google.gerrit.testutil.InMemoryRepositoryManager.Repo;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
public class ElasticQueryChangesTest extends AbstractQueryChangesTest { public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
private static ElasticNodeInfo nodeInfo; private static ElasticNodeInfo nodeInfo;
@@ -66,12 +63,4 @@ public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix); ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration)); return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
} }
@Test
public void byOwnerInvalidQuery() throws Exception {
TestRepository<Repo> repo = createProject("repo");
insert(repo, newChange(repo), userId);
String nameEmail = user.asIdentifiedUser().getNameEmail();
assertQuery("owner: \"" + nameEmail + "\"\\");
}
} }

View File

@@ -0,0 +1,66 @@
// 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.testutil.InMemoryModule;
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 ElasticV5QueryAccountsTest extends AbstractQueryAccountsTest {
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.V5_6);
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));
}
}

View File

@@ -0,0 +1,66 @@
// 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.testutil.InMemoryModule;
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 ElasticV5QueryChangesTest extends AbstractQueryChangesTest {
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.V5_6);
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));
}
}

View File

@@ -0,0 +1,66 @@
// 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.testutil.InMemoryModule;
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 ElasticV5QueryGroupsTest extends AbstractQueryGroupsTest {
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.V5_6);
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));
}
}

View File

@@ -2593,6 +2593,14 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
assertQuery("query:query4"); assertQuery("query:query4");
} }
@Test
public void byOwnerInvalidQuery() throws Exception {
TestRepository<Repo> repo = createProject("repo");
insert(repo, newChange(repo), userId);
String nameEmail = user.asIdentifiedUser().getNameEmail();
assertQuery("owner: \"" + nameEmail + "\"\\");
}
protected ChangeInserter newChange(TestRepository<Repo> repo) throws Exception { protected ChangeInserter newChange(TestRepository<Repo> repo) throws Exception {
return newChange(repo, null, null, null, null, false); return newChange(repo, null, null, null, null, false);
} }

View File

@@ -64,6 +64,7 @@ public class LuceneQueryChangesTest extends AbstractQueryChangesTest {
} }
@Test @Test
@Override
public void byOwnerInvalidQuery() throws Exception { public void byOwnerInvalidQuery() throws Exception {
TestRepository<Repo> repo = createProject("repo"); TestRepository<Repo> repo = createProject("repo");
Change change1 = insert(repo, newChange(repo), userId); Change change1 = insert(repo, newChange(repo), userId);