1

i have a script made using monkeyrunner. The script will install an app, make some key preses to the emulator and then uninstall. In the middle of something I get Shell Command Unresponsive Exception and that will ruin my script.

Do you know what have I done wrong to result to this kind of exception. here's the error message

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] Error starting command: monkey --port 12345

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice]com.android.ddmlib.ShellCommandUnresponsiveException

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:408)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at com.android.ddmlib.Device.executeShellCommand(Device.java:453)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at com.android.chimpchat.adb.AdbChimpDevice$1.run(AdbChimpDevice.java:105)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.util.concurrent.FutureTask.run(FutureTask.java:166)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

130228 16:44:49.210:I [pool-1-thread-1] [com.android.chimpchat.adb.AdbChimpDevice] at java.lang.Thread.run(Thread.java:679) 130228 16:46:25.631:I [main] [com.android.chimpchat.ChimpManager] Monkey Command: quit.

Here's the code

def getTimeNow():
    timeStamp = ""
    timeStamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return timeStamp

def saveScreenshot(screenshot, apkID, Code, path):
    fName = "".join([path, '/', Code, apkID, '.png'])
    screenshot.writeToFile(fName,'png')

def found(screenshot, ScreenshotRef, apkPack):
    Result = "N"
    acceptance = 0.9
    imageCap = ScreenshotRef + 'sshot'

    imageRef = MonkeyRunner.loadImageFromFile(imageCap)

    imageTuple = 78, 447, 547, 64
    #imageTuple = 16, 177, 64, 60
    ref = imageRef.getSubImage(imageTuple)
    y=0

    while y < 1280 - 64:
            imageTuple2 = 78, int(y), 547, 64

            if screenshot.getSubImage(imageTuple2).sameAs(ref, acceptance):
                    detResult = "B"
            uninAppMk(apkPack)
            MonkeyRunner.sleep(15)
            device.press("KEYCODE_ESCAPE", MonkeyDevice.DOWN_AND_UP)
            MonkeyRunner.sleep(15)
            device.press("KEYCODE_HOME", MonkeyDevice.DOWN_AND_UP)
            MonkeyRunner.sleep(15)
            print "Found at points 78," + str(y)
                    break
            y=y+1   
        return Result


def uninAppMk(apkPack):
    device.removePackage(apkPack)
    print "Package Uninstalled."


def writeToLogFile(logFile, Code, apkID, apkName, status, timeStamp):
    logText = "\t".join([Code, apkID, apkName, status, timeStamp, '\n'])

    db = zxJDBC.connect("jdbc:mysql://" + server + ":" + str(portnum) + "/" + schema, username , password, "com.mysql.jdbc.Driver")

    c = db.cursor() 
    mysql_output = c.execute("INSERT INTO table VALUES(?, ?, ?, ?, ?)",(Code, status, timeStamp, apkID , "0"))
    db.commit()
    print "mysql error output => " + str(mysql_output)

    f = open(logFile, "a")
    f.write(logText)
    f.close()


#+++++ ######## START HERE ######## ++++++#
#+++++ Connect to emulator ++++++#
timeout = 120

device = MonkeyRunner.waitForConnection()
MonkeyRunner.sleep(10)

#+++++ Getting CMD parameters ++++++#
apkID = sys.argv[1]
apkName = sys.argv[2]
apkPack = sys.argv[3]

#+++++ Read config file ++++++#
ConfigFileName = os.path.dirname(os.path.realpath(__file__)) + '/config.ini'
cp = ConfigParser.ConfigParser()
cp.read(ConfigFileName)
adbLoc = cp.get('tools','adb')
Code = cp.get('product','prodcode')
outputFolder = cp.get('output','App')
apkPath = cp.get('source','App')
ScreenshotRef = cp.get('source','ScreenshotRef')
logFile = outputFolder + 'logs.txt'

#----------read database section----------#
server = cp.get('database','server')
portnum = int(cp.get('database','port'))
username = cp.get('database','username')
password = cp.get('database','password')
schema= cp.get('database','schema')

#+++++ Check if output folder exist ++++++#
print "All screenshots will be found here " + outputFolder
if not os.path.exists(outputFolder):
    os.makedirs(outputFolder)

#++++++ Test Starts ++++++#

print "APK ID: " + apkID
print "APK Name: " + apkName
print "APK Package Name: " + apkPack
print "APK Path: " + apkPath

apkIns = apkPath  + apkName
print "APK:: " + apkIns 
try:
    device.installPackage(apkIns)
except(SocketException):
    print "~~~~Error installing"
MonkeyRunner.sleep(95)

#++++++ Take screenshot ++++++#
screenshot = device.takeSnapshot()
MonkeyRunner.sleep(10)
timeStamp = getTimeNow()
saveScreenshot(screenshot, apkID, Code, outputFolder)
MonkeyRunner.sleep(3)


#++++++ Check detection ++++++#
status = found(screenshot, ScreenshotRef, apkPack)
if status == 'N':
    uninAppMk(apkPack)

#++++++ Write to log file ++++++#

writeToLogFile(logFile, Code, apkID, apkName, status, timeStamp)
srh snl
  • 797
  • 1
  • 19
  • 42
  • The code would help. Could you add that also? And please state at which line you get the exception. – Gabriel Porumb Mar 01 '13 at 07:37
  • @dtmilano if this is a bug, what can I do to avoid this? what commands should I not use so that I wont get the same error? thanks! – srh snl Mar 03 '13 at 15:06
  • @srh snl:are you calling any MonkeyDevice.shell() to execute adb shell commands ? – Rilwan Mar 04 '13 at 04:51
  • restarting adb usually helps – Diego Torres Milano Mar 04 '13 at 06:59
  • @GabrielPorumb I already added the code. Please see the code above. Honestly I dont know which part the exception appears. But ill retest the script and reply once I discover. Thanks :) – srh snl Mar 04 '13 at 07:35
  • @Rilwan No.I dont. The modified the question and added the code. Kindly check if there's something that I need to change / remove. Thanks – srh snl Mar 04 '13 at 07:38
  • @srh I have seen this error couple of times, i replaced MonkeyDevice.shell() command with os.system(),then it dis appeared. In your case i am not sure. one more hint is i have seen this issue in Windows,Then i migrated to linux and issue dis appeared. . I posted this long back,but didnt get any answers. http://stackoverflow.com/questions/9177645/monkeyrunner-throwing-shellcommandunresponsiveexception-any-work-around..Please Try updating sdk and run again.Good luck – Rilwan Mar 04 '13 at 07:45
  • @Rilwan actually I'm running the script in Centos but I did experiece the problem. Im not using MonkeyDevice.shell() but I'm using device.installPackage() maybe changing it to os.system will solve the problem. Thanks! – srh snl Mar 04 '13 at 07:55
  • @srh: Please comment or answer here if you could avoid these issues by any means. – Rilwan Mar 06 '13 at 01:09
  • @Rilwan Yes. Sure. I'll update this thread if I find a solution to this problem. :) – srh snl Mar 06 '13 at 08:05

1 Answers1

2

Kind of late for an answer but MonkeyRunner is probably running on top of Google's ddmlib. In ddmlib, all shell commands that are called on a device have a default timeout of 5000ms. If the process doesn't print anything for that 5000ms, the process will be shut down and a ShellCommandUnresponsiveException will be thrown. If your process takes more than 5000ms to run, you may want to optimise your code to avoid having long processing within the time that the shell commands are called. Alternatively, you can check the MonkeyRunner API to see if there's any way of extending the timeout. Or you could simply continuously output to the shell somehow to prevent the timeout from expiring.

starkipraggy
  • 41
  • 1
  • 9