Merge branch 'stable-3.10'

* stable-3.10:
  Document Owned Files tab in the Change screen's owners UI
  Expire the owners cache after 1 minute and make it unlimited
  Optimize the 'path_owners_entries' cache eviction
  Introduce PathOwners cache from Ic7d61de07

Change-Id: I57d7ab110be6729e437e86add05df408b7c2ec9e
diff --git a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
index bdfa7f6..e9acc43 100644
--- a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
+++ b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
@@ -140,13 +140,15 @@
         }
 
         in.ignoreAutomaticAttentionSetRules = true;
-        in.addToAttentionSet =
-            ownersForAttentionSet.get().addToAttentionSet(changeInfo, reviewersAccounts).stream()
-                .map(
-                    (reviewer) ->
-                        new AttentionSetInput(
-                            reviewer.toString(), "Selected as member of the OWNERS file"))
-                .collect(Collectors.toList());
+        if (ownersForAttentionSet != null) {
+          in.addToAttentionSet =
+              ownersForAttentionSet.get().addToAttentionSet(changeInfo, reviewersAccounts).stream()
+                  .map(
+                      (reviewer) ->
+                          new AttentionSetInput(
+                              reviewer.toString(), "Selected as member of the OWNERS file"))
+                  .collect(Collectors.toList());
+        }
 
         gApi.changes().id(changeInfo.id).current().review(in);
       }
diff --git a/owners/src/main/resources/Documentation/config.md b/owners/src/main/resources/Documentation/config.md
index 811325b..5b85b7e 100644
--- a/owners/src/main/resources/Documentation/config.md
+++ b/owners/src/main/resources/Documentation/config.md
@@ -69,7 +69,7 @@
     > 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
+    > The minimal configuration looks like below (see
     > [submit requirements documentation](/Documentation/config-submit-requirements.html) for more details):
     > ```
     > [submit-requirement "Owner-Approval"]
@@ -160,7 +160,7 @@
 > configuration is used) so that owners don't have to be granted with the
 > maximum label's score. Note that only single digit (0..9) is allowed.
 
-For example, imagine the following tree:
+For example, imagine the following tree with a default Gerrit project labels configuration:
 
 ```
 /OWNERS
@@ -212,7 +212,7 @@
 - Doug Smith
 ```
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 Then Gerrit would:
 
@@ -263,7 +263,7 @@
 - Doug Smith
 ```
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 This case is supported with the `Code-Review` label and `OWNERS` file
 modifications.
@@ -348,7 +348,7 @@
      label-Owner-Approved = -1..+1 group Registered Users
 ```
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 Given now an OWNERS configuration of:
 
@@ -398,7 +398,7 @@
 shouldn't be granted with `Code-Review +2` for all project files as it might be
 outside of their comptenence/comfort zone.
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 Given an OWNERS configuration of:
 
@@ -439,7 +439,7 @@
   - Matt Designer
 ```
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 Then for any change that contains files with .sql or .css extensions, besides
 to the default Gerrit submit rules, the extra constraints on the additional
@@ -473,7 +473,7 @@
 
 ## Example 6 - Owners details on a per-file basis
 
-### When `owners.enableSubmitRequirement = true`
+### When `owners.enableSubmitRequirement = true` with a default Gerrit project labels configuration
 
 This case is obsolete and _only_ prolog specific. The list of which file is
 owned by whom is available through the [REST API](rest-api.md).
diff --git a/owners/src/main/resources/Documentation/how-to-use.md b/owners/src/main/resources/Documentation/how-to-use.md
index 4a4d17f..1ccff9d 100644
--- a/owners/src/main/resources/Documentation/how-to-use.md
+++ b/owners/src/main/resources/Documentation/how-to-use.md
@@ -98,9 +98,9 @@
 ![submit rule](./submit-rule.png "Submit rule")
 
 
-    > Note that in replacement mode, owner's votes are displayed next to the
-    > `Code Review from owners` submit requirement instead of its status.
-    > It is a Gerrit's core representation of submit rule.
+    > Note that when default submit requirements are enabled, owner's votes are
+    > displayed next to the `Code Review from owners` submit requirement instead
+    > of its status. It is a Gerrit's core representation of submit rule.
 
 * Next to all owned files (when the newest patchset is selected)
 \
@@ -111,8 +111,8 @@
 
 #### <a id="ownersStatus.submitRule.owners">`Code Review from owners` submit requirement
 
