Beispiel #1
0
def handle_cmd():
    appdb.collect_apps("../apks/")

    serial = sys.argv[1]
    cmd = sys.argv[2]
    args = sys.argv[3:]

    dev = device.Device(serial=serial, no_uimon=True)

    if cmd == "clear":
        if args[0] == 'all':
            for app in appdb.apps:
                clear(dev, appdb.get_app(app))
        else:
            clear(dev, appdb.get_app(args[0]))
    elif cmd == "install":
        appname = args[0]
        install(dev, appname)
    elif cmd == "uninstall":
        appname = args[0]
        uninstall(dev, appname)
    elif cmd == "version":
        appname = args[0]
        apk_version(appname)
    elif cmd == "dver":
        appname = args[0]
        ret = check_dev_version(dev, appname)
        if ret:
            sys.exit(0)
        else:
            sys.exit(1)
Beispiel #2
0
def check_dev_version(dev, appname):
    app = appdb.get_app(appname)
    ret = dev.run_adb_shell("pm list packages").decode('utf-8')

    found = False
    for line in ret.split('\n'):
        line = line.strip()
        if line == 'package:' + app:
            found = True
            break
    if not found:
        print(appname, "NOT INSTALLED")
        return False

    ret = dev.run_adb_shell("pm dump %s" % app).decode('utf-8')
    vercode = None
    vername = None
    for line in ret.split('\n'):
        if dver_vercode_re.match(line):
            vercode = dver_vercode_re.match(line).group(1)
        elif dver_vername_re.match(line):
            vername = dver_vername_re.match(line).group(1)

    print(appname, vercode, vername)
    ver_code_apk = apk_version(appname)
    if ver_code_apk == vercode:
        print(appname, "VERSION MATCH")
        return True
    else:
        print(appname, "VERSION MISMATCH!")
        return False
Beispiel #3
0
def dump_to_file(dev, basename, appname=None, scrname=None, guispath=None):
    ret = grab_full(dev)
    if appname is None:
        appname = appdb.guess_app(ret['act'])
        logger.info("app guessed as %s", appname)
    else:
        logger.info("dumping for app %s", appname)

    webdatas = None
    if 'WebView' in ret['xml']:
        app = appdb.get_app(appname)
        if app is None:
            app = appdb.app_from_act(ret['act'])
            logger.warning("unknown app, using %s directly", app)
        webgrabber = webview.WebGrabber(app)
        pages = webgrabber.find_webviews(dev)
        webdata = []
        for page in pages:
            webgrabber.capture_webnodes(dev, page)
            webdata.append({'title': page['title'], 'pageinfo': page,
                            'page': webgrabber.dump()})
            webgrabber.clear()
        webdatas = yaml.dump(webdata)

    with open(basename + ".xml", 'w') as xmlf:
        xmlf.write(ret['xml'])
    shutil.move(ret['scr'], basename + ".png")
    #with open(basename + ".png", 'wb') as pngf:
    #pngf.write(open(ret['scr'], 'rb').read())
    with open(basename + ".txt", "w") as actf:
        actf.write(ret['act'])
    if webdatas is not None:
        with open(basename + ".web", "w") as webf:
            webf.write(webdatas)
