コード例 #1
0
def main(argv):
    global ip_addr

    if (len(argv) < 4):
        log.info(
            "usage: logcat.py <device ip address> <output filename> <logcat options>"
        )
        return 1
    ip_addr = argv[1]
    output_filename = argv[2]
    logcat_options = argv[3]
    max_runtime = 3600  # 3600 seconds == 1 hour

    status = 0
    dm = devicemanager.DeviceManagerSUT(ip_addr)
    if not dm:
        log.error("logcat.py: unable to open device manager")
        return 2
    command = 'execext su t=%d logcat %s' % (max_runtime, logcat_options)
    log.debug('logcat.py running SUT command: %s' % command)
    try:
        with open(output_filename, 'w') as f:
            dm._sendCmds([{'cmd': command}], f)
    except devicemanager.DMError, e:
        log.error("Remote Device Error: Exception caught running logcat: %s" %
                  str(e))
        status = -1
コード例 #2
0
def main(argv):

    if (len(argv) < 3):
        print "usage: installWatcher.py <ip address> <localfilename>"
        sys.exit(1)

    ip_addr = argv[1]
    path_to_main_apk = argv[2]

    dm = droid.DroidSUT(ip_addr)
    if not dm:
        log.error("could not get device manager!")
        return 1
    devRoot = checkDeviceRoot(dm)

    if install(dm, devRoot, path_to_main_apk, "com.mozilla.watcher"):
        log.error("install failed")
        return 1

    dm.reboot()
    waitForDevice(dm)

    # we can't use the following dm.getFile method, since only Watcher runtime user has read access
    # to this file, so we need to be root to read it, hence the slightly more convoluted version
    # using dm._runCmds below...
    # cannot use -> print dm.getFile('/data/data/com.mozilla.watcher/files/version.txt')
    status = dm._runCmds([{'cmd': 'exec su -c "cat /data/data/com.mozilla.watcher/files/version.txt"'}]).split('\n')
    log.info('Watcher version: %s' % status)
    return 0
コード例 #3
0
ファイル: verify.py プロジェクト: IanConnolly/build-tools
def isMozpoolReady(device):
    """ Checks if the mozpool server is available and the device is in 'ready' state

    Returns MOZPOOL_STATE_READY if Mozpool is indeed listing device as ready
    Returns MOZPOOL_STATE_UNKNOWN if Mozpool claims the device is in a non-ready state
    Returns MOZPOOL_STATE_ERROR if Mozpool reports some other error.
    Returns MOZPOOL_STATE_MISSING if there is no Mozpool server found in DNS.
    """
    import socket
    default_timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(5)  # Don't let networking delay us too long
    try:
        socket.gethostbyname(MOZPOOL_CNAME)
    except:
        log.info("No mozpool server in this VLAN")
        return MOZPOOL_STATE_MISSING
    finally:
        # Set socket timeout back
        socket.setdefaulttimeout(default_timeout)

    mpc = MozpoolHandler("http://%s" % MOZPOOL_CNAME, log)
    try:
        result = mpc.query_device_state(device)
    except MozpoolException as e:
        log.error("Unable to get mozpool state, mozpool returned error: %s" % sys.exc_info()[1])
        return MOZPOOL_STATE_ERROR

    if result['state'] == "ready":
        log.debug("Mozpool state is 'ready'")
        return MOZPOOL_STATE_READY
    else:
        log.error("Mozpool state is '%s'" % result['state'])
        return MOZPOOL_STATE_UNKNOWN
コード例 #4
0
def isMozpoolReady(device):
    """ Checks if the mozpool server is available and the device is in 'ready' state

    Returns MOZPOOL_STATE_READY if Mozpool is indeed listing device as ready
    Returns MOZPOOL_STATE_UNKNOWN if Mozpool claims the device is in a non-ready state
    Returns MOZPOOL_STATE_ERROR if Mozpool reports some other error.
    Returns MOZPOOL_STATE_MISSING if there is no Mozpool server found in DNS.
    """
    import socket
    default_timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(5)  # Don't let networking delay us too long
    try:
        socket.gethostbyname(MOZPOOL_CNAME)
    except:
        log.info("No mozpool server in this VLAN")
        return MOZPOOL_STATE_MISSING
    finally:
        # Set socket timeout back
        socket.setdefaulttimeout(default_timeout)

    mpc = MozpoolHandler("http://%s" % MOZPOOL_CNAME, log)
    try:
        result = mpc.query_device_state(device)
    except MozpoolException as e:
        log.error("Unable to get mozpool state, mozpool returned error: %s" %
                  sys.exc_info()[1])
        return MOZPOOL_STATE_ERROR

    if result['state'] == "ready":
        log.debug("Mozpool state is 'ready'")
        return MOZPOOL_STATE_READY
    else:
        log.error("Mozpool state is '%s'" % result['state'])
        return MOZPOOL_STATE_UNKNOWN