-The `Code Review from owners` (that is available only in
-[replacement mode](config.html#owners.enableSubmitRequirement)) submit
+The `Code Review from owners` (i.e. the
+[default submit requirement](config.html#owners.enableSubmitRequirement)) submit
 requirement provides general information if all owned files were approved
 (requirement is satisfied). When hovered, a detailed description is shown
 
@@ -120,8 +120,9 @@
 
 #### <a id="ownersStatus.submitRule.files">Per file owners statuses
 
-The owners status per file in replacement mode doesn't differ from
-[submit requirements mode](#ownersStatus.submitRequirement.files).
+The owners status per file when [default submit
+requirements](config.html#owners.enableSubmitRequirement) are enabled doesn't
+differ from [submit requirements mode](#ownersStatus.submitRequirement.files).
 
 ### Files that are assigned to the current user based on the OWNERS
 
diff --git a/owners/src/main/resources/Documentation/metrcis.md b/owners/src/main/resources/Documentation/metrics.md
similarity index 100%
rename from owners/src/main/resources/Documentation/metrcis.md
rename to owners/src/main/resources/Documentation/metrics.md
diff --git a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersRegressionIT.java b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersRegressionIT.java
index 2fc37ce..1f23510 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersRegressionIT.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersRegressionIT.java
@@ -72,19 +72,24 @@
 
   private void verifySubmitRequirement(
       Collection<SubmitRequirementResultInfo> requirements, String name, Status status) {
-    assertThat(requirements).hasSize(1);
+    // in post stable-3.10 Gerrit has default submit requirement no-unresolved-comments turned on by
+    // default therefore 2 requirements will be always present
+    assertThat(requirements).hasSize(2);
 
-    SubmitRequirementResultInfo requirement = requirements.iterator().next();
-    if (!requirement.name.equals(name) || !(requirement.status == status)) {
-      throw new AssertionError(
-          String.format(
-              "No submit requirement %s with status %s (existing = %s)",
-              name,
-              status,
-              requirements.stream()
-                  .map(r -> String.format("%s=%s", r.name, r.status))
-                  .collect(toImmutableList())));
+    for (SubmitRequirementResultInfo requirement : requirements) {
+      if (requirement.name.equals(name) && requirement.status == status) {
+        return;
+      }
     }
+
+    throw new AssertionError(
+        String.format(
+            "Could not find submit requirement %s with status %s (results = %s)",
+            name,
+            status,
+            requirements.stream()
+                .map(r -> String.format("%s=%s", r.name, r.status))
+                .collect(toImmutableList())));
   }
 
   private ChangeApi forChange(PushOneCommit.Result r) throws RestApiException {
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 3db9dcb..ba35cdb 100644
--- a/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java
+++ b/owners/src/test/java/com/googlesource/gerrit/owners/OwnersSubmitRequirementITAbstract.java
@@ -88,7 +88,7 @@
     assertThat(changeNotReady.requirements).isEmpty();
 
     changeApi.current().review(ReviewInput.approve());
-    ChangeInfo changeReady = changeApi.get();
+    ChangeInfo changeReady = forChange(r).get();
     assertThat(changeReady.submittable).isTrue();
     assertThat(changeReady.requirements).isEmpty();
   }
@@ -157,9 +157,10 @@
         forChange(r).get().submitRecords, LabelId.VERIFIED, SubmitRecordInfo.Label.Status.NEED);
 
     changeApi.current().review(new ReviewInput().label(LabelId.VERIFIED, 1));
-    assertThat(changeApi.get().submittable).isTrue();
+    ChangeInfo changeReady = forChange(r).get();
+    assertThat(changeReady.submittable).isTrue();
     verifyHasSubmitRecord(
-        changeApi.get().submitRecords, LabelId.VERIFIED, SubmitRecordInfo.Label.Status.OK);
+        changeReady.submitRecords, LabelId.VERIFIED, SubmitRecordInfo.Label.Status.OK);
   }
 
   @Test
@@ -269,7 +270,7 @@
 
     requestScopeOperations.setApiUser(admin2.id());
     forChange(r).current().review(ReviewInput.recommend());
-    ChangeInfo ownersVoteNotSufficient = changeApi.get();
+    ChangeInfo ownersVoteNotSufficient = forChange(r).get();
     assertThat(ownersVoteNotSufficient.submittable).isFalse();
     verifyChangeReady(ownersVoteNotSufficient);
     verifyHasSubmitRecord(