Fix bizzare NPE in context generation for DeviceClient.
Add test for remote client
This commit is contained in:
parent
b1121d61cb
commit
8bd9bcc6a6
@ -12,6 +12,7 @@ description = """
|
||||
kscience {
|
||||
jvm()
|
||||
js()
|
||||
useCoroutines("1.8.0")
|
||||
useSerialization {
|
||||
json()
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package space.kscience.controls.client
|
||||
|
||||
import com.benasher44.uuid.uuid4
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.newCoroutineContext
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import space.kscience.controls.api.*
|
||||
@ -28,8 +28,8 @@ public class DeviceClient(
|
||||
private val send: suspend (DeviceMessage) -> Unit,
|
||||
) : CachingDevice {
|
||||
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
override val coroutineContext: CoroutineContext = newCoroutineContext(context.coroutineContext)
|
||||
|
||||
override val coroutineContext: CoroutineContext = context.coroutineContext + Job(context.coroutineContext[Job])
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
|
@ -0,0 +1,87 @@
|
||||
package space.kscience.controls.client
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.serialization.json.Json
|
||||
import space.kscience.controls.api.Device
|
||||
import space.kscience.controls.manager.DeviceManager
|
||||
import space.kscience.controls.manager.install
|
||||
import space.kscience.controls.manager.respondMessage
|
||||
import space.kscience.controls.spec.*
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.Factory
|
||||
import space.kscience.dataforge.context.request
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.int
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.magix.api.MagixEndpoint
|
||||
import space.kscience.magix.api.MagixMessage
|
||||
import space.kscience.magix.api.MagixMessageFilter
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContains
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
|
||||
public suspend fun <T> Device.readUnsafe(propertySpec: DevicePropertySpec<*, T>): T =
|
||||
propertySpec.converter.metaToObject(readProperty(propertySpec.name)) ?: error("Property read result is not valid")
|
||||
|
||||
internal class RemoteDeviceConnect {
|
||||
|
||||
class TestDevice(context: Context, meta: Meta) : DeviceBySpec<TestDevice>(TestDevice, context, meta) {
|
||||
private val rng = Random(meta["seed"].int ?: 0)
|
||||
|
||||
private val randomValue get() = rng.nextDouble()
|
||||
|
||||
companion object : DeviceSpec<TestDevice>(), Factory<TestDevice> {
|
||||
|
||||
override fun build(context: Context, meta: Meta): TestDevice = TestDevice(context, meta)
|
||||
|
||||
val value by doubleProperty { randomValue }
|
||||
|
||||
override suspend fun TestDevice.onOpen() {
|
||||
doRecurring((meta["delay"].int ?: 10).milliseconds) {
|
||||
read(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wrapper() = runTest {
|
||||
val context = Context {
|
||||
plugin(DeviceManager)
|
||||
}
|
||||
|
||||
val device = context.request(DeviceManager).install("test", TestDevice)
|
||||
|
||||
val virtualMagixEndpoint = object : MagixEndpoint {
|
||||
|
||||
|
||||
override fun subscribe(filter: MagixMessageFilter): Flow<MagixMessage> = device.messageFlow.map {
|
||||
MagixMessage(
|
||||
format = DeviceManager.magixFormat.defaultFormat,
|
||||
payload = MagixEndpoint.magixJson.encodeToJsonElement(DeviceManager.magixFormat.serializer, it),
|
||||
sourceEndpoint = "test",
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun broadcast(message: MagixMessage) {
|
||||
device.respondMessage(
|
||||
Name.EMPTY,
|
||||
Json.decodeFromJsonElement(DeviceManager.magixFormat.serializer, message.payload)
|
||||
)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
val remoteDevice = virtualMagixEndpoint.remoteDevice(context, "test", Name.EMPTY)
|
||||
|
||||
assertContains(0.0..1.0, remoteDevice.readUnsafe(TestDevice.value))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user