コード例 #5
0
def main(argv):

    if (len(argv) < 3):
        print "usage: installWatcher.py <ip address> <localfilename>"
        sys.exit(1)

    ip_addr = argv[1]
    path_to_main_apk = argv[2]

    dm = droid.DroidSUT(ip_addr)
    if not dm:
        log.error("could not get device manager!")
        return 1
    devRoot = checkDeviceRoot(dm)

    if install(dm, devRoot, path_to_main_apk, "com.mozilla.watcher"):
        log.error("install failed")
        return 1

    dm.reboot()
    waitForDevice(dm)

    # we can't use the following dm.getFile method, since only Watcher runtime user has read access
    # to this file, so we need to be root to read it, hence the slightly more convoluted version
    # using dm._runCmds below...
    # cannot use -> print dm.getFile('/data/data/com.mozilla.watcher/files/version.txt')
    status = dm._runCmds([{
        'cmd':
        'exec su -c "cat /data/data/com.mozilla.watcher/files/version.txt"'
    }]).split('\n')
    log.info('Watcher version: %s' % status)
    return 0
コード例 #6
0
ファイル: updateSUT.py プロジェクト: wlach/build-tools
def doUpdate(dm):
    _oldDebug = dm.debug
    log.info("updateSUT.py: We're going to try to install SUTAgentAndroid Version %s" % target_version)
    try:
        data = download_apk()
    except Exception, e:
        log.error("Automation Error: updateSUT.py: We have failed to retrieve the SUT Agent. %s" % str(e))
        return RETCODE_APK_DL_FAILED
コード例 #7
0
ファイル: updateSUT.py プロジェクト: magnyld/build-tools
def doUpdate(dm):
    _oldDebug = dm.debug
    log.info("updateSUT.py: We're going to try to install SUTAgentAndroid Version %s" % target_version)
    try:
        data = download_apk()
    except Exception, e:
        log.error("Automation Error: updateSUT.py: We have failed to retrieve the SUT Agent. %s" % str(e))
        return RETCODE_APK_DL_FAILED
コード例 #8
0
ファイル: cleanup.py プロジェクト: B-Rich/build-tools
def cleanupFoopy(device=None):
    errcode = checkStalled(device)
    if errcode == 2:
        log.error("processes from previous run were detected and cleaned up")
    elif errcode == 3:
        pidDir = os.path.join('/builds/', device)
        errorFile = os.path.join(pidDir, 'error.flg')
        setFlag(errorFile,
                "Remote Device Error: process from previous test run present")
        return RETCODE_KILLSTALLED
    return RETCODE_SUCCESS
コード例 #9
0
ファイル: cleanup.py プロジェクト: wlach/build-tools
def cleanupFoopy(device=None):
    errcode = checkStalled(device)
    if errcode == 2:
        log.error("processes from previous run were detected and cleaned up")
    elif errcode == 3:
        pidDir = os.path.join('/builds/', device)
        errorFile = os.path.join(pidDir, 'error.flg')
        setFlag(errorFile,
                "Remote Device Error: process from previous test run present")
        return RETCODE_KILLSTALLED
    return RETCODE_SUCCESS
コード例 #10
0
def cleanup():
    # Kill remote logcat process. Most process operations in devicemanager
    # work on applications, like org.mozilla.fennec, but not on native
    # processes like logcat. We work around that by directly executing
    # ps and kill.
    dm = devicemanager.DeviceManagerSUT(ip_addr)
    pid = findpid(dm, "logcat")
    if pid and pid > 0:
        log.debug('logcat.py killing logcat with pid %d' % pid)
        try:
            dm.shellCheckOutput(['kill', str(pid)], root=True)
        except devicemanager.DMError, e:
            log.error("Error killing logcat (pid %s): %s" % (str(pid), str(e)))