Beispiel #4
0
def dump_page(dev, path, appname=None, scrname=None, guispath=None):
    ret = grab_full(dev)
    if appname is None or scrname is None:
        template = "page%d"
    else:
        template = "%s_%%d_%s" % (appname, scrname)

    if appname is None or scrname is None or guispath is None:
        page_id = 0
        while (os.path.exists(
                os.path.join(path, ("%s.xml" % template) % page_id))
               and os.path.exists(
                   os.path.join(path, ("%s.png" % template) % page_id))):
            page_id += 1
    else:
        page_id = dump.get_next_page_id([guispath, path], appname, scrname)
        if page_id > config.PER_PAGE_CAPTURE_LIMIT:
            return

    if appname is None:
        appname = appdb.guess_app(ret['act'])
        logger.info("app guessed as %s", appname)
    else:
        logger.info("dumping for app %s", appname)

    webdatas = None
    if 'WebView' in ret['xml']:
        app = appdb.get_app(appname)
        if app is None:
            app = appdb.app_from_act(ret['act'])
            logger.warning("unknown app, using %s directly", app)
        webgrabber = webview.WebGrabber(app)
        pages = webgrabber.find_webviews(dev)
        webdata = []
        for page in pages:
            webgrabber.capture_webnodes(dev, page)
            webdata.append({
                'title': page['title'],
                'pageinfo': page,
                'page': webgrabber.dump()
            })
            webgrabber.clear()
        webdatas = yaml.dump(webdata)

    logger.info("dumping to page %s", template % page_id)
    basename = os.path.join(path, template % page_id)
    with open(basename + ".xml", 'w') as xmlf:
        xmlf.write(ret['xml'])
    shutil.move(ret['scr'], basename + ".png")
    #with open(basename + ".png", 'wb') as pngf:
    #pngf.write(open(ret['scr'], 'rb').read())
    with open(basename + ".txt", "w") as actf:
        actf.write(ret['act'])
    if webdatas is not None:
        with open(basename + ".web", "w") as webf:
            webf.write(webdatas)
Beispiel #5
0
def load_app(app, ob, tlib, envs):
    ob.set_app(app)
    tlib.set_app(app)
    envs['app'] = app

    value.init_params("../etc/", app)
    ob.load("../model/", "../guis/", "../guis-extra/", config.extra_screens,
            config.extra_element_scrs)

    tlib.add_test(microtest.init_test(appdb.get_app(app)))
Beispiel #6
0
    def __init__(self, dev, guispath, modelpath, tlibpath, batch, appname,
                 statpath, errpath, skippath, extrapath, mempath,
                 need_observer):
        self.dev = dev
        self.appname = appname  # type: str
        self.app = appdb.get_app(appname)  # type: str
        self.tlib = testlib.collect_pieces(tlibpath)
        self.tlib.set_app(appname)
        if skippath is not None:
            self.tlib.load_skip(skippath)
        self.slib = screenlib.Screenlib(self.tlib.essential_props())
        if need_observer:
            self.observer = observer.Observer(errpath)
            self.observer.set_app(appname)
            self.observer.load(modelpath, guispath, extrapath,
                               config.extra_screens, config.extra_element_scrs)
            self.observer.tlib = self.tlib  # TODO: so ugly
        else:
            self.observer = None
        self.watchdog = watchdog.create(config.WATCHDOG_TIMEOUT)
        self.statemgr = statemgr.StateMgr(self.tlib, self.slib, self.dev,
                                          self.observer, self.watchdog)

        self.statpath = statpath
        self.batch = batch
        if batch:
            self.console = None
        else:
            self.console = console.Console(self.handle_cmd)
            self.console.start()
        self.explored_ops = {
        }  # type: Dict[state.State, Set[operation.Operation]]
        self.round_no = 0
        self.progress = ''

        self.tlib.add_test(microtest.init_test(self.app))
        restart_test = microtest.restart_test(self.app)
        if not config.allow_restart:
            restart_test.set_prio(-1000)
        self.tlib.add_test(restart_test)

        self.mempath = mempath
        self.load_memory()
