user3018934
user3018934

Reputation: 121

Monkey Runner throwing socket exception broken pipe on touuch

I see the below error sometimes while running monkeyrunner scripts. 140501 17:01:58.950:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice] Error sending touch event: 500 515 DOWN_AND_UP 140501 17:01:58.950:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice]java.net.SocketException: Broken pipe 140501 17:01:58.950:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice] at java.net.SocketOutputStream.socketWrite0(Native Method) 140501 17:01:58.950:S [MainThread] [com.android.chimpchat.adb.AdbChimpDevice] at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)

How do I catch these? There are post suggesting to use SocketException from java.net import SocketException

However this doesnt seem to work

Upvotes: 4

Views: 2140

Answers (3)

Woxxy
Woxxy

Reputation: 1298

It is impossible to catch it as an exception. You can't even use stderr.

If you'd really like to try catching it even an improper manner, you need to get into Java's logger:

from java.util.logging import Level, Logger, StreamHandler, SimpleFormatter
from java.io import ByteArrayOutputStream

device = # your code to get the device object
errors = ByteArrayOutputStream(100)
logger = Logger.getLogger('com.android.chimpchat.adb.AdbChimpDevice')
logger.addHandler(StreamHandler(errors, SimpleFormatter()))

device.touch(120, 120, 'DOWN_AND_UP')

if errors.size() > 0:
    # any code you want
    raise YourException

To catch any other Java error in MonkeyRunner you have to change the TAG in Logger.getLogger(TAG) to the class printing the log.

To actually get around the issue, you may also want to try: How do I catch SocketExceptions in MonkeyRunner?

Upvotes: 2

Kyle Falconer
Kyle Falconer

Reputation: 8490

I really like Brian's answer, but didn't like having to maintain another file just for this, so I ran the commands directly. Seems to be working so far.

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
import sys
import signal
import subprocess

device = None

def execute():
    device = MonkeyRunner.waitForConnection()
    #my code here

def exitGracefully(signum, frame):
    """
    Kill monkey on the device or future connections will fail
    """
    print "Exiting Gracefully..."
    try:
        subprocess.call("adb shell kill -9 $(adb shell ps | grep monkey | awk '{print $2}')", shell=True)
    except Exception, e:
        print(e)
    sys.exit(1)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, exitGracefully)
    execute()

Upvotes: 0

Brian
Brian

Reputation: 907

It may not be the most elegant solution, but here is what I came up with.

Since the issue is that when you kill a monkey script, the process on the android device doesn't clean up properly, so when you try to connect again, you get the pipe issue. You can kill -9 the monkey process on the device itself and you won't run into it anymore.

I have two scripts that work around the problem here. This is the python:

 3 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
  4 from time import sleep
  5 import sys
  6 import signal
  7 import subprocess
  8
  9 device = None
 10
 11 def execute():
 12     device = MonkeyRunner.waitForConnection()
 13     #my code here
 17
 18 def exitGracefully(signum, frame):
 19     print "Exiting Gracefully..."
 20     subprocess.call(['./killmonkey.sh'])
 21     sys.exit(1)
 22
 23 if __name__ == '__main__':
 24     signal.signal(signal.SIGINT, exitGracefully)
 25     execute()

And the kill monkey script:

#!/bin/bash

var=$(adb shell ps | grep monkey | awk '{print $2}')
echo $var
adb shell kill -9 $var

When I ctrl+c the python monkey script, it calls the killmonkey, which kills the process on the attached android device

This specifically only works if there are only one device attached as it doesn't specify a device ID. Not very elegant, but I find it effective.

Upvotes: 3

Related Questions