blob: 03e12960201461facbe3390b3f5230f1db6b6990 [file] [log] [blame]
// Copyright (C) 2016 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.supermanifest;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.inject.Inject;
import com.google.inject.util.Providers;
import java.net.URI;
import java.util.Arrays;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.BlobBasedConfig;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
@TestPlugin(
name = "supermanifest",
sysModule = "com.googlesource.gerrit.plugins.supermanifest.SuperManifestModule")
public class JiriSuperManifestIT extends LightweightPluginDaemonTest {
Project.NameKey[] testRepoKeys;
@Inject private ProjectOperations projectOperations;
@Inject private DynamicMap<DownloadScheme> downloadScheme;
void setupTestRepos(String prefix) throws Exception {
// Set up download schemes for test repos.
PrivateInternals_DynamicMapImpl<DownloadScheme> downloadSchemeImpl =
(PrivateInternals_DynamicMapImpl<DownloadScheme>) downloadScheme;
String host = URI.create(canonicalWebUrl.get()).getHost();
downloadSchemeImpl.put("supermanifest", "https", Providers.of(new TestDownloadScheme(host)));
testRepoKeys = new Project.NameKey[2];
for (int i = 0; i < 2; i++) {
testRepoKeys[i] =
projectOperations
.newProject()
.name(RandomStringUtils.randomAlphabetic(8) + prefix + i)
.create();
TestRepository<InMemoryRepository> repo = cloneProject(testRepoKeys[i], admin);
PushOneCommit push =
pushFactory.create(admin.newIdent(), repo, "Subject", "file" + i, "file");
push.to("refs/heads/master").assertOkStatus();
}
}
void pushConfig(String config) throws Exception {
// This will trigger a configuration reload.
TestRepository<InMemoryRepository> allProjectRepo = cloneProject(allProjects, admin);
GitUtil.fetch(allProjectRepo, RefNames.REFS_CONFIG + ":config");
allProjectRepo.reset("config");
PushOneCommit push =
pushFactory.create(
admin.newIdent(), allProjectRepo, "Subject", "supermanifest.config", config);
PushOneCommit.Result res = push.to("refs/meta/config");
res.assertOkStatus();
}
@Test
public void basicFunctionalityWorks() throws Exception {
setupTestRepos("project");
// Make sure the manifest exists so the configuration loads successfully.
Project.NameKey manifestKey = projectOperations.newProject().name(name("manifest")).create();
TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/destbranch\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
// XML change will trigger commit to superproject.
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
Config base = new Config();
BlobBasedConfig cfg =
new BlobBasedConfig(base, branch.file(".gitmodules").asString().getBytes(UTF_8));
assertThat(cfg.getString("submodule", "project1", "branch")).isEqualTo("master");
assertThrows(ResourceNotFoundException.class, () -> branch.file("project2"));
xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ " <project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ " <project name=\""
+ testRepoKeys[1].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[1].get()
+ "\" path=\"project2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch2 = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch2.file("project2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
// Make sure config change gets picked up.
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/other\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
// Push another XML change; this should trigger a commit using the new config.
xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ " <project name=\""
+ testRepoKeys[1].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[1].get()
+ "\" path=\"project3\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch3 = gApi.projects().name(superKey.get()).branch("refs/heads/other");
assertThat(branch3.file("project3").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
}
@Test
public void ImportTagWorks() throws Exception {
setupTestRepos("project");
// Make sure the manifest exists so the configuration loads successfully.
Project.NameKey manifest1Key = projectOperations.newProject().name(name("manifest1")).create();
TestRepository<InMemoryRepository> manifest1Repo = cloneProject(manifest1Key, admin);
Project.NameKey manifest2Key = projectOperations.newProject().name(name("manifest2")).create();
TestRepository<InMemoryRepository> manifest2Repo = cloneProject(manifest2Key, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/destbranch\"]\n"
+ " srcRepo = "
+ manifest1Key.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
// XML change will trigger commit to superproject.
String xml1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<imports>\n"
+ "<import name=\""
+ manifest2Key.get()
+ "\" manifest=\"default\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" />\n</imports>"
+ "<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
String xml2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ manifest2Key.get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" path=\"manifest2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest2Repo, "Subject", "default", xml2)
.to("refs/heads/master")
.assertOkStatus();
pushFactory
.create(admin.newIdent(), manifest1Repo, "Subject", "default", xml1)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThat(branch.file("manifest2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
}
@Test
public void ImportTagWithRevisionWorks() throws Exception {
setupTestRepos("project");
// Make sure the manifest exists so the configuration loads successfully.
Project.NameKey manifest1Key = projectOperations.newProject().name(name("manifest1")).create();
TestRepository<InMemoryRepository> manifest1Repo = cloneProject(manifest1Key, admin);
Project.NameKey manifest2Key = projectOperations.newProject().name(name("manifest2")).create();
TestRepository<InMemoryRepository> manifest2Repo = cloneProject(manifest2Key, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/destbranch\"]\n"
+ " srcRepo = "
+ manifest1Key.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
String xml2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ manifest2Key.get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" path=\"manifest2\" />\n"
+ "</projects>\n</manifest>\n";
Result c =
pushFactory
.create(admin.newIdent(), manifest2Repo, "Subject", "default", xml2)
.to("refs/heads/master");
c.assertOkStatus();
RevCommit commit = c.getCommit();
// Add new project, that should not be imported
xml2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ manifest2Key.get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" path=\"manifest2\" />\n"
+ "<project name=\""
+ testRepoKeys[1].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[1].get()
+ "\" path=\"project2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest2Repo, "Subject", "default", xml2)
.to("refs/heads/master")
.assertOkStatus();
// XML change will trigger commit to superproject.
String xml1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<imports>\n"
+ "<import name=\""
+ manifest2Key.get()
+ "\" manifest=\"default\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" revision=\""
+ commit.name()
+ "\"/>\n</imports>"
+ "<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest1Repo, "Subject", "default", xml1)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThat(branch.file("manifest2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThat(branch.file("manifest2").asString()).contains(commit.name());
assertThrows(ResourceNotFoundException.class, () -> branch.file("project2"));
}
@Test
public void ImportTagWithRemoteBranchWorks() throws Exception {
setupTestRepos("project");
// Make sure the manifest exists so the configuration loads successfully.
Project.NameKey manifest1Key = projectOperations.newProject().name(name("manifest1")).create();
TestRepository<InMemoryRepository> manifest1Repo = cloneProject(manifest1Key, admin);
Project.NameKey manifest2Key = projectOperations.newProject().name(name("manifest2")).create();
TestRepository<InMemoryRepository> manifest2Repo = cloneProject(manifest2Key, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/destbranch\"]\n"
+ " srcRepo = "
+ manifest1Key.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
String xml2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ manifest2Key.get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" path=\"manifest2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest2Repo, "Subject", "default", xml2)
.to("refs/heads/b1")
.assertOkStatus();
// Add new project, that should not be imported
xml2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ manifest2Key.get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" path=\"manifest2\" />\n"
+ "<project name=\""
+ testRepoKeys[1].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[1].get()
+ "\" path=\"project2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest2Repo, "Subject", "default", xml2)
.to("refs/heads/master")
.assertOkStatus();
// XML change will trigger commit to superproject.
String xml1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<imports>\n"
+ "<import name=\""
+ manifest2Key.get()
+ "\" manifest=\"default\" remote=\""
+ canonicalWebUrl.get()
+ manifest2Key.get()
+ "\" remotebranch=\"b1\" />\n</imports>"
+ "<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifest1Repo, "Subject", "default", xml1)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThat(branch.file("manifest2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThrows(ResourceNotFoundException.class, () -> branch.file("project2"));
}
private void outer() throws Exception {
inner();
}
private void inner() {
throw new IllegalStateException();
}
private void innerTest() throws Exception {
IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> outer());
StackTraceElement[] trimmed =
SuperManifestRefUpdatedListener.trimStack(
thrown.getStackTrace(), Thread.currentThread().getStackTrace()[1]);
String str = Arrays.toString(trimmed);
assertThat(str).doesNotContain("trimStackTrace");
assertThat(str).contains("innerTest");
}
@Test
public void trimStackTrace() throws Exception {
innerTest();
}
@Test
public void wildcardDestBranchWorks() throws Exception {
setupTestRepos("project");
// Make sure the manifest exists so the configuration loads successfully.
Project.NameKey manifestKey = projectOperations.newProject().name(name("manifest")).create();
TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/*\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = blablabla\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
// XML change will trigger commit to superproject.
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ " <project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/src1")
.assertOkStatus();
xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ " <project name=\""
+ testRepoKeys[1].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[1].get()
+ "\" path=\"project2\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/src2")
.assertOkStatus();
BranchApi branch1 = gApi.projects().name(superKey.get()).branch("refs/heads/src1");
assertThat(branch1.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThrows(ResourceNotFoundException.class, () -> branch1.file("project2"));
BranchApi branch2 = gApi.projects().name(superKey.get()).branch("refs/heads/src2");
assertThat(branch2.file("project2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThrows(ResourceNotFoundException.class, () -> branch2.file("project1"));
}
@Test
public void relativeFetch() throws Exception {
// Test that first party gerrit repos are represented by relative URLs in supermanifest and
// external repos by their absolute URLs.
setupTestRepos("platform/project");
String realPrefix = testRepoKeys[0].get().split("/")[0];
Project.NameKey manifestKey =
projectOperations.newProject().name(name(realPrefix + "/manifest")).create();
TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/destbranch\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = refs/heads/srcbranch\n"
+ " srcPath = default\n"
+ " toolType = jiri\n");
// XML change will trigger commit to superproject.
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "<project name=\"external1\""
+ " remote=\"https://external/repo\""
+ " revision=\"c438d02cdf08a08fe29550cb11cb6ae8190919f1\""
+ " path=\"project2\" />\n"
+ "<project name=\"external2\""
+ " remote=\"https://external/"
+ testRepoKeys[1].get()
+ "\""
+ " revision=\"c438d02cdf08a08fe29550cb11cb6ae8190919f1\""
+ " path=\"project3\" />\n"
+ "</projects>\n</manifest>\n";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/srcbranch")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/destbranch");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
assertThat(branch.file("project2").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
Config base = new Config();
BlobBasedConfig cfg =
new BlobBasedConfig(base, branch.file(".gitmodules").asString().getBytes(UTF_8));
String subUrl = cfg.getString("submodule", "project1", "url");
// URL is valid.
URI.create(subUrl);
// The suburl must be interpreted as relative to the parent project as a directory, i.e.
// to go from superproject/ to platform/project0, you have to do ../platform/project0
// URL is clean.
assertThat(subUrl).isEqualTo("../" + realPrefix + "/project0");
subUrl = cfg.getString("submodule", "project2", "url");
// URL is valid.
URI.create(subUrl);
// The suburl must be absolute as this is external repo
assertThat(subUrl).isEqualTo("https://external/repo");
subUrl = cfg.getString("submodule", "project3", "url");
// URL is valid.
URI.create(subUrl);
// Though the this project has the same name as a local repo, the subUrl must be absolute
// as this is an external repo.
assertThat(subUrl).isEqualTo("https://external/" + testRepoKeys[1].get());
assertThat(cfg.getString("submodule", "project1", "branch")).isEqualTo("master");
assertThat(cfg.getString("submodule", "project2", "branch")).isNull();
assertThat(cfg.getString("submodule", "project3", "branch")).isNull();
}
@Test
public void manifestIncludesOtherManifest() throws Exception {
setupTestRepos("project");
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
Project.NameKey manifestKey = projectOperations.newProject().name(name("manifest")).create();
TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/master")
.assertOkStatus();
String superXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<manifest>\n<imports>\n"
+ " <localimport file=\"default\"/>"
+ "</imports>\n</manifest>";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "super", superXml)
.to("refs/heads/master")
.assertOkStatus();
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/master\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = refs/heads/master\n"
+ " srcPath = super\n"
+ " toolType = jiri\n");
// Push a change to the source branch. We intentionally change the included XML file
// (rather than the one mentioned in srcPath), to double check that we don't try to be too
// smart about eluding nops.
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml + " ")
.to("refs/heads/master")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/master");
assertThat(branch.file("project1").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
}
@Test
public void remoteImportFails() throws Exception {
setupTestRepos("project");
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<manifest>\n<projects>\n"
+ "<project name=\""
+ testRepoKeys[0].get()
+ "\" remote=\""
+ canonicalWebUrl.get()
+ testRepoKeys[0].get()
+ "\" path=\"project1\" />\n"
+ "</projects>\n</manifest>\n";
Project.NameKey manifestKey = projectOperations.newProject().name(name("manifest")).create();
Project.NameKey superKey = projectOperations.newProject().name(name("superproject")).create();
cloneProject(superKey, admin);
pushConfig(
"[superproject \""
+ superKey.get()
+ ":refs/heads/master\"]\n"
+ " srcRepo = "
+ manifestKey.get()
+ "\n"
+ " srcRef = refs/heads/master\n"
+ " srcPath = super\n"
+ " toolType = jiri\n");
TestRepository<InMemoryRepository> manifestRepo = cloneProject(manifestKey, admin);
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "default", xml)
.to("refs/heads/master")
.assertOkStatus();
String superXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<manifest>\n<imports>\n"
+ "<import manifest=\""
+ manifestKey.get()
+ "\" name=\"default\" remote=\""
+ canonicalWebUrl.get()
+ manifestKey.get()
+ "\"/>"
+ "</imports>\n</manifest>";
pushFactory
.create(admin.newIdent(), manifestRepo, "Subject", "super", superXml)
.to("refs/heads/master")
.assertOkStatus();
BranchApi branch = gApi.projects().name(superKey.get()).branch("refs/heads/master");
assertThrows(ResourceNotFoundException.class, () -> branch.file("project1"));
}
void testRelative(String a, String b, String want) throws Exception {
String got = JiriUpdater.relativize(URI.create(a), URI.create(b)).toString();
assertWithMessage("relative('%s', '%s')", a, b).that(got).isEqualTo(want);
}
@Test
public void relative() throws Exception {
testRelative("a/b/", "a/", "../");
// Normalization:
testRelative("a/p/..//b/", "a/", "../");
testRelative("a/b", "a/", "");
testRelative("a/", "a/b/", "b/");
testRelative("a/", "a/b", "b");
testRelative("/a/b/c", "/b/c", "../../b/c");
testRelative("/abc", "bcd", "bcd");
testRelative("abc", "def", "def");
testRelative("abc", "/bcd", "/bcd");
testRelative("http://a", "a/b", "a/b");
testRelative("http://base.com/a/", "http://child.com/a/b", "http://child.com/a/b");
}
// Modified from com.google.gerrit.acceptance.api.accounts.GeneralPreferencesIT.TestDownloadScheme
private static class TestDownloadScheme extends DownloadScheme {
private String host;
public TestDownloadScheme(String host) {
this.host = host;
}
@Override
public String getUrl(String project) {
return "https://" + this.host + "/" + project;
}
@Override
public boolean isAuthRequired() {
return false;
}
@Override
public boolean isAuthSupported() {
return false;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isHidden() {
return false;
}
}
}