From 94c172feace128b782ef30fdff9b3c5332087b2d Mon Sep 17 00:00:00 2001 From: Anastasia Katsman Date: Wed, 3 Jul 2024 18:46:20 +0200 Subject: [PATCH] [rdct-tests] add performGetComponentData GitOrigin-RevId: 5e0392c7973cf29cd37f9423bc1f3a11e375c931 --- .../DistributedTestModel.Generated.kt | 79 ++++++++++++++++++- .../modelSources/DistributedTestModel.kt | 6 ++ .../intellij/remoteDev/tests/AgentAction.kt | 9 ++- .../remoteDev/tests/DistributedTestPlayer.kt | 4 +- .../tests/impl/DistributedTestHost.kt | 68 +++++++++++----- 5 files changed, 140 insertions(+), 26 deletions(-) diff --git a/platform/remoteDev-util/modelGenerated/DistributedTestModel.Generated.kt b/platform/remoteDev-util/modelGenerated/DistributedTestModel.Generated.kt index d70e5fc10f74..fdc75e792f26 100644 --- a/platform/remoteDev-util/modelGenerated/DistributedTestModel.Generated.kt +++ b/platform/remoteDev-util/modelGenerated/DistributedTestModel.Generated.kt @@ -34,6 +34,7 @@ class DistributedTestModel private constructor( serializers.register(LazyCompanionMarshaller(RdId(3844250127064816121), classLoader, "com.intellij.remoteDev.tests.modelGenerated.RdTestSessionExceptionCause")) serializers.register(LazyCompanionMarshaller(RdId(-6820612235039581104), classLoader, "com.intellij.remoteDev.tests.modelGenerated.RdTestSessionException")) serializers.register(LazyCompanionMarshaller(RdId(8999514109111023287), classLoader, "com.intellij.remoteDev.tests.modelGenerated.RdTestActionParameters")) + serializers.register(LazyCompanionMarshaller(RdId(1797576418817339312), classLoader, "com.intellij.remoteDev.tests.modelGenerated.RdTestComponentData")) serializers.register(LazyCompanionMarshaller(RdId(-3821381997278381377), classLoader, "com.intellij.remoteDev.tests.modelGenerated.RdTestSession")) } @@ -56,7 +57,7 @@ class DistributedTestModel private constructor( private val __RdTestSessionNullableSerializer = RdTestSession.nullable() - const val serializationHash = 1373418669341890532L + const val serializationHash = 5182389909649567871L } override val serializersOwner: ISerializersOwner get() = DistributedTestModel @@ -293,6 +294,71 @@ data class RdTestActionParameters ( } +/** + * #### Generated from [DistributedTestModel.kt] + */ +data class RdTestComponentData ( + val width: Int, + val height: Int +) : IPrintable { + //companion + + companion object : IMarshaller { + override val _type: KClass = RdTestComponentData::class + override val id: RdId get() = RdId(1797576418817339312) + + @Suppress("UNCHECKED_CAST") + override fun read(ctx: SerializationCtx, buffer: AbstractBuffer): RdTestComponentData { + val width = buffer.readInt() + val height = buffer.readInt() + return RdTestComponentData(width, height) + } + + override fun write(ctx: SerializationCtx, buffer: AbstractBuffer, value: RdTestComponentData) { + buffer.writeInt(value.width) + buffer.writeInt(value.height) + } + + + } + //fields + //methods + //initializer + //secondary constructor + //equals trait + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || other::class != this::class) return false + + other as RdTestComponentData + + if (width != other.width) return false + if (height != other.height) return false + + return true + } + //hash code trait + override fun hashCode(): Int { + var __r = 0 + __r = __r*31 + width.hashCode() + __r = __r*31 + height.hashCode() + return __r + } + //pretty print + override fun print(printer: PrettyPrinter) { + printer.println("RdTestComponentData (") + printer.indent { + print("width = "); width.print(printer); println() + print("height = "); height.print(printer); println() + } + printer.print(")") + } + //deepClone + //contexts + //threading +} + + /** * #### Generated from [DistributedTestModel.kt] */ @@ -310,6 +376,7 @@ class RdTestSession private constructor( private val _forceLeaveAllModals: RdCall, private val _closeProjectIfOpened: RdCall, private val _runNextAction: RdCall, + private val _runNextActionGetComponentData: RdCall, private val _requestFocus: RdCall, private val _visibleFrameNames: RdCall>, private val _projectsNames: RdCall>, @@ -339,13 +406,14 @@ class RdTestSession private constructor( val _forceLeaveAllModals = RdCall.read(ctx, buffer, FrameworkMarshallers.Bool, FrameworkMarshallers.Void) val _closeProjectIfOpened = RdCall.read(ctx, buffer, FrameworkMarshallers.Void, FrameworkMarshallers.Bool) val _runNextAction = RdCall.read(ctx, buffer, RdTestActionParameters, __StringNullableSerializer) + val _runNextActionGetComponentData = RdCall.read(ctx, buffer, RdTestActionParameters, RdTestComponentData) val _requestFocus = RdCall.read(ctx, buffer, FrameworkMarshallers.String, FrameworkMarshallers.Bool) val _visibleFrameNames = RdCall.read(ctx, buffer, FrameworkMarshallers.Void, __StringListSerializer) val _projectsNames = RdCall.read(ctx, buffer, FrameworkMarshallers.Void, __StringListSerializer) val _makeScreenshot = RdCall.read(ctx, buffer, FrameworkMarshallers.String, FrameworkMarshallers.Bool) val _isResponding = RdCall.read(ctx, buffer, FrameworkMarshallers.Void, FrameworkMarshallers.Bool) val _projectsAreInitialised = RdCall.read(ctx, buffer, FrameworkMarshallers.Void, FrameworkMarshallers.Bool) - return RdTestSession(agentInfo, testClassName, testMethodName, traceCategories, debugCategories, _ready, _sendException, _exitApp, _showNotification, _closeProject, _forceLeaveAllModals, _closeProjectIfOpened, _runNextAction, _requestFocus, _visibleFrameNames, _projectsNames, _makeScreenshot, _isResponding, _projectsAreInitialised).withId(_id) + return RdTestSession(agentInfo, testClassName, testMethodName, traceCategories, debugCategories, _ready, _sendException, _exitApp, _showNotification, _closeProject, _forceLeaveAllModals, _closeProjectIfOpened, _runNextAction, _runNextActionGetComponentData, _requestFocus, _visibleFrameNames, _projectsNames, _makeScreenshot, _isResponding, _projectsAreInitialised).withId(_id) } override fun write(ctx: SerializationCtx, buffer: AbstractBuffer, value: RdTestSession) { @@ -363,6 +431,7 @@ class RdTestSession private constructor( RdCall.write(ctx, buffer, value._forceLeaveAllModals) RdCall.write(ctx, buffer, value._closeProjectIfOpened) RdCall.write(ctx, buffer, value._runNextAction) + RdCall.write(ctx, buffer, value._runNextActionGetComponentData) RdCall.write(ctx, buffer, value._requestFocus) RdCall.write(ctx, buffer, value._visibleFrameNames) RdCall.write(ctx, buffer, value._projectsNames) @@ -385,6 +454,7 @@ class RdTestSession private constructor( val forceLeaveAllModals: RdCall get() = _forceLeaveAllModals val closeProjectIfOpened: RdCall get() = _closeProjectIfOpened val runNextAction: RdCall get() = _runNextAction + val runNextActionGetComponentData: RdCall get() = _runNextActionGetComponentData val requestFocus: RdCall get() = _requestFocus val visibleFrameNames: RdCall> get() = _visibleFrameNames val projectsNames: RdCall> get() = _projectsNames @@ -404,6 +474,7 @@ class RdTestSession private constructor( _forceLeaveAllModals.async = true _closeProjectIfOpened.async = true _runNextAction.async = true + _runNextActionGetComponentData.async = true _requestFocus.async = true _visibleFrameNames.async = true _projectsNames.async = true @@ -421,6 +492,7 @@ class RdTestSession private constructor( bindableChildren.add("forceLeaveAllModals" to _forceLeaveAllModals) bindableChildren.add("closeProjectIfOpened" to _closeProjectIfOpened) bindableChildren.add("runNextAction" to _runNextAction) + bindableChildren.add("runNextActionGetComponentData" to _runNextActionGetComponentData) bindableChildren.add("requestFocus" to _requestFocus) bindableChildren.add("visibleFrameNames" to _visibleFrameNames) bindableChildren.add("projectsNames" to _projectsNames) @@ -450,6 +522,7 @@ class RdTestSession private constructor( RdCall(FrameworkMarshallers.Bool, FrameworkMarshallers.Void), RdCall(FrameworkMarshallers.Void, FrameworkMarshallers.Bool), RdCall(RdTestActionParameters, __StringNullableSerializer), + RdCall(RdTestActionParameters, RdTestComponentData), RdCall(FrameworkMarshallers.String, FrameworkMarshallers.Bool), RdCall>(FrameworkMarshallers.Void, __StringListSerializer), RdCall>(FrameworkMarshallers.Void, __StringListSerializer), @@ -477,6 +550,7 @@ class RdTestSession private constructor( print("forceLeaveAllModals = "); _forceLeaveAllModals.print(printer); println() print("closeProjectIfOpened = "); _closeProjectIfOpened.print(printer); println() print("runNextAction = "); _runNextAction.print(printer); println() + print("runNextActionGetComponentData = "); _runNextActionGetComponentData.print(printer); println() print("requestFocus = "); _requestFocus.print(printer); println() print("visibleFrameNames = "); _visibleFrameNames.print(printer); println() print("projectsNames = "); _projectsNames.print(printer); println() @@ -502,6 +576,7 @@ class RdTestSession private constructor( _forceLeaveAllModals.deepClonePolymorphic(), _closeProjectIfOpened.deepClonePolymorphic(), _runNextAction.deepClonePolymorphic(), + _runNextActionGetComponentData.deepClonePolymorphic(), _requestFocus.deepClonePolymorphic(), _visibleFrameNames.deepClonePolymorphic(), _projectsNames.deepClonePolymorphic(), diff --git a/platform/remoteDev-util/modelSources/DistributedTestModel.kt b/platform/remoteDev-util/modelSources/DistributedTestModel.kt index cfb885dc5fc7..7cba592cdcfa 100644 --- a/platform/remoteDev-util/modelSources/DistributedTestModel.kt +++ b/platform/remoteDev-util/modelSources/DistributedTestModel.kt @@ -56,6 +56,11 @@ object DistributedTestModel : Ext(TestRoot) { field("parameters", immutableList(string).nullable) } + private val RdTestComponentData = structdef { + field("width", int) + field("height", int) + } + private val RdTestSession = classdef { field("agentInfo", RdAgentInfo) field("testClassName", string.nullable) @@ -70,6 +75,7 @@ object DistributedTestModel : Ext(TestRoot) { call("forceLeaveAllModals", bool, void).async call("closeProjectIfOpened", void, bool).async call("runNextAction", RdTestActionParameters, string.nullable).async + call("runNextActionGetComponentData", RdTestActionParameters, RdTestComponentData).async call("requestFocus", string, bool).async call("visibleFrameNames", void, immutableList(string)).async call("projectsNames", void, immutableList(string)).async diff --git a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/AgentAction.kt b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/AgentAction.kt index 14dbd8bc4535..f766b8300a41 100644 --- a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/AgentAction.kt +++ b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/AgentAction.kt @@ -1,5 +1,6 @@ package com.intellij.remoteDev.tests +import com.intellij.remoteDev.tests.modelGenerated.RdTestComponentData import org.jetbrains.annotations.ApiStatus import kotlin.coroutines.CoroutineContext import kotlin.time.Duration @@ -11,4 +12,10 @@ import kotlin.time.Duration class AgentAction(val timeout: Duration, val coroutineContextGetter: () -> CoroutineContext, val requestFocusBeforeStart: Boolean? = null, - val action: suspend (AgentContext).(List?) -> String?) \ No newline at end of file + val action: suspend (AgentContext).(List?) -> String?) + +@ApiStatus.Internal +class AgentActionGetComponentData(val timeout: Duration, + val coroutineContextGetter: () -> CoroutineContext, + val requestFocusBeforeStart: Boolean? = null, + val action: suspend (AgentContext).(List?) -> RdTestComponentData) \ No newline at end of file diff --git a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/DistributedTestPlayer.kt b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/DistributedTestPlayer.kt index 626ba7ac1a25..c33aeaf54386 100644 --- a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/DistributedTestPlayer.kt +++ b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/DistributedTestPlayer.kt @@ -2,7 +2,7 @@ package com.intellij.remoteDev.tests import org.jetbrains.annotations.ApiStatus import java.lang.reflect.Method -import java.util.Queue +import java.util.* /** * This internal interface should be implemented by distributed tests @@ -10,7 +10,7 @@ import java.util.Queue */ @ApiStatus.Internal interface DistributedTestPlayer { - fun initAgent(agent: AgentInfo): Map> + fun initAgent(agent: AgentInfo): Pair>, Map>> fun performInit(method: Method) } diff --git a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/impl/DistributedTestHost.kt b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/impl/DistributedTestHost.kt index 4adaa5e27a6c..ebdfe9f1cd5b 100644 --- a/platform/remoteDev-util/src/com/intellij/remoteDev/tests/impl/DistributedTestHost.kt +++ b/platform/remoteDev-util/src/com/intellij/remoteDev/tests/impl/DistributedTestHost.kt @@ -29,10 +29,7 @@ import com.intellij.openapi.wm.WindowManager import com.intellij.remoteDev.tests.* import com.intellij.remoteDev.tests.impl.utils.getArtifactsFileName import com.intellij.remoteDev.tests.impl.utils.runLogged -import com.intellij.remoteDev.tests.modelGenerated.RdAgentType -import com.intellij.remoteDev.tests.modelGenerated.RdProductType -import com.intellij.remoteDev.tests.modelGenerated.RdTestSession -import com.intellij.remoteDev.tests.modelGenerated.distributedTestModel +import com.intellij.remoteDev.tests.modelGenerated.* import com.intellij.ui.AppIcon import com.intellij.ui.WinFocusStealer import com.intellij.util.ui.EDT.isCurrentThreadEdt @@ -56,7 +53,9 @@ import java.io.File import java.net.InetAddress import java.time.LocalTime import javax.imageio.ImageIO +import kotlin.coroutines.CoroutineContext import kotlin.reflect.full.createInstance +import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds import kotlin.time.toJavaDuration @@ -164,42 +163,44 @@ open class DistributedTestHost(coroutineScope: CoroutineScope) { // Tell test we are running it inside an agent val agentInfo = AgentInfo(session.agentInfo, session.testClassName, session.testMethodName) - val map = testClassObject.initAgent(agentInfo) + val (actionsMap, dimensionRequests) = testClassObject.initAgent(agentInfo) // Play test method val testMethod = testClass.getMethod(session.testMethodName) testClassObject.performInit(testMethod) testMethod.invoke(testClassObject) - // Advice for processing events - session.runNextAction.setSuspendPreserveClientId { _, parameters -> - val actionTitle = parameters.title - val actionParameters = parameters.parameters - val queue = map[actionTitle] ?: error("There is no Action with name '$actionTitle', something went terribly wrong") - val action = queue.remove() - val timeout = action.timeout + val agentContext = when (session.agentInfo.agentType) { + RdAgentType.HOST -> HostAgentContextImpl(session.agentInfo, protocol) + RdAgentType.CLIENT -> ClientAgentContextImpl(session.agentInfo, protocol) + RdAgentType.GATEWAY -> GatewayAgentContextImpl(session.agentInfo, protocol) + } + + + suspend fun runNext( + actionTitle: String, + timeout: Duration, + contextGetter: () -> CoroutineContext, + requestFocusBeforeStart: Boolean?, + action: suspend () -> T, + ): T { try { assert(ClientId.current.isLocal) { "ClientId '${ClientId.current}' should be local before test method starts" } LOG.info("'$actionTitle': received action execution request") - val providedContext = action.coroutineContextGetter.invoke() + val providedContext = contextGetter.invoke() val clientId = providedContext.clientId() ?: ClientId.current - return@setSuspendPreserveClientId withContext(providedContext + clientId.asContextElement()) { + return withContext(providedContext + clientId.asContextElement()) { assert(ClientId.current == clientId) { "ClientId '${ClientId.current}' should equal $clientId one when test method starts" } - if (!app.isHeadlessEnvironment && isNotRdHost && (action.requestFocusBeforeStart ?: isCurrentThreadEdt())) { + if (!app.isHeadlessEnvironment && isNotRdHost && (requestFocusBeforeStart ?: isCurrentThreadEdt())) { requestFocus(actionTitle) } assert(ClientId.current == clientId) { "ClientId '${ClientId.current}' should equal $clientId one when after request focus" } - val agentContext = when (session.agentInfo.agentType) { - RdAgentType.HOST -> HostAgentContextImpl(session.agentInfo, protocol) - RdAgentType.CLIENT -> ClientAgentContextImpl(session.agentInfo, protocol) - RdAgentType.GATEWAY -> GatewayAgentContextImpl(session.agentInfo, protocol) - } val result = runLogged(actionTitle, timeout) { - action.action(agentContext, actionParameters) + action() } // Assert state @@ -213,7 +214,32 @@ open class DistributedTestHost(coroutineScope: CoroutineScope) { throw ex } } + + // Advice for processing events + session.runNextAction.setSuspendPreserveClientId { _, parameters -> + val actionTitle = parameters.title + val queue = actionsMap[actionTitle] ?: error("There is no Action with name '$actionTitle', something went terribly wrong") + val action = queue.remove() + + return@setSuspendPreserveClientId runNext(actionTitle, action.timeout, action.coroutineContextGetter, action.requestFocusBeforeStart) { + action.action(agentContext, parameters.parameters) + } + } + + + session.runNextActionGetComponentData.setSuspendPreserveClientId { _, parameters -> + val actionTitle = parameters.title + val queue = dimensionRequests[actionTitle] + ?: error("There is no Action with name '$actionTitle', something went terribly wrong") + val action = queue.remove() + val timeout = action.timeout + + return@setSuspendPreserveClientId runNext(actionTitle, timeout, action.coroutineContextGetter, action.requestFocusBeforeStart) { + action.action(agentContext, parameters.parameters) + } + } } + // actually doesn't really preserve clientId, not really important here // https://youtrack.jetbrains.com/issue/RDCT-653/setSuspendPreserveClientId-with-custom-dispatcher-doesnt-preserve-ClientId session.isResponding.setSuspendPreserveClientId(handlerScheduler = Dispatchers.Default.asRdScheduler) { _, _ ->