コード例 #11
0
ファイル: logcat.py プロジェクト: B-Rich/build-tools
def cleanup():
    # Kill remote logcat process. Most process operations in devicemanager
    # work on applications, like org.mozilla.fennec, but not on native
    # processes like logcat. We work around that by directly executing
    # ps and kill.
    dm = devicemanager.DeviceManagerSUT(ip_addr)
    pid = findpid(dm, "logcat")
    if pid and pid > 0:
        log.debug('logcat.py killing logcat with pid %d' % pid)
        try:
            dm.shellCheckOutput(['kill', str(pid)], root=True)
        except devicemanager.DMError, e:
            log.error("Error killing logcat (pid %s): %s" % (str(pid), str(e)))
コード例 #12
0
ファイル: smoketest.py プロジェクト: wlach/build-tools
def runTests(device, proc_name, number):
    numfailed = -1
    log.info("Starting to run tests")
    httpport = 8000 + int(number)

    # TODO: fix the host/port information so we don't have conflicts in
    # parallel runs
    cmd = [
        "python",
        os.path.join(os.path.dirname(__file__),
                     "tests/mochitest/runtestsremote.py"),
        "--app=%s" % proc_name,
        "--deviceIP=%s" % device,
        "--xre-path=%s" % os.path.join(os.path.dirname(__file__), "xre"),
        "--utility-path=%s" % os.path.join(os.path.dirname(__file__), "bin"),
        # "--test-path=dom/tests/mochitest/dom-level0",
        "--test-path=dom/tests/mochitest",
        "--http-port=%s" % httpport
    ]
    log.info("Going to run test: %s" % subprocess.list2cmdline(cmd))
    proc = ""
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        proc = p.communicate()[0]
    except:
        log.error("Exception found while running unittests: %s" %
                  sys.exc_info()[1])
    log.info("Finished running mochitests")
    refinished = re.compile('([0-9]+) INFO SimpleTest FINISHED')
    refailed = re.compile('([0-9]+) INFO Failed: ([0-9]+)')
    for line in proc.split('\n'):
        log.debug(line)
        finished = refinished.match(line)
        failed = refailed.match(line)
        if failed:
            numfailed = int(failed.group(2))
        if finished:
            if numfailed > 0:
                log.error("Found %s failures while running mochitest" %
                          numfailed)
                return False
            return True
    return False
コード例 #13
0
def main(argv):

    if len(argv) < 2:
        print "usage: installWatcher.py <ip address>"
        sys.exit(1)

    ip_addr = argv[1]

    dm = droid.DroidSUT(ip_addr)
    if not dm:
        log.error("could not get device manager!")
        return 1
    devRoot = checkDeviceRoot(dm)

    # we can't use the following dm.getFile method, since only Watcher runtime user has read access
    # to this file, so we need to be root to read it, hence the slightly more convoluted version
    # using dm._runCmds below...
    # cannot use -> print dm.getFile('/data/data/com.mozilla.watcher/files/version.txt')
    status = dm._runCmds([{"cmd": 'exec su -c "cat /data/data/com.mozilla.watcher/files/version.txt"'}]).split("\n")
    log.info("Watcher version: %s" % status)
    return 0
コード例 #14
0
ファイル: smoketest.py プロジェクト: wlach/build-tools
def smoketest(device_name, number):
    global dm
    global appFileName, processName

    dm = devicemanager.DeviceManagerSUT(device_name, 20701)
    deviceRoot = dm.getDeviceRoot()

    # This does all the steps of verify.py including the cleanup.
    if verifyDevice(device_name, checksut=False,
                    doCheckStalled=False) is False:
        log.error("failed to run verify on %s" % (device_name))
        return 1  # Not ok to proceed
    log.info("Successfully verified the device")

    if dm._sock:
        dm._sock.close()
    time.sleep(30)
    dm = devicemanager.DeviceManagerSUT(device_name, 20701)
    print "in smoketest, going to call installOneApp with dm: %s, %s" \
          % (dm, dm._sock)
    if installOneApp(dm,
                     deviceRoot,
                     os.path.abspath(appFileName),
                     None,
                     logcat=False):
        log.error("failed to install %s on device %s" %
                  (appFileName, device_name))
        return 1
    log.info("Successfully installed the application")

    if not runTests(device_name, processName, number):
        log.error("failed to run dom tests on %s" % (device_name))
        return 1
    log.info("Successfully ran the mochitests")
    return 0
