def main(args=sys.argv[1:]):
    parser = eideticker.OptionParser(usage="usage: %prog")

    options, args = parser.parse_args()

    # Create a device object to interface with the phone
    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    print "READY"
    sys.stdout.flush()

    while 1:
        try:
            line = sys.stdin.readline()
        except KeyboardInterrupt:
            break

        if not line:
            break

        tokens = line.rstrip().split()
        if len(tokens) < 1:
            raise Exception("No command")

        (cmd, args) = (tokens[0], tokens[1:])
        device.executeCommand(cmd, args)
Exemplo n.º 2
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog [product1] [product2]"
    parser = eideticker.OptionParser(usage=usage)

    options, args = parser.parse_args()
    if len(args):
        products = [
            product for product in default_products if product['name'] in args
        ]
    else:
        products = default_products

    if not products:
        print "No products matching arguments!"
        sys.exit(1)

    print products

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    for product in products:
        if not product.get('url'):
            print "No download / installation needed for %s" % product['name']
        else:
            print "Downloading %s" % product['name']
            product_fname = os.path.join(DOWNLOAD_DIR,
                                         "%s.apk" % product['name'])

            dl = urllib2.urlopen(product['url'])
            with open(product_fname, 'w') as f:
                f.write(dl.read())
            print "Installing %s" % product['name']
            device.updateApp(product_fname)
Exemplo n.º 3
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog <product> <date>"
    parser = eideticker.OptionParser(usage=usage)

    options, args = parser.parse_args()
    if len(args) != 2:
        parser.error("incorrect number of arguments")

    (productname, datestr) = args

    product = eideticker.get_product(productname)

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    if device.type != 'android':
        print "Device type '%s' does not currently support updates" % \
            device.type
        sys.exit(0)

    if not product.get('reponame'):
        print "No download / installation needed for %s" % product['name']
    else:
        print "Downloading %s (date: %s)" % (product['name'], datestr)
        br = eideticker.BuildRetriever()
        if datestr == 'latest':
            date = None
        else:
            date = eideticker.BuildRetriever.get_date(datestr)
        filename = br.get_build(product, date)

        print "Installing %s (%s)" % (product['name'], filename)
        device.updateApp(filename)
Exemplo n.º 4
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog"
    parser = eideticker.OptionParser(usage=usage)

    options, args = parser.parse_args()

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    if device.type == 'b2g':
        print "No cleanup presently required on b2g"
        return

    for product in eideticker.products:
        if product['platform'] == device.type:
            device.killProcess(product['appname'])

    # clean up any test stuff (profiles, etc.)
    device.removeDir(device.getDeviceRoot())

    # profile files are dumped directly to the sdcard,
    # not the testroot so we need to clean them up
    # seperately
    files = device.listFiles('/mnt/sdcard/')
    for file in files:
        if re.match('profile_.*txt', file):
            device.removeFile('/mnt/sdcard/%s' % file)
Exemplo n.º 5
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog"
    parser = eideticker.OptionParser(usage=usage)

    options, args = parser.parse_args()

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)
    device.cleanup()
Exemplo n.º 6
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog"
    parser = eideticker.OptionParser(usage=usage)

    options, args = parser.parse_args()

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    for product in default_products:
        device.killProcess(product['appname'])

    # clean up any test stuff (profiles, etc.)
    device.removeDir(device.getDeviceRoot())
