1package com.peachpasswords.sync23import org.junit.Assert.assertEquals4import org.junit.Assert.assertFalse5import org.junit.Assert.assertTrue6import org.junit.Test7import java.util.concurrent.CountDownLatch8import java.util.concurrent.TimeUnit9import kotlin.concurrent.thread1011class PairedDeviceStoreConcurrencyTest {12 @Test13 fun `a pairing snapshot cannot overwrite a concurrent sync update`() {14 val gate = RegistryMutationGate()15 val devices = mutableListOf("firefox")16 val pairingRead = CountDownLatch(1)17 val releasePairing = CountDownLatch(1)18 val syncEntered = CountDownLatch(1)1920 val pairing = thread {21 gate.withLock {22 val snapshot = devices.toList()23 pairingRead.countDown()24 assertTrue(releasePairing.await(5, TimeUnit.SECONDS))25 devices.clear()26 devices += snapshot + "chrome"27 }28 }2930 assertTrue(pairingRead.await(5, TimeUnit.SECONDS))31 val sync = thread {32 gate.withLock {33 syncEntered.countDown()34 val snapshot = devices.toList()35 devices.clear()36 devices += snapshot.map { if (it == "firefox") "firefox-synced" else it }37 }38 }3940 assertFalse(syncEntered.await(100, TimeUnit.MILLISECONDS))41 releasePairing.countDown()42 pairing.join(5_000)43 sync.join(5_000)4445 assertEquals(setOf("firefox-synced", "chrome"), devices.toSet())46 }47}