コード例 #15
0
ファイル: smoketest.py プロジェクト: Callek/build-tools
def smoketest(device_name, number):
    global dm
    global appFileName, processName

    dm = devicemanager.DeviceManagerSUT(device_name, 20701)
    deviceRoot = dm.getDeviceRoot()

    # This does all the steps of verify.py including the cleanup.
    if verifyDevice(device_name, checksut=False, doCheckStalled=False) is False:
        log.error("failed to run verify on %s" % (device_name))
        return 1  # Not ok to proceed
    log.info("Successfully verified the device")

    if dm._sock:
        dm._sock.close()
    time.sleep(30)
    dm = devicemanager.DeviceManagerSUT(device_name, 20701)
    print "in smoketest, going to call installOneApp with dm: %s, %s" \
          % (dm, dm._sock)
    if installOneApp(dm, deviceRoot, os.path.abspath(appFileName), None, logcat=False):
        log.error("failed to install %s on device %s" % (appFileName, device_name))
        return 1
    log.info("Successfully installed the application")

    if not runTests(device_name, processName, number):
        log.error("failed to run dom tests on %s" % (device_name))
        return 1
    log.info("Successfully ran the mochitests")
    return 0
コード例 #16
0
ファイル: smoketest.py プロジェクト: Callek/build-tools
def runTests(device, proc_name, number):
    numfailed = -1
    log.info("Starting to run tests")
    httpport = 8000 + int(number)

    # TODO: fix the host/port information so we don't have conflicts in
    # parallel runs
    cmd = ["python",
           os.path.join(os.path.dirname(__file__), "tests/mochitest/runtestsremote.py"),
           "--app=%s" % proc_name,
           "--deviceIP=%s" % device,
           "--xre-path=%s" % os.path.join(os.path.dirname(__file__), "xre"),
           "--utility-path=%s" % os.path.join(os.path.dirname(__file__), "bin"),
           # "--test-path=dom/tests/mochitest/dom-level0",
           "--test-path=dom/tests/mochitest",
           "--http-port=%s" % httpport]
    log.info("Going to run test: %s" % subprocess.list2cmdline(cmd))
    proc = ""
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        proc = p.communicate()[0]
    except:
        log.error("Exception found while running unittests: %s" % sys.exc_info()[1])
    log.info("Finished running mochitests")
    refinished = re.compile('([0-9]+) INFO SimpleTest FINISHED')
    refailed = re.compile('([0-9]+) INFO Failed: ([0-9]+)')
    for line in proc.split('\n'):
        log.debug(line)
        finished = refinished.match(line)
        failed = refailed.match(line)
        if failed:
            numfailed = int(failed.group(2))
        if finished:
            if numfailed > 0:
                log.error("Found %s failures while running mochitest"
                          % numfailed)
                return False
            return True
    return False
コード例 #17
0
ファイル: logcat.py プロジェクト: B-Rich/build-tools
def main(argv):
    global ip_addr

    if (len(argv) < 4):
        log.info("usage: logcat.py <device ip address> <output filename> <logcat options>")
        return 1
    ip_addr = argv[1]
    output_filename = argv[2]
    logcat_options = argv[3]
    max_runtime = 3600   # 3600 seconds == 1 hour

    status = 0
    dm = devicemanager.DeviceManagerSUT(ip_addr)
    if not dm:
        log.error("logcat.py: unable to open device manager")
        return 2
    command = 'execext su t=%d logcat %s' % (max_runtime, logcat_options)
    log.debug('logcat.py running SUT command: %s' % command)
    try:
        with open(output_filename, 'w') as f:
            dm._sendCmds([{'cmd': command}], f)
    except devicemanager.DMError, e:
        log.error("Remote Device Error: Exception caught running logcat: %s" % str(e))
        status = -1
コード例 #18
0
    except devicemanager.DMError, e:
        log.info('uninstallation failed -- maybe not installed? '+str(e))

    osversion = dm.getInfo('os')['os'][0].split()[0]
    if osversion == 'pandaboard-eng':
        log.info('installing %s on panda' % target)
        status = dm._runCmds([{'cmd': 'exec su -c "export LD_LIBRARY_PATH=/vendor/lib:/system/lib; pm install /data/local/watcher.apk; am start -a android.intent.action.MAIN -n com.mozilla.watcher/.WatcherMain"'}]).split('\n')
    else:
        log.info('installing %s on tegra' % target)
        status = dm._runCmds([{'cmd': 'exec su -c "pm install /data/local/watcher.apk; am start -a android.intent.action.MAIN -n com.mozilla.watcher/.WatcherMain"'}]).split('\n')

    if len(status) > 2 and status[1].strip() == 'Success':
        log.info('-' * 42)
        log.info('installation successful')
    else:
        log.error('installApp() failed: %s' % status)
        return 1

    time.sleep(15)
    return 0


