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) {} }