Beispiel #7
0
def handle_console_cmd(cons, cmd, envs):
    threading.current_thread().name = 'MainThread'

    dev = envs['dev']
    ob = envs['ob']
    st = envs['state']
    tlib = envs['tlib']
    env = envs['env']

    if 'app' in envs:
        app = envs['app']
    else:
        app = 'cui'

    def save_stat():
        tlib.save_stat(os.path.join("../stat/", "%s.txt" % app))

    if cmd == 'q':
        save_stat()
        dev.finish()
        sys.exit(0)
    elif cmd == 'sense':
        scr = ob.grab_state(dev, no_verify=True, no_print=True)
        if scr.get('guess_descs') is None:
            util.print_tree(scr.get('tree'))
        else:
            util.print_tree(scr.get('tree'), scr.get('guess_descs'),
                            scr.get('guess_score'))
        st.merge(scr)
        return
    elif cmd == 'tags':
        config.show_guess_tags = True
        scr = ob.grab_state(dev, no_verify=True, no_print=True)
        util.print_tree(scr.get('tree'), scr.get('guess_descs'), scr.get('guess_score'))
        st.merge(scr)
        config.show_guess_tags = False
        return
    elif cmd == 'tree':
        scr = ob.grab_state(dev, no_img=True)
        util.print_tree(scr.get('tree'))
        st.merge(scr)
        return
    elif cmd.startswith('app '):
        app = cmd.split(' ')[1]
        load_app(app, ob, tlib, envs)
        return
    elif cmd == 'load':
        tlib = testlib.collect_pieces("../tlib/")
        envs['tlib'] = tlib
        load_app(app, ob, tlib, envs)
        return
    elif cmd == 'reload':
        value.init_params("../etc/", app)
        try:
            if app:
                os.remove("../model/screen_%s" % app)
                os.remove("../model/element_%s" % app)
            else:
                os.remove("../model/screen")
                os.remove("../model/element")
        except:
            pass
        ob.load("../model/", "../guis/", "../guis-extra/", config.extra_screens,
                config.extra_element_scrs)
        return
    elif cmd == 'tlib':
        tlib = testlib.collect_pieces("../tlib/")
        envs['tlib'] = tlib
        return
    elif cmd == 'test':
        tlib = testlib.collect_pieces("../tlib/")
        tlib.set_app(app)
        tlib.add_test(microtest.init_test(appdb.get_app(app)))
        envs['tlib'] = tlib

        config.show_guess_tags = True
        scr = ob.grab_state(dev)
        config.show_guess_tags = False
        st.merge(scr)
        begin_state = st.to_essential(tlib.essential_props())

        tests = tlib.usable_tests(st)
        tests.sort(key=lambda test: test.prio)

        for i in range(len(tests)):
            testinfo = tlib.get_testinfo(tests[i])
            print("%2d. %s: %s [%d %d]" % (i, tests[i].feature_name, tests[i].name,
                                           testinfo.succs, testinfo.fails))
        if len(tests) == 0:
            print("no test available!")
            return
        if len(tests) == 1:
            tid = 0
        else:
            tid = input("which one? ")
            try:
                tid = int(tid)
            except:
                return
        test = tests[tid]
        ret = test.attempt(dev, ob, st, tlib, environ.empty)

        util.print_tree(st.get('tree'), st.get('guess_descs'))
        end_state = st.to_essential(tlib.essential_props())
        if ret:
            print("test SUCC")
            tlib.clear_stat(test)
            tlib.mark_succ(test, begin_state, end_state)
        else:
            print("test FAIL")
            tlib.mark_fail(test, begin_state)
        save_stat()
        return
    elif cmd == 'save':
        save_stat()
        return
    elif cmd == 'stat':
        tlib.print_stat()
        return
    elif cmd == 'items':
        scr = ob.grab_state(dev, no_img=True)
        util.printitems(scr.get('items'))
        return
    elif cmd.startswith('item'):
        itemid = int(cmd.split(' ')[1])
        scr = ob.grab_state(dev, no_img=True)
        items = scr.get('items')
        if itemid in items:
            print(util.describe(items[itemid]))
        else:
            print("no such item: %d" % itemid)
        return
    elif cmd == 'debug':
        logging.basicConfig(level=logging.DEBUG)
        return
    elif cmd == 'idle':
        dev.wait_idle()
        return
    elif cmd == 'dialog':
        scr = ob.grab_state(dev)
        ret = tlib.handle_dialog(scr, dev, ob)
        if ret:
            print("dialog handled")
        else:
            print("dialog not handled")
        return
    elif cmd.startswith('find '):
        tag = cmd.split(' ', 1)[1]
        con = concept.parse(tag)
        if con is None:
            print("invalid locator")
            return
        scr = ob.grab_state(dev)
        widgets = con.locate(scr, ob, environ.Environment())
        if widgets == []:
            print("can't find")
        else:
            for widget in widgets:
                print("FOUND: %s" % widget)
                print("    content:", widget.content())
        return
    elif cmd == 'perf':
        perfmon.print_stat()
        return
    elif cmd == 'clear':
        init = tlib.find_test('meta', 'start app')
        st.reset()
        init.attempt(dev, ob, st, tlib, None)
        ob.update_state(dev, st)
        tlib.mark_succ(init, state.init_state, st)
        return
    elif cmd.startswith('set'):
        parts = cmd.split(' ', 2)
        if len(parts) == 2:
            key = parts[1]
            val = "1"
        else:
            (key, val) = parts[1:]
        st.set(key, val)
        return
    elif cmd.startswith('del'):
        parts = cmd.split(' ', 1)
        key = parts[1]
        st.remove(key)
        return
    elif cmd == 'dump':
        filename = util.choose_filename("../cap/", "page%d")
        logger.info("dumping to page %s", filename)
        dev.dump(filename)
        #sense.dump_page(dev, "../cap/")
        return
    elif cmd == 'list':
        scr = ob.grab_state(dev, no_img=True)
        tree = scr.get('tree')
        treeinfo = analyze.collect_treeinfo(tree)
        for root in sorted(treeinfo['listlike']):
            print("ROOT:", util.describe_node(tree[root]))
            for item in sorted(treeinfo['itemlike']):
                if listinfo.get_lca(tree, [root, item]) == root:
                    print("  NODE:", util.describe_node(tree[item]))
                    for field in sorted(treeinfo['dupid']):
                        if listinfo.get_lca(tree, [item, field]) == item:
                            print("    FIELD:", util.describe_node(tree[field]))
        return
    elif cmd == 'webon':
        config.GRAB_WEBVIEW = True
        return
    elif cmd == 'weboff':
        config.GRAB_WEBVIEW = False
        return
    elif cmd.startswith('ob '):
        prop = cmd.split(' ', 1)[1]
        wd = watchdog.Watchdog(100000)
        smgr = statemgr.StateMgr(tlib, None, dev, ob, wd)
        ret = smgr.observe_prop(prop, st)
        if ret:
            print("prop %s = %s" % (prop, st.get(prop, '')))
        else:
            print("observe error")
        return
    elif cmd.startswith('clean '):
        parts = cmd.split(' ', 2)
        if len(parts) == 2:
            prop = parts[1]
            val = "1"
        else:
            (prop, val) = parts[1:]
        wd = watchdog.Watchdog(100000)
        smgr = statemgr.StateMgr(tlib, None, dev, ob, wd)
        ret = smgr.cleanup_prop(prop, val, st)
        if ret:
            print("prop %s cleaned" % prop)
        else:
            print("clean error")
        return
    elif cmd.startswith('oc '):
        prop = cmd.split(' ', 1)[1]
        wd = watchdog.Watchdog(100000)
        smgr = statemgr.StateMgr(tlib, None, dev, ob, wd)
        ret = smgr.observe_and_clean(prop, st)
        if ret:
            print("prop %s is clean now" % prop)
        else:
            print("observe/clean error")
        return
    elif cmd == 'dbg':
        print(tlib)
        return
    elif cmd.startswith('skip '):
        name = cmd.split(' ', 1)[1]
        add_skip(app, name)
        print("skipping %s" % name)
        return
    elif cmd == 'skip':
        skips = load_skip(app)
        for skip in skips:
            print("now skipping %s" % skip)
        return
    elif cmd.startswith('noskip '):
        name = cmd.split(' ', 1)[1]
        del_skip(app, name)
        print("not skipping %s" % name)
        return
    elif cmd == 'src':
        if st.get('xml') is not None:
            print(st.get('xml'))
        if st.get('src') is not None:
            print(st.get('src'))
        return
    elif cmd == 'install':
        apputils.install(dev, app)
        return
    elif cmd == 'uninstall':
        apputils.uninstall(dev, app)
        return

    op = operation.parse_line(cmd)
    if op is None:
        print("unknown op")
        return

    ret = op.do(dev, ob, st, env, tlib)
    if not ret:
        print("op failed")
