Optimize the 'path_owners_entries' cache eviction
The OWNERS file can be present either under the `refs/meta/config` or
`refs/heads/*` ref. Ignore evictions to All-Users project and to other
(gerrit technical refs).
Bug: Issue 16830
Change-Id: I2c2d4a6ec3950f7890ae1d8e372f71bffcc7796b
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
index 07be702..c2ec085 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntriesCache.java
@@ -15,11 +15,13 @@
package com.googlesource.gerrit.owners.common;
import com.google.common.cache.RemovalNotification;
+import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.cache.CacheRemovalListener;
+import com.google.gerrit.server.config.AllUsersName;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
@@ -103,15 +105,25 @@
@Singleton
class OwnersRefUpdateListener implements GitReferenceUpdatedListener {
private final PathOwnersEntriesCache cache;
+ private final String allUsersName;
@Inject
- OwnersRefUpdateListener(PathOwnersEntriesCache cache) {
+ OwnersRefUpdateListener(PathOwnersEntriesCache cache, AllUsersName allUsersName) {
this.cache = cache;
+ this.allUsersName = allUsersName.get();
}
@Override
public void onGitReferenceUpdated(Event event) {
- cache.invalidate(event.getProjectName(), event.getRefName());
+ if (supportedEvent(allUsersName, event)) {
+ cache.invalidate(event.getProjectName(), event.getRefName());
+ }
+ }
+
+ static boolean supportedEvent(String allUsersName, Event event) {
+ String refName = event.getRefName();
+ return !allUsersName.equals(event.getProjectName())
+ && (refName.equals(RefNames.REFS_CONFIG) || !RefNames.isGerritRef(refName));
}
}
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java
new file mode 100644
index 0000000..fa20c79
--- /dev/null
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/OwnersRefUpdateListenerTest.java
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 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.owners.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+import com.google.gerrit.server.config.AllProjectsNameProvider;
+import com.google.gerrit.server.config.AllUsersNameProvider;
+import com.googlesource.gerrit.owners.common.PathOwnersEntriesCache.OwnersRefUpdateListener;
+import java.util.Arrays;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class OwnersRefUpdateListenerTest {
+ @Parameterized.Parameters
+ public static Collection<Object[]> events() {
+ return Arrays.asList(
+ new Object[][] {
+ {mockEvent(ALL_USERS_NAME, null), false},
+ {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_CHANGES), false},
+ {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_SEQUENCES), false},
+ {mockEvent(AllProjectsNameProvider.DEFAULT, RefNames.REFS_CONFIG), true},
+ {mockEvent("foo", RefNames.fullName("bar")), true},
+ {mockEvent("foo", RefNames.REFS_CONFIG), true}
+ });
+ }
+
+ private static String ALL_USERS_NAME = AllUsersNameProvider.DEFAULT;
+
+ private final GitReferenceUpdatedListener.Event input;
+ private final boolean expected;
+
+ public OwnersRefUpdateListenerTest(GitReferenceUpdatedListener.Event input, boolean expected) {
+ this.input = input;
+ this.expected = expected;
+ }
+
+ @Test
+ public void shouldParseLabelDefinition() {
+ // when
+ boolean result = OwnersRefUpdateListener.supportedEvent(ALL_USERS_NAME, input);
+
+ // then
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static GitReferenceUpdatedListener.Event mockEvent(String project, String ref) {
+ GitReferenceUpdatedListener.Event eventMock = mock(GitReferenceUpdatedListener.Event.class);
+ when(eventMock.getProjectName()).thenReturn(project);
+ when(eventMock.getRefName()).thenReturn(ref);
+ return eventMock;
+ }
+}