Merge branch 'stable-2.16' into stable-3.0
* stable-2.16:
Make sure to always compare the latest local ref
Change-Id: I89e43fe7623977abf8ebea3db6d684c58caed1f9
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 59b5753..33be190 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
@@ -21,6 +21,7 @@
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -92,7 +93,7 @@
}
try (CloseableSet<AutoCloseable> locks = new CloseableSet<>()) {
- checkIfLocalRefIsUpToDateWithSharedRefDb(refsToUpdate, locks);
+ refsToUpdate = compareAndGetLatestLocalRefs(refsToUpdate, locks);
delegateUpdate.invoke();
updateSharedRefDb(batchRefUpdate.getCommands().stream(), refsToUpdate);
}
@@ -143,10 +144,12 @@
return command.getNewId();
}
- private void checkIfLocalRefIsUpToDateWithSharedRefDb(
+ private List<RefPair> compareAndGetLatestLocalRefs(
List<RefPair> refsToUpdate, CloseableSet<AutoCloseable> locks) throws IOException {
+ List<RefPair> latestRefsToUpdate = new ArrayList<>();
for (RefPair refPair : refsToUpdate) {
- checkIfLocalRefIsUpToDateWithSharedRefDb(refPair, locks);
+ latestRefsToUpdate.add(compareAndGetLatestLocalRef(refPair, locks));
}
+ return latestRefsToUpdate;
}
}
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 18f8654..dec6ae4 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
@@ -14,6 +14,8 @@
package com.googlesource.gerrit.plugins.multisite.validation;
+import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase.nullRef;
+
import com.google.common.base.MoreObjects;
import com.google.common.flogger.FluentLogger;
import com.google.inject.Inject;
@@ -26,6 +28,7 @@
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
import java.io.IOException;
import java.util.HashMap;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
@@ -113,7 +116,7 @@
throws IOException {
try (CloseableSet<AutoCloseable> locks = new CloseableSet<>()) {
RefPair refPairForUpdate = newRefPairFrom(refUpdate);
- checkIfLocalRefIsUpToDateWithSharedRefDb(refPairForUpdate, locks);
+ compareAndGetLatestLocalRef(refPairForUpdate, locks);
RefUpdate.Result result = refUpdateFunction.invoke();
if (isSuccessful(result)) {
updateSharedDbOrThrowExceptionFor(refPairForUpdate);
@@ -146,32 +149,39 @@
}
}
- protected void checkIfLocalRefIsUpToDateWithSharedRefDb(
+ protected RefPair compareAndGetLatestLocalRef(
RefPair refPair, CloseableSet<AutoCloseable> locks)
throws SharedLockException, OutOfSyncException, IOException {
String refName = refPair.getName();
EnforcePolicy refEnforcementPolicy = refEnforcement.getPolicy(projectName, refName);
if (refEnforcementPolicy == EnforcePolicy.IGNORED) {
- return;
+ return refPair;
}
- Ref localRef = refPair.compareRef;
-
locks.addResourceIfNotExist(
String.format("%s-%s", projectName, refName),
() -> sharedRefDb.lockRef(projectName, refName));
+ RefPair latestRefPair = getLatestLocalRef(refPair);
boolean isInSync =
- (localRef != null)
- ? sharedRefDb.isUpToDate(projectName, localRef)
- : !sharedRefDb.exists(projectName, refName);
+ (latestRefPair.compareRef.getObjectId().equals(ObjectId.zeroId()))
+ ? !sharedRefDb.exists(projectName, refName)
+ : sharedRefDb.isUpToDate(projectName, latestRefPair.compareRef);
if (!isInSync) {
validationMetrics.incrementSplitBrainPrevention();
softFailBasedOnEnforcement(
- new OutOfSyncException(projectName, localRef), refEnforcementPolicy);
+ new OutOfSyncException(projectName, latestRefPair.compareRef), refEnforcementPolicy);
}
+
+ return latestRefPair;
+ }
+
+ private RefPair getLatestLocalRef(RefPair refPair) throws IOException {
+ Ref latestRef = refDb.exactRef(refPair.getName());
+ return new RefPair(
+ latestRef == null ? nullRef(refPair.getName()) : latestRef, refPair.putValue);
}
protected boolean isSuccessful(RefUpdate.Result result) {
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 7e0dc6e..9b8b562 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
@@ -98,6 +98,7 @@
.thenReturn(asList(successReceiveCommandAfterExecution));
doReturn(oldRef).when(refDatabase).getRef(A_TEST_REF_NAME);
+ doReturn(oldRef).when(refDatabase).exactRef(A_TEST_REF_NAME);
multiSiteRefUpdate = getMultiSiteBatchRefUpdateWithDefaultPolicyEnforcement();
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 e7624bd..d95860c 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
@@ -67,6 +67,7 @@
localRef = newRef(refName, AN_OBJECT_ID_3);
doReturn(localRef).when(localRefDb).getRef(refName);
+ doReturn(localRef).when(localRefDb).exactRef(refName);
doReturn(oldUpdateRef).when(refUpdate).getRef();
doReturn(newUpdateRef.getObjectId()).when(refUpdate).getNewObjectId();
doReturn(refName).when(refUpdate).getName();