def __start_async_logcat(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "adb -s {device_id} logcat -v time".format(device_id=self.source) logger.debug("Execute : %s", cmd) self.logcat_process = popen(cmd) self.logcat_reader_stdout = LogReader(self.logcat_process.stdout, self.compiled_regexp) self.drain_logcat_stdout = Drain(self.logcat_reader_stdout, self.phone_q) self.drain_logcat_stdout.start() self.phone_q_err=q.Queue() self.logcat_reader_stderr = LogReader(self.logcat_process.stderr, self.compiled_regexp) self.drain_logcat_stderr = Drain(self.logcat_reader_stderr, self.phone_q_err) self.drain_logcat_stderr.start()
def __start_async_log(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "{path}cfgutil -e {device_id} syslog".format( path=self.path_to_util, device_id=self.source) logger.debug("Execute : %s", cmd) self.log_process = popen(cmd) self.log_reader_stdout = LogReader(self.log_process.stdout, iphone_logevent_re) self.drain_log_stdout = Drain(self.log_reader_stdout, self.phone_q) self.drain_log_stdout.start() self.phone_q_err = q.Queue() self.log_reader_stderr = LogReader(self.log_process.stderr, iphone_logevent_re) self.drain_log_stderr = Drain(self.log_reader_stderr, self.phone_q_err) self.drain_log_stderr.start()
class AndroidOldPhone(Phone): """ Android Old phone worker class - work w/ phone, read phone logs, run test apps and store data Attributes: source (string): path to data source, phone id (adb devices) unplug_type (string): type of test execution `auto`: disable battery charge (by software) or use special USB cord limiting charge over USB `manual`: disable phone from USB by your own hands during test exection and click your test lightning_apk_path (string, optional): path to lightning app may be url, e.g. 'http://myhost.tld/path/to/file' may be path to file, e.g. '/home/users/netort/path/to/file.apk' lightning_apk_class (string, optional): lightning class test_apps (list, optional): list of apps to be installed to device for test test_class (string, optional): app class to be started during test execution test_package (string, optional): app package to be started during test execution test_runner (string, optional): app runner to be started during test execution Todo: unplug_type manual - remove raw_input() """ def __init__(self, config): """ Args: config (VoltaConfig): module configuration data """ Phone.__init__(self, config) self.logcat_stdout_reader = None self.logcat_stderr_reader = None # mandatory options self.source = config.get_option('phone', 'source') #self.unplug_type = config.get('unplug_type', 'auto') # lightning app configuration self.lightning_apk_path = config.get_option( 'phone', 'lightning', pkg_resources.resource_filename( 'volta.providers.phones', 'binary/lightning-new3.apk' ) ) self.lightning_apk_class = config.get_option('phone', 'lightning_class') self.lightning_apk_fname = None # test app configuration self.test_apps = config.get_option('phone', 'test_apps') self.test_class = config.get_option('phone', 'test_class') self.test_package = config.get_option('phone', 'test_package') self.test_runner = config.get_option('phone', 'test_runner') self.cleanup_apps = config.get_option('phone', 'cleanup_apps') self.regexp = config.get_option('phone', 'event_regexp', event_regexp) try: self.compiled_regexp = re.compile(self.regexp, re.VERBOSE | re.IGNORECASE) except: logger.debug('Unable to parse specified regexp', exc_info=True) raise RuntimeError("Unable to parse specified regexp") self.test_performer = None def prepare(self): """ Phone preparements stage: install apps etc pipeline: install lightning install apks clean log """ # apps cleanup for apk in self.cleanup_apps: execute("adb -s {device_id} uninstall {app}".format(device_id=self.source, app=apk)) # install lightning self.lightning_apk_fname = resource.get_opener(self.lightning_apk_path).get_filename logger.info('Installing lightning apk...') execute("adb -s {device_id} install -r -d -t {apk}".format(device_id=self.source, apk=self.lightning_apk_fname)) # install apks for apk in self.test_apps: apk_fname = resource.get_opener(apk).get_filename execute("adb -s {device_id} install -r -d -t {apk}".format(device_id=self.source, apk=apk_fname)) # clean logcat execute("adb -s {device_id} logcat -c".format(device_id=self.source)) # unplug device or start logcat #if self.unplug_type == 'manual': # logger.info('Detach the phone %s from USB and press enter to continue...', self.source) # # TODO make API and remove this # raw_input() def start(self, results): """ Grab stage: starts log reader, make sync w/ flashlight pipeline: if uplug_type is manual: remind user to start flashlight app if unplug_type is auto: start async logcat reader start lightning flashes Args: results (queue-like object): Phone should put there dataframes, format: ['sys_uts', 'message'] """ self.phone_q = results #if self.unplug_type == 'manual': # logger.info("It's time to start flashlight app!") # return #if self.unplug_type == 'auto': self.__start_async_logcat() # start flashes app execute( "adb -s {device_id} shell am start -n {package}/{runner}.MainActivity".format( device_id=self.source, package=self.lightning_apk_class, runner=self.lightning_apk_class ) ) logger.info('Waiting 15 seconds till flashlight app end its work...') time.sleep(15) return def __start_async_logcat(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "adb -s {device_id} logcat -v time".format(device_id=self.source) logger.debug("Execute : %s", cmd) self.logcat_process = popen(cmd) self.logcat_reader_stdout = LogReader(self.logcat_process.stdout, self.compiled_regexp) self.drain_logcat_stdout = Drain(self.logcat_reader_stdout, self.phone_q) self.drain_logcat_stdout.start() self.phone_q_err=q.Queue() self.logcat_reader_stderr = LogReader(self.logcat_process.stderr, self.compiled_regexp) self.drain_logcat_stderr = Drain(self.logcat_reader_stderr, self.phone_q_err) self.drain_logcat_stderr.start() def run_test(self): """ App stage: run app/phone tests """ if self.test_package: command = "adb -s {device_id} shell am instrument -w -e class {test_class} {test_package}/{test_runner}".format( test_class=self.test_class, device_id=self.source, test_package=self.test_package, test_runner=self.test_runner ) else: logger.info('Infinite loop for volta because there are no tests specified, waiting for SIGINT') command = 'while [ 1 ]; do sleep 1; done' self.test_performer = PhoneTestPerformer(command) self.test_performer.start() return def end(self): """ Stop test and grabbers """ if self.test_performer: self.test_performer.close() self.logcat_reader_stdout.close() self.logcat_reader_stderr.close() self.logcat_process.kill() self.drain_logcat_stdout.close() self.drain_logcat_stderr.close() # apps cleanup for apk in self.cleanup_apps: execute("adb -s {device_id} uninstall {app}".format(device_id=self.source, app=apk)) return def get_info(self): data = {} if self.drain_logcat_stdout: data['grabber_alive'] = self.drain_logcat_stdout.isAlive() if self.phone_q: data['grabber_queue_size'] = self.phone_q.qsize() if self.test_performer: data['test_performer_alive'] = self.test_performer.isAlive() return data
class AndroidPhone(Phone): """ Android phone worker class - work w/ phone, read phone logs, run test apps and store data Attributes: source (string): path to data source, phone id (adb devices) lightning_apk_path (string, optional): path to lightning app may be url, e.g. 'http://myhost.tld/path/to/file' may be path to file, e.g. '/home/users/netort/path/to/file.apk' lightning_apk_class (string, optional): lightning class test_apps (list, optional): list of apps to be installed to device for test test_class (string, optional): app class to be started during test execution test_package (string, optional): app package to be started during test execution test_runner (string, optional): app runner to be started during test execution """ def __init__(self, config): """ Args: config (VoltaConfig): module configuration data """ Phone.__init__(self, config) self.logcat_stdout_reader = None self.logcat_stderr_reader = None # mandatory options self.source = config.get_option('phone', 'source') # lightning app configuration self.lightning_apk_path = config.get_option( 'phone', 'lightning', pkg_resources.resource_filename('volta.providers.phones', 'binary/lightning-new3.apk')) self.lightning_apk_class = config.get_option('phone', 'lightning_class') self.lightning_apk_fname = None # test app configuration self.test_apps = config.get_option('phone', 'test_apps') self.test_class = config.get_option('phone', 'test_class') self.test_package = config.get_option('phone', 'test_package') self.test_runner = config.get_option('phone', 'test_runner') self.regexp = config.get_option('phone', 'event_regexp', event_regexp) try: self.compiled_regexp = re.compile(self.regexp, re.VERBOSE | re.IGNORECASE) except: logger.debug('Unable to parse specified regexp', exc_info=True) raise RuntimeError("Unable to parse specified regexp") self.drain_logcat_stdout = None self.test_performer = None def prepare(self): """ Phone preparements stage: install apps etc pipeline: install lightning install apks clean log """ # install lightning self.lightning_apk_fname = resource.get_opener( self.lightning_apk_path).get_filename logger.info('Installing lightning apk...') execute("adb -s {device_id} install -r -d -t {apk}".format( device_id=self.source, apk=self.lightning_apk_fname)) # install apks for apk in self.test_apps: apk_fname = resource.get_opener(apk).get_filename execute("adb -s {device_id} install -r -d -t {apk}".format( device_id=self.source, apk=apk_fname)) # clean logcat execute("adb -s {device_id} logcat -c".format(device_id=self.source)) def start(self, results): """ Grab stage: starts log reader, make sync w/ flashlight Args: results (queue-like object): Phone should put there dataframes, format: ['sys_uts', 'message'] """ self.phone_q = results self.__start_async_logcat() # start flashes app execute( "adb -s {device_id} shell am start -n {package}/{runner}.MainActivity" .format(device_id=self.source, package=self.lightning_apk_class, runner=self.lightning_apk_class)) return def __start_async_logcat(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "adb -s {device_id} logcat".format(device_id=self.source) logger.debug("Execute : %s", cmd) self.logcat_process = popen(cmd) self.logcat_reader_stdout = LogReader(self.logcat_process.stdout, self.compiled_regexp) self.drain_logcat_stdout = Drain(self.logcat_reader_stdout, self.phone_q) self.drain_logcat_stdout.start() self.phone_q_err = q.Queue() self.logcat_reader_stderr = LogReader(self.logcat_process.stderr, self.compiled_regexp) self.drain_logcat_stderr = Drain(self.logcat_reader_stderr, self.phone_q_err) self.drain_logcat_stderr.start() def run_test(self): """ App stage: run app/phone tests """ if self.test_package: command = "adb -s {device_id} shell am instrument -w -e class {test_class} {test_package}/{test_runner}".format( test_class=self.test_class, device_id=self.source, test_package=self.test_package, test_runner=self.test_runner) else: logger.info( 'Infinite loop for volta because there are no tests specified, waiting for SIGINT' ) command = 'while [ 1 ]; do sleep 1; done' self.test_performer = PhoneTestPerformer(command) self.test_performer.start() return def end(self): """ Stop test and grabbers """ if self.test_performer: self.test_performer.close() self.logcat_reader_stdout.close() self.logcat_reader_stderr.close() self.logcat_process.kill() self.drain_logcat_stdout.close() self.drain_logcat_stderr.close() return def get_info(self): data = {} if self.drain_logcat_stdout: data['grabber_alive'] = self.drain_logcat_stdout.isAlive() if self.phone_q: data['grabber_queue_size'] = self.phone_q.qsize() if self.test_performer: data['test_performer_alive'] = self.test_performer.isAlive() return data
class AndroidPhone(Phone): """ Android phone worker class - work w/ phone, read phone logs, run test apps and store data Attributes: source (string): path to data source, phone id (adb devices) unplug_type (string): type of test execution `auto`: disable battery charge (by software) or use special USB cord limiting charge over USB `manual`: disable phone from USB by your own hands during test exection and click your test lightning_apk_path (string, optional): path to lightning app may be url, e.g. 'http://myhost.tld/path/to/file' may be path to file, e.g. '/home/users/netort/path/to/file.apk' lightning_apk_class (string, optional): lightning class test_apps (list, optional): list of apps to be installed to device for test test_class (string, optional): app class to be started during test execution test_package (string, optional): app package to be started during test execution test_runner (string, optional): app runner to be started during test execution Todo: unplug_type manual - remove raw_input() """ def __init__(self, config): """ Args: config (dict): module configuration data """ Phone.__init__(self, config) self.logcat_stdout_reader = None self.logcat_stderr_reader = None # mandatory options self.source = config.get('source', '00dc3419957ba583') self.unplug_type = config.get('unplug_type', 'auto') # lightning app configuration self.lightning_apk_path = config.get( 'lightning', pkg_resources.resource_filename('volta.providers.phones', 'binary/lightning-new3.apk')) self.lightning_apk_class = config.get('lightning_class', 'net.yandex.overload.lightning') self.lightning_apk_fname = None # test app configuration self.test_apps = config.get('test_apps', []) self.test_class = config.get('test_class', '') self.test_package = config.get('test_package', '') self.test_runner = config.get('test_runner', '') def prepare(self): """ Phone preparements stage: install apps etc pipeline: install lightning install apks clean log """ # install lightning self.lightning_apk_fname = resource.get_opener( self.lightning_apk_path).get_filename logger.info('Installing lightning apk...') execute("adb -s {device_id} install -r -d -t {apk}".format( device_id=self.source, apk=self.lightning_apk_fname)) # install apks for apk in self.test_apps: apk_fname = resource.get_opener(apk).get_filename execute("adb -s {device_id} install -r -d -t {apk}".format( device_id=self.source, apk=apk_fname)) # clean logcat execute("adb -s {device_id} logcat -c".format(device_id=self.source)) # unplug device or start logcat if self.unplug_type == 'manual': logger.info( 'Detach the phone %s from USB and press enter to continue...', self.source) # TODO make API and remove this raw_input() def start(self, results): """ Grab stage: starts log reader, make sync w/ flashlight pipeline: if uplug_type is manual: remind user to start flashlight app if unplug_type is auto: start async logcat reader start lightning flashes Args: results (queue-like object): Phone should put there dataframes, format: ['sys_uts', 'message'] """ self.phone_q = results if self.unplug_type == 'manual': logger.info("It's time to start flashlight app!") return if self.unplug_type == 'auto': self.__start_async_logcat() # start flashes app execute( "adb -s {device_id} shell am start -n {package}/{runner}.MainActivity" .format(device_id=self.source, package=self.lightning_apk_class, runner=self.lightning_apk_class)) return def __start_async_logcat(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "adb -s {device_id} logcat".format(device_id=self.source) logger.debug("Execute : %s", cmd) self.logcat_process = popen(cmd) self.logcat_reader_stdout = LogReader(self.logcat_process.stdout, android_logevent_re) self.drain_logcat_stdout = Drain(self.logcat_reader_stdout, self.phone_q) self.drain_logcat_stdout.start() self.phone_q_err = q.Queue() self.logcat_reader_stderr = LogReader(self.logcat_process.stderr, android_logevent_re) self.drain_logcat_stderr = Drain(self.logcat_reader_stderr, self.phone_q_err) self.drain_logcat_stderr.start() def run_test(self): """ App stage: run app/phone tests, pipeline: if unplug_type is auto: run test if unplug_type is manual: skip """ if self.unplug_type == 'manual': return if self.unplug_type == 'auto': execute( "adb shell am instrument -w -e class {test_class} {test_package}/{test_runner}" .format(test_class=self.test_class, test_package=self.test_package, test_runner=self.test_runner)) return def end(self): """ Stop test and grabbers pipeline: if uplug_type is manual: ask user to plug device in get logcat dump from device if unplug_type is auto: stop async logcat process, readers and queues """ if self.unplug_type == 'manual': logger.warning( "Plug the phone in and press `enter` to continue...") # TODO make API and remove this raw_input() _, stdout, stderr = execute( "adb -s {device_id} logcat -d".format(device_id=self.source), catch_out=True) logger.debug('Recieved %d logcat data', len(stdout)) self.phone_q.put(chunk_to_df(stdout, android_logevent_re)) return if self.unplug_type == 'auto': self.logcat_reader_stdout.close() self.logcat_reader_stderr.close() self.logcat_process.kill() self.drain_logcat_stdout.close() self.drain_logcat_stderr.close() return
class Nexus4(Phone): """ Android phone worker class - work w/ phone, read phone logs, run test apps and store data Attributes: source (string): path to data source, phone id (adb devices) unplug_type (string): type of test execution `auto`: disable battery charge (by software) or use special USB cord limiting charge over USB `manual`: disable phone from USB by your own hands during test exection and click your test lightning_apk_path (string, optional): path to lightning app may be url, e.g. 'http://myhost.tld/path/to/file' may be path to file, e.g. '/home/users/netort/path/to/file.apk' lightning_apk_class (string, optional): lightning class test_apps (list, optional): list of apps to be installed to device for test test_class (string, optional): app class to be started during test execution test_package (string, optional): app package to be started during test execution test_runner (string, optional): app runner to be started during test execution Todo: unplug_type manual - remove raw_input() """ def __init__(self, config): """ Args: config (dict): module configuration data """ Phone.__init__(self, config) self.logcat_stdout_reader = None self.logcat_stderr_reader = None # mandatory options self.source = config.get('source', '01dd6e7352c97826') self.unplug_type = config.get('unplug_type', 'auto') # lightning app configuration self.lightning_apk_path = config.get('lightning', pkg_resources.resource_filename( 'volta.providers.phones', 'binary/lightning-new3.apk') ) logger.info('lightning_apk_path '+self.lightning_apk_path) self.blink_delay = config.get('blink_delay', 0) self.blink_toast = config.get('blink_toast', 0) self.lightning_apk_class = config.get('lightning_class', 'net.yandex.overload.lightning') self.lightning_apk_fname = None # test app configuration self.test_apps = config.get('test_apps', []) self.test_class = config.get('test_class', '') self.test_package = config.get('test_package', '') self.test_runner = config.get('test_runner', '') def prepare(self): """ Phone preparements stage: install apps etc pipeline: install lightning install apks clean log """ # install lightning self.lightning_apk_fname = resource.get_opener(self.lightning_apk_path).get_filename logger.info('Installing lightning apk '+self.lightning_apk_fname) execute("adb -s {device_id} install -r -d -t {apk}".format(device_id=self.source, apk=self.lightning_apk_fname)) # install apks for apk in self.test_apps: apk_fname = resource.get_opener(apk).get_filename execute("adb -s {device_id} install -r -d -t {apk}".format(device_id=self.source, apk=apk_fname)) # clean logcat execute("adb -s {device_id} logcat -c".format(device_id=self.source)) def start(self, results): """ Grab stage: starts log reader, make sync w/ flashlight pipeline: if unplug_type is manual: remind user to start flashlight app if unplug_type is auto: start async logcat reader start lightning flashes Args: results (queue-like object): Phone should put there dataframes, format: ['sys_uts', 'message'] """ self.phone_q = results self.__start_async_logcat() # start flashes app execute( "adb -s {device_id} shell am startservice -a BLINK --ei DELAY 10000 -n com.yandex.pmu_blinker/.PmuIntentService".format( device_id=self.source, ) ) return def __start_async_logcat(self): """ Start logcat read in subprocess and make threads to read its stdout/stderr to queues """ cmd = "adb -s {device_id} logcat -v time".format(device_id=self.source) logger.debug("Execute : %s", cmd) self.logcat_process = popen(cmd) self.logcat_reader_stdout = LogReader(self.logcat_process.stdout, android_logevent_re) self.drain_logcat_stdout = Drain(self.logcat_reader_stdout, self.phone_q) self.drain_logcat_stdout.start() self.phone_q_err=q.Queue() self.logcat_reader_stderr = LogReader(self.logcat_process.stderr, android_logevent_re) self.drain_logcat_stderr = Drain(self.logcat_reader_stderr, self.phone_q_err) self.drain_logcat_stderr.start() def run_test(self): """ App stage: run app/phone tests, pipeline: if unplug_type is auto: run test if unplug_type is manual: skip """ #execute( # "adb shell am instrument -w -e class {test_class} {test_package}/{test_runner}".format( # test_class=self.test_class, # test_package=self.test_package, # test_runner=self.test_runner # ) #) return def end(self): """ Stop test and grabbers pipeline: if uplug_type is manual: ask user to plug device in get logcat dump from device if unplug_type is auto: stop async logcat process, readers and queues """ self.logcat_reader_stdout.close() self.logcat_reader_stderr.close() self.logcat_process.kill() self.drain_logcat_stdout.close() self.drain_logcat_stderr.close() return