def main(args=sys.argv[1:]):
    usage = "usage: %prog [options] <test> <output dir>"

    parser = eideticker.OptionParser(usage=usage)
    parser.add_option("--enable-profiling",
                      action="store_true",
                      dest="enable_profiling",
                      help="Create SPS profile to go along with capture")
    parser.add_option("--device-id",
                      action="store",
                      dest="device_id",
                      help="id of device (used in output json)")
    parser.add_option(
        "--product",
        action="store",
        dest="product",
        help="Restrict testing to product (options: %s)" %
        ", ".join([product["name"] for product in default_products]))
    parser.add_option("--num-runs",
                      action="store",
                      type="int",
                      dest="num_runs",
                      help="number of runs (default: 1)")

    options, args = parser.parse_args()
    if len(args) != 2:
        parser.error("incorrect number of arguments")

    (testname, outputdir) = args
    num_runs = 1
    if options.num_runs:
        num_runs = options.num_runs

    testnames = [test["name"] for test in default_tests]
    if testname not in testnames:
        print "ERROR: No tests matching '%s' (options: %s)" % (
            testname, ", ".join(testnames))
        sys.exit(1)
    else:
        test = [test for test in default_tests if test['name'] == testname][0]

    device_id = options.device_id
    if not device_id:
        device_id = os.environ.get('DEVICE_ID')
    if not device_id:
        print "ERROR: Must specify device id (either with --device-id or with DEVICE_ID environment variable)"
        sys.exit(1)

    products = default_products
    if options.product:
        products = [
            product for product in default_products
            if product['name'] == options.product
        ]
        if not products:
            print "ERROR: No products matching '%s'" % options.product
            sys.exit(1)

    current_date = time.strftime("%Y-%m-%d")
    datafile = os.path.join(outputdir, 'data-%s.json' % device_id)

    data = NestedDict()
    if os.path.isfile(datafile):
        data.update(json.loads(open(datafile).read()))

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    # update the device list for the dashboard
    devices = {}
    devicefile = os.path.join(outputdir, 'devices.json')
    if os.path.isfile(devicefile):
        devices = json.loads(open(devicefile).read())['devices']
    devices[device_id] = {
        'name': device.model,
        'version': device.getprop('ro.build.version.release')
    }
    with open(devicefile, 'w') as f:
        f.write(json.dumps({'devices': devices}))

    for product in products:
        if product.get('url'):
            product_fname = os.path.join(DOWNLOAD_DIR,
                                         "%s.apk" % product['name'])
            appinfo = eideticker.get_fennec_appinfo(product_fname)
            appname = appinfo['appname']
            print "Using application name '%s' from apk '%s'" % (appname,
                                                                 product_fname)
            capture_name = "%s %s" % (product['name'], appinfo['date'])
        else:
            appinfo = {}
            appname = product['appname']
            capture_name = "%s (taken on %s)" % (product['name'], current_date)

        if appinfo.get('appname'):
            appname = appinfo['appname']
        else:
            appname = product['appname']

        # Run the test the specified number of times
        for i in range(num_runs):
            # Now run the test
            runtest(device,
                    product,
                    current_date,
                    appname,
                    appinfo,
                    test,
                    capture_name + " #%s" % i,
                    outputdir,
                    datafile,
                    data,
                    enable_profiling=options.enable_profiling,
                    **devicePrefs)

            # Kill app after test complete
            device.killProcess(appname)
def main(args=sys.argv[1:]):
    usage = "usage: %prog <test> [appname1] [appname2] ..."
    parser = eideticker.OptionParser(usage=usage)
    parser.add_option("--num-runs",
                      action="store",
                      type="int",
                      dest="num_runs",
                      default=1,
                      help="number of runs (default: 1)")
    parser.add_option("--output-dir",
                      action="store",
                      type="string",
                      dest="outputdir",
                      help="output results to json file")
    parser.add_option("--no-capture",
                      action="store_true",
                      dest="no_capture",
                      help="run through the test, but don't actually "
                      "capture anything")
    parser.add_option(
        "--profile-file",
        action="store",
        type="string",
        dest="profile_file",
        help="Collect a performance profile using the built in profiler.")
    parser.add_option("--get-internal-checkerboard-stats",
                      action="store_true",
                      dest="get_internal_checkerboard_stats",
                      help="get and calculate internal checkerboard stats")
    parser.add_option("--startup-test",
                      action="store_true",
                      dest="startup_test",
                      help="measure startup times instead of normal metrics")
    parser.add_option("--url-params",
                      action="store",
                      dest="url_params",
                      default="",
                      help="additional url parameters for test")
    parser.add_option(
        "--use-apks",
        action="store_true",
        dest="use_apks",
        help=
        "use and install android APKs as part of test (instead of specifying appnames)"
    )
    parser.add_option("--date",
                      action="store",
                      dest="date",
                      metavar="YYYY-MM-DD",
                      help="get and test nightly build for date")
    parser.add_option("--start-date",
                      action="store",
                      dest="start_date",
                      metavar="YYYY-MM-DD",
                      help="start date for range of nightlies to test")
    parser.add_option("--end-date",
                      action="store",
                      dest="end_date",
                      metavar="YYYY-MM-DD",
                      help="end date for range of nightlies to test")

    options, args = parser.parse_args()

    if len(args) == 0:
        parser.error(
            "Must specify at least one argument: the path to the test")

    dates = []
    appnames = []
    apks = []
    if options.start_date and options.end_date and len(args) == 1:
        test = args[0]
        start_date = get_date(options.start_date)
        end_date = get_date(options.end_date)
        days = (end_date - start_date).days
        for numdays in range(days + 1):
            dates.append(start_date + datetime.timedelta(days=numdays))
    elif options.date and len(args) == 1:
        test = args[0]
        dates = [get_date(options.date)]
    elif not options.date and len(args) >= 2:
        test = args[0]
        if options.use_apks:
            apks = args[1:]
        else:
            appnames = args[1:]
    elif not options.date or (not options.start_date and not options.end_date):
        parser.error(
            "Must specify date, date range, a set of appnames (e.g. org.mozilla.fennec) or a set of apks (if --use-apks is specified)"
        )

    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    if options.outputdir:
        outputfile = os.path.join(options.outputdir,
                                  "metric-test-%s.json" % time.time())
    else:
        outputfile = None

    if appnames:
        for appname in appnames:
            run_test(device,
                     options.outputdir,
                     outputfile,
                     test,
                     options.url_params,
                     options.num_runs,
                     options.startup_test,
                     options.no_capture,
                     options.get_internal_checkerboard_stats,
                     appname=appname,
                     profile_file=options.profile_file,
                     **devicePrefs)
    elif apks:
        for apk in apks:
            run_test(device,
                     options.outputdir,
                     outputfile,
                     test,
                     options.url_params,
                     options.num_runs,
                     options.startup_test,
                     options.no_capture,
                     options.get_internal_checkerboard_stats,
                     apk=apk,
                     profile_file=options.profile_file,
                     **devicePrefs)
    else:
        for date in dates:
            apk = get_build_for_date(date)
            run_test(device,
                     options.outputdir,
                     outputfile,
                     test,
                     options.url_params,
                     options.num_runs,
                     options.startup_test,
                     options.no_capture,
                     options.get_internal_checkerboard_stats,
                     apk=apk,
                     appdate=date,
                     profile_file=options.profile_file,
                     **devicePrefs)
