blob: 94e7fd5238f8ddceefd9cfa7f33a9d777742fb1d [file] [log] [blame]
// Copyright (C) 2021 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.pull.api;
import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toList;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.SkipProjectClone;
import com.google.gerrit.acceptance.TestAccount;
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.entities.Project.NameKey;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.CredentialsFactory;
import com.googlesource.gerrit.plugins.replication.pull.RevisionReader;
import com.googlesource.gerrit.plugins.replication.pull.Source;
import com.googlesource.gerrit.plugins.replication.pull.SourcesCollection;
import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
import com.googlesource.gerrit.plugins.replication.pull.client.SourceHttpClient;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
@SkipProjectClone
@UseLocalDisk
@TestPlugin(
name = "pull-replication",
sysModule = "com.googlesource.gerrit.plugins.replication.pull.PullReplicationModule",
httpModule = "com.googlesource.gerrit.plugins.replication.pull.api.HttpModule")
public abstract class ActionITBase extends LightweightPluginDaemonTest {
protected static final Optional<String> ALL_PROJECTS = Optional.empty();
protected static final int TEST_REPLICATION_DELAY = 60;
protected static final String TEST_REPLICATION_SUFFIX = "suffix1";
protected static final String TEST_REPLICATION_REMOTE = "remote1";
protected Path gitPath;
protected FileBasedConfig config;
protected FileBasedConfig secureConfig;
protected RevisionReader revisionReader;
@Inject private SitePaths sitePaths;
@Inject private ProjectOperations projectOperations;
CredentialsFactory credentials;
Source source;
SourceHttpClient.Factory httpClientFactory;
String url;
protected abstract String getURL();
@Override
public void setUpTestPlugin() throws Exception {
gitPath = sitePaths.site_path.resolve("git");
config =
new FileBasedConfig(sitePaths.etc_dir.resolve("replication.config").toFile(), FS.DETECTED);
setReplicationSource(
TEST_REPLICATION_REMOTE,
TEST_REPLICATION_SUFFIX,
ALL_PROJECTS); // Simulates a full replication.config initialization
config.save();
secureConfig =
new FileBasedConfig(sitePaths.etc_dir.resolve("secure.config").toFile(), FS.DETECTED);
setReplicationCredentials(TEST_REPLICATION_REMOTE, admin.username(), admin.httpPassword());
secureConfig.save();
super.setUpTestPlugin();
httpClientFactory = plugin.getSysInjector().getInstance(SourceHttpClient.Factory.class);
credentials = plugin.getSysInjector().getInstance(CredentialsFactory.class);
revisionReader = plugin.getSysInjector().getInstance(RevisionReader.class);
source = plugin.getSysInjector().getInstance(SourcesCollection.class).getAll().get(0);
url = getURL();
}
protected HttpPost createRequest(String sendObjectPayload) {
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(sendObjectPayload, StandardCharsets.UTF_8));
post.addHeader(new BasicHeader("Content-Type", "application/json"));
return post;
}
protected HttpPut createPutRequest(String sendObjectPayload) {
HttpPut put = new HttpPut(url);
put.setEntity(new StringEntity(sendObjectPayload, StandardCharsets.UTF_8));
put.addHeader(new BasicHeader("Content-Type", "application/json"));
return put;
}
protected String createRef() throws Exception {
return createRef(Project.nameKey(project + TEST_REPLICATION_SUFFIX));
}
protected String createRef(NameKey projectName) throws Exception {
testRepo = cloneProject(createTestProject(projectName.get()));
Result pushResult = createChange("topic", "test.txt", "test_content");
return RefNames.changeMetaRef(pushResult.getChange().getId());
}
protected Optional<RevisionData> createRevisionData(String refName) throws Exception {
return createRevisionData(Project.nameKey(project + TEST_REPLICATION_SUFFIX), refName);
}
protected Optional<RevisionData> createRevisionData(NameKey projectName, String refName)
throws Exception {
return revisionReader.read(projectName, refName);
}
protected Object encode(byte[] content) {
return Base64.getEncoder().encodeToString(content);
}
public ResponseHandler<Object> assertHttpResponseCode(int responseCode) {
return new ResponseHandler<Object>() {
@Override
public Object handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(responseCode);
return null;
}
};
}
protected HttpClientContext getContext() {
return getContextForAccount(admin);
}
protected HttpClientContext getUserContext() {
return getContextForAccount(user);
}
protected HttpClientContext getAnonymousContext() {
HttpClientContext ctx = HttpClientContext.create();
return ctx;
}
private Project.NameKey createTestProject(String name) throws Exception {
return projectOperations.newProject().name(name).parent(project).create();
}
private void setReplicationSource(
String remoteName, String replicaSuffix, Optional<String> project) throws IOException {
setReplicationSource(remoteName, Arrays.asList(replicaSuffix), project);
}
private void setReplicationSource(
String remoteName, List<String> replicaSuffixes, Optional<String> project)
throws IOException {
List<String> replicaUrls =
replicaSuffixes.stream()
.map(suffix -> gitPath.resolve("${name}" + suffix + ".git").toString())
.collect(toList());
config.setString("replication", null, "instanceLabel", remoteName);
config.setStringList("remote", remoteName, "url", replicaUrls);
config.setString("remote", remoteName, "apiUrl", adminRestSession.url());
config.setString("remote", remoteName, "fetch", "+refs/tags/*:refs/tags/*");
config.setInt("remote", remoteName, "timeout", 600);
config.setInt("remote", remoteName, "replicationDelay", TEST_REPLICATION_DELAY);
project.ifPresent(prj -> config.setString("remote", remoteName, "projects", prj));
config.setBoolean("gerrit", null, "autoReload", true);
config.save();
}
private void setReplicationCredentials(String remoteName, String username, String password)
throws IOException {
secureConfig.setString("remote", remoteName, "username", username);
secureConfig.setString("remote", remoteName, "password", password);
secureConfig.save();
}
private HttpClientContext getContextForAccount(TestAccount account) {
HttpClientContext ctx = HttpClientContext.create();
CredentialsProvider adapted = new BasicCredentialsProvider();
adapted.setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(account.username(), account.httpPassword()));
ctx.setCredentialsProvider(adapted);
return ctx;
}
}