def main(argv):

    if (len(argv) < 3):
        print "usage: installWatcher.py <ip address> <localfilename>"
        sys.exit(1)

    ip_addr = argv[1]
    path_to_main_apk = argv[2]
コード例 #19
0
ファイル: installApp.py プロジェクト: B-Rich/build-tools
def one_time_setup(ip_addr, major_source):
    ''' One time setup of state

    ip_addr - of the device we want to install app at
    major_source - we've hacked this script to install
            may-also-be-needed tools, but the source we're asked to
            install has the meta data we need

    Side Effects:
        global, needed for error reporting:
            errorFile
    '''

    # set up the flag files, used throughout
    cwd = os.getcwd()
    global errorFile
    errorFile = os.path.join(cwd, '..', 'error.flg')
    deviceName = os.path.basename(cwd)

    proxyIP = getOurIP()
    proxyPort = calculatePort()

    workdir = os.path.dirname(major_source)
    inifile = os.path.join(workdir, 'fennec', 'application.ini')
    remoteappini = os.path.join(workdir, 'talos', 'remoteapp.ini')
    log.info('copying %s to %s' % (inifile, remoteappini))
    runCommand(['cp', inifile, remoteappini])

    log.info("connecting to: %s" % ip_addr)
    dm = devicemanager.DeviceManagerSUT(ip_addr)
# Moar data!
    dm.debug = 3

    devRoot = checkDeviceRoot(dm)

    if devRoot is None or devRoot == '/tests':
        setFlag(errorFile, "Remote Device Error: devRoot from devicemanager [%s] is not correct - exiting" % devRoot)
        return None, None

    try:
        log.info("%s, %s" % (proxyIP, proxyPort))
        getDeviceTimestamp(dm)
        setDeviceTimestamp(dm)
        getDeviceTimestamp(dm)
        dm.getInfo('process')
        dm.getInfo('memory')
        dm.getInfo('uptime')

        width, height = getResolution(dm)
        # adjust resolution down to allow fennec to install without memory
        # issues
        if (width == 1600 or height == 1200):
            dm.adjustResolution(1024, 768, 'crt')
            log.info('forcing device reboot')
            if not powermanagement.soft_reboot_and_verify(device=deviceName, dm=dm, ipAddr=proxyIP, port=proxyPort):
                return None, None

            width, height = getResolution(dm)
            if width != 1024 and height != 768:
                setFlag(errorFile, "Remote Device Error: Resolution change failed.  Should be %d/%d but is %d/%d" % (1024, 768, width, height))
                return None, None

    except devicemanager.AgentError, err:
        log.error("remoteDeviceError: while doing one time setup for installation: %s" % err)
        return None, None
コード例 #20
0
ファイル: updateSUT.py プロジェクト: magnyld/build-tools
    dm._sock = None
    dm = None
    ver = None
    tries = 0
    while tries < 5:
        try:
            dm = connect(device_name, sleep=90)
            break
        except:
            tries += 1
            log.warning("Automation Error: updateSUT.py: We have tried to connect %s time(s) after trying to update." % tries)

    try:
        ver = version(dm)
    except Exception, e:
        log.error("Automation Error: updateSUT.py: We should have been able to get the version")
        log.error("Automation Error: updateSUT.py: %s" % e)
        return RETCODE_REVERIFY_FAILED

    dm.debug = _oldDebug  # Restore it

    if ver is None:
        log.error("Automation Error: updateSUT.py: We should have been able to connect and determine the version.")
        return RETCODE_REVERIFY_FAILED
    elif not isVersionCorrect(ver=ver):
        log.error("Automation Error: updateSUT.py: We should have had the %s version but instead we have %s" %
                 (target_version, ver))
        return RETCODE_REVERIFY_WRONG
    else:
        log.info("updateSUT.py: We're now running %s" % ver)
        return RETCODE_SUCCESS
