Merge branch 'stable-3.6' into stable-3.7
* stable-3.6:
Remove redundant format calls in log calls
Add put method to create/update global-refdb entry
Add happy path test for BatchRefUpdateValidator
Remove Maven legacy pom.xml
Return immediately if local ref update fails
Remove references to Zookeeper in logs
Squash filter/findFirst/isPresent into anyMatch
Fix typo in private method
Bump Gerrit and module to v3.6.6
Bump Gerrit and module to v3.5.6
Change-Id: Ibcc361909822c956b74721fdd8eee03649f1d8c5
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index a7c7c02..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,168 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>com.gerritforge</groupId>
- <artifactId>global-refdb</artifactId>
- <version>3.7.4</version>
- <packaging>jar</packaging>
-
- <name>global-refdb</name>
- <description>Global ref-database for use with Gerrit Code Review</description>
- <url>https://github.com/gerritforge/global-refdb</url>
-
- <licenses>
- <license>
- <name>The Apache Software License, Version 2.0</name>
- <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
- <distribution>repo</distribution>
- </license>
- </licenses>
-
- <scm>
- <url>https://review.gerrithub.io/GerritForge/global-refdb.git</url>
- <connection>https://review.gerrithub.io/GerritForge/global-refdb.git</connection>
- </scm>
-
- <developers>
- <developer>
- <name>Luca Milanesio</name>
- </developer>
- <developer>
- <name>Marcin Czech</name>
- </developer>
- <developer>
- <name>Antonio Barone</name>
- </developer>
- </developers>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <gerrit.version>3.7.4</gerrit.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>com.google.gerrit</groupId>
- <artifactId>gerrit-plugin-api</artifactId>
- <version>${gerrit.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.ryanharter.auto.value</groupId>
- <artifactId>auto-value-gson</artifactId>
- <version>1.3.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.google.gerrit</groupId>
- <artifactId>gerrit-acceptance-framework</artifactId>
- <version>${gerrit.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- <version>1.61</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.6.1</version>
- <configuration>
- <source>11</source>
- <target>11</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>3.1.0</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>3.2.0</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>2.5.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>1.6</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>com.theoryinpractise</groupId>
- <artifactId>googleformatter-maven-plugin</artifactId>
- <version>1.7.3</version>
- <executions>
- <execution>
- <id>reformat-sources</id>
- <configuration>
- <includeStale>false</includeStale>
- <style>GOOGLE</style>
- <formatMain>true</formatMain>
- <formatTest>true</formatTest>
- <filterModified>false</filterModified>
- <skip>false</skip>
- <fixImports>true</fixImports>
- <maxLineLength>100</maxLineLength>
- </configuration>
- <goals>
- <goal>format</goal>
- </goals>
- <phase>process-sources</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <distributionManagement>
- <repository>
- <id>sonatype-nexus-staging</id>
- <name>Sonatype Nexus Staging</name>
- <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
- </repository>
- </distributionManagement>
-</project>
-
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabase.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabase.java
new file mode 100644
index 0000000..c6f8de7
--- /dev/null
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabase.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2023 GerritForge Ltd
+//
+// 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.gerritforge.gerrit.globalrefdb;
+
+import com.google.gerrit.entities.Project;
+
+public interface ExtendedGlobalRefDatabase extends GlobalRefDatabase {
+
+ /**
+ * Set a value of generic type T.
+ *
+ * <p>Set is executed as an atomic operation.
+ *
+ * @param project project name of the ref.
+ * @param refName to store the value for.
+ * @param newValue new value to store.
+ * @param <T> Type of the current and new value
+ * @throws GlobalRefDbSystemError the reference cannot be set due to a system error.
+ */
+ <T> void put(Project.NameKey project, String refName, T newValue) throws GlobalRefDbSystemError;
+}
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidator.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidator.java
index 22aae61..f461a9a 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidator.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidator.java
@@ -140,7 +140,7 @@
return;
}
- List<RefPair> refsToUpdate = getRefsPairs(commands).collect(Collectors.toList());
+ List<RefPair> refsToUpdate = getRefPairs(commands).collect(Collectors.toList());
List<RefPair> refsFailures =
refsToUpdate.stream().filter(RefPair::hasFailed).collect(Collectors.toList());
if (!refsFailures.isEmpty()) {
@@ -195,10 +195,7 @@
private void updateSharedRefDb(Stream<ReceiveCommand> commandStream, List<RefPair> refsToUpdate)
throws IOException {
- if (commandStream
- .filter(cmd -> cmd.getResult() != ReceiveCommand.Result.OK)
- .findFirst()
- .isPresent()) {
+ if (commandStream.anyMatch(cmd -> cmd.getResult() != ReceiveCommand.Result.OK)) {
return;
}
@@ -207,7 +204,7 @@
}
}
- private Stream<RefPair> getRefsPairs(List<ReceiveCommand> receivedCommands) {
+ private Stream<RefPair> getRefPairs(List<ReceiveCommand> receivedCommands) {
return receivedCommands.stream().map(this::getRefPairForCommand);
}
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
index 3b4dbb2..04ffeed 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/Log4jSharedRefLogger.java
@@ -140,6 +140,18 @@
}
}
+ @Override
+ public <T> void logRefUpdate(String project, String refName, T newRefValue) {
+ if (newRefValue != null) {
+ sharedRefDBLog.info(
+ gson.toJson(
+ new SharedRefLogEntry.UpdateRef(
+ project, refName, null, safeToString(newRefValue), null, null)));
+ } else {
+ sharedRefDBLog.info(gson.toJson(new SharedRefLogEntry.DeleteRef(project, refName, null)));
+ }
+ }
+
/**
* {@inheritDoc}.
*
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/RefUpdateValidator.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/RefUpdateValidator.java
index 40e168c..ec8ff82 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/RefUpdateValidator.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/RefUpdateValidator.java
@@ -189,10 +189,11 @@
RefPair refPairForUpdate = newRefPairFrom(refUpdate);
compareAndGetLatestLocalRef(refPairForUpdate, locks);
RefUpdate.Result result = refUpdateFunction.invoke();
+ if (!isSuccessful(result)) {
+ return result;
+ }
try {
- if (isSuccessful(result)) {
- updateSharedDbOrThrowExceptionFor(refPairForUpdate);
- }
+ updateSharedDbOrThrowExceptionFor(refPairForUpdate);
} catch (Exception e) {
result = rollbackFunction.invoke(refPairForUpdate.compareRef.getObjectId());
if (isSuccessful(result)) {
@@ -224,7 +225,7 @@
Project.nameKey(projectName), refPair.compareRef, refPair.putValue);
} catch (GlobalRefDbSystemError e) {
logger.atWarning().withCause(e).log(
- "Not able to persist the data in Zookeeper for project '%s' and ref '%s', message: %s",
+ "Not able to persist the data in global-refdb for project '%s' and ref '%s', message: %s",
projectName, refPair.getName(), e.getMessage());
throw e;
}
@@ -232,9 +233,9 @@
if (!succeeded) {
String errorMessage =
String.format(
- "Not able to persist the data in Zookeeper for project '%s' and ref '%s',"
+ "Not able to persist the data in SharedRef for project '%s' and ref '%s',"
+ "the cluster is now in Split Brain since the commit has been "
- + "persisted locally but not in SharedRef the value %s",
+ + "persisted locally but not in global-refdb the value %s",
projectName, refPair.getName(), refPair.putValue);
throw new SharedDbSplitBrainException(errorMessage);
}
@@ -343,7 +344,7 @@
logger.atSevere().withCause(closingException).log(
"Exception trying to release resource %s, "
+ "the locked resources won't be accessible in all cluster unless"
- + " the lock is removed from ZK manually",
+ + " the lock is removed from global-refdb manually",
closeable);
}
});
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDBMetrics.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDBMetrics.java
index ff483ab..c907831 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDBMetrics.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDBMetrics.java
@@ -28,6 +28,7 @@
private final Timer0 getOperationExecutionTime;
private final Timer0 existsExecutionTime;
private Timer0 compareAndPutExecutionTime;
+ private Timer0 setExecutionTime;
private Timer0 removeExecutionTime;
private Timer0 isUpToDateExecutionTime;
@@ -39,6 +40,12 @@
new Description("Time spent on compareAndPut.")
.setCumulative()
.setUnit(Description.Units.MILLISECONDS));
+ setExecutionTime =
+ metricMaker.newTimer(
+ "global_refdb/set_latency",
+ new Description("Time spent on set.")
+ .setCumulative()
+ .setUnit(Description.Units.MILLISECONDS));
getOperationExecutionTime =
metricMaker.newTimer(
"global_refdb/get_latency",
@@ -76,6 +83,10 @@
return compareAndPutExecutionTime.start();
}
+ public Context startSetExecutionTime() {
+ return setExecutionTime.start();
+ }
+
public Context startGetExecutionTime() {
return getOperationExecutionTime.start();
}
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDatabaseWrapper.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDatabaseWrapper.java
index c3b41e8..c9a6c7d 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDatabaseWrapper.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDatabaseWrapper.java
@@ -14,6 +14,7 @@
package com.gerritforge.gerrit.globalrefdb.validation;
+import com.gerritforge.gerrit.globalrefdb.ExtendedGlobalRefDatabase;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
@@ -35,7 +36,7 @@
* {@link NoopSharedRefDatabase} instance is wrapped instead.
*/
@Singleton
-public class SharedRefDatabaseWrapper implements GlobalRefDatabase {
+public class SharedRefDatabaseWrapper implements ExtendedGlobalRefDatabase {
private static final FluentLogger log = FluentLogger.forEnclosingClass();
private static final GlobalRefDatabase NOOP_REFDB = new NoopSharedRefDatabase();
@@ -99,6 +100,23 @@
}
}
+ @Override
+ public <T> void put(Project.NameKey project, String refName, T newValue)
+ throws GlobalRefDbSystemError {
+ if (!isSetOperationSupported()) {
+ throw new UnsupportedOperationException(
+ "GlobalRefDb implementation doesn't support set operation");
+ }
+ try (Context context = metrics.startSetExecutionTime()) {
+ ((ExtendedGlobalRefDatabase) sharedRefDb()).put(project, refName, newValue);
+ sharedRefLogger.logRefUpdate(project.get(), refName, newValue);
+ }
+ }
+
+ public boolean isSetOperationSupported() {
+ return sharedRefDb() instanceof ExtendedGlobalRefDatabase;
+ }
+
/** {@inheritDoc}. The operation is logged. */
@Override
public AutoCloseable lockRef(Project.NameKey project, String refName)
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogEntry.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogEntry.java
index c72ab7c..4b8132f 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogEntry.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogEntry.java
@@ -41,7 +41,7 @@
UpdateRef(
String projectName,
String refName,
- String oldId,
+ @Nullable String oldId,
String newId,
@Nullable GitPerson committer,
@Nullable String comment) {
@@ -68,7 +68,7 @@
public String refName;
public String oldId;
- DeleteRef(String projectName, String refName, String oldId) {
+ DeleteRef(String projectName, String refName, @Nullable String oldId) {
this.type = Type.DELETE_REF;
this.projectName = projectName;
this.refName = refName;
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogger.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogger.java
index 858ba18..f61f253 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogger.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefLogger.java
@@ -42,6 +42,16 @@
<T> void logRefUpdate(String project, String refName, T currRef, T newRefValue);
/**
+ * Log the update of ref pointed to by refName, in project 'project' to ref 'newRefValue'
+ *
+ * @param project the project the update is for
+ * @param refName the name of the ref being updatex
+ * @param newRefValue the new value of the ref being updated
+ * @param <T> Type of the 'currRef' and the 'newRefValue'
+ */
+ <T> void logRefUpdate(String project, String refName, T newRefValue);
+
+ /**
* Log the deletion of 'project' from the global refdb
*
* @param project the project being deleted
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/NoopSharedRefDatabase.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/NoopSharedRefDatabase.java
index 960b311..1ce480a 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/NoopSharedRefDatabase.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/NoopSharedRefDatabase.java
@@ -14,6 +14,7 @@
package com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb;
+import com.gerritforge.gerrit.globalrefdb.ExtendedGlobalRefDatabase;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
@@ -29,7 +30,7 @@
* <p>This is useful for setting up a test environment and allows multi-site library to be installed
* independently from any additional libModules or the existence of a specific Ref-DB installation.
*/
-public class NoopSharedRefDatabase implements GlobalRefDatabase {
+public class NoopSharedRefDatabase implements ExtendedGlobalRefDatabase {
/**
* Project/ref is always considered up-to-date
@@ -126,4 +127,10 @@
throws GlobalRefDbSystemError {
return Optional.empty();
}
+
+ @Override
+ public <T> void put(Project.NameKey project, String refName, T newValue)
+ throws GlobalRefDbSystemError {
+ // do nothing
+ }
}
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabaseTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabaseTest.java
new file mode 100644
index 0000000..d58e0f3
--- /dev/null
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/ExtendedGlobalRefDatabaseTest.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2023 GerritForge Ltd
+//
+// 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.gerritforge.gerrit.globalrefdb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.Optional;
+import org.junit.Test;
+
+public class ExtendedGlobalRefDatabaseTest extends GlobalRefDatabaseTest {
+
+ @Test
+ public void shouldSetLongValueInTheGlobalRefDB() {
+ objectUnderTest.put(project, refName, 1L);
+
+ Optional<Long> o = objectUnderTest.get(project, refName, Long.class);
+
+ assertThat(o.isPresent()).isTrue();
+ assertThat(o.get()).isEqualTo(1L);
+ }
+}
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/FakeGlobalRefDatabase.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/FakeGlobalRefDatabase.java
index 44c4fbb..5d4175f 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/FakeGlobalRefDatabase.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/FakeGlobalRefDatabase.java
@@ -16,6 +16,7 @@
import com.google.common.collect.MapMaker;
import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;
@@ -26,7 +27,7 @@
import org.junit.Ignore;
@Ignore
-public class FakeGlobalRefDatabase implements GlobalRefDatabase {
+public class FakeGlobalRefDatabase implements ExtendedGlobalRefDatabase {
private ConcurrentMap<Project.NameKey, ConcurrentMap<String, AtomicReference<ObjectId>>>
keyValueStore;
@@ -132,6 +133,12 @@
return projectRefLock;
}
+ @Override
+ public <T> void put(NameKey project, String refName, T newValue) throws GlobalRefDbSystemError {
+ String key = String.format("%s/%s", project.get(), refName);
+ genericKeyValueStore.put(key, new AtomicReference<>(newValue));
+ }
+
private static class RefLock implements AutoCloseable {
private Lock lock;
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabaseTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabaseTest.java
index bb5ad8d..8ed1f4c 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabaseTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabaseTest.java
@@ -31,7 +31,8 @@
public class GlobalRefDatabaseTest extends AbstractDaemonTest {
- private String refName = RefNames.REFS_HEADS + "branch";
+ protected ExtendedGlobalRefDatabase objectUnderTest;
+ protected String refName = RefNames.REFS_HEADS + "branch";
private ObjectId objectId1;
private ObjectId objectId2;
@@ -45,8 +46,6 @@
private Executor executor = Executors.newFixedThreadPool(1);
- private GlobalRefDatabase objectUnderTest;
-
@Before
public void setup() throws Exception {
this.objectUnderTest = new FakeGlobalRefDatabase();
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidatorTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidatorTest.java
index bb572a8..2c4a1ea 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidatorTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/BatchRefUpdateValidatorTest.java
@@ -91,7 +91,38 @@
}
@Test
- public void immutableChangeShouldNotBeWrittenIntoZk() throws Exception {
+ public void shouldUpdateSharedRefDbForAllRefUpdates() throws IOException {
+ String REF_NAME_A = "refs/changes/01/1/1";
+ String REF_NAME_B = "refs/changes/02/1/1";
+ BatchRefUpdate batchRefUpdate =
+ newBatchUpdate(
+ List.of(
+ new ReceiveCommand(A, B, REF_NAME_A, UPDATE),
+ new ReceiveCommand(A, B, REF_NAME_B, UPDATE)));
+ BatchRefUpdateValidator batchRefUpdateValidator =
+ getRefValidatorForEnforcement(A_TEST_PROJECT_NAME, tmpRefEnforcement);
+
+ doReturn(SharedRefEnforcement.EnforcePolicy.REQUIRED)
+ .when(batchRefUpdateValidator.refEnforcement)
+ .getPolicy(A_TEST_PROJECT_NAME, REF_NAME_A);
+
+ doReturn(true).when(sharedRefDatabase).isUpToDate(any(), any());
+
+ doReturn(true).when(sharedRefDatabase).compareAndPut(any(), any(), any());
+
+ batchRefUpdateValidator.executeBatchUpdateWithValidation(
+ batchRefUpdate, () -> execute(batchRefUpdate), rollbackFunction);
+
+ verify(rollbackFunction, never()).invoke(any());
+
+ List<ReceiveCommand> commands = batchRefUpdate.getCommands();
+ assertThat(commands.size()).isEqualTo(2);
+ commands.forEach(
+ (command) -> assertThat(command.getResult()).isEqualTo(ReceiveCommand.Result.OK));
+ }
+
+ @Test
+ public void immutableChangeShouldNotBeWrittenIntoSharedRefDb() throws Exception {
String AN_IMMUTABLE_REF = "refs/changes/01/1/1";
List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(A, B, AN_IMMUTABLE_REF, UPDATE));
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/DisabledSharedRefLogger.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/DisabledSharedRefLogger.java
index f9a1e57..d6dd338 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/DisabledSharedRefLogger.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/DisabledSharedRefLogger.java
@@ -35,4 +35,7 @@
@Override
public <T> void logRefUpdate(String project, String refName, T currRef, T newRefValue) {}
+
+ @Override
+ public <T> void logRefUpdate(String project, String refName, T newRefValue) {}
}