appium/appium

Not able to run parallel tests using uiautomator2

ptsiakos77 opened this issue ยท 11 comments

Appium version 1.6.3
automationName: uiautomator2

I have connected 2 Android devices in my MAC

I launch 2 appium servers each associated with the specific device id in different ports and bootstrap ports.

501 10294 10291 0 4:56PM ?? 0:02.83 /Users/panagiotistsiakos/.nvm/versions/node/v6.5.0/bin/node /usr/local/lib/node_modules/appium/build/lib/main.js --port 4725 --address 0.0.0.0 --udid 00e4064d69a752c7 --log-level error --bootstrap-port 5204 --no-reset --command-timeout 300
501 10297 10291 0 4:56PM ?? 0:02.78 /Users/panagiotistsiakos/.nvm/versions/node/v6.5.0/bin/node /usr/local/lib/node_modules/appium/build/lib/main.js --port 4727 --address 0.0.0.0 --udid 42008bb6d2332325 --log-level error --bootstrap-port 5206 --no-reset --command-timeout 300

The test are not run. Usually 1 of the devices or even none starts running the tests
The same setup exactly with automationName:appium runs with no problem

Is this a limitation of the uiautomator2 or have I misses something? (e,g some extra desired capability)

I take errors such as:
org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8202 (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 40 milliseconds

OR

org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: java.lang.IllegalThreadStateException: Thread already started
at java.lang.Thread.checkNotStarted(Thread.java:849)
at java.lang.Thread.start(Thread.java:1059)
at io.appium.uiautomator2.model.NotificationListener.start(NotificationListener.java:32)
at io.appium.uiautomator2.model.Session.(Session.java:23)
at io.appium.uiautomator2.model.AppiumUiAutomatorDriver.initializeSession(AppiumUiAutomatorDriver.java:19)
at io.appium.uiautomator2.handler.NewSession.safeHandle(NewSession.java:31)
at io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:54)
at io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:202)
at io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:193)
at io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:44)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:611)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:514)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:818)
(WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 27.98 seconds
Build info: version: '2.48.2', revision: '41bccdd10cf2c0560f637404c2d96164b67d9d67', time: '2015-10-09 13:08:06'

Sending in the appium logs would be helpful, at a debug loglevel.

Just took a quick look through the uiautomator2 driver's code. I'm not seeing anything that should prevent it from working offhand. @sravanmedarapu is the one to ask though.

You should also not need to use the --bootstrap-port options since uiautomator2 finds its own system ports which aren't in use.

For what I can see in the logs maybe the fact that the 2 parallel tests use the same port of the uiautomator2 server is the cause.

When I run two session I have:

Session1:

adb -s 9885e642324e32474e shell am instrument -w io.appium.uiautomator2.server.test/android.support.test.runner.AndroidJUnitRunner...
[UiAutomator2] Waiting for UiAutomator2 to be online...
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Got response with status 200: "{"sessionId":"SESSIONID","status":0,"value":"Status Invoked"}"
[debug] [JSONWP Proxy] Proxying [POST /session] to [POST http://localhost:8202/wd/hub/session] with body: {"desiredCapabilities":{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"appActivity":"com.workable.sign_in.WelcomeActivity","app":"/Users/panagiotistsiakos/Desktop/app-stg4.apk","recreateChromeDriverSessions":true,"newCommandTimeout":300,"platformVersion":"6.0.1","automationName":"uiautomator2","platformName":"Android","deviceName":"9885e642324e32474e"},"appActivity":"com.workable.sign_in.WelcomeActivity","app":"/Users/panagiotistsiakos/Desktop/app-stg4.apk","recreateChromeDriverSessions":true,"newCommandTimeout":300,"platformVersion":"6.0.1","automationName":"uiautomator2","platformName":"Android","deviceName":"9885e642324e32474e","deviceUDID":"9885e642324e32474e","appPackage":"com.workable.ats.stg4"}}
[debug] [JSONWP Proxy] Got response with status 200: {"sessionId":"520b452b-a881-475b-9b3e-4035a6b08570","status":0,"value":"Created Session"}
[UiAutomator2] UiAutomator2 did not start the activity we were waiting for, 'com.workable.ats.stg4/com.workable.sign_in.WelcomeActivity'. Starting it ourselves
[debug] [ADB] Device API level: 23
[debug] [ADB] Getting connected devices...
[debug] [ADB] 2 device(s) connected
[debug] [ADB] Running '/Users/panagiotistsiakos/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","9885e642324e32474e","shell","am","start","-W","-n","com.workable.ats.stg4/com.workable.sign_in.WelcomeActivity","-S","-a","android.intent.action.MAIN","-c","android.intent.category.LAUNCHER","-f","0x10200000"]
[debug] [ADB] Waiting for pkg: 'com.workable.ats.stg4' and activity: 'com.workable.sign_in.WelcomeActivity' to be focused
[debug] [ADB] Possible activities, to be checked: com.workable.sign_in.WelcomeActivity, .com.workable.sign_in.WelcomeActivity
[debug] [ADB] Getting focused package and activity
[debug] [ADB] Getting connected devices...
[debug] [ADB] 2 device(s) connected
[debug] [ADB] Running '/Users/panagiotistsiakos/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","9885e642324e32474e","shell","dumpsys","window","windows"]
[debug] [ADB] Found package: 'com.workable.ats.stg4' and activity: 'com.workable.sign_in.WelcomeActivity'
[Appium] New AndroidUiautomator2Driver session created successfully, session d46bb33c-9392-4380-8bed-acc2ff5324dc added to master session list
[debug] [MJSONWP] Responding to client with driver.createSession() result: {"appActivity":"com.workable.sign_in.WelcomeActivity","app":"/Users/panagiotistsiakos/Desktop/app-stg4.apk","recreateChromeDriverSessions":true,"newCommandTimeout":"300","platformVersion":"6.0.1","automationName":"uiautomator2","platformName":"Android","deviceName":"9885e642324e32474e"}
[HTTP] <-- POST /wd/hub/session 200 17839 ms - 359
[HTTP] --> POST /wd/hub/session/d46bb33c-9392-4380-8bed-acc2ff5324dc/elements {"using":"xpath","value":"//[contains(@resource-id,'toolbarTitle')][@text='Java Developer']"}
[debug] [MJSONWP] Calling AppiumDriver.findElements() with args: ["xpath","//
[contains(@resource-id,'toolbarTitle')][@text='Java Developer']","d46bb33c-9392-4380-8bed-acc2ff5324dc"]
[debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
[debug] [BaseDriver] Waiting up to 0 ms for condition
[debug] [JSONWP Proxy] Proxying [POST /elements] to [POST http://localhost:8202/wd/hub/session/520b452b-a881-475b-9b3e-4035a6b08570/elements] with body: {"strategy":"xpath","selector":"//*[contains(@resource-id,'toolbarTitle')][@text='Java Developer']","context":"","multiple":true}
[MJSONWP] Encountered internal error running command: ProxyRequestError: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8202
at JWProxy.proxy$ (../../../lib/jsonwp-proxy/proxy.js:126:13)
at tryCatch (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
[HTTP] <-- POST /wd/hub/session/d46bb33c-9392-4380-8bed-acc2ff5324dc/elements 500 10 ms - 271

Session2:
UiAutomator2] Waiting for UiAutomator2 to be online...
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8202/wd/hub/status] with no body
[debug] [JSONWP Proxy] Got response with status 200: "{"sessionId":"SESSIONID","status":0,"value":"Status Invoked"}"
[debug] [JSONWP Proxy] Proxying [POST /session] to [POST http://localhost:8202/wd/hub/session] with body: {"desiredCapabilities":{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"appActivity":"com.workable.sign_in.WelcomeActivity","app":"/Users/panagiotistsiakos/jenkins-slave/workspace/build-android-qa/app/build/outputs/apk/app-stg4.apk","recreateChromeDriverSessions":true,"newCommandTimeout":300,"platformVersion":"5.0.2","automationName":"uiautomator2","platformName":"Android","deviceName":"33000ead6f17a257"},"appActivity":"com.workable.sign_in.WelcomeActivity","app":"/Users/panagiotistsiakos/jenkins-slave/workspace/build-android-qa/app/build/outputs/apk/app-stg4.apk","recreateChromeDriverSessions":true,"newCommandTimeout":300,"platformVersion":"5.0.2","automationName":"uiautomator2","platformName":"Android","deviceName":"33000ead6f17a257","deviceUDID":"33000ead6f17a257","appPackage":"com.workable.ats.stg4"}}
[debug] [UiAutomator2] Deleting UiAutomator2 session
[debug] [UiAutomator2] Deleting UiAutomator2 server session
[UiAutomator2] Did not get confirmation UiAutomator2 deleteSession worked; Error was: Error: Trying to proxy a session command without session id
[debug] [ADB] Getting connected devices...
[debug] [ADB] 2 device(s) connected
[debug] [ADB] Running '/Users/panagiotistsiakos/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","33000ead6f17a257","shell","am","force-stop","com.workable.ats.stg4"]
[debug] [Logcat] Stopping logcat capture
[debug] [ADB] Removing forwarded port socket connection: 8202

I was wondering if there is a capability for the port of UIAutomator2

UiAutomator2 driver should be able to find the available free port, however you can also explicitly specify port number using systemPort capability ("systemPort",XXXX). Can you try by restarting the devices.

Can you please share full server logs in gist ?

It worked!!!

Maybe the problem lies in
this.opts.systemPort = this.opts.systemPort || await findAPortNotInUse(SYSTEM_PORT_RANGE[0], SYSTEM_PORT_RANGE[1]);

which determines the not used port

In my system it used the same port for the 2 different threads and appium instances

hmm, maybe a race condition of sometime. anyway, closing this out since it seems like specifying systemPort works well.

Do we need to set the systemPort capability same as the appium server port or it should be always different ?
If not then to which process is systemPort assigned ?

How to solve the problem of not being able to test in parallel?How to set different systemPort numbers for appium instances ๏ผŒ
Great God answer, thank you

please anyone share where and how to set the systemPort number

You can see the capability in http://appium.io/docs/en/writing-running-appium/caps/ .
https://github.com/appium/appium/blob/fabe063a85ce6bde238b66cbbeef56472ebef89c/docs/en/writing-running-appium/caps.md

You can set it like other capabilities like platformName as below.

{
    "platformName": "iOS",
    "platformVersion": "11.0",
    "deviceName": "iPhone 7",
    "automationName": "XCUITest",
    "app": "/path/to/my.app"
    "systemPort": "8201"
}
lock commented

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.