Exemplo n.º 9
0
def main(args=sys.argv[1:]):
    usage = "usage: %prog [options] <appname> <test path>"
    parser = eideticker.OptionParser(usage=usage)
    parser.add_option("--url-params",
                      action="store",
                      dest="url_params",
                      help="additional url parameters for test")
    parser.add_option("--name",
                      action="store",
                      type="string",
                      dest="capture_name",
                      help="name to give capture")
    parser.add_option("--capture-file",
                      action="store",
                      type="string",
                      dest="capture_file",
                      help="name to give to capture file")
    parser.add_option("--no-capture",
                      action="store_true",
                      dest="no_capture",
                      help="run through the test, but don't actually "
                      "capture anything")
    parser.add_option("--checkerboard-log-file",
                      action="store",
                      type="string",
                      dest="checkerboard_log_file",
                      help="name to give checkerboarding stats file")
    parser.add_option("--startup-test",
                      action="store_true",
                      dest="startup_test",
                      help="do a startup test: full capture, no actions")
    parser.add_option(
        "--b2g",
        action="store_true",
        dest="b2g",
        default=False,
        help="Run in B2G environment. You do not need to pass an appname")
    parser.add_option(
        "--profile-file",
        action="store",
        type="string",
        dest="profile_file",
        help="Collect a performance profile using the built in profiler.")

    options, args = parser.parse_args()
    testpath, appname = None, None
    if options.b2g:
        if len(args) != 1:
            parser.error("incorrect number of arguments")
            sys.exit(1)
        testpath = args[0]
    else:
        if len(args) != 2:
            parser.error("incorrect number of arguments")
            sys.exit(1)

        (appname, testpath) = args
    # Tests must be in src/tests/... unless it is a startup test and the
    # path is about:home (indicating we want to measure startup to the
    # home screen)
    if options.startup_test and testpath == "about:home":
        testpath_rel = testpath
        capture_timeout = 5  # 5 seconds to wait for fennec to start after it claims to have started
    else:
        capture_timeout = None
        try:
            testpath_rel = os.path.abspath(testpath).split(TEST_DIR)[1][1:]
        except:
            print "Test must be relative to %s" % TEST_DIR
            sys.exit(1)

    actions = None
    if not options.startup_test:
        actions_path = os.path.join(os.path.dirname(testpath), "actions.json")
        try:
            with open(actions_path) as f:
                actions = json.loads(f.read())
        except EnvironmentError:
            print "Couldn't open actions file '%s'" % actions_path
            sys.exit(1)

    if not os.path.exists(EIDETICKER_TEMP_DIR):
        os.mkdir(EIDETICKER_TEMP_DIR)
    if not os.path.isdir(EIDETICKER_TEMP_DIR):
        print "Could not open eideticker temporary directory"
        sys.exit(1)

    capture_name = options.capture_name
    if not capture_name:
        capture_name = testpath_rel
    capture_file = options.capture_file
    if not capture_file and not options.no_capture:
        capture_file = os.path.join(
            CAPTURE_DIR,
            "capture-%s.zip" % datetime.datetime.now().isoformat())

    # Create a device object to interface with the phone
    devicePrefs = eideticker.getDevicePrefs(options)
    device = eideticker.getDevice(**devicePrefs)

    if appname and device.processExist(appname):
        print "An instance of %s is running. Please stop it before running Eideticker." % appname
        sys.exit(1)

    # If we're logging checkerboard stats, set that up here (seems like it
    # takes a second or so to accept the new setting, so let's do that here --
    # ideally we would detect when that's working, but I'm not sure how to do
    # so trivially)
    if options.checkerboard_log_file:
        old_log_val = device.getprop("log.tag.GeckoLayerRendererProf")
        device.setprop("log.tag.GeckoLayerRendererProf", "DEBUG")

    print "Creating webserver..."
    capture_metadata = {
        'name': capture_name,
        'testpath': testpath_rel,
        'app': appname,
        'device': device.model,
        'startupTest': options.startup_test
    }

    # something of a hack. if profiling is enabled, carve off an area to
    # ignore in the capture
    if options.profile_file:
        capture_metadata['ignoreAreas'] = [[0, 0, 3 * 64, 3]]

    capture_server = CaptureServer(capture_metadata, capture_file,
                                   options.checkerboard_log_file,
                                   capture_controller, device, actions)
    host = mozhttpd.iface.get_lan_ip()
    http = mozhttpd.MozHttpd(docroot=TEST_DIR,
                             host=host,
                             port=0,
                             urlhandlers=[{
                                 'method':
                                 'GET',
                                 'path':
                                 '/api/captures/start/?',
                                 'function':
                                 capture_server.start_capture
                             }, {
                                 'method':
                                 'GET',
                                 'path':
                                 '/api/captures/end/?',
                                 'function':
                                 capture_server.end_capture
                             }, {
                                 'method': 'POST',
                                 'path': '/api/captures/input/?',
                                 'function': capture_server.input
                             }])
    http.start(block=False)

    connected = False
    tries = 0
    while not connected and tries < 20:
        tries += 1
        import socket
        s = socket.socket()
        try:
            s.connect((host, http.httpd.server_port))
            connected = True
        except Exception:
            print "Can't connect to %s:%s, retrying..." % (
                host, http.httpd.server_port)

    if not connected:
        print "Could not open webserver. Error!"
        sys.exit(1)

    # note: url params for startup tests currently not supported
    if options.url_params:
        testpath_rel += "?%s" % urllib.quote_plus(options.url_params)

    if options.startup_test:
        if testpath == "about:home":
            url = testpath
        else:
            url = "http://%s:%s/%s?startup_test=1" % (
                host, http.httpd.server_port, testpath_rel)
    else:
        url = "http://%s:%s/start.html?testpath=%s" % (
            host, http.httpd.server_port, testpath_rel)
    print "Test URL is: %s" % url
    if options.b2g:
        runner = eideticker.B2GRunner(device, url, EIDETICKER_TEMP_DIR)
    else:
        runner = eideticker.BrowserRunner(device, appname, url)
    # FIXME: currently start capture before launching app because we wait until app is
    # launched -- would be better to make waiting optional and then start capture
    # after triggering app launch to reduce latency?
    if options.startup_test and not options.no_capture:
        capture_controller.start_capture(capture_file, device.hdmiResolution,
                                         capture_metadata)
    runner.start(profile_file=options.profile_file)

    # Keep on capturing until we timeout
    if capture_timeout:
        timeout = capture_timeout
    else:
        timeout = 100
    timer = 0
    interval = 0.1

    try:
        while not capture_server.finished and timer < timeout:
            time.sleep(interval)
            timer += interval
    except KeyboardInterrupt:
        print "Aborting"
        runner.stop()
        capture_server.terminate_capture()
        sys.exit(1)

    if capture_timeout and not capture_server.finished:
        capture_server.terminate_capture()
    elif not capture_server.finished:
        print "Did not finish test! Error!"
        runner.stop()
        capture_server.terminate_capture()
        sys.exit(1)

    runner.stop()

    if capture_file:
        print "Converting capture..."
        try:
            capture_controller.convert_capture(capture_server.start_frame,
                                               capture_server.end_frame)
        except KeyboardInterrupt:
            print "Aborting"
            sys.exit(1)

    # Clean up checkerboard logging preferences
    if options.checkerboard_log_file:
        device.setprop("log.tag.GeckoLayerRendererProf", old_log_val)