LCOV - code coverage report
Current view: top level - testing - InMemoryModule.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 136 141 96.5 %
Date: 2022-11-19 15:00:39 Functions: 25 25 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2013 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.testing;
      16             : 
      17             : import static com.google.common.base.Preconditions.checkState;
      18             : import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
      19             : import static com.google.inject.Scopes.SINGLETON;
      20             : 
      21             : import com.google.common.base.Strings;
      22             : import com.google.common.collect.ImmutableSet;
      23             : import com.google.common.util.concurrent.ListeningExecutorService;
      24             : import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
      25             : import com.google.gerrit.acceptance.testsuite.project.ProjectOperationsImpl;
      26             : import com.google.gerrit.auth.AuthModule;
      27             : import com.google.gerrit.extensions.client.AuthType;
      28             : import com.google.gerrit.extensions.config.FactoryModule;
      29             : import com.google.gerrit.extensions.registration.DynamicSet;
      30             : import com.google.gerrit.extensions.systemstatus.ServerInformation;
      31             : import com.google.gerrit.gpg.GpgModule;
      32             : import com.google.gerrit.httpd.auth.restapi.OAuthRestModule;
      33             : import com.google.gerrit.index.IndexType;
      34             : import com.google.gerrit.index.SchemaDefinitions;
      35             : import com.google.gerrit.index.project.ProjectSchemaDefinitions;
      36             : import com.google.gerrit.metrics.DisabledMetricMaker;
      37             : import com.google.gerrit.metrics.MetricMaker;
      38             : import com.google.gerrit.server.CacheRefreshExecutor;
      39             : import com.google.gerrit.server.FanOutExecutor;
      40             : import com.google.gerrit.server.GerritPersonIdent;
      41             : import com.google.gerrit.server.GerritPersonIdentProvider;
      42             : import com.google.gerrit.server.LibModuleType;
      43             : import com.google.gerrit.server.PluginUser;
      44             : import com.google.gerrit.server.account.GroupBackend;
      45             : import com.google.gerrit.server.api.GerritApiModule;
      46             : import com.google.gerrit.server.api.PluginApiModule;
      47             : import com.google.gerrit.server.audit.AuditModule;
      48             : import com.google.gerrit.server.cache.h2.H2CacheModule;
      49             : import com.google.gerrit.server.cache.mem.DefaultMemoryCacheModule;
      50             : import com.google.gerrit.server.change.FileInfoJsonModule;
      51             : import com.google.gerrit.server.config.AllProjectsConfigProvider;
      52             : import com.google.gerrit.server.config.AllProjectsName;
      53             : import com.google.gerrit.server.config.AllProjectsNameProvider;
      54             : import com.google.gerrit.server.config.AllUsersName;
      55             : import com.google.gerrit.server.config.AllUsersNameProvider;
      56             : import com.google.gerrit.server.config.AnonymousCowardName;
      57             : import com.google.gerrit.server.config.AnonymousCowardNameProvider;
      58             : import com.google.gerrit.server.config.AuthConfig;
      59             : import com.google.gerrit.server.config.CanonicalWebUrlModule;
      60             : import com.google.gerrit.server.config.CanonicalWebUrlProvider;
      61             : import com.google.gerrit.server.config.DefaultUrlFormatter.DefaultUrlFormatterModule;
      62             : import com.google.gerrit.server.config.FileBasedAllProjectsConfigProvider;
      63             : import com.google.gerrit.server.config.FileBasedGlobalPluginConfigProvider;
      64             : import com.google.gerrit.server.config.GerritGlobalModule;
      65             : import com.google.gerrit.server.config.GerritImportedServerIds;
      66             : import com.google.gerrit.server.config.GerritImportedServerIdsProvider;
      67             : import com.google.gerrit.server.config.GerritInstanceIdModule;
      68             : import com.google.gerrit.server.config.GerritInstanceNameModule;
      69             : import com.google.gerrit.server.config.GerritOptions;
      70             : import com.google.gerrit.server.config.GerritRuntime;
      71             : import com.google.gerrit.server.config.GerritServerConfig;
      72             : import com.google.gerrit.server.config.GerritServerId;
      73             : import com.google.gerrit.server.config.GerritServerIdProvider;
      74             : import com.google.gerrit.server.config.GlobalPluginConfigProvider;
      75             : import com.google.gerrit.server.config.SendEmailExecutor;
      76             : import com.google.gerrit.server.config.SitePath;
      77             : import com.google.gerrit.server.config.TrackingFooters;
      78             : import com.google.gerrit.server.config.TrackingFootersProvider;
      79             : import com.google.gerrit.server.experiments.ConfigExperimentFeatures.ConfigExperimentFeaturesModule;
      80             : import com.google.gerrit.server.git.GarbageCollection;
      81             : import com.google.gerrit.server.git.GitRepositoryManager;
      82             : import com.google.gerrit.server.git.PerThreadRequestScope;
      83             : import com.google.gerrit.server.git.SearchingChangeCacheImpl.SearchingChangeCacheImplModule;
      84             : import com.google.gerrit.server.git.WorkQueue;
      85             : import com.google.gerrit.server.git.WorkQueue.WorkQueueModule;
      86             : import com.google.gerrit.server.group.testing.TestGroupBackend;
      87             : import com.google.gerrit.server.index.account.AccountSchemaDefinitions;
      88             : import com.google.gerrit.server.index.account.AllAccountsIndexer;
      89             : import com.google.gerrit.server.index.change.AllChangesIndexer;
      90             : import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
      91             : import com.google.gerrit.server.index.group.AllGroupsIndexer;
      92             : import com.google.gerrit.server.index.group.GroupIndexCollection;
      93             : import com.google.gerrit.server.index.group.GroupSchemaDefinitions;
      94             : import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier.SignedTokenEmailTokenVerifierModule;
      95             : import com.google.gerrit.server.patch.DiffExecutor;
      96             : import com.google.gerrit.server.permissions.DefaultPermissionBackendModule;
      97             : import com.google.gerrit.server.plugins.ServerInformationImpl;
      98             : import com.google.gerrit.server.project.DefaultProjectNameLockManager.DefaultProjectNameLockManagerModule;
      99             : import com.google.gerrit.server.restapi.RestApiModule;
     100             : import com.google.gerrit.server.schema.JdbcAccountPatchReviewStore;
     101             : import com.google.gerrit.server.schema.SchemaCreator;
     102             : import com.google.gerrit.server.schema.SchemaCreatorImpl;
     103             : import com.google.gerrit.server.securestore.DefaultSecureStore;
     104             : import com.google.gerrit.server.securestore.SecureStore;
     105             : import com.google.gerrit.server.ssh.NoSshKeyCache;
     106             : import com.google.gerrit.server.submit.LocalMergeSuperSetComputation.LocalMergeSuperSetComputationModule;
     107             : import com.google.gerrit.server.submit.SubscriptionGraph.SubscriptionGraphModule;
     108             : import com.google.gerrit.server.update.SuperprojectUpdateSubmissionListener.SuperprojectUpdateSubmissionListenerModule;
     109             : import com.google.gerrit.server.util.ReplicaUtil;
     110             : import com.google.gerrit.testing.FakeEmailSender.FakeEmailSenderModule;
     111             : import com.google.inject.AbstractModule;
     112             : import com.google.inject.Guice;
     113             : import com.google.inject.Injector;
     114             : import com.google.inject.Module;
     115             : import com.google.inject.Provider;
     116             : import com.google.inject.Provides;
     117             : import com.google.inject.ProvisionException;
     118             : import com.google.inject.Singleton;
     119             : import com.google.inject.servlet.RequestScoped;
     120             : import com.google.inject.util.Providers;
     121             : import java.lang.reflect.InvocationTargetException;
     122             : import java.lang.reflect.Method;
     123             : import java.nio.file.Path;
     124             : import java.nio.file.Paths;
     125             : import java.util.HashMap;
     126             : import java.util.Map;
     127             : import java.util.concurrent.ExecutorService;
     128             : import org.eclipse.jgit.lib.Config;
     129             : import org.eclipse.jgit.lib.PersonIdent;
     130             : 
     131             : public class InMemoryModule extends FactoryModule {
     132             :   public static Config newDefaultConfig() {
     133           3 :     Config cfg = new Config();
     134           3 :     setDefaults(cfg);
     135           3 :     return cfg;
     136             :   }
     137             : 
     138             :   public static void setDefaults(Config cfg) {
     139          16 :     cfg.setString(
     140             :         "accountPatchReviewDb", null, "url", JdbcAccountPatchReviewStore.TEST_IN_MEMORY_URL);
     141          16 :     cfg.setEnum("auth", null, "type", AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT);
     142          16 :     cfg.setString("gerrit", null, "allProjects", "Test-Projects");
     143          16 :     cfg.setString("gerrit", null, "basePath", "git");
     144          16 :     cfg.setString("gerrit", null, "canonicalWebUrl", "http://test/");
     145          16 :     cfg.setString("user", null, "name", "Gerrit Code Review");
     146          16 :     cfg.setString("user", null, "email", "gerrit@localhost");
     147          16 :     cfg.unset("cache", null, "directory");
     148          16 :     cfg.setBoolean("index", "lucene", "testInmemory", true);
     149          16 :     cfg.setInt("sendemail", null, "threadPoolSize", 0);
     150          16 :     cfg.setBoolean("receive", null, "enableSignedPush", false);
     151          16 :     cfg.setString("receive", null, "certNonceSeed", "sekret");
     152          16 :   }
     153             : 
     154             :   private final Config cfg;
     155             : 
     156             :   public InMemoryModule() {
     157           2 :     this(newDefaultConfig());
     158           2 :   }
     159             : 
     160          16 :   public InMemoryModule(Config cfg) {
     161          16 :     this.cfg = cfg;
     162          16 :   }
     163             : 
     164             :   public void inject(Object instance) {
     165           1 :     Guice.createInjector(this).injectMembers(instance);
     166           1 :   }
     167             : 
     168             :   @Override
     169             :   protected void configure() {
     170             :     // Do NOT bind @RemotePeer, as it is bound in a child injector of
     171             :     // ChangeMergeQueue (bound via GerritGlobalModule below), so there cannot be
     172             :     // a binding in the parent injector. If you need @RemotePeer, you must bind
     173             :     // it in a child injector of the one containing InMemoryModule. But unless
     174             :     // you really need to test something request-scoped, you likely don't
     175             :     // actually need it.
     176             : 
     177             :     // For simplicity, don't create child injectors, just use this one to get a
     178             :     // few required modules.
     179          16 :     Injector cfgInjector =
     180          16 :         Guice.createInjector(
     181          16 :             new AbstractModule() {
     182             :               @Override
     183             :               protected void configure() {
     184          16 :                 bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
     185          16 :               }
     186             :             });
     187          16 :     bind(GerritRuntime.class).toInstance(GerritRuntime.DAEMON);
     188          16 :     bind(MetricMaker.class).to(DisabledMetricMaker.class);
     189          16 :     install(cfgInjector.getInstance(GerritGlobalModule.class));
     190             : 
     191          16 :     AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
     192          16 :     install(new AuthModule(authConfig));
     193          16 :     install(new GerritApiModule());
     194          16 :     factory(PluginUser.Factory.class);
     195          16 :     install(new PluginApiModule());
     196          16 :     install(new DefaultPermissionBackendModule());
     197          16 :     install(new SearchingChangeCacheImplModule());
     198          16 :     factory(GarbageCollection.Factory.class);
     199          16 :     install(new AuditModule());
     200          16 :     install(new SubscriptionGraphModule());
     201          16 :     install(new SuperprojectUpdateSubmissionListenerModule());
     202          16 :     install(new WorkQueueModule());
     203             : 
     204          16 :     bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);
     205             : 
     206             :     // It would be nice to use Jimfs for the SitePath, but the biggest blocker is that JGit does not
     207             :     // support Path-based Configs, only FileBasedConfig.
     208          16 :     bind(Path.class).annotatedWith(SitePath.class).toInstance(Paths.get("."));
     209          16 :     bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
     210          16 :     bind(GerritOptions.class).toInstance(new GerritOptions(false, false));
     211          16 :     bind(AllProjectsConfigProvider.class).to(FileBasedAllProjectsConfigProvider.class);
     212          16 :     bind(GlobalPluginConfigProvider.class).to(FileBasedGlobalPluginConfigProvider.class);
     213             : 
     214          16 :     bind(GitRepositoryManager.class).to(InMemoryRepositoryManager.class);
     215          16 :     bind(InMemoryRepositoryManager.class).in(SINGLETON);
     216          16 :     bind(TrackingFooters.class).toProvider(TrackingFootersProvider.class).in(SINGLETON);
     217          16 :     bind(SecureStore.class).to(DefaultSecureStore.class);
     218             : 
     219          16 :     install(new InMemorySchemaModule());
     220          16 :     install(NoSshKeyCache.module());
     221          16 :     install(new GerritInstanceNameModule());
     222          16 :     install(new GerritInstanceIdModule());
     223          16 :     install(
     224          16 :         new CanonicalWebUrlModule() {
     225             :           @Override
     226             :           protected Class<? extends Provider<String>> provider() {
     227          16 :             return CanonicalWebUrlProvider.class;
     228             :           }
     229             :         });
     230          16 :     install(new DefaultUrlFormatterModule());
     231             :     // Replacement of DiffExecutorModule to not use thread pool in the tests
     232          16 :     install(
     233          16 :         new AbstractModule() {
     234             :           @Override
     235          16 :           protected void configure() {}
     236             : 
     237             :           @Provides
     238             :           @Singleton
     239             :           @DiffExecutor
     240             :           public ExecutorService createDiffExecutor() {
     241          16 :             return newDirectExecutorService();
     242             :           }
     243             :         });
     244          16 :     install(new DefaultMemoryCacheModule());
     245          16 :     install(new H2CacheModule());
     246          16 :     install(new FakeEmailSenderModule());
     247          16 :     install(new SignedTokenEmailTokenVerifierModule());
     248          16 :     install(new GpgModule(cfg));
     249          16 :     install(new LocalMergeSuperSetComputationModule());
     250             : 
     251          16 :     bind(AllAccountsIndexer.class).toProvider(Providers.of(null));
     252          16 :     bind(AllChangesIndexer.class).toProvider(Providers.of(null));
     253          16 :     bind(AllGroupsIndexer.class).toProvider(Providers.of(null));
     254             : 
     255             :     // Index lib module has a higher priority than index type configuration.
     256          16 :     String indexModule =
     257          16 :         cfg.getString("index", null, "install" + LibModuleType.INDEX_MODULE_TYPE.getConfigKey());
     258          16 :     if (indexModule != null) {
     259           0 :       install(indexModule(indexModule));
     260             :     } else {
     261          16 :       String indexTypeCfg = cfg.getString("index", null, "type");
     262          16 :       IndexType indexType = new IndexType(indexTypeCfg != null ? indexTypeCfg : "fake");
     263          16 :       if (indexType.isLucene()) {
     264           5 :         install(luceneIndexModule());
     265          11 :       } else if (indexType.isFake()) {
     266          11 :         install(fakeIndexModule());
     267             :       }
     268             :     }
     269          16 :     bind(ServerInformationImpl.class);
     270          16 :     bind(ServerInformation.class).to(ServerInformationImpl.class);
     271          16 :     install(new RestApiModule());
     272          16 :     install(new OAuthRestModule());
     273          16 :     install(new DefaultProjectNameLockManagerModule());
     274          16 :     install(new FileInfoJsonModule());
     275          16 :     install(new ConfigExperimentFeaturesModule());
     276             : 
     277          16 :     bind(ProjectOperations.class).to(ProjectOperationsImpl.class);
     278          16 :     bind(TestGroupBackend.class).in(SINGLETON);
     279          16 :     DynamicSet.bind(binder(), GroupBackend.class).to(TestGroupBackend.class);
     280          16 :   }
     281             : 
     282             :   /** Copy of SchemaModule with a slightly different server ID provider. */
     283             :   // TODO(dborowitz): Better code sharing.
     284          16 :   private class InMemorySchemaModule extends FactoryModule {
     285             :     @Override
     286             :     public void configure() {
     287          16 :       bind(PersonIdent.class)
     288          16 :           .annotatedWith(GerritPersonIdent.class)
     289          16 :           .toProvider(GerritPersonIdentProvider.class);
     290             : 
     291          16 :       bind(AllProjectsName.class).toProvider(AllProjectsNameProvider.class).in(SINGLETON);
     292             : 
     293          16 :       bind(AllUsersName.class).toProvider(AllUsersNameProvider.class).in(SINGLETON);
     294             : 
     295          16 :       bind(String.class)
     296          16 :           .annotatedWith(AnonymousCowardName.class)
     297          16 :           .toProvider(AnonymousCowardNameProvider.class);
     298             : 
     299          16 :       bind(GroupIndexCollection.class);
     300          16 :       bind(SchemaCreator.class).to(SchemaCreatorImpl.class);
     301          16 :     }
     302             : 
     303             :     @Provides
     304             :     @Singleton
     305             :     @GerritServerId
     306             :     public String createServerId() {
     307          16 :       String serverId =
     308          16 :           cfg.getString(GerritServerIdProvider.SECTION, null, GerritServerIdProvider.KEY);
     309          16 :       if (!Strings.isNullOrEmpty(serverId)) {
     310           0 :         return serverId;
     311             :       }
     312             : 
     313          16 :       return "gerrit";
     314             :     }
     315             :   }
     316             : 
     317             :   @Provides
     318             :   @Singleton
     319             :   @GerritImportedServerIds
     320             :   public ImmutableSet<String> createImportedServerIds() {
     321          16 :     ImmutableSet<String> serverIds =
     322          16 :         ImmutableSet.copyOf(
     323          16 :             cfg.getStringList(
     324             :                 GerritServerIdProvider.SECTION, null, GerritImportedServerIdsProvider.KEY));
     325          16 :     return serverIds;
     326             :   }
     327             : 
     328             :   @Provides
     329             :   @Singleton
     330             :   @SendEmailExecutor
     331             :   public ExecutorService createSendEmailExecutor() {
     332           8 :     return newDirectExecutorService();
     333             :   }
     334             : 
     335             :   @Provides
     336             :   @Singleton
     337             :   @FanOutExecutor
     338             :   public ExecutorService createFanOutExecutor(WorkQueue queues) {
     339           8 :     return queues.createQueue(2, "FanOut");
     340             :   }
     341             : 
     342             :   @Provides
     343             :   @Singleton
     344             :   @CacheRefreshExecutor
     345             :   public ListeningExecutorService createCacheRefreshExecutor() {
     346          16 :     return newDirectExecutorService();
     347             :   }
     348             : 
     349             :   private Module luceneIndexModule() {
     350           5 :     return indexModule("com.google.gerrit.lucene.LuceneIndexModule");
     351             :   }
     352             : 
     353             :   private Module fakeIndexModule() {
     354          11 :     return indexModule("com.google.gerrit.index.testing.FakeIndexModule");
     355             :   }
     356             : 
     357             :   private Module indexModule(String moduleClassName) {
     358             :     try {
     359          16 :       Class<?> clazz = Class.forName(moduleClassName);
     360          16 :       Method m =
     361          16 :           clazz.getMethod("singleVersionWithExplicitVersions", Map.class, int.class, boolean.class);
     362          16 :       return (Module) m.invoke(null, getSingleSchemaVersions(), 0, ReplicaUtil.isReplica(cfg));
     363           0 :     } catch (ClassNotFoundException
     364             :         | SecurityException
     365             :         | NoSuchMethodException
     366             :         | IllegalArgumentException
     367             :         | IllegalAccessException
     368             :         | InvocationTargetException e) {
     369           0 :       e.printStackTrace();
     370           0 :       throw new ProvisionException(e.getMessage(), e);
     371             :     }
     372             :   }
     373             : 
     374             :   private Map<String, Integer> getSingleSchemaVersions() {
     375          16 :     Map<String, Integer> singleVersions = new HashMap<>();
     376          16 :     putSchemaVersion(singleVersions, AccountSchemaDefinitions.INSTANCE);
     377          16 :     putSchemaVersion(singleVersions, ChangeSchemaDefinitions.INSTANCE);
     378          16 :     putSchemaVersion(singleVersions, GroupSchemaDefinitions.INSTANCE);
     379          16 :     putSchemaVersion(singleVersions, ProjectSchemaDefinitions.INSTANCE);
     380          16 :     return singleVersions;
     381             :   }
     382             : 
     383             :   private void putSchemaVersion(
     384             :       Map<String, Integer> singleVersions, SchemaDefinitions<?> schemaDef) {
     385          16 :     String schemaName = schemaDef.getName();
     386          16 :     int version = cfg.getInt("index", "lucene", schemaName + "TestVersion", -1);
     387          16 :     if (version > 0) {
     388           8 :       checkState(
     389           8 :           !singleVersions.containsKey(schemaName),
     390             :           "version for schema %s was alreay set",
     391             :           schemaName);
     392           8 :       singleVersions.put(schemaName, version);
     393             :     }
     394          16 :   }
     395             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750