LCOV - code coverage report
Current view: top level - acceptance - StandaloneSiteTest.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 69 80 86.2 %
Date: 2022-11-19 15:00:39 Functions: 21 24 87.5 %

          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.acceptance;
      16             : 
      17             : import static com.google.common.truth.Truth.assertWithMessage;
      18             : import static java.nio.charset.StandardCharsets.UTF_8;
      19             : import static java.util.stream.Collectors.joining;
      20             : import static org.junit.Assert.fail;
      21             : 
      22             : import com.google.common.base.Joiner;
      23             : import com.google.common.collect.ImmutableList;
      24             : import com.google.common.collect.ImmutableMap;
      25             : import com.google.common.collect.Streams;
      26             : import com.google.common.io.ByteStreams;
      27             : import com.google.gerrit.common.Nullable;
      28             : import com.google.gerrit.extensions.api.GerritApi;
      29             : import com.google.gerrit.extensions.api.groups.GroupInput;
      30             : import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
      31             : import com.google.gerrit.launcher.GerritLauncher;
      32             : import com.google.gerrit.server.CurrentUser;
      33             : import com.google.gerrit.server.config.SitePaths;
      34             : import com.google.gerrit.server.util.ManualRequestContext;
      35             : import com.google.gerrit.server.util.OneOffRequestContext;
      36             : import com.google.gerrit.server.util.RequestContext;
      37             : import com.google.gerrit.server.util.git.DelegateSystemReader;
      38             : import com.google.gerrit.testing.ConfigSuite;
      39             : import com.google.inject.Injector;
      40             : import com.google.inject.Module;
      41             : import java.io.File;
      42             : import java.io.IOException;
      43             : import java.io.InputStream;
      44             : import java.io.InterruptedIOException;
      45             : import java.nio.file.Path;
      46             : import java.util.Arrays;
      47             : import java.util.Collections;
      48             : import org.eclipse.jgit.lib.Config;
      49             : import org.eclipse.jgit.storage.file.FileBasedConfig;
      50             : import org.eclipse.jgit.util.FS;
      51             : import org.eclipse.jgit.util.SystemReader;
      52             : import org.junit.Rule;
      53             : import org.junit.rules.RuleChain;
      54             : import org.junit.rules.TemporaryFolder;
      55             : import org.junit.rules.TestRule;
      56             : import org.junit.runner.Description;
      57             : import org.junit.runner.RunWith;
      58             : import org.junit.runners.model.Statement;
      59             : 
      60             : @RunWith(ConfigSuite.class)
      61             : @UseLocalDisk
      62           7 : public abstract class StandaloneSiteTest {
      63             :   protected class ServerContext implements RequestContext, AutoCloseable {
      64             :     private final GerritServer server;
      65             :     private final ManualRequestContext ctx;
      66             : 
      67           7 :     private ServerContext(GerritServer server) throws Exception {
      68           7 :       this.server = server;
      69           7 :       Injector i = server.getTestInjector();
      70           7 :       if (admin == null) {
      71           7 :         admin = i.getInstance(AccountCreator.class).admin();
      72             :       }
      73           7 :       ctx = i.getInstance(OneOffRequestContext.class).openAs(admin.id());
      74           7 :       GerritApi gApi = i.getInstance(GerritApi.class);
      75             : 
      76             :       try {
      77             :         // ServerContext ctor is called multiple times but the group can be only created once
      78           1 :         gApi.groups().id("Group");
      79           7 :       } catch (ResourceNotFoundException e) {
      80           7 :         GroupInput in = new GroupInput();
      81           7 :         in.members = Collections.singletonList("admin");
      82           7 :         in.name = "Group";
      83           7 :         gApi.groups().create(in);
      84           1 :       }
      85           7 :     }
      86             : 
      87             :     @Override
      88             :     public CurrentUser getUser() {
      89           0 :       return ctx.getUser();
      90             :     }
      91             : 
      92             :     public Injector getInjector() {
      93           7 :       return server.getTestInjector();
      94             :     }
      95             : 
      96             :     @Override
      97             :     public void close() throws Exception {
      98             :       try {
      99           7 :         ctx.close();
     100             :       } finally {
     101           7 :         server.close();
     102             :       }
     103           7 :     }
     104             :   }
     105             : 
     106             :   @ConfigSuite.Parameter public Config baseConfig;
     107             :   @ConfigSuite.Name private String configName;
     108             : 
     109           7 :   private final TemporaryFolder tempSiteDir = new TemporaryFolder();
     110             : 
     111           7 :   private final TestRule testRunner =
     112             :       (base, description) ->
     113           7 :           new Statement() {
     114             :             @Override
     115             :             public void evaluate() throws Throwable {
     116             :               try {
     117           7 :                 beforeTest(description);
     118           7 :                 base.evaluate();
     119             :               } finally {
     120           7 :                 afterTest();
     121             :               }
     122           7 :             }
     123             :           };
     124             : 
     125           7 :   @Rule public RuleChain ruleChain = RuleChain.outerRule(tempSiteDir).around(testRunner);
     126             : 
     127             :   protected SitePaths sitePaths;
     128             :   protected TestAccount admin;
     129             : 
     130             :   private GerritServer.Description serverDesc;
     131             :   private SystemReader oldSystemReader;
     132             : 
     133             :   private void beforeTest(Description description) throws Exception {
     134             :     // SystemReader must be overridden before creating any repos, since they read the user/system
     135             :     // configs at initialization time, and are then stored in the RepositoryCache forever.
     136           7 :     oldSystemReader = setFakeSystemReader(tempSiteDir.getRoot());
     137             : 
     138           7 :     serverDesc = GerritServer.Description.forTestMethod(description, configName);
     139           7 :     sitePaths = new SitePaths(tempSiteDir.getRoot().toPath());
     140           7 :     GerritServer.init(serverDesc, baseConfig, sitePaths.site_path);
     141           7 :   }
     142             : 
     143             :   private static SystemReader setFakeSystemReader(File tempDir) {
     144           7 :     SystemReader oldSystemReader = SystemReader.getInstance();
     145           7 :     SystemReader.setInstance(
     146           7 :         new DelegateSystemReader(oldSystemReader) {
     147             :           @Override
     148             :           public FileBasedConfig openJGitConfig(Config parent, FS fs) {
     149           7 :             return new FileBasedConfig(parent, new File(tempDir, "jgit.config"), FS.detect());
     150             :           }
     151             : 
     152             :           @Override
     153             :           public FileBasedConfig openUserConfig(Config parent, FS fs) {
     154           7 :             return new FileBasedConfig(parent, new File(tempDir, "user.config"), FS.detect());
     155             :           }
     156             : 
     157             :           @Override
     158             :           public FileBasedConfig openSystemConfig(Config parent, FS fs) {
     159           7 :             return new FileBasedConfig(parent, new File(tempDir, "system.config"), FS.detect());
     160             :           }
     161             :         });
     162           7 :     return oldSystemReader;
     163             :   }
     164             : 
     165             :   private void afterTest() throws Exception {
     166           7 :     SystemReader.setInstance(oldSystemReader);
     167           7 :     oldSystemReader = null;
     168           7 :   }
     169             : 
     170             :   protected ServerContext startServer() throws Exception {
     171           7 :     return startServer(null);
     172             :   }
     173             : 
     174             :   protected ServerContext startServer(@Nullable Module testSysModule, String... additionalArgs)
     175             :       throws Exception {
     176           7 :     return new ServerContext(startImpl(testSysModule, additionalArgs));
     177             :   }
     178             : 
     179             :   protected void assertServerStartupFails() throws Exception {
     180           0 :     try (GerritServer server = startImpl(null)) {
     181           0 :       fail("expected server startup to fail");
     182           1 :     } catch (GerritServer.StartupException e) {
     183             :       // Expected.
     184           0 :     }
     185           1 :   }
     186             : 
     187             :   private GerritServer startImpl(@Nullable Module testSysModule, String... additionalArgs)
     188             :       throws Exception {
     189           7 :     return GerritServer.start(
     190             :         serverDesc,
     191             :         baseConfig,
     192             :         sitePaths.site_path,
     193             :         testSysModule,
     194             :         null,
     195             :         null,
     196             :         null,
     197             :         additionalArgs);
     198             :   }
     199             : 
     200             :   protected static void runGerrit(String... args) throws Exception {
     201             :     // Use invokeProgram with the current classloader, rather than mainImpl, which would create a
     202             :     // new classloader. This is necessary so that static state, particularly the SystemReader, is
     203             :     // shared with the test method.
     204           1 :     assertWithMessage("gerrit.war " + Arrays.stream(args).collect(joining(" ")))
     205           1 :         .that(GerritLauncher.invokeProgram(StandaloneSiteTest.class.getClassLoader(), args))
     206           1 :         .isEqualTo(0);
     207           1 :   }
     208             : 
     209             :   @SafeVarargs
     210             :   protected static void runGerrit(Iterable<String>... multiArgs) throws Exception {
     211           0 :     runGerrit(Arrays.stream(multiArgs).flatMap(Streams::stream).toArray(String[]::new));
     212           0 :   }
     213             : 
     214             :   protected static String execute(
     215             :       ImmutableList<String> cmd, File dir, ImmutableMap<String, String> env) throws IOException {
     216           5 :     return execute(cmd, dir, env, null);
     217             :   }
     218             : 
     219             :   protected static String execute(
     220             :       ImmutableList<String> cmd,
     221             :       File dir,
     222             :       ImmutableMap<String, String> env,
     223             :       @Nullable Path outputPath)
     224             :       throws IOException {
     225           5 :     ProcessBuilder pb = new ProcessBuilder(cmd);
     226           5 :     pb.directory(dir);
     227           5 :     if (outputPath != null) {
     228           1 :       pb.redirectOutput(outputPath.toFile());
     229             :     } else {
     230           5 :       pb.redirectErrorStream(true);
     231             :     }
     232           5 :     pb.environment().putAll(env);
     233           5 :     Process p = pb.start();
     234             :     byte[] out;
     235           5 :     try (InputStream in = p.getInputStream()) {
     236           5 :       out = ByteStreams.toByteArray(in);
     237             :     } finally {
     238           5 :       p.getOutputStream().close();
     239             :     }
     240             : 
     241             :     int status;
     242             :     try {
     243           5 :       status = p.waitFor();
     244           0 :     } catch (InterruptedException e) {
     245           0 :       InterruptedIOException iioe =
     246             :           new InterruptedIOException(
     247           0 :               "interrupted waiting for: " + Joiner.on(' ').join(pb.command()));
     248           0 :       iioe.initCause(e);
     249           0 :       throw iioe;
     250           5 :     }
     251             : 
     252           5 :     String result = new String(out, UTF_8);
     253           5 :     if (status != 0) {
     254           5 :       throw new IOException(result);
     255             :     }
     256             : 
     257           5 :     return result.trim();
     258             :   }
     259             : }

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