blob: 74327457899dfbc4a4a3f11473dcfd23216e1537 [file] [log] [blame]
// Copyright (C) 2020 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.googlesource.gerrit.plugins.replication;
import static java.util.stream.Collectors.toList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
/**
* This class can be extended by any Replication*IT class and provides common setup and helper
* methods.
*/
@UseLocalDisk
@TestPlugin(
name = "replication",
sysModule = "com.googlesource.gerrit.plugins.replication.ReplicationModule")
public class ReplicationDaemon extends LightweightPluginDaemonTest {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
protected static final Optional<String> ALL_PROJECTS = Optional.empty();
protected static final int TEST_REPLICATION_DELAY_SECONDS = 1;
protected static final int TEST_REPLICATION_RETRY_MINUTES = 1;
protected static final int TEST_PUSH_TIME_SECONDS = 1;
protected static final int TEST_PROJECT_CREATION_SECONDS = 10;
protected static final Duration TEST_PUSH_TIMEOUT =
Duration.ofSeconds(TEST_REPLICATION_DELAY_SECONDS + TEST_PUSH_TIME_SECONDS);
protected static final Duration TEST_NEW_PROJECT_TIMEOUT =
Duration.ofSeconds(
(TEST_REPLICATION_DELAY_SECONDS + TEST_REPLICATION_RETRY_MINUTES * 60)
+ TEST_PROJECT_CREATION_SECONDS);
@Inject protected SitePaths sitePaths;
@Inject private ProjectOperations projectOperations;
protected Path gitPath;
protected FileBasedConfig config;
protected void setReplicationDestination(
String remoteName, String replicaSuffix, Optional<String> project) throws IOException {
setReplicationDestination(
remoteName, Arrays.asList(replicaSuffix), project, TEST_REPLICATION_DELAY_SECONDS);
}
protected void setReplicationDestination(
String remoteName, String replicaSuffix, Optional<String> project, boolean mirror)
throws IOException {
setReplicationDestination(
remoteName, Arrays.asList(replicaSuffix), project, TEST_REPLICATION_DELAY_SECONDS, mirror);
}
protected void setReplicationDestination(
String remoteName, String replicaSuffix, Optional<String> project, int replicationDelay)
throws IOException {
setReplicationDestination(remoteName, Arrays.asList(replicaSuffix), project, replicationDelay);
}
protected void setReplicationDestination(
String remoteName,
List<String> replicaSuffixes,
Optional<String> project,
int replicationDelay)
throws IOException {
setReplicationDestination(remoteName, replicaSuffixes, project, replicationDelay, false);
}
protected void setReplicationDestination(
String remoteName,
String replicaSuffix,
Optional<String> project,
int replicationDelay,
boolean mirror)
throws IOException {
setReplicationDestination(
remoteName, Arrays.asList(replicaSuffix), project, replicationDelay, mirror);
}
protected void setReplicationDestination(
String remoteName,
List<String> replicaSuffixes,
Optional<String> project,
int replicationDelay,
boolean mirror)
throws IOException {
setReplicationDestination(
config, remoteName, replicaSuffixes, project, replicationDelay, mirror);
config.setBoolean("gerrit", null, "autoReload", true);
config.save();
}
protected void setReplicationDestination(
FileBasedConfig config,
List<String> replicaSuffixes,
Optional<String> project,
int replicationDelay)
throws IOException {
setReplicationDestination(config, null, replicaSuffixes, project, replicationDelay, false);
}
protected void setReplicationDestination(
FileBasedConfig remoteConfig,
String remoteName,
List<String> replicaSuffixes,
Optional<String> project,
int replicationDelay,
boolean mirror)
throws IOException {
List<String> replicaUrls =
replicaSuffixes.stream()
.map(suffix -> gitPath.resolve("${name}" + suffix + ".git").toString())
.collect(toList());
remoteConfig.setStringList("remote", remoteName, "url", replicaUrls);
remoteConfig.setInt("remote", remoteName, "replicationDelay", replicationDelay);
remoteConfig.setInt("remote", remoteName, "replicationRetry", TEST_REPLICATION_RETRY_MINUTES);
remoteConfig.setBoolean("remote", remoteName, "mirror", mirror);
project.ifPresent(prj -> remoteConfig.setString("remote", remoteName, "projects", prj));
remoteConfig.save();
}
protected Project.NameKey createTestProject(String name) throws Exception {
return projectOperations.newProject().name(name).create();
}
protected boolean isPushCompleted(Project.NameKey project, String ref, Duration timeOut) {
try (Repository repo = repoManager.openRepository(project)) {
WaitUtil.waitUntil(() -> checkedGetRef(repo, ref) != null, timeOut);
return true;
} catch (InterruptedException e) {
return false;
} catch (Exception e) {
throw new RuntimeException("Cannot open repo for project" + project, e);
}
}
protected Ref checkedGetRef(Repository repo, String branchName) {
try {
return repo.getRefDatabase().exactRef(branchName);
} catch (Exception e) {
logger.atSevere().withCause(e).log("failed to get ref %s in repo %s", branchName, repo);
return null;
}
}
protected Ref getRef(Repository repo, String branchName) throws IOException {
return repo.getRefDatabase().exactRef(branchName);
}
protected void reloadConfig() {
getAutoReloadConfigDecoratorInstance().reload();
}
protected AutoReloadConfigDecorator getAutoReloadConfigDecoratorInstance() {
return getInstance(AutoReloadConfigDecorator.class);
}
protected <T> T getInstance(Class<T> classObj) {
return plugin.getSysInjector().getInstance(classObj);
}
protected boolean nonEmptyProjectExists(Project.NameKey name) {
try (Repository r = repoManager.openRepository(name)) {
return !r.getAllRefsByPeeledObjectId().isEmpty();
} catch (Exception e) {
return false;
}
}
protected void initConfig() throws IOException {
if (config == null) {
gitPath = sitePaths.site_path.resolve("git");
config =
new FileBasedConfig(
sitePaths.etc_dir.resolve("replication.config").toFile(), FS.DETECTED);
config.save();
}
}
}