Merge branch 'stable-3.2'
* stable-3.2:
Allow filter events broadcasting by project name
Refine protocol assignment in scenarios using multiple protocols
Change-Id: I0737217f52ebc6aaad2f57f213e80e373508d3ab
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index ebe28d4..f509cd4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -61,6 +61,7 @@
private final Supplier<Cache> cache;
private final Supplier<Event> event;
private final Supplier<Index> index;
+ private final Supplier<Projects> projects;
private final Supplier<SharedRefDatabase> sharedRefDb;
private final Supplier<Collection<Message>> replicationConfigValidation;
private final Supplier<Broker> broker;
@@ -79,6 +80,7 @@
cache = memoize(() -> new Cache(lazyMultiSiteCfg));
event = memoize(() -> new Event(lazyMultiSiteCfg));
index = memoize(() -> new Index(lazyMultiSiteCfg));
+ projects = memoize(() -> new Projects(lazyMultiSiteCfg));
sharedRefDb = memoize(() -> new SharedRefDatabase(lazyMultiSiteCfg));
broker = memoize(() -> new Broker(lazyMultiSiteCfg));
}
@@ -107,6 +109,10 @@
return broker.get();
}
+ public Projects projects() {
+ return projects.get();
+ }
+
public Collection<Message> validate() {
return replicationConfigValidation.get();
}
@@ -198,6 +204,20 @@
}
}
+ public static class Projects {
+ public static final String SECTION = "projects";
+ public static final String PATTERN_KEY = "pattern";
+ public List<String> patterns;
+
+ public Projects(Supplier<Config> cfg) {
+ patterns = ImmutableList.copyOf(cfg.get().getStringList("projects", null, PATTERN_KEY));
+ }
+
+ public List<String> getPatterns() {
+ return patterns;
+ }
+ }
+
/** Common parameters to cache, event, index */
public abstract static class Forwarding {
static final boolean DEFAULT_SYNCHRONIZE = true;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
new file mode 100644
index 0000000..d6fac47
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
@@ -0,0 +1,109 @@
+// Copyright (C) 2020 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.plugins.multisite;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+import com.google.gerrit.common.data.AccessSection;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.server.events.Event;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.util.List;
+import java.util.Set;
+
+@Singleton
+public class ProjectsFilter {
+ public enum PatternType {
+ REGEX,
+ WILDCARD,
+ EXACT_MATCH;
+
+ public static PatternType getPatternType(String pattern) {
+ if (pattern.startsWith(AccessSection.REGEX_PREFIX)) {
+ return REGEX;
+ } else if (pattern.endsWith("*")) {
+ return WILDCARD;
+ } else {
+ return EXACT_MATCH;
+ }
+ }
+ }
+
+ private Set<NameKey> globalProjects = Sets.newConcurrentHashSet();
+ private Set<NameKey> localProjects = Sets.newConcurrentHashSet();
+ private final List<String> projectPatterns;
+
+ @Inject
+ public ProjectsFilter(Configuration cfg) {
+ projectPatterns = cfg.projects().getPatterns();
+ }
+
+ public boolean matches(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException("Event object cannot be null");
+ }
+ if (event instanceof ProjectEvent) {
+ return matches(((ProjectEvent) event).getProjectNameKey());
+ }
+ return false;
+ }
+
+ public boolean matches(String projectName) {
+ return matches(NameKey.parse(projectName));
+ }
+
+ public boolean matches(Project.NameKey name) {
+ if (name == null || Strings.isNullOrEmpty(name.get())) {
+ throw new IllegalArgumentException(
+ String.format("Project name cannot be null or empty, but was %s", name));
+ }
+ if (projectPatterns.isEmpty() || globalProjects.contains(name)) {
+ return true;
+ }
+
+ if (localProjects.contains(name)) {
+ return false;
+ }
+
+ String projectName = name.get();
+
+ for (String pattern : projectPatterns) {
+ if (matchesPattern(projectName, pattern)) {
+ globalProjects.add(name);
+ return true;
+ }
+ }
+ localProjects.add(name);
+ return false;
+ }
+
+ private boolean matchesPattern(String projectName, String pattern) {
+ boolean match = false;
+ switch (PatternType.getPatternType(pattern)) {
+ case REGEX:
+ match = projectName.matches(pattern);
+ break;
+ case WILDCARD:
+ match = projectName.startsWith(pattern.substring(0, pattern.length() - 1));
+ break;
+ case EXACT_MATCH:
+ match = projectName.equals(pattern);
+ }
+ return match;
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
index 1060977..2e2f9de 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
@@ -20,6 +20,7 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
@@ -31,12 +32,16 @@
private final DynamicSet<ProjectListUpdateForwarder> forwarders;
private final Executor executor;
+ private final ProjectsFilter projectsFilter;
@Inject
public ProjectListUpdateHandler(
- DynamicSet<ProjectListUpdateForwarder> forwarders, @CacheExecutor Executor executor) {
+ DynamicSet<ProjectListUpdateForwarder> forwarders,
+ @CacheExecutor Executor executor,
+ ProjectsFilter filter) {
this.forwarders = forwarders;
this.executor = executor;
+ this.projectsFilter = filter;
}
@Override
@@ -52,7 +57,7 @@
}
private void process(ProjectEvent event, boolean delete) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(event.getProjectName())) {
executor.execute(
new ProjectListUpdateTask(new ProjectListUpdateEvent(event.getProjectName(), delete)));
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
index aafd59f..a1b7a53 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
@@ -19,6 +19,7 @@
import com.google.gerrit.server.events.EventListener;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
import java.util.concurrent.Executor;
@@ -26,17 +27,24 @@
class EventHandler implements EventListener {
private final Executor executor;
private final DynamicSet<StreamEventForwarder> forwarders;
+ private final ProjectsFilter projectsFilter;
@Inject
- EventHandler(DynamicSet<StreamEventForwarder> forwarders, @EventExecutor Executor executor) {
+ EventHandler(
+ DynamicSet<StreamEventForwarder> forwarders,
+ @EventExecutor Executor executor,
+ ProjectsFilter projectsFilter) {
this.forwarders = forwarders;
this.executor = executor;
+ this.projectsFilter = projectsFilter;
}
@Override
public void onEvent(Event event) {
if (!Context.isForwardedEvent() && event instanceof ProjectEvent) {
- executor.execute(new EventTask(event));
+ if (projectsFilter.matches(event)) {
+ executor.execute(new EventTask(event));
+ }
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
index 62359cb..fe6bdac 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
@@ -21,6 +21,7 @@
import com.google.gerrit.extensions.events.ProjectIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
@@ -45,15 +46,18 @@
private final DynamicSet<IndexEventForwarder> forwarders;
private final Set<IndexTask> queuedTasks = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final ChangeCheckerImpl.Factory changeChecker;
+ private final ProjectsFilter projectsFilter;
@Inject
IndexEventHandler(
@IndexExecutor Executor executor,
DynamicSet<IndexEventForwarder> forwarders,
- ChangeCheckerImpl.Factory changeChecker) {
+ ChangeCheckerImpl.Factory changeChecker,
+ ProjectsFilter projectsFilter) {
this.forwarders = forwarders;
this.executor = executor;
this.changeChecker = changeChecker;
+ this.projectsFilter = projectsFilter;
}
@Override
@@ -88,7 +92,7 @@
@Override
public void onProjectIndexed(String projectName) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(projectName)) {
IndexProjectTask task = new IndexProjectTask(new ProjectIndexEvent(projectName));
if (queuedTasks.add(task)) {
executor.execute(task);
@@ -97,7 +101,7 @@
}
private void executeIndexChangeTask(String projectName, int id) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(projectName)) {
ChangeChecker checker = changeChecker.create(projectName + "~" + id);
try {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
index cfe585d..ebc17b7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
@@ -18,6 +18,7 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.multisite.LockWrapper;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
@@ -51,15 +52,24 @@
ValidationMetrics validationMetrics,
SharedRefEnforcement refEnforcement,
LockWrapper.Factory lockWrapperFactory,
+ ProjectsFilter projectsFilter,
@Assisted String projectName,
@Assisted RefDatabase refDb) {
- super(sharedRefDb, validationMetrics, refEnforcement, lockWrapperFactory, projectName, refDb);
+ super(
+ sharedRefDb,
+ validationMetrics,
+ refEnforcement,
+ lockWrapperFactory,
+ projectsFilter,
+ projectName,
+ refDb);
}
public void executeBatchUpdateWithValidation(
BatchRefUpdate batchRefUpdate, NoParameterVoidFunction batchRefUpdateFunction)
throws IOException {
- if (refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED) {
+ if (refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED
+ || !isGlobalProject(projectName)) {
batchRefUpdateFunction.invoke();
return;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
index 73bab49..c8ddb43 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
@@ -31,6 +31,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import java.io.IOException;
@@ -58,6 +59,7 @@
private final GitRepositoryManager gitRepositoryManager;
private final GitReferenceUpdated gitReferenceUpdated;
private final ProjectVersionLogger verLogger;
+ private final ProjectsFilter projectsFilter;
protected final SharedRefDatabaseWrapper sharedRefDb;
@@ -66,11 +68,13 @@
GitRepositoryManager gitRepositoryManager,
SharedRefDatabaseWrapper sharedRefDb,
GitReferenceUpdated gitReferenceUpdated,
- ProjectVersionLogger verLogger) {
+ ProjectVersionLogger verLogger,
+ ProjectsFilter projectsFilter) {
this.gitRepositoryManager = gitRepositoryManager;
this.sharedRefDb = sharedRefDb;
this.gitReferenceUpdated = gitReferenceUpdated;
this.verLogger = verLogger;
+ this.projectsFilter = projectsFilter;
}
@Override
@@ -78,7 +82,9 @@
logger.atFine().log("Processing event type: " + event.type);
// Producer of the Event use RefUpdatedEvent to trigger the version update
if (!Context.isForwardedEvent() && event instanceof RefUpdatedEvent) {
- updateProducerProjectVersionUpdate((RefUpdatedEvent) event);
+ if (projectsFilter.matches(event)) {
+ updateProducerProjectVersionUpdate((RefUpdatedEvent) event);
+ }
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
index 89c6792..a882e2d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
@@ -21,6 +21,7 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.multisite.LockWrapper;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
@@ -45,6 +46,7 @@
private final LockWrapper.Factory lockWrapperFactory;
protected final RefDatabase refDb;
protected final SharedRefEnforcement refEnforcement;
+ protected final ProjectsFilter projectsFilter;
public static interface Factory {
RefUpdateValidator create(String projectName, RefDatabase refDb);
@@ -73,6 +75,7 @@
ValidationMetrics validationMetrics,
SharedRefEnforcement refEnforcement,
LockWrapper.Factory lockWrapperFactory,
+ ProjectsFilter projectsFilter,
@Assisted String projectName,
@Assisted RefDatabase refDb) {
this.sharedRefDb = sharedRefDb;
@@ -81,12 +84,14 @@
this.refDb = refDb;
this.projectName = projectName;
this.refEnforcement = refEnforcement;
+ this.projectsFilter = projectsFilter;
}
public RefUpdate.Result executeRefUpdate(
RefUpdate refUpdate, NoParameterFunction<RefUpdate.Result> refUpdateFunction)
throws IOException {
if (isProjectVersionUpdate(refUpdate.getName())
+ || !isGlobalProject(projectName)
|| refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED) {
return refUpdateFunction.invoke();
}
@@ -124,6 +129,12 @@
}
}
+ protected Boolean isGlobalProject(String projectName) {
+ Boolean isGlobalProject = projectsFilter.matches(projectName);
+ logger.atFine().log("Is global project? " + isGlobalProject);
+ return isGlobalProject;
+ }
+
protected RefUpdate.Result doExecuteRefUpdate(
RefUpdate refUpdate, NoParameterFunction<RefUpdate.Result> refUpdateFunction)
throws IOException {
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 662f46e..b1f3369 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -100,4 +100,28 @@
Relax the alignment with the shared ref-database for AProject on refs/heads/feature.
- Defaults: No rules = All projects are REQUIRED to be consistent on all refs.
\ No newline at end of file
+ Defaults: No rules = All projects are REQUIRED to be consistent on all refs.
+
+```projects.pattern```
+: Specifies which projects events should be send via broker. It can be provided more
+ than once, and supports three formats: regular expressions, wildcard matching, and single
+ project matching. All three formats match case-sensitive.
+
+ Values starting with a caret `^` are treated as regular
+ expressions. For the regular expressions details please follow
+ official [java documentation](https://docs.oracle.com/javase/tutorial/essential/regex/).
+
+ Please note that regular expressions could also be used
+ with inverse match.
+
+ Values that are not regular expressions and end in `*` are
+ treated as wildcard matches. Wildcards match projects whose
+ name agrees from the beginning until the trailing `*`. So
+ `foo/b*` would match the projects `foo/b`, `foo/bar`, and
+ `foo/baz`, but neither `foobar`, nor `bar/foo/baz`.
+
+ Values that are neither regular expressions nor wildcards are
+ treated as single project matches. So `foo/bar` matches only
+ the project `foo/bar`, but no other project.
+
+ By default, all projects are matched.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
new file mode 100644
index 0000000..e81c906
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
@@ -0,0 +1,180 @@
+// Copyright (C) 2020 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.plugins.multisite;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.Lists;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.server.events.Event;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.gerrit.server.events.RefUpdatedEvent;
+import com.google.gerrit.testing.GerritJUnit;
+import com.googlesource.gerrit.plugins.multisite.Configuration.Projects;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectsFilterTest {
+
+ @Mock private Configuration configuration;
+ @Mock private Projects projects;
+
+ private ProjectsFilter objectUnderTest;
+
+ @Test
+ public void shouldMatchByExactProjectName() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchByWildcard() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project*"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("2test_project"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchByRegex() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("^test_(project|project2)"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ }
+
+ @Test
+ public void shouldExcludeByRegex() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("^(?:(?!test_project3).)*$"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ }
+
+ @Test
+ public void shouldExcludeByMultipleProjectsRegexPattern() {
+ when(projects.getPatterns())
+ .thenReturn(Lists.newArrayList("^(?:(?!(test_project3|test_project4)).)*$"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project4"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchWhenNoPatternProvided() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ }
+
+ @Test
+ public void shouldMatchProjectEvent() {
+ ProjectEvent event = mock(ProjectEvent.class);
+ when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isTrue();
+ }
+
+ @Test
+ public void shouldMatchRefUpdatedEvent() {
+ RefUpdatedEvent event = mock(RefUpdatedEvent.class);
+ when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isTrue();
+ }
+
+ @Test
+ public void shouldExcludedNonProjectEvents() {
+ Event event = mock(Event.class);
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project)"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isFalse();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenProjecNameIsNull() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches((NameKey) null));
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenProjecNameIsEmpty() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches(NameKey.parse("")));
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenEventIsNull() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches((Event) null));
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
index b86f8af..2a25c37 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -26,6 +27,7 @@
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.cache.ProjectListUpdateHandler.ProjectListUpdateTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
@@ -42,10 +44,14 @@
private ProjectListUpdateHandler handler;
@Mock private ProjectListUpdateForwarder forwarder;
+ @Mock private ProjectsFilter projectsFilter;
@Before
public void setUp() {
- handler = new ProjectListUpdateHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor());
+ when(projectsFilter.matches(any(String.class))).thenReturn(true);
+ handler =
+ new ProjectListUpdateHandler(
+ asDynamicSet(forwarder), MoreExecutors.directExecutor(), projectsFilter);
}
private DynamicSet<ProjectListUpdateForwarder> asDynamicSet(
@@ -87,6 +93,18 @@
}
@Test
+ public void shouldNotForwardIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+ String projectName = "projectToAdd";
+ NewProjectCreatedListener.Event event = mock(NewProjectCreatedListener.Event.class);
+ when(event.getProjectName()).thenReturn(projectName);
+ handler.onNewProjectCreated(event);
+ verify(forwarder, never())
+ .updateProjectList(
+ any(ProjectListUpdateTask.class), eq(new ProjectListUpdateEvent(projectName, true)));
+ }
+
+ @Test
public void testProjectUpdateTaskToString() throws Exception {
String projectName = "someProjectName";
ProjectListUpdateTask task =
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
index 990a03f..bac0851 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
@@ -15,15 +15,19 @@
package com.googlesource.gerrit.plugins.multisite.event;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.event.EventHandler.EventTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
@@ -39,10 +43,13 @@
private EventHandler eventHandler;
@Mock private StreamEventForwarder forwarder;
+ @Mock private ProjectsFilter projectsFilter;
@Before
public void setUp() {
- eventHandler = new EventHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor());
+ when(projectsFilter.matches(any(ProjectEvent.class))).thenReturn(true);
+ eventHandler =
+ new EventHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor(), projectsFilter);
}
private DynamicSet<StreamEventForwarder> asDynamicSet(StreamEventForwarder forwarder) {
@@ -53,7 +60,7 @@
@Test
public void shouldForwardAnyProjectEvent() throws Exception {
- Event event = mock(ProjectEvent.class);
+ ProjectEvent event = mock(ProjectEvent.class);
eventHandler.onEvent(event);
verify(forwarder).send(event);
}
@@ -73,6 +80,16 @@
}
@Test
+ public void shouldNotForwardIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(ProjectEvent.class))).thenReturn(false);
+
+ ProjectEvent event = mock(ProjectEvent.class);
+
+ eventHandler.onEvent(event);
+ verify(forwarder, never()).send(event);
+ }
+
+ @Test
public void tesEventTaskToString() throws Exception {
Event event = new RefUpdatedEvent();
EventTask task = eventHandler.new EventTask(event);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
new file mode 100644
index 0000000..0a57851
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
@@ -0,0 +1,75 @@
+// Copyright (C) 2020 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.plugins.multisite.index;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
+import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.index.IndexEventHandler.IndexProjectTask;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IndexEventHandlerTest {
+
+ private IndexEventHandler eventHandler;
+
+ @Mock private ProjectsFilter projectsFilter;
+ @Mock private IndexEventForwarder forwarder;
+ @Mock private ChangeCheckerImpl.Factory changeChecker;
+
+ @Before
+ public void setUp() {
+ eventHandler =
+ new IndexEventHandler(
+ MoreExecutors.directExecutor(), asDynamicSet(forwarder), changeChecker, projectsFilter);
+ }
+
+ private DynamicSet<IndexEventForwarder> asDynamicSet(IndexEventForwarder forwarder) {
+ DynamicSet<IndexEventForwarder> result = new DynamicSet<>();
+ result.add("multi-site", forwarder);
+ return result;
+ }
+
+ @Test
+ public void shouldNotForwardProjectIndexedIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+
+ eventHandler.onProjectIndexed("test_project");
+ verify(forwarder, never())
+ .index(any(IndexProjectTask.class), eq(new ProjectIndexEvent("test_project")));
+ }
+
+ @Test
+ public void shouldNotForwardIndexChangeIfFilteredOutByProjectName() throws Exception {
+ int changeId = 1;
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+
+ eventHandler.onChangeIndexed("test_project", changeId);
+ verifyZeroInteractions(changeChecker);
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
index 20b6da8..cd919f4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
@@ -16,14 +16,18 @@
import static com.google.common.truth.Truth.assertThat;
import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import com.google.gerrit.entities.Project;
import com.google.gerrit.metrics.DisabledMetricMaker;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
@@ -64,11 +68,12 @@
@Mock SharedRefDatabaseWrapper sharedRefDatabase;
@Mock SharedRefEnforcement tmpRefEnforcement;
+ @Mock ProjectsFilter projectsFilter;
@Before
public void setup() throws Exception {
super.setUp();
-
+ when(projectsFilter.matches(anyString())).thenReturn(true);
gitRepoSetup();
}
@@ -137,6 +142,24 @@
(command) -> assertThat(command.getResult()).isEqualTo(ReceiveCommand.Result.LOCK_FAILURE));
}
+ @Test
+ public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
+ when(projectsFilter.matches(anyString())).thenReturn(true);
+
+ String AN_OUT_OF_SYNC_REF = "refs/changes/01/1/1";
+ BatchRefUpdate batchRefUpdate =
+ newBatchUpdate(
+ Collections.singletonList(new ReceiveCommand(A, B, AN_OUT_OF_SYNC_REF, UPDATE)));
+ BatchRefUpdateValidator batchRefUpdateValidator =
+ getRefValidatorForEnforcement(A_TEST_PROJECT_NAME, tmpRefEnforcement);
+
+ batchRefUpdateValidator.executeBatchUpdateWithValidation(
+ batchRefUpdate, () -> execute(batchRefUpdate));
+
+ verify(sharedRefDatabase, never())
+ .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
+ }
+
private BatchRefUpdateValidator newDefaultValidator(String projectName) {
return getRefValidatorForEnforcement(projectName, new DefaultSharedRefEnforcement());
}
@@ -148,6 +171,7 @@
new ValidationMetrics(new DisabledMetricMaker()),
sharedRefEnforcement,
new DummyLockWrapper(),
+ projectsFilter,
projectName,
diskRepo.getRefDatabase());
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
index fcbafbb..a155752 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.multisite.validation;
import static java.util.Arrays.asList;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
@@ -24,6 +25,7 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
@@ -38,6 +40,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceiveCommand.Result;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
@@ -56,6 +59,7 @@
@Mock RevWalk revWalk;
@Mock ProgressMonitor progressMonitor;
@Mock ValidationMetrics validationMetrics;
+ @Mock ProjectsFilter projectsFilter;
private final Ref oldRef =
new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_1);
@@ -91,6 +95,11 @@
return "branch_" + nameRule.getMethodName();
}
+ @Before
+ public void setup() {
+ when(projectsFilter.matches(anyString())).thenReturn(true);
+ }
+
@SuppressWarnings("deprecation")
private void setMockRequiredReturnValues() throws IOException {
@@ -167,6 +176,7 @@
validationMetrics,
new DefaultSharedRefEnforcement(),
new DummyLockWrapper(),
+ projectsFilter,
projectName,
refDb);
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
index d9e5c07..029a4c6 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
@@ -16,11 +16,14 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.Factory;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
@@ -33,6 +36,7 @@
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -49,6 +53,7 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
@Mock ValidationMetrics validationMetrics;
@Mock RefDatabase refDb;
+ @Mock ProjectsFilter projectsFilter;
private final Ref oldRef =
new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_1);
@@ -62,6 +67,11 @@
return "branch_" + nameRule.getMethodName();
}
+ @Before
+ public void setup() {
+ when(projectsFilter.matches(anyString())).thenReturn(true);
+ }
+
@Test
public void newUpdateShouldValidateAndSucceed() throws Exception {
@@ -182,6 +192,7 @@
validationMetrics,
new DefaultSharedRefEnforcement(),
new DummyLockWrapper(),
+ projectsFilter,
projectName,
refDb);
return RefUpdateValidator;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
index 2eefb5a..d437a73 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
@@ -26,6 +26,7 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.project.ProjectConfig;
@@ -33,6 +34,7 @@
import com.google.gerrit.testing.InMemoryTestEnvironment;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
@@ -63,6 +65,7 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
@Mock GitReferenceUpdated gitReferenceUpdated;
@Mock ProjectVersionLogger verLogger;
+ @Mock ProjectsFilter projectsFilter;
@Inject private ProjectConfig.Factory projectConfigFactory;
@Inject private InMemoryRepositoryManager repoManager;
@@ -73,6 +76,7 @@
@Before
public void setUp() throws Exception {
+ when(projectsFilter.matches(any(Event.class))).thenReturn(true);
InMemoryRepository inMemoryRepo = repoManager.createRepository(A_TEST_PROJECT_NAME_KEY);
project = projectConfigFactory.create(A_TEST_PROJECT_NAME_KEY);
project.load(inMemoryRepo);
@@ -105,7 +109,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -150,7 +155,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -190,7 +196,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -227,7 +234,8 @@
when(refUpdatedEvent.getRefName()).thenReturn(magicRefName);
repo.branch(magicRefName).commit().create();
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -242,7 +250,30 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(Project.nameKey("aNonExistentProject"));
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
+ .onEvent(refUpdatedEvent);
+
+ Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
+ assertThat(ref).isNull();
+
+ verifyZeroInteractions(verLogger);
+ }
+
+ @Test
+ public void shouldNotUpdateProjectVersionWhenProjectFilteredOut() throws Exception {
+ when(projectsFilter.matches(any(Event.class))).thenReturn(false);
+
+ Context.setForwardedEvent(false);
+
+ Thread.sleep(1000L);
+ repo.branch("master").commit().create();
+
+ Thread.sleep(1000L);
+ repo.branch("master").update(masterCommit);
+
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -257,7 +288,8 @@
.thenReturn(Optional.of("123"));
Optional<Long> version =
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.getProjectRemoteVersion(A_TEST_PROJECT_NAME);
assertThat(version.isPresent()).isTrue();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
index 3f4d1bb..2951c89 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
@@ -16,12 +16,15 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import com.google.gerrit.entities.Project;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
@@ -53,6 +56,8 @@
@Mock RefUpdate refUpdate;
+ @Mock ProjectsFilter projectsFilter;
+
String refName;
Ref oldUpdateRef;
Ref newUpdateRef;
@@ -74,6 +79,8 @@
doReturn(refName).when(refUpdate).getName();
lenient().doReturn(oldUpdateRef.getObjectId()).when(refUpdate).getOldObjectId();
+ doReturn(true).when(projectsFilter).matches(anyString());
+
refUpdateValidator = newRefUpdateValidator(sharedRefDb);
}
@@ -193,12 +200,23 @@
assertThat(result).isEqualTo(RefUpdate.Result.LOCK_FAILURE);
}
+ @Test
+ public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
+ when(projectsFilter.matches(anyString())).thenReturn(false);
+
+ refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
+
+ verify(sharedRefDb, never())
+ .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
+ }
+
private RefUpdateValidator newRefUpdateValidator(SharedRefDatabaseWrapper refDbWrapper) {
return new RefUpdateValidator(
refDbWrapper,
validationMetrics,
defaultRefEnforcement,
new DummyLockWrapper(),
+ projectsFilter,
A_TEST_PROJECT_NAME,
localRefDb);
}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CloneUsingMultiGerrit1.scala b/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CloneUsingMultiGerrit1.scala
index f1d2727..cc80577 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CloneUsingMultiGerrit1.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CloneUsingMultiGerrit1.scala
@@ -50,10 +50,10 @@
test.inject(
nothingFor(stepWaitTime(this) seconds),
atOnceUsers(single)
- ),
+ ).protocols(gitProtocol),
deleteProject.test.inject(
nothingFor(createProject.maxExecutionTime + maxExecutionTime seconds),
atOnceUsers(single)
),
- ).protocols(gitProtocol, httpProtocol)
+ ).protocols(httpProtocol)
}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CreateProjectUsingMultiGerritTwice.scala b/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CreateProjectUsingMultiGerritTwice.scala
index 68508c7..5270ce0 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CreateProjectUsingMultiGerritTwice.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/multisite/scenarios/CreateProjectUsingMultiGerritTwice.scala
@@ -44,10 +44,10 @@
verifyProject.test.inject(
nothingFor(stepWaitTime(verifyProject) seconds),
atOnceUsers(single)
- ),
+ ).protocols(gitProtocol),
deleteItAfter.test.inject(
nothingFor(stepWaitTime(deleteItAfter) seconds),
atOnceUsers(single)
),
- ).protocols(gitProtocol, httpProtocol)
+ ).protocols(httpProtocol)
}