Always expose `has:approval_owners` submit requirement predicate
The `owners.enableSubmitRequirement = true` is a global switch that
allows for quick site switch from `prolog` submit rule to plugin's
provided submit rule. However in case when such migration is not
feasible (e.g. when `prolog` rules need to be slowly phased out or when
more control is needed over rule's applicability) one can now turn
submit requirement in `project.config` for a certain project (or
hierarchy of projects), without turning it on globally.
Changes:
* the `approval_owners` submit requirement operand is always registered
* operand propagates rule error through the
`SubmitRequirementEvaluationException` so that it can be properly
handled in the UI
* all existing integration tests were adjusted to verify that plugin
works correctly also in new mode
* the configuration was updated to highlight such possibility
Bug: Issue 345837787
Change-Id: Iaca45dd47e23d5f2d40a2732b52abdaeba170e8d
diff --git a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersApprovalHasPredicate.java b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersApprovalHasPredicate.java
index bb2d474..4e8f3b0 100644
--- a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersApprovalHasPredicate.java
+++ b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersApprovalHasPredicate.java
@@ -16,6 +16,7 @@
import com.google.gerrit.entities.SubmitRecord;
import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.project.SubmitRequirementEvaluationException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.SubmitRequirementPredicate;
import com.google.gerrit.server.rules.SubmitRule;
@@ -43,7 +44,15 @@
@Override
public boolean match(ChangeData cd) {
Optional<SubmitRecord> submitRecord = ownersSubmitRequirement.evaluate(cd);
- return submitRecord.map(sr -> sr.status == SubmitRecord.Status.OK).orElse(true);
+ return submitRecord
+ .map(
+ sr -> {
+ if (sr.status == SubmitRecord.Status.RULE_ERROR) {
+ throw new SubmitRequirementEvaluationException(sr.errorMessage);
+ }
+ return sr.status == SubmitRecord.Status.OK;
+ })
+ .orElse(true);
}
/**
diff --git a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersModule.java b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersModule.java
index 7d2c4d5..be8a6ca 100644
--- a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersModule.java
+++ b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersModule.java
@@ -40,13 +40,12 @@
.to(OwnerPredicateProvider.class)
.asEagerSingleton();
install(new OwnersRestApiModule());
+ install(new OwnersApprovalHasOperand.OwnerApprovalHasOperandModule());
if (pluginSettings.enableSubmitRequirement()) {
install(new OwnersSubmitRequirement.OwnersSubmitRequirementModule());
- install(new OwnersApprovalHasOperand.OwnerApprovalHasOperandModule());
- } else {
- logger.atInfo().log(
- "OwnersSubmitRequirement is disabled therefore it will not be evaluated.");
}
+ logger.atInfo().log(
+ "Global `owners.enableSubmitRequirement = %b`.", pluginSettings.enableSubmitRequirement());
}
}
diff --git a/owners/src/main/resources/Documentation/config.md b/owners/src/main/resources/Documentation/config.md
index 6e62857..1d157c6 100644
--- a/owners/src/main/resources/Documentation/config.md
+++ b/owners/src/main/resources/Documentation/config.md
@@ -28,9 +28,11 @@
expandGroups = false
```
-owners.enableSubmitRequirement
-: If set to `true` the approvals are evaluated through the owners submit rule without a need of
- prolog predicate being added to a project. Defaults to `false`.
+<a name="owners.enableSubmitRequirement">owners.enableSubmitRequirement</a>
+: If set to `true` the approvals are evaluated through the owners plugin
+ provided submit rule without a need of prolog predicate being added to a
+ project or submit requirement configured in the `project.config` as it is
+ automatically applied to all projects. Defaults to `false`.
Example:
@@ -39,6 +41,31 @@
enableSubmitRequirement = true
```
+ > **Notes:**
+ >
+ > The `owners.enableSubmitRequirement = true` is a global
+ > setting and allows for quick site switch from `prolog` submit rule to
+ > plugin's provided submit rule. It is a drop-in replacement therefore,
+ > similarly to `prolog` rule, it cannot be overridden by Gerrit. In case
+ > when one-step migration is not feasible (e.g. when `prolog` rules need to
+ > be slowly phased out or when more control is needed over rule's
+ > applicability, submitability or ability to overide) one can configure
+ > submit requirement in `project.config` for a certain project (or
+ > hierarchy of projects), without turning it on globally, as
+ > `approval_owners` predicate is _always_ available.
+ >
+ > Please also note, that project's `rules.pl` should be removed in this
+ > case so that it doesn't interfere with a change evaluation.
+ >
+ > The minial configuration looks like below (see
+ > [submit requirements documentation](/Documentation/config-submit-requirements.html) for more details):
+ > ```
+ > [submit-requirement "Owner-Approval"]
+ > description = Files needs to be approved by owners
+ > submittableIf = has:approval_owners
+ > ```
+
+
cache."owners.path_owners_entries".memoryLimit
: The cache is used to hold the parsed version of `OWNERS` files in the
repository so that when submit rules are calculated (either through prolog
@@ -185,6 +212,9 @@
`Code-Review from owners` requirement is added making the change not
submittable.
+> See [notes](#owners.enableSubmitRequirement) for an example on how to enable
+> submit requirements for a specific project only.
+
### When `owners.enableSubmitRequirement = false` (default)
And sample rules.pl that uses this predicate to enable the submit rule if
@@ -258,6 +288,9 @@
As a result Gerrit would make the change Submittable only if 'John Doe' or
'Doug Smith' have provided at least a `Code-Review +1`.
+> See [notes](#owners.enableSubmitRequirement) for an example on how to enable
+> submit requirements for a specific project only.
+
### When `owners.enableSubmitRequirement = false` (default)
And a rule which makes submittable a change if at least one of the owners has
@@ -318,6 +351,9 @@
A change cannot be submitted until 'John Doe' or 'Doug Smith' add a label
`Owner-Approved`, independently from being able to provide any Code-Review.
+> See [notes](#owners.enableSubmitRequirement) for an example on how to enable
+> submit requirements for a specific project only.
+
### When `owners.enableSubmitRequirement = false` (default)
Finally, define prolog rules as shown in below (an amended version of
@@ -367,6 +403,9 @@
`Code-Review+2` for a change to be submittable as default submit rule is
still evaluated.
+> See [notes](#owners.enableSubmitRequirement) for an example on how to enable
+> submit requirements for a specific project only.
+
## Example 5 - Owners based on matchers
Often the ownership comes from the developer's skills and competencies and
@@ -398,6 +437,9 @@
have provided their `Code-Review +2` feedback (as `Code-Review` is default
label for owners submit requirement).
+> See [notes](#owners.enableSubmitRequirement) for an example on how to enable
+> submit requirements for a specific project only.
+
### When `owners.enableSubmitRequirement = false` (default)
And a rules.pl of:
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersApprovalHasOperandIT.java b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersApprovalHasOperandIT.java
index 55bfa3c..7e057cd 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersApprovalHasOperandIT.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersApprovalHasOperandIT.java
@@ -16,6 +16,7 @@
package com.googlesource.gerrit.owners;
import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.gerrit.extensions.common.SubmitRequirementResultInfo.Status.ERROR;
import static com.google.gerrit.extensions.common.SubmitRequirementResultInfo.Status.SATISFIED;
import static com.google.gerrit.extensions.common.SubmitRequirementResultInfo.Status.UNSATISFIED;
@@ -23,7 +24,8 @@
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
-import com.google.gerrit.acceptance.config.GlobalPluginConfig;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
import com.google.gerrit.entities.SubmitRequirement;
import com.google.gerrit.entities.SubmitRequirementExpression;
import com.google.gerrit.extensions.api.changes.ChangeApi;
@@ -44,20 +46,10 @@
@Before
public void setup() throws Exception {
- configSubmitRequirement(
- project,
- SubmitRequirement.builder()
- .setName(REQUIREMENT_NAME)
- .setSubmittabilityExpression(SubmitRequirementExpression.create("has:approval_owners"))
- .setAllowOverrideInChildProjects(false)
- .build());
+ enableSubmitRequirementsPredicateForProject(project);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldOwnersRequirementBeSatisfied() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, LabelDefinition.parse("Code-Review,1").get(), admin2);
@@ -65,12 +57,34 @@
PushOneCommit.Result r = createChange("Add a file", "foo", "bar");
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get(ListChangesOption.SUBMIT_REQUIREMENTS);
- verifySubmitRequirements(changeNotReady.submitRequirements, REQUIREMENT_NAME, UNSATISFIED);
+ verifyChangeNotReady(changeNotReady);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.recommend());
ChangeInfo ownersVoteSufficient = forChange(r).get(ListChangesOption.SUBMIT_REQUIREMENTS);
- verifySubmitRequirements(ownersVoteSufficient.submitRequirements, REQUIREMENT_NAME, SATISFIED);
+ verifyChangeReady(ownersVoteSufficient);
+ }
+
+ @Override
+ protected void verifyChangeNotReady(ChangeInfo notReady) {
+ verifySubmitRequirements(notReady.submitRequirements, REQUIREMENT_NAME, UNSATISFIED);
+ }
+
+ @Override
+ protected void verifyChangeReady(ChangeInfo ready) {
+ verifySubmitRequirements(ready.submitRequirements, REQUIREMENT_NAME, SATISFIED);
+ }
+
+ @Override
+ protected void verifyRuleError(ChangeInfo change) {
+ verifySubmitRequirements(change.submitRequirements, REQUIREMENT_NAME, ERROR);
+ }
+
+ @Override
+ protected void updateChildProjectConfiguration(NameKey childProject) throws Exception {
+ // submit requirement predicate has to be configured either on a project level or somewhere in
+ // the project hierarchy
+ enableSubmitRequirementsPredicateForProject(childProject);
}
private void verifySubmitRequirements(
@@ -90,4 +104,15 @@
.map(r -> String.format("%s=%s", r.name, r.status))
.collect(toImmutableList())));
}
+
+ private void enableSubmitRequirementsPredicateForProject(Project.NameKey forProject)
+ throws Exception {
+ configSubmitRequirement(
+ forProject,
+ SubmitRequirement.builder()
+ .setName(REQUIREMENT_NAME)
+ .setSubmittabilityExpression(SubmitRequirementExpression.create("has:approval_owners"))
+ .setAllowOverrideInChildProjects(false)
+ .build());
+ }
}
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementIT.java b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementIT.java
index 0d5c2c5..0e7e40b 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementIT.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementIT.java
@@ -15,9 +15,64 @@
package com.googlesource.gerrit.owners;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.LegacySubmitRequirementInfo;
+import com.google.gerrit.extensions.common.SubmitRecordInfo;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
@TestPlugin(name = "owners", sysModule = "com.googlesource.gerrit.owners.OwnersModule")
@UseLocalDisk
-public class OwnersSubmitRequirementIT extends OwnersSubmitRequirementITAbstract {}
+public class OwnersSubmitRequirementIT extends OwnersSubmitRequirementITAbstract {
+ private static final LegacySubmitRequirementInfo NOT_READY =
+ new LegacySubmitRequirementInfo("NOT_READY", "Owners", "owners");
+ private static final LegacySubmitRequirementInfo READY =
+ new LegacySubmitRequirementInfo("OK", "Owners", "owners");
+
+ @Inject private SitePaths sitePaths;
+
+ @Override
+ public void setUpTestPlugin() throws Exception {
+ // ensure that `owners.enableSubmitRequirements = true` for each integration test without
+ // relying on `GlobalPluginConfig` annotation
+ FileBasedConfig ownersConfig =
+ new FileBasedConfig(sitePaths.etc_dir.resolve("owners.config").toFile(), FS.DETECTED);
+ ownersConfig.setBoolean("owners", null, "enableSubmitRequirement", true);
+ ownersConfig.save();
+ super.setUpTestPlugin();
+ }
+
+ @Override
+ protected void verifyChangeNotReady(ChangeInfo notReady) {
+ assertThat(notReady.requirements).containsExactly(NOT_READY);
+ }
+
+ @Override
+ protected void verifyChangeReady(ChangeInfo ready) {
+ assertThat(ready.requirements).containsExactly(READY);
+ }
+
+ @Override
+ protected void verifyRuleError(ChangeInfo change) {
+ assertThat(
+ change.submitRecords.stream()
+ .filter(record -> SubmitRecordInfo.Status.RULE_ERROR == record.status)
+ .filter(record -> record.errorMessage.startsWith("Invalid owners file: OWNERS"))
+ .findAny())
+ .isPresent();
+ }
+
+ @Override
+ protected void updateChildProjectConfiguration(NameKey childProject) {
+ // there is no need to further customize project when `owners.enableSubmitRequirements = true`
+ // as it is globally enabled
+ }
+}
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java
index 3f7362d..2135b40 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java
@@ -27,7 +27,6 @@
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
-import com.google.gerrit.acceptance.config.GlobalPluginConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.entities.LabelFunction;
@@ -39,7 +38,6 @@
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ChangeInfo;
-import com.google.gerrit.extensions.common.LegacySubmitRequirementInfo;
import com.google.gerrit.extensions.common.SubmitRecordInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.project.testing.TestLabels;
@@ -52,19 +50,10 @@
import org.junit.Test;
abstract class OwnersSubmitRequirementITAbstract extends LightweightPluginDaemonTest {
- private static final LegacySubmitRequirementInfo NOT_READY =
- new LegacySubmitRequirementInfo("NOT_READY", "Owners", "owners");
- private static final LegacySubmitRequirementInfo READY =
- new LegacySubmitRequirementInfo("OK", "Owners", "owners");
-
@Inject protected RequestScopeOperations requestScopeOperations;
@Inject private ProjectOperations projectOperations;
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireAtLeastOneApprovalForMatchingPathFromOwner() throws Exception {
TestAccount admin2 = accountCreator.admin2();
TestAccount user1 = accountCreator.user1();
@@ -74,25 +63,21 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeNotReadyAfterSelfApproval = changeApi.get();
assertThat(changeNotReadyAfterSelfApproval.submittable).isFalse();
- assertThat(changeNotReadyAfterSelfApproval.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReadyAfterSelfApproval);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldNotRequireApprovalForNotMatchingPath() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileWithMatchersToRoot(true, ".md", admin2);
@@ -110,10 +95,6 @@
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireApprovalFromRootOwner() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, admin2);
@@ -122,25 +103,21 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeNotReadyAfterSelfApproval = changeApi.get();
assertThat(changeNotReadyAfterSelfApproval.submittable).isFalse();
- assertThat(changeNotReadyAfterSelfApproval.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReadyAfterSelfApproval);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldBlockOwnersApprovalForMaxNegativeVote() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, admin2);
@@ -149,23 +126,19 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
changeApi.current().review(ReviewInput.reject());
assertThat(forChange(r).get().submittable).isFalse();
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireVerifiedApprovalEvenIfCodeOwnerApproved() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, admin2);
@@ -175,12 +148,12 @@
PushOneCommit.Result r = createChange("Add a file", "foo", "bar");
ChangeApi changeApi = forChange(r);
assertThat(changeApi.get().submittable).isFalse();
- assertThat(changeApi.get().requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeApi.get());
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.approve());
assertThat(forChange(r).get().submittable).isFalse();
- assertThat(forChange(r).get().requirements).containsExactly(READY);
+ verifyChangeReady(forChange(r).get());
verifyHasSubmitRecord(
forChange(r).get().submitRecords, LabelId.VERIFIED, SubmitRecordInfo.Label.Status.NEED);
@@ -191,10 +164,6 @@
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireCodeOwnerApprovalEvenIfVerifiedWasApproved() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, admin2);
@@ -204,27 +173,23 @@
PushOneCommit.Result r = createChange("Add a file", "foo", "bar");
ChangeApi changeApi = forChange(r);
assertThat(changeApi.get().submittable).isFalse();
- assertThat(changeApi.get().requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeApi.get());
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(new ReviewInput().label(LabelId.VERIFIED, 1));
ChangeInfo changeNotReady = forChange(r).get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
verifyHasSubmitRecord(
changeNotReady.submitRecords, LabelId.VERIFIED, SubmitRecordInfo.Label.Status.OK);
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireConfiguredLabelByCodeOwner() throws Exception {
TestAccount admin2 = accountCreator.admin2();
String labelId = "Foo";
@@ -235,26 +200,22 @@
PushOneCommit.Result r = createChange("Add a file", "foo", "bar");
ChangeApi changeApi = forChange(r);
assertThat(changeApi.get().submittable).isFalse();
- assertThat(changeApi.get().requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeApi.get());
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeStillNotReady = changeApi.get();
assertThat(changeStillNotReady.submittable).isFalse();
- assertThat(changeStillNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeStillNotReady);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(new ReviewInput().label(labelId, 1));
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
verifyHasSubmitRecord(changeReady.submitRecords, labelId, SubmitRecordInfo.Label.Status.OK);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireConfiguredLabelByCodeOwnerEvenIfItIsNotConfiguredForProject()
throws Exception {
TestAccount admin2 = accountCreator.admin2();
@@ -264,19 +225,15 @@
PushOneCommit.Result r = createChange("Add a file", "foo", "bar");
ChangeApi changeApi = forChange(r);
assertThat(changeApi.get().submittable).isFalse();
- assertThat(changeApi.get().requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeApi.get());
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeStillNotReady = changeApi.get();
assertThat(changeStillNotReady.submittable).isFalse();
- assertThat(changeStillNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeStillNotReady);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireConfiguredLabelScoreByCodeOwner() throws Exception {
TestAccount admin2 = accountCreator.admin2();
addOwnerFileToRoot(true, LabelDefinition.parse("Code-Review,1").get(), admin2);
@@ -285,25 +242,21 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeNotReadyAfterSelfApproval = changeApi.get();
assertThat(changeNotReadyAfterSelfApproval.submittable).isFalse();
- assertThat(changeNotReadyAfterSelfApproval.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReadyAfterSelfApproval);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.recommend());
ChangeInfo changeReadyWithOwnerScore = forChange(r).get();
assertThat(changeReadyWithOwnerScore.submittable).isTrue();
- assertThat(changeReadyWithOwnerScore.requirements).containsExactly(READY);
+ verifyChangeReady(changeReadyWithOwnerScore);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldConfiguredLabelScoreByCodeOwnerBeNotSufficientIfLabelRequiresMaxValue()
throws Exception {
TestAccount admin2 = accountCreator.admin2();
@@ -313,13 +266,13 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.recommend());
ChangeInfo ownersVoteNotSufficient = changeApi.get();
assertThat(ownersVoteNotSufficient.submittable).isFalse();
- assertThat(ownersVoteNotSufficient.requirements).containsExactly(READY);
+ verifyChangeReady(ownersVoteNotSufficient);
verifyHasSubmitRecord(
ownersVoteNotSufficient.submitRecords,
LabelId.CODE_REVIEW,
@@ -329,7 +282,7 @@
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReadyWithMaxScore = forChange(r).get();
assertThat(changeReadyWithMaxScore.submittable).isTrue();
- assertThat(changeReadyWithMaxScore.requirements).containsExactly(READY);
+ verifyChangeReady(changeReadyWithMaxScore);
verifyHasSubmitRecord(
changeReadyWithMaxScore.submitRecords,
LabelId.CODE_REVIEW,
@@ -337,10 +290,6 @@
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldConfiguredLabelScoreByCodeOwnersOverwriteSubmitRequirement() throws Exception {
installLabel(TestLabels.codeReview().toBuilder().setFunction(LabelFunction.NO_OP).build());
@@ -351,25 +300,22 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.recommend());
ChangeInfo ownersVoteSufficient = forChange(r).get();
assertThat(ownersVoteSufficient.submittable).isTrue();
- assertThat(ownersVoteSufficient.requirements).containsExactly(READY);
+ verifyChangeReady(ownersVoteSufficient);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldRequireApprovalFromGrandParentProjectOwner() throws Exception {
Project.NameKey parentProjectName =
createProjectOverAPI("parent", allProjects, true, SubmitType.FAST_FORWARD_ONLY);
Project.NameKey childProjectName =
createProjectOverAPI("child", parentProjectName, true, SubmitType.FAST_FORWARD_ONLY);
+ updateChildProjectConfiguration(childProjectName);
TestRepository<InMemoryRepository> childRepo = cloneProject(childProjectName);
TestAccount admin2 = accountCreator.admin2();
@@ -380,25 +326,21 @@
ChangeApi changeApi = forChange(r);
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
- assertThat(changeNotReady.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReady);
changeApi.current().review(ReviewInput.approve());
ChangeInfo changeNotReadyAfterSelfApproval = changeApi.get();
assertThat(changeNotReadyAfterSelfApproval.submittable).isFalse();
- assertThat(changeNotReadyAfterSelfApproval.requirements).containsExactly(NOT_READY);
+ verifyChangeNotReady(changeNotReadyAfterSelfApproval);
requestScopeOperations.setApiUser(admin2.id());
forChange(r).current().review(ReviewInput.approve());
ChangeInfo changeReady = forChange(r).get();
assertThat(changeReady.submittable).isTrue();
- assertThat(changeReady.requirements).containsExactly(READY);
+ verifyChangeReady(changeReady);
}
@Test
- @GlobalPluginConfig(
- pluginName = "owners",
- name = "owners.enableSubmitRequirement",
- value = "true")
public void shouldIndicateRuleErrorForBrokenOwnersFile() throws Exception {
addBrokenOwnersFileToRoot();
@@ -407,17 +349,17 @@
ChangeInfo changeNotReady = changeApi.get();
assertThat(changeNotReady.submittable).isFalse();
assertThat(changeNotReady.requirements).isEmpty();
- verifyHasSubmitRecordWithRuleError(changeNotReady.submitRecords);
+ verifyRuleError(changeNotReady);
}
- private void verifyHasSubmitRecordWithRuleError(Collection<SubmitRecordInfo> records) {
- assertThat(
- records.stream()
- .filter(record -> SubmitRecordInfo.Status.RULE_ERROR == record.status)
- .filter(record -> record.errorMessage.startsWith("Invalid owners file: OWNERS"))
- .findAny())
- .isPresent();
- }
+ protected abstract void verifyChangeNotReady(ChangeInfo notReady);
+
+ protected abstract void verifyChangeReady(ChangeInfo ready);
+
+ protected abstract void verifyRuleError(ChangeInfo change);
+
+ protected abstract void updateChildProjectConfiguration(Project.NameKey childProject)
+ throws Exception;
private void verifyHasSubmitRecord(
Collection<SubmitRecordInfo> records, String label, SubmitRecordInfo.Label.Status status) {