maestro icon indicating copy to clipboard operation
maestro copied to clipboard

Running 2 different Tests on 2 Devices on the Same Machine

Open Revono opened this issue 6 months ago • 5 comments

Use case

Hi all,

I'm trying to run two different tests simultaneously on the same machine, each targeting a different locally connected ADB device.

Yes know there is the "shards" feature but with this i can't specify a device and a specific test.

However, it seems like the issue is due to the connection already being in use. Our use case involves starting different tests on multiple ADB-connected devices at the same time—not duplicating the same test.

Unfortunately, Maestro seems unable to handle this. I consistently get the following error:

Maestro can't handle this i get always an error like this: Exception in thread "pool-4-thread-1" java.io.IOException: Command failed (tcp:7001): closed at dadb.adbserver.AdbServer.send$dadb(AdbServer.kt:103) at dadb.adbserver.AdbServerDadb.open(AdbServer.kt:149) at dadb.forwarding.TcpForwarder.handleForwarding$lambda-1(TcpForwarder.kt:64) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840)

i know on the screenshot is the same test but it doesn't matter, mostly I don't use the same test.

Image

Has anyone successfully run multiple parallel tests like this? Or is there a known workaround for handling multiple ADB sessions concurrently with Maestro?

I tried fancy stuff like this but without success (run in different terminals): maestro --device ROF4P3BXQ test --shard-all 1 validate_all_settings_available.yaml maestro --device ROSCIXF16 test --shard-all 1 validate_all_settings_available.yaml

Another Error i see sometimes:

io.grpc.StatusRuntimeException: UNAVAILABLE: io exception at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:275) at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:256) at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:169) at maestro_android.MaestroDriverGrpc$MaestroDriverBlockingStub.deviceInfo(MaestroDriverGrpc.java:634) at maestro.drivers.AndroidDriver$deviceInfo$1.invoke(AndroidDriver.kt:185) at maestro.drivers.AndroidDriver$deviceInfo$1.invoke(AndroidDriver.kt:184) at maestro.drivers.AndroidDriver.runDeviceCall(AndroidDriver.kt:1147) at maestro.drivers.AndroidDriver.deviceInfo(AndroidDriver.kt:184) at maestro.Maestro$cachedDeviceInfo$2.invoke(Maestro.kt:51) at maestro.Maestro$cachedDeviceInfo$2.invoke(Maestro.kt:49) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at maestro.Maestro.getCachedDeviceInfo(Maestro.kt:49) at maestro.orchestra.Orchestra.initJsEngine(Orchestra.kt:240) at maestro.orchestra.Orchestra.runFlow(Orchestra.kt:118) at maestro.cli.runner.MaestroCommandRunner.runCommands(MaestroCommandRunner.kt:187) at maestro.cli.runner.TestRunner$runSingle$result$1.invoke(TestRunner.kt:64) at maestro.cli.runner.TestRunner$runSingle$result$1.invoke(TestRunner.kt:55) at maestro.cli.runner.TestRunner.runCatching(TestRunner.kt:165) at maestro.cli.runner.TestRunner.runSingle(TestRunner.kt:55) at maestro.cli.command.TestCommand.runSingleFlow(TestCommand.kt:382) at maestro.cli.command.TestCommand.access$runSingleFlow(TestCommand.kt:65) at maestro.cli.command.TestCommand$runShardSuite$2.invoke(TestCommand.kt:353) at maestro.cli.command.TestCommand$runShardSuite$2.invoke(TestCommand.kt:323) at maestro.cli.session.MaestroSessionManager.newSession(MaestroSessionManager.kt:105) at maestro.cli.session.MaestroSessionManager.newSession$default(MaestroSessionManager.kt:53) at maestro.cli.command.TestCommand.runShardSuite(TestCommand.kt:323) at maestro.cli.command.TestCommand.access$runShardSuite(TestCommand.kt:65) at maestro.cli.command.TestCommand$handleSessions$1$results$1$1.invokeSuspend(TestCommand.kt:290) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693) Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/[0:0:0:0:0:0:0:1]:7001 Caused by: java.net.ConnectException: Connection refused at java.base/sun.nio.ch.Net.pollConnect(Native Method) at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:337) at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:776) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:840)

Thanks in advance!

Proposal

Maestro should handle multiple instances

Anything else?

No response

Revono avatar Jun 26 '25 12:06 Revono