Test skipping code owner config validation when rebasing via API If a patch set is created via the Rebase REST endpoint the code owner config file validation validates any OWNERS file that is touched in the commit. This validation fails if such an OWNERS file contains conflicts (conflicts are possible if rebaseInput.allowConflicts = true was set), since the conflict markers in the file will be detected as invalid content. Change If025ac253 in Gerrit core allows to set validation options in the rebase input that are forwarded to the CommitValidationListeners. This makes it possible to skip the code owner config validation when creating a patch set via the Rebase REST endpoint, by specifying code-owners~skip-validation=true as validation option. This change adds a test to verify that skipping the code owner config validation by setting code-owners~skip-validation=true in the rebase input works. Signed-off-by: Edwin Kempin <ekempin@google.com> Change-Id: I852391f4d3ba823056a603052dcb259bad5b97bc
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 130f067..ab76995 100644 --- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java +++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/api/CodeOwnerConfigValidatorIT.java
@@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.TruthJUnit.assume; +import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow; import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability; import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block; import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS; @@ -33,11 +34,14 @@ import com.google.gerrit.entities.BranchNameKey; import com.google.gerrit.entities.Permission; import com.google.gerrit.entities.Project; +import com.google.gerrit.entities.RefNames; import com.google.gerrit.extensions.api.changes.CherryPickInput; +import com.google.gerrit.extensions.api.changes.RebaseInput; import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.api.projects.ConfigInput; import com.google.gerrit.extensions.client.ChangeStatus; import com.google.gerrit.extensions.client.ProjectState; +import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ChangeInput; import com.google.gerrit.extensions.common.MergeInput; import com.google.gerrit.extensions.restapi.MergeConflictException; @@ -2368,6 +2372,95 @@ } @Test + public void skipValidationForRebaseWithConflicts() throws Exception { + // Create code owner config with 'admin' as code owner. + CodeOwnerConfig.Key codeOwnerConfigKey = + codeOwnerConfigOperations + .newCodeOwnerConfig() + .project(project) + .branch("master") + .folderPath("/") + .addCodeOwnerEmail(admin.email()) + .create(); + + // Create a change with a conflicting code owner config that makes 'user' the code owner. + // No need to reset the repo, since the commit that created to code owner config above wasn't + // fetched into testRepo. + PushOneCommit push = + pushFactory.create( + admin.newIdent(), + testRepo, + "Add user as code owner", + codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getJGitFilePath(), + format( + CodeOwnerConfig.builder(codeOwnerConfigKey, TEST_REVISION) + .addCodeOwnerSet(CodeOwnerSet.builder().addCodeOwnerEmail(user.email()).build()) + .build())); + PushOneCommit.Result r = push.to("refs/for/master"); + r.assertOkStatus(); + + RebaseInput rebaseInput = new RebaseInput(); + rebaseInput.allowConflicts = true; + rebaseInput.validationOptions = + ImmutableMap.of( + String.format("code-owners~%s", SkipCodeOwnerConfigValidationPushOption.NAME), "true"); + ChangeInfo changeInfo = gApi.changes().id(r.getChangeId()).current().rebaseAsInfo(rebaseInput); + assertThat(changeInfo.containsGitConflicts).isTrue(); + } + + @Test + public void userWithoutCapabilitySkipValidationCannotSkipValidationWithRebase() throws Exception { + // Create code owner config with 'admin' as code owner. + CodeOwnerConfig.Key codeOwnerConfigKey = + codeOwnerConfigOperations + .newCodeOwnerConfig() + .project(project) + .branch("master") + .folderPath("/") + .addCodeOwnerEmail(admin.email()) + .create(); + + // Create a change with a conflicting code owner config that makes 'user' the code owner. + // No need to reset the repo, since the commit that created to code owner config above wasn't + // fetched into testRepo. + PushOneCommit push = + pushFactory.create( + admin.newIdent(), + testRepo, + "Add user as code owner", + codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getJGitFilePath(), + format( + CodeOwnerConfig.builder(codeOwnerConfigKey, TEST_REVISION) + .addCodeOwnerSet(CodeOwnerSet.builder().addCodeOwnerEmail(user.email()).build()) + .build())); + PushOneCommit.Result r = push.to("refs/for/master"); + r.assertOkStatus(); + + requestScopeOperations.setApiUser(user.id()); + projectOperations + .project(project) + .forUpdate() + .add(allow(Permission.REBASE).ref(RefNames.REFS_HEADS + "*").group(REGISTERED_USERS)) + .update(); + + RebaseInput rebaseInput = new RebaseInput(); + rebaseInput.allowConflicts = true; + rebaseInput.validationOptions = + ImmutableMap.of( + String.format("code-owners~%s", SkipCodeOwnerConfigValidationPushOption.NAME), "true"); + ResourceConflictException resourceConflictException = + assertThrows( + ResourceConflictException.class, + () -> gApi.changes().id(r.getChangeId()).current().rebaseAsInfo(rebaseInput)); + assertThat(resourceConflictException) + .hasMessageThat() + .contains( + String.format( + "[code-owners] %s for plugin code-owners not permitted", + SkipCodeOwnerConfigValidationCapability.ID)); + } + + @Test @GerritConfig(name = "plugin.code-owners.rejectNonResolvableCodeOwners", value = "false") @GerritConfig(name = "plugin.code-owners.enableValidationOnSubmit", value = "true") public void canUploadAndSubmitConfigWithUnresolvableCodeOwners() throws Exception {