コード例 #21
0
    tries = 0
    while tries < 5:
        try:
            dm = connect(device_name, sleep=90)
            break
        except:
            tries += 1
            log.warning(
                "Automation Error: updateSUT.py: We have tried to connect %s time(s) after trying to update."
                % tries)

    try:
        ver = version(dm)
    except Exception, e:
        log.error(
            "Automation Error: updateSUT.py: We should have been able to get the version"
        )
        log.error("Automation Error: updateSUT.py: %s" % e)
        return RETCODE_REVERIFY_FAILED

    dm.debug = _oldDebug  # Restore it

    if ver == None:
        log.error(
            "Automation Error: updateSUT.py: We should have been able to connect and determine the version."
        )
        return RETCODE_REVERIFY_FAILED
    elif not isVersionCorrect(ver=ver):
        log.error("Automation Error: updateSUT.py: We should have had the %s version but instead we have %s" % \
              (target_version, ver))
        return RETCODE_REVERIFY_WRONG
コード例 #22
0
def one_time_setup(ip_addr, major_source):
    ''' One time setup of state

    ip_addr - of the device we want to install app at
    major_source - we've hacked this script to install
            may-also-be-needed tools, but the source we're asked to
            install has the meta data we need

    Side Effects:
        global, needed for error reporting:
            errorFile
    '''

    # set up the flag files, used throughout
    cwd = os.getcwd()
    global errorFile
    errorFile = os.path.join(cwd, '..', 'error.flg')
    deviceName = os.path.basename(cwd)

    proxyIP = getOurIP()
    proxyPort = calculatePort()

    workdir = os.path.dirname(major_source)
    inifile = os.path.join(workdir, 'fennec', 'application.ini')
    remoteappini = os.path.join(workdir, 'talos', 'remoteapp.ini')
    log.info('copying %s to %s' % (inifile, remoteappini))
    runCommand(['cp', inifile, remoteappini])

    log.info("connecting to: %s" % ip_addr)
    dm = devicemanager.DeviceManagerSUT(ip_addr)
    # Moar data!
    dm.debug = 3

    devRoot = checkDeviceRoot(dm)

    if devRoot is None or devRoot == '/tests':
        setFlag(
            errorFile,
            "Remote Device Error: devRoot from devicemanager [%s] is not correct - exiting"
            % devRoot)
        return None, None

    try:
        log.info("%s, %s" % (proxyIP, proxyPort))
        getDeviceTimestamp(dm)
        setDeviceTimestamp(dm)
        getDeviceTimestamp(dm)
        dm.getInfo('process')
        dm.getInfo('memory')
        dm.getInfo('uptime')

        width, height = getResolution(dm)
        # adjust resolution down to allow fennec to install without memory
        # issues
        if (width == 1600 or height == 1200):
            dm.adjustResolution(1024, 768, 'crt')
            log.info('forcing device reboot')
            if not powermanagement.soft_reboot_and_verify(
                    device=deviceName, dm=dm, ipAddr=proxyIP, port=proxyPort):
                return None, None

            width, height = getResolution(dm)
            if width != 1024 and height != 768:
                setFlag(
                    errorFile,
                    "Remote Device Error: Resolution change failed.  Should be %d/%d but is %d/%d"
                    % (1024, 768, width, height))
                return None, None

    except devicemanager.AgentError, err:
        log.error(
            "remoteDeviceError: while doing one time setup for installation: %s"
            % err)
        return None, None
コード例 #23
0
        status = dm._runCmds([{
            'cmd':
            'exec su -c "export LD_LIBRARY_PATH=/vendor/lib:/system/lib; pm install /data/local/watcher.apk; am start -a android.intent.action.MAIN -n com.mozilla.watcher/.WatcherMain"'
        }]).split('\n')
    else:
        log.info('installing %s on tegra' % target)
        status = dm._runCmds([{
            'cmd':
            'exec su -c "pm install /data/local/watcher.apk; am start -a android.intent.action.MAIN -n com.mozilla.watcher/.WatcherMain"'
        }]).split('\n')

    if len(status) > 2 and status[1].strip() == 'Success':
        log.info('-' * 42)
        log.info('installation successful')
    else:
        log.error('installApp() failed: %s' % status)
        return 1

    time.sleep(15)
    return 0


def main(argv):

    if (len(argv) < 3):
        print "usage: installWatcher.py <ip address> <localfilename>"
        sys.exit(1)

    ip_addr = argv[1]
    path_to_main_apk = argv[2]