Adding concurrent locks/reclaiming locks tests
Change-Id: Ia5b22d1f4fb83c85a2e14de144afcd1f983a7b4e
diff --git a/src/test/java/com/googlesource/gerrit/plugins/spannerrefdb/LockTest.java b/src/test/java/com/googlesource/gerrit/plugins/spannerrefdb/LockTest.java
index cd5d65c..4f03f64 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/spannerrefdb/LockTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/spannerrefdb/LockTest.java
@@ -26,6 +26,10 @@
import com.google.gerrit.entities.Project;
import java.util.Arrays;
import java.util.Collections;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -117,6 +121,44 @@
.contains(String.format("Unable to lock ref %s on project %s", REF_NAME, PROJECT_NAME_KEY));
}
+ @Test
+ public void concurrentLocks_OnlyOneSuccess() throws Exception {
+ CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
+ ExecutorService pool = Executors.newFixedThreadPool(2);
+
+ for (int i = 0; i < 10; i++) {
+ Future<Boolean> f1 = pool.submit(() -> tryLockAwaitBarrier(cyclicBarrier));
+ Future<Boolean> f2 = pool.submit(() -> tryLockAwaitBarrier(cyclicBarrier));
+ assertThat(f1.get()).isNotEqualTo(f2.get());
+ }
+ pool.shutdown();
+ }
+
+ @Test
+ public void concurrentReclamations_OnlyOneSuccess() throws Exception {
+ Timestamp staleTimestamp = Timestamp.ofTimeSecondsAndNanos(0, 0);
+ CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
+ ExecutorService pool = Executors.newFixedThreadPool(2);
+
+ for (int i = 0; i < 10; i++) {
+ insertLockRow(staleTimestamp);
+ Future<Boolean> f1 = pool.submit(() -> tryLockAwaitBarrier(cyclicBarrier));
+ Future<Boolean> f2 = pool.submit(() -> tryLockAwaitBarrier(cyclicBarrier));
+ assertThat(f1.get()).isNotEqualTo(f2.get());
+ }
+ pool.shutdown();
+ }
+
+ private boolean tryLockAwaitBarrier(CyclicBarrier barrier) throws Exception {
+ try (AutoCloseable refLock = refDb.lockRef(PROJECT_NAME_KEY, REF_NAME)) {
+ barrier.await();
+ return true;
+ } catch (GlobalRefDbLockException e) {
+ barrier.await();
+ }
+ return false;
+ }
+
private Timestamp getLockTimestamp(Project.NameKey project, String refName, String column) {
Struct row = getLockRow(project, refName);
return row != null ? row.getTimestamp(column) : null;