Beispiel #8
0
def uninstall(dev, appname):
    app = appdb.get_app(appname)
    dev.run_adb_shell("pm uninstall %s" % app)
    return True
Beispiel #9
0
 def set_app(self, appname):
     self.appname = appname
     self.app = appdb.get_app(appname)
Beispiel #10
0
                    else:
                        logger.error("ERROR! parent missing!")

    def dump(self):
        dumper = objdump.ObjDumper(self.props)
        return dumper.dump(self)

    def load(self, s):
        dumper = objdump.ObjDumper(self.props)
        return dumper.load(self, s)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    import appdb
    appdb.collect_apps("../apks/")

    serial = sys.argv[1]
    app = sys.argv[2]
    appname = appdb.get_app(app)

    import device
    dev = device.Device(serial=serial, no_uimon=True)

    webgrabber = WebGrabber(appname)
    pages = webgrabber.find_webviews(dev)
    for page in pages:
        webgrabber.capture_webnodes(dev, page, print_nodes=True)
        webgrabber.check_convert()
        webgrabber.clear()
Beispiel #11
0
    def do(self, dev, observer, state, env, tlib):
        logger.info("doing %s", self)
        perfmon.record_start("op", self)

        if self.name == 'call':
            realargs = []
            for arg in self.attr['args']:
                realargs.append(arg.get(env))

            return tlib.call(self.attr['func'], realargs, dev, observer, state)
        elif self.name == 'not':
            return not self.attr['op'].do(dev, observer, state, env, tlib)
        elif self.name == 'restart':
            appname = appdb.get_app(tlib.app)
            return microtest.restart_test(appname).attempt(
                dev, observer, state, tlib, env)

        widgets = []
        if self.target is not None:
            logger.info("finding target %s", self.target)
            perfmon.record_start("find", "%s" % self.target)
            state = observer.grab_state(dev)
            init_scr = state.get('screen')
            last_state = state
            for scroll_count in range(config.NOTFOUND_SCROLLDOWN_LIMIT):
                widgets = self.target.locate(state, observer, env)
                if widgets != []:
                    break

                if self.target.no_scroll():
                    logger.info("not found, scroll forbidden, fail")
                    perfmon.record_stop("find", "%s" % self.target)
                    return False

                logger.info("%s not found, scroll down", self.target)
                scroll_act = action.Action("scroll", {'direction': 'down'})
                if not scroll_act.do(dev, observer, env):
                    logger.info("nothing to scroll, fail")
                    perfmon.record_stop("find", "%s" % self.target)
                    return False
                state = observer.grab_state(dev, known_scr=init_scr)
                if state.same_as(last_state):
                    logger.info("scrolled to the bottom")
                    break

                # TODO: hack!
                tlib.handle_sys_screen(state, dev, observer)

            if widgets == []:
                for scroll_count in range(config.NOTFOUND_SCROLLUP_LIMIT):
                    widgets = self.target.locate(state, observer, env)
                    if widgets != []:
                        break

                    logger.info("%s not found, scroll up", self.target)
                    scroll_act = action.Action("scroll", {'direction': 'up'})
                    if not scroll_act.do(dev, observer, env):
                        logger.info("nothing to scroll, fail")
                        perfmon.record_stop("find", "%s" % self.target)
                        return False
                    state = observer.grab_state(dev, known_scr=init_scr)
                    if state.same_as(last_state):
                        logger.info("scrolled to the top")
                        break

                    # TODO: hack!
                    tlib.handle_sys_screen(state, dev, observer)

            if widgets == []:
                logger.warn("fail to find %s", self.target)
                return False

            perfmon.record_stop("find", "%s" % self.target)
            logger.info("found %s", widgets[0])

        actions = self.to_actions(widgets, env)
        if actions is None:
            return False
        for act in actions:
            ret = act.do(dev, observer, env)
            if not ret:
                return False
            # TODO: maybe wait for idle?
            time.sleep(0.1)

        usedtime = perfmon.record_stop("op", self)
        logger.info("%s finished %.3fs", self, usedtime)

        return True