fix: snapshot infrared fake calls
This commit is contained in:
+9
-7
@@ -12,8 +12,8 @@ import com.flagship.abox.manager.domain.SocketPowerState
|
|||||||
import com.flagship.abox.manager.domain.SocketStatus
|
import com.flagship.abox.manager.domain.SocketStatus
|
||||||
import com.flagship.abox.manager.domain.TemperatureHumidityGateway
|
import com.flagship.abox.manager.domain.TemperatureHumidityGateway
|
||||||
import com.flagship.abox.manager.domain.TemperatureHumidityReading
|
import com.flagship.abox.manager.domain.TemperatureHumidityReading
|
||||||
import java.util.Collections
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
|
||||||
class FakeSocketGateway : SocketGateway {
|
class FakeSocketGateway : SocketGateway {
|
||||||
private val states = ConcurrentHashMap<DeviceKey, SocketPowerState>()
|
private val states = ConcurrentHashMap<DeviceKey, SocketPowerState>()
|
||||||
@@ -78,10 +78,9 @@ class FakeTemperatureHumidityGateway : TemperatureHumidityGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FakeInfraredGateway : InfraredGateway {
|
class FakeInfraredGateway : InfraredGateway {
|
||||||
val sentKeys: MutableList<InfraredCall> = Collections.synchronizedList(mutableListOf())
|
val sentKeys = CopyOnWriteArrayList<InfraredCall>()
|
||||||
val learnedKeys: MutableList<InfraredCall> = Collections.synchronizedList(mutableListOf())
|
val learnedKeys = CopyOnWriteArrayList<InfraredCall>()
|
||||||
val downloadCalls: MutableList<InfraredDownloadCall> =
|
val downloadCalls = CopyOnWriteArrayList<InfraredDownloadCall>()
|
||||||
Collections.synchronizedList(mutableListOf())
|
|
||||||
private val sendResults = ConcurrentHashMap<InfraredOperationKey, DomainResult<Unit>>()
|
private val sendResults = ConcurrentHashMap<InfraredOperationKey, DomainResult<Unit>>()
|
||||||
private val learnResults = ConcurrentHashMap<InfraredOperationKey, DomainResult<Unit>>()
|
private val learnResults = ConcurrentHashMap<InfraredOperationKey, DomainResult<Unit>>()
|
||||||
|
|
||||||
@@ -134,9 +133,12 @@ class FakeInfraredGateway : InfraredGateway {
|
|||||||
profileId: ProviderProfileId,
|
profileId: ProviderProfileId,
|
||||||
codes: List<InfraredCode>,
|
codes: List<InfraredCode>,
|
||||||
): DomainResult<List<InfraredCodeDownloadResult>> {
|
): DomainResult<List<InfraredCodeDownloadResult>> {
|
||||||
|
val codesSnapshot = codes.toList()
|
||||||
downloadError?.let { return DomainResult.Failure(it) }
|
downloadError?.let { return DomainResult.Failure(it) }
|
||||||
downloadCalls += InfraredDownloadCall(profileId, codes)
|
downloadCalls += InfraredDownloadCall(profileId, codesSnapshot)
|
||||||
return DomainResult.Success(codes.map { InfraredCodeDownloadResult(it, successful = true) })
|
return DomainResult.Success(
|
||||||
|
codesSnapshot.map { InfraredCodeDownloadResult(it, successful = true) },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+69
@@ -4,8 +4,14 @@ import com.flagship.abox.manager.domain.DeviceName
|
|||||||
import com.flagship.abox.manager.domain.DomainError
|
import com.flagship.abox.manager.domain.DomainError
|
||||||
import com.flagship.abox.manager.domain.DomainResult
|
import com.flagship.abox.manager.domain.DomainResult
|
||||||
import com.flagship.abox.manager.domain.InfraredCode
|
import com.flagship.abox.manager.domain.InfraredCode
|
||||||
|
import com.flagship.abox.manager.domain.InfraredCodeDownloadResult
|
||||||
import com.flagship.abox.manager.domain.ProviderProfileId
|
import com.flagship.abox.manager.domain.ProviderProfileId
|
||||||
import com.flagship.abox.manager.domain.SocketPowerState
|
import com.flagship.abox.manager.domain.SocketPowerState
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.joinAll
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
@@ -55,6 +61,69 @@ class FakeDeviceGatewaysTest {
|
|||||||
assertTrue(download is DomainResult.Success)
|
assertTrue(download is DomainResult.Success)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun infraredDownloadRecordsAndReturnsAnInputSnapshot() = runTest {
|
||||||
|
val gateway = FakeInfraredGateway()
|
||||||
|
val code = InfraredCode(DeviceName("ir-1"), "power", "code-value")
|
||||||
|
val mutableCodes = mutableListOf(code)
|
||||||
|
|
||||||
|
val result = gateway.downloadCodes(profileOne, mutableCodes)
|
||||||
|
mutableCodes.clear()
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
InfraredDownloadCall(profileOne, listOf(code)),
|
||||||
|
gateway.downloadCalls.single(),
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
DomainResult.Success(listOf(InfraredCodeDownloadResult(code, successful = true))),
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun infraredCallLogCanBeIteratedSafelyAroundConcurrentWrites() = runTest {
|
||||||
|
val gateway = FakeInfraredGateway()
|
||||||
|
val deviceName = DeviceName("ir-1")
|
||||||
|
gateway.sendKey(profileOne, deviceName, "initial")
|
||||||
|
val staleIterators = List(10) { gateway.sentKeys.iterator() }
|
||||||
|
val start = CountDownLatch(1)
|
||||||
|
val failures = ConcurrentLinkedQueue<Throwable>()
|
||||||
|
val writerCount = 4
|
||||||
|
val callsPerWriter = 100
|
||||||
|
|
||||||
|
val writers = List(writerCount) { writerIndex ->
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
start.await()
|
||||||
|
repeat(callsPerWriter) { callIndex ->
|
||||||
|
gateway.sendKey(profileOne, deviceName, "$writerIndex-$callIndex")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val reader = launch(Dispatchers.Default) {
|
||||||
|
start.await()
|
||||||
|
repeat(100) {
|
||||||
|
try {
|
||||||
|
gateway.sentKeys.forEach { call -> call.key.length }
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
failures += failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start.countDown()
|
||||||
|
(writers + reader).joinAll()
|
||||||
|
staleIterators.forEach { iterator ->
|
||||||
|
try {
|
||||||
|
iterator.forEachRemaining { call -> call.key.length }
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
failures += failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(failures.toList().joinToString(), failures.isEmpty())
|
||||||
|
assertEquals(1 + writerCount * callsPerWriter, gateway.sentKeys.size)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun infraredLearnResultsCanDifferByProfileDeviceAndKey() = runTest {
|
fun infraredLearnResultsCanDifferByProfileDeviceAndKey() = runTest {
|
||||||
val gateway = FakeInfraredGateway()
|
val gateway = FakeInfraredGateway()
|
||||||
|
|||||||
Reference in New Issue
Block a user