Line data Source code
1 : // Copyright (C) 2017 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 com.google.gerrit.entities.Account; 18 : import com.google.gerrit.lifecycle.LifecycleManager; 19 : import com.google.gerrit.server.IdentifiedUser; 20 : import com.google.gerrit.server.account.AccountManager; 21 : import com.google.gerrit.server.account.AuthRequest; 22 : import com.google.gerrit.server.schema.SchemaCreator; 23 : import com.google.gerrit.server.util.ThreadLocalRequestContext; 24 : import com.google.inject.Guice; 25 : import com.google.inject.Inject; 26 : import com.google.inject.Injector; 27 : import com.google.inject.Provider; 28 : import org.eclipse.jgit.lib.Config; 29 : import org.junit.rules.MethodRule; 30 : import org.junit.runners.model.FrameworkMethod; 31 : import org.junit.runners.model.Statement; 32 : 33 : /** 34 : * An in-memory test environment for integration tests. 35 : * 36 : * <p>This test environment emulates the internals of a Gerrit server without starting a Gerrit 37 : * site. Git repositories, including NoteDb, are stored in memory. 38 : * 39 : * <p>Each test is executed with a fresh and clean test environment. Hence, modifications applied in 40 : * one test don't carry over to subsequent ones. 41 : */ 42 : public final class InMemoryTestEnvironment implements MethodRule { 43 : private final Provider<Config> configProvider; 44 : 45 : @Inject private AccountManager accountManager; 46 : @Inject private IdentifiedUser.GenericFactory userFactory; 47 : @Inject private SchemaCreator schemaCreator; 48 : @Inject private ThreadLocalRequestContext requestContext; 49 : @Inject private AuthRequest.Factory authRequestFactory; 50 : 51 : private LifecycleManager lifecycle; 52 : 53 : /** Create a test environment using an empty base config. */ 54 : public InMemoryTestEnvironment() { 55 3 : this(Config::new); 56 3 : } 57 : 58 : /** 59 : * Create a test environment using the specified base config. 60 : * 61 : * <p>The config is passed as a provider so it can be lazily initialized after this rule is 62 : * instantiated, for example using {@link ConfigSuite}. 63 : * 64 : * @param configProvider possibly-lazy provider for the base config. 65 : */ 66 4 : public InMemoryTestEnvironment(Provider<Config> configProvider) { 67 4 : this.configProvider = configProvider; 68 4 : } 69 : 70 : @Override 71 : public Statement apply(Statement base, FrameworkMethod method, Object target) { 72 4 : return new Statement() { 73 : @Override 74 : public void evaluate() throws Throwable { 75 : try { 76 4 : setUp(target); 77 4 : base.evaluate(); 78 : } finally { 79 4 : tearDown(); 80 : } 81 4 : } 82 : }; 83 : } 84 : 85 : public void setApiUser(Account.Id id) { 86 4 : IdentifiedUser user = userFactory.create(id); 87 4 : requestContext.setContext(() -> user); 88 4 : } 89 : 90 : private void setUp(Object target) throws Exception { 91 4 : Config cfg = configProvider.get(); 92 4 : InMemoryModule.setDefaults(cfg); 93 : 94 4 : Injector injector = Guice.createInjector(new InMemoryModule(cfg)); 95 4 : injector.injectMembers(this); 96 4 : lifecycle = new LifecycleManager(); 97 4 : lifecycle.add(injector); 98 4 : lifecycle.start(); 99 : 100 4 : schemaCreator.create(); 101 : 102 : // The first user is added to the "Administrators" group. See AccountManager#create(). 103 4 : setApiUser( 104 4 : accountManager.authenticate(authRequestFactory.createForUser("admin")).getAccountId()); 105 : 106 : // Inject target members after setting API user, so it can @Inject request-scoped objects if it 107 : // wants. 108 4 : injector.injectMembers(target); 109 4 : } 110 : 111 : private void tearDown() { 112 4 : if (lifecycle != null) { 113 4 : lifecycle.stop(); 114 : } 115 4 : if (requestContext != null) { 116 4 : requestContext.setContext(null); 117 : } 118 4 : } 119 : }