Make indexes available during init invoked by tests

Tests do site initialization, but during this site initialization the
indexes were not available. Due to this SchemaCreator had to do a null
check on the search index when indexing new groups.

Add the necessary Guice bindings to make the indexes available during
init that is triggered by tests and ensure that the indexes are
properly started before and stopped after the site initialization.

Change-Id: Id2bd2157239f39395e594438fe877253a4906704
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2017-01-25 15:39:21 +01:00
parent 4a4db8cfbe
commit c3fe0838cc
6 changed files with 55 additions and 21 deletions

View File

@@ -124,6 +124,7 @@ java_library(
"//lib/powermock:powermock-module-junit4-common", "//lib/powermock:powermock-module-junit4-common",
], ],
deps = TESTUTIL_DEPS + [ deps = TESTUTIL_DEPS + [
"//gerrit-pgm:init",
"//lib/auto:auto-value", "//lib/auto:auto-value",
"//lib/easymock:easymock", "//lib/easymock:easymock",
"//lib/powermock:powermock-api-easymock", "//lib/powermock:powermock-api-easymock",

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.index.change; package com.google.gerrit.server.index.change;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.index.IndexDefinition; import com.google.gerrit.server.index.IndexDefinition;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
@@ -27,7 +28,7 @@ public class ChangeIndexDefinition
ChangeIndexDefinition( ChangeIndexDefinition(
ChangeIndexCollection indexCollection, ChangeIndexCollection indexCollection,
ChangeIndex.Factory indexFactory, ChangeIndex.Factory indexFactory,
AllChangesIndexer allChangesIndexer) { @Nullable AllChangesIndexer allChangesIndexer) {
super(ChangeSchemaDefinitions.INSTANCE, indexCollection, indexFactory, super(ChangeSchemaDefinitions.INSTANCE, indexCollection, indexFactory,
Providers.of(allChangesIndexer)); Providers.of(allChangesIndexer));
} }

View File

@@ -118,9 +118,7 @@ public class SchemaCreator {
} }
private void index(AccountGroup group) throws IOException { private void index(AccountGroup group) throws IOException {
if (indexCollection.getSearchIndex() != null) { indexCollection.getSearchIndex().replace(group);
indexCollection.getSearchIndex().replace(group);
}
} }
private AccountGroup newGroup(ReviewDb c, String name, AccountGroup.UUID uuid) private AccountGroup newGroup(ReviewDb c, String name, AccountGroup.UUID uuid)

View File

@@ -57,6 +57,7 @@ import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider; import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.ProjectConfig; import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.schema.SchemaCreator; import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.RequestContext; import com.google.gerrit.server.util.RequestContext;
@@ -240,6 +241,7 @@ public class RefControlTest {
@Inject private CapabilityCollection.Factory capabilityCollectionFactory; @Inject private CapabilityCollection.Factory capabilityCollectionFactory;
@Inject private CapabilityControl.Factory capabilityControlFactory; @Inject private CapabilityControl.Factory capabilityControlFactory;
@Inject private SchemaCreator schemaCreator; @Inject private SchemaCreator schemaCreator;
@Inject private SingleVersionListener singleVersionListener;
@Inject private InMemoryDatabase schemaFactory; @Inject private InMemoryDatabase schemaFactory;
@Inject private ThreadLocalRequestContext requestContext; @Inject private ThreadLocalRequestContext requestContext;
@Inject private Provider<InternalChangeQuery> queryProvider; @Inject private Provider<InternalChangeQuery> queryProvider;
@@ -317,7 +319,12 @@ public class RefControlTest {
} }
db = schemaFactory.open(); db = schemaFactory.open();
schemaCreator.create(db); singleVersionListener.start();
try {
schemaCreator.create(db);
} finally {
singleVersionListener.stop();
}
Cache<SectionSortCache.EntryKey, SectionSortCache.EntryVal> c = Cache<SectionSortCache.EntryKey, SectionSortCache.EntryVal> c =
CacheBuilder.newBuilder().build(); CacheBuilder.newBuilder().build();

View File

@@ -17,10 +17,13 @@ package com.google.gerrit.testutil;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.lifecycle.LifecycleManager; import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.pgm.init.index.elasticsearch.ElasticIndexModuleOnInit;
import com.google.gerrit.pgm.init.index.lucene.LuceneIndexModuleOnInit;
import com.google.gerrit.reviewdb.client.CurrentSchemaVersion; import com.google.gerrit.reviewdb.client.CurrentSchemaVersion;
import com.google.gerrit.reviewdb.client.SystemConfig; import com.google.gerrit.reviewdb.client.SystemConfig;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.index.group.GroupIndexCollection; import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.schema.SchemaCreator; import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.schema.SchemaVersion; import com.google.gerrit.server.schema.SchemaVersion;
import com.google.gwtorm.jdbc.Database; import com.google.gwtorm.jdbc.Database;
@@ -73,6 +76,8 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
} }
private final SchemaCreator schemaCreator; private final SchemaCreator schemaCreator;
private final SingleVersionListener singleVersionListener;
private Connection openHandle; private Connection openHandle;
private Database<ReviewDb> database; private Database<ReviewDb> database;
@@ -80,25 +85,35 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
@Inject @Inject
InMemoryDatabase(Injector injector) throws OrmException { InMemoryDatabase(Injector injector) throws OrmException {
// Don't inject SchemaCreator directly. Injector childInjector = injector.createChildInjector(new AbstractModule() {
// SchemaCreator needs to get GroupIndexCollection injected, but
// GroupIndexCollection was not bound yet. Creating a child injector with a
// binding for GroupIndexCollection to create an instance of SchemaCreator
// prevents that Guice creates a just-in-time binding for
// GroupIndexCollection in the root injector. If a binding for
// GroupIndexCollection is created in the root injector then IndexModule
// fails to create this binding later, because it already exists.
this(injector.createChildInjector(new AbstractModule() {
@Override @Override
protected void configure() { protected void configure() {
bind(GroupIndexCollection.class); switch (IndexModule.getIndexType(injector)) {
case LUCENE:
install(new LuceneIndexModuleOnInit());
break;
case ELASTICSEARCH:
install(new ElasticIndexModuleOnInit());
break;
default:
throw new IllegalStateException("unsupported index.type");
}
} }
}).getInstance(SchemaCreator.class)); });
this.schemaCreator = childInjector.getInstance(SchemaCreator.class);
this.singleVersionListener =
childInjector.getInstance(SingleVersionListener.class);
initDatabase();
} }
InMemoryDatabase(SchemaCreator schemaCreator) throws OrmException { InMemoryDatabase(SchemaCreator schemaCreator,
SingleVersionListener singleVersionListener) throws OrmException {
this.schemaCreator = schemaCreator; this.schemaCreator = schemaCreator;
this.singleVersionListener = singleVersionListener;
initDatabase();
}
private void initDatabase() throws OrmException {
try { try {
DataSource dataSource = newDataSource(); DataSource dataSource = newDataSource();
@@ -131,9 +146,12 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
if (!created) { if (!created) {
created = true; created = true;
try (ReviewDb c = open()) { try (ReviewDb c = open()) {
singleVersionListener.start();
schemaCreator.create(c); schemaCreator.create(c);
} catch (IOException | ConfigInvalidException e) { } catch (IOException | ConfigInvalidException e) {
throw new OrmException("Cannot create in-memory database", e); throw new OrmException("Cannot create in-memory database", e);
} finally {
singleVersionListener.stop();
} }
} }
return this; return this;

View File

@@ -49,7 +49,11 @@ import com.google.gerrit.server.git.PerThreadRequestScope;
import com.google.gerrit.server.git.SearchingChangeCacheImpl; import com.google.gerrit.server.git.SearchingChangeCacheImpl;
import com.google.gerrit.server.git.SendEmailExecutor; import com.google.gerrit.server.git.SendEmailExecutor;
import com.google.gerrit.server.index.IndexModule.IndexType; import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.index.account.AllAccountsIndexer;
import com.google.gerrit.server.index.change.AllChangesIndexer;
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions; import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
import com.google.gerrit.server.index.group.AllGroupsIndexer;
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
import com.google.gerrit.server.notedb.ChangeBundleReader; import com.google.gerrit.server.notedb.ChangeBundleReader;
import com.google.gerrit.server.notedb.GwtormChangeBundleReader; import com.google.gerrit.server.notedb.GwtormChangeBundleReader;
@@ -73,6 +77,7 @@ import com.google.inject.ProvisionException;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.google.inject.servlet.RequestScoped; import com.google.inject.servlet.RequestScoped;
import com.google.inject.util.Providers;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
@@ -209,6 +214,10 @@ public class InMemoryModule extends FactoryModule {
install(new GpgModule(cfg)); install(new GpgModule(cfg));
install(new H2AccountPatchReviewStore.InMemoryModule()); install(new H2AccountPatchReviewStore.InMemoryModule());
bind(AllAccountsIndexer.class).toProvider(Providers.of(null));
bind(AllChangesIndexer.class).toProvider(Providers.of(null));
bind(AllGroupsIndexer.class).toProvider(Providers.of(null));
IndexType indexType = null; IndexType indexType = null;
try { try {
indexType = cfg.getEnum("index", null, "type", IndexType.LUCENE); indexType = cfg.getEnum("index", null, "type", IndexType.LUCENE);
@@ -239,9 +248,9 @@ public class InMemoryModule extends FactoryModule {
@Provides @Provides
@Singleton @Singleton
InMemoryDatabase getInMemoryDatabase(SchemaCreator schemaCreator) InMemoryDatabase getInMemoryDatabase(SchemaCreator schemaCreator,
throws OrmException { SingleVersionListener singleVersionListener) throws OrmException {
return new InMemoryDatabase(schemaCreator); return new InMemoryDatabase(schemaCreator, singleVersionListener);
} }
private Module luceneIndexModule() { private Module luceneIndexModule() {