Merge changes Id885bde0,I6b9124e7,Ifdb65a25,I240cfb73
* changes:
Add method to test API to retrieve raw file content of code owner config
CodeOwnerResolver: Add null check for email in isEmailDomainAllowed
Do not reject '*' as email if allowed email domains are configured
CodeOwnerConfigValidatorIT: Test that code owner with allowed email domain can be added
diff --git a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
index 4d7f536..d98c735 100644
--- a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
+++ b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
@@ -110,6 +110,16 @@
String getFilePath();
/**
+ * Retrieves the raw file content of the code owner config.
+ *
+ * <p><strong>Note:</strong> This call will fail with an {@link IllegalStateException} if the
+ * requested code owner config doesn't exist.
+ *
+ * @return the raw file content of the code owner config
+ */
+ String getContent() throws Exception;
+
+ /**
* Starts the fluent chain to update a code owner config. The returned builder can be used to
* specify how the attributes of the code owner config should be modified. To update the code
* owner config for real, {@link TestCodeOwnerConfigUpdate.Builder#update()} must be called.
diff --git a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
index 1e98136..8462d52 100644
--- a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
+++ b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
@@ -25,11 +25,20 @@
import com.google.gerrit.plugins.codeowners.backend.CodeOwnersUpdate;
import com.google.gerrit.plugins.codeowners.config.BackendConfig;
import com.google.gerrit.server.ServerInitiated;
+import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.nio.file.Path;
import java.util.Optional;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.RawParseUtils;
/**
* The implementation of {@link CodeOwnerConfigOperations}.
@@ -38,6 +47,7 @@
* the separation between interface and implementation to enhance clarity.
*/
public class CodeOwnerConfigOperationsImpl implements CodeOwnerConfigOperations {
+ private final GitRepositoryManager repoManager;
private final CodeOwners codeOwners;
private final Provider<CodeOwnersUpdate> codeOwnersUpdate;
private final ProjectCache projectCache;
@@ -45,10 +55,12 @@
@Inject
CodeOwnerConfigOperationsImpl(
+ GitRepositoryManager repoManager,
CodeOwners codeOwners,
@ServerInitiated Provider<CodeOwnersUpdate> codeOwnersUpdate,
ProjectCache projectCache,
BackendConfig backendConfig) {
+ this.repoManager = repoManager;
this.codeOwners = codeOwners;
this.codeOwnersUpdate = codeOwnersUpdate;
this.projectCache = projectCache;
@@ -145,6 +157,33 @@
}
@Override
+ public String getContent() throws Exception {
+ try (TestRepository<Repository> testRepo =
+ new TestRepository<>(repoManager.openRepository(codeOwnerConfigKey.project()))) {
+ Ref ref = testRepo.getRepository().exactRef(codeOwnerConfigKey.ref());
+ if (ref == null) {
+ throw new IllegalStateException(
+ String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+ RevCommit commit = testRepo.getRevWalk().parseCommit(ref.getObjectId());
+ try (TreeWalk tw =
+ TreeWalk.forPath(
+ testRepo.getRevWalk().getObjectReader(), getJGitFilePath(), commit.getTree())) {
+ if (tw == null) {
+ throw new IllegalStateException(
+ String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+ }
+ RevObject blob = testRepo.get(commit.getTree(), getJGitFilePath());
+ byte[] data = testRepo.getRepository().open(blob).getCachedBytes(Integer.MAX_VALUE);
+ return RawParseUtils.decode(data);
+ } catch (RepositoryNotFoundException e) {
+ throw new IllegalStateException(
+ String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+ }
+
+ @Override
public TestCodeOwnerConfigUpdate.Builder forUpdate() {
return TestCodeOwnerConfigUpdate.builder(this::updateCodeOwnerConfig);
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolver.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolver.java
index fdd4da2..3cb377b 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolver.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolver.java
@@ -370,6 +370,8 @@
* {@code false}
*/
public boolean isEmailDomainAllowed(String email) {
+ requireNonNull(email, "email");
+
ImmutableSet<String> allowedEmailDomains =
codeOwnersPluginConfiguration.getAllowedEmailDomains();
if (allowedEmailDomains.isEmpty()) {
@@ -377,6 +379,10 @@
return true;
}
+ if (email.equals(ALL_USERS_WILDCARD)) {
+ return true;
+ }
+
int emailAtIndex = email.lastIndexOf('@');
if (emailAtIndex >= 0 && emailAtIndex < email.length() - 1) {
String emailDomain = email.substring(emailAtIndex + 1);
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java
index 142c0ae..357c5d8 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java
@@ -43,6 +43,7 @@
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigImportMode;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigImportType;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigReference;
+import com.google.gerrit.plugins.codeowners.backend.CodeOwnerResolver;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerSet;
import com.google.gerrit.plugins.codeowners.backend.findowners.FindOwnersBackend;
import com.google.gerrit.plugins.codeowners.backend.findowners.FindOwnersCodeOwnerConfigParser;
@@ -99,6 +100,35 @@
}
@Test
+ public void canUploadConfigWhichAssignsCodeOwnershipToAllUsers() throws Exception {
+ testCanUploadConfigWhichAssignsCodeOwnershipToAllUsers();
+ }
+
+ @Test
+ @GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.com")
+ public void canUploadConfigWhichAssignsCodeOwnershipToAllUsers_restrictedAllowedEmailDomain()
+ throws Exception {
+ testCanUploadConfigWhichAssignsCodeOwnershipToAllUsers();
+ }
+
+ private void testCanUploadConfigWhichAssignsCodeOwnershipToAllUsers() throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey = createCodeOwnerConfigKey("/");
+
+ // Create a code owner config without issues that assigns code ownership to all users.
+ PushOneCommit.Result r =
+ createChange(
+ "Add code owners",
+ codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getJGitFilePath(),
+ format(
+ CodeOwnerConfig.builder(codeOwnerConfigKey, TEST_REVISION)
+ .addCodeOwnerSet(
+ CodeOwnerSet.createWithoutPathExpressions(
+ CodeOwnerResolver.ALL_USERS_WILDCARD))
+ .build()));
+ assertOkWithHints(r, "code owner config files validated, no issues found");
+ }
+
+ @Test
public void canSubmitConfigWithoutIssues() throws Exception {
CodeOwnerConfig.Key codeOwnerConfigKey = createCodeOwnerConfigKey("/");
@@ -608,6 +638,24 @@
@Test
@GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.com")
+ public void canUploadConfigThatAssignsCodeOwnershipToAnEmailWithAnAllowedEmailDomain()
+ throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey = createCodeOwnerConfigKey("/");
+
+ assertThat(admin.email()).endsWith("@example.com");
+ PushOneCommit.Result r =
+ createChange(
+ "Add code owners",
+ codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getJGitFilePath(),
+ format(
+ CodeOwnerConfig.builder(codeOwnerConfigKey, TEST_REVISION)
+ .addCodeOwnerSet(CodeOwnerSet.createWithoutPathExpressions(admin.email()))
+ .build()));
+ assertOkWithHints(r, "code owner config files validated, no issues found");
+ }
+
+ @Test
+ @GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.com")
public void cannotUploadConfigThatAssignsCodeOwnershipToAnEmailWithANonAllowedEmailDomain()
throws Exception {
CodeOwnerConfig.Key codeOwnerConfigKey = createCodeOwnerConfigKey("/");
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
index 542fc3d..c0e9040 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
@@ -639,6 +639,58 @@
.isEqualTo("/foo/OWNERS");
}
+ @Test
+ public void getContent() throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey =
+ codeOwnerConfigOperations
+ .newCodeOwnerConfig()
+ .project(project)
+ .branch("master")
+ .folderPath("/foo/")
+ .addCodeOwnerEmail(admin.email())
+ .create();
+ assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent())
+ .isEqualTo(admin.email() + "\n");
+ }
+
+ @Test
+ public void getContent_nonExistingCodeOwnerConfig() throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey = CodeOwnerConfig.Key.create(project, "master", "/foo/");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+
+ @Test
+ public void getContent_nonExistingBranch() throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey =
+ CodeOwnerConfig.Key.create(project, "non-existing", "/foo/");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+
+ @Test
+ public void getContent_nonExistingProject() throws Exception {
+ CodeOwnerConfig.Key codeOwnerConfigKey =
+ CodeOwnerConfig.Key.create(Project.nameKey("non-existing"), "master", "/foo/");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+ }
+
private CodeOwnerConfig getCodeOwnerConfigFromServer(CodeOwnerConfig.Key codeOwnerConfigKey) {
return codeOwners
.getFromCurrentRevision(codeOwnerConfigKey)
diff --git a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
index f390336..bd1bad1 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/backend/CodeOwnerResolverTest.java
@@ -322,6 +322,14 @@
}
@Test
+ public void isEmailDomainAllowedRequiresEmailToBeNonNull() throws Exception {
+ NullPointerException npe =
+ assertThrows(
+ NullPointerException.class, () -> codeOwnerResolver.get().isEmailDomainAllowed(null));
+ assertThat(npe).hasMessageThat().isEqualTo("email");
+ }
+
+ @Test
@GerritConfig(
name = "plugin.code-owners.allowedEmailDomain",
values = {"example.com", "example.net"})
@@ -334,6 +342,8 @@
assertThat(codeOwnerResolver.get().isEmailDomainAllowed("foo")).isFalse();
assertThat(codeOwnerResolver.get().isEmailDomainAllowed("foo@example.com@example.org"))
.isFalse();
+ assertThat(codeOwnerResolver.get().isEmailDomainAllowed(CodeOwnerResolver.ALL_USERS_WILDCARD))
+ .isTrue();
}
@Test
@@ -346,6 +356,8 @@
assertThat(codeOwnerResolver.get().isEmailDomainAllowed("foo")).isTrue();
assertThat(codeOwnerResolver.get().isEmailDomainAllowed("foo@example.com@example.org"))
.isTrue();
+ assertThat(codeOwnerResolver.get().isEmailDomainAllowed(CodeOwnerResolver.ALL_USERS_WILDCARD))
+ .isTrue();
}
@Test