def __run_webapi_test(self, latest_dir): """ run webAPI test""" if self.bdryrun: LOGGER.info("[ WRTLauncher mode does not support dryrun ]") return True list_auto = [] list_manual = [] for i in self.exe_sequence: if i[-4::1] == "auto": list_auto.append(i) if i[-6::1] == "manual": list_manual.append(i) list_auto.sort() list_manual.sort() self.exe_sequence = [] self.exe_sequence.extend(list_auto) self.exe_sequence.extend(list_manual) for webapi_total_file in self.exe_sequence: for webapi_file in self.testsuite_dict[webapi_total_file]: # print identical xml file name if self.current_test_xml != JOIN(latest_dir, webapi_total_file): time.sleep(3) LOGGER.info("\n[ testing xml: %s.xml ]\n" % JOIN(latest_dir, webapi_total_file)) self.current_test_xml = JOIN(latest_dir, webapi_total_file) self.__run_with_commodule(webapi_file)
def __run_with_commodule(self, webapi_file): """run_with_commodule,Initialization,check status,get result""" try: # prepare test set list test_xml_set_list = self.__split_xml_to_set(webapi_file) # create temporary parameter for test_xml_set in test_xml_set_list: LOGGER.info("\n[ run set: %s ]" % test_xml_set) # prepare the test JSON self.__prepare_external_test_json(test_xml_set) # init test here init_status = self.__init_com_module(test_xml_set) if not init_status: continue # send set JSON Data to com_module self.testworker.run_test( self.session_id, self.set_parameters) while True: time.sleep(1) # check the test status ,if the set finished,get # the set_result,and finalize_test if self.__check_test_status(): set_result = self.testworker.get_test_result( self.session_id) # write_result to set_xml self.__write_set_result( test_xml_set, set_result) # shut down server self.finalize_test(self.session_id) break except IOError as error: LOGGER.error( "[ Error: fail to run webapi test xml, error: %s ]" % error)
def killall(ppid): """Kill all children process by parent process ID""" sys_platform = platform.system() try: if sys_platform == "Linux": ppid = str(ppid) pidgrp = [] def getchildpids(ppid): """Return a list of children process""" command = "ps -ef | awk '{if ($3 == %s) print $2;}'" % str(ppid) pids = os.popen(command).read() pids = pids.split() return pids pidgrp.extend(getchildpids(ppid)) for pid in pidgrp: pidgrp.extend(getchildpids(pid)) # Insert self process ID to PID group list pidgrp.insert(0, ppid) while len(pidgrp) > 0: pid = pidgrp.pop() try: os.kill(int(pid), signal.SIGKILL) except OSError, error: pattern = re.compile('No such process') match = pattern.search(str(error)) if not match: LOGGER.info( "[ Error: fail to kill pid: %s, error: %s ]\n" % ( int(pid), error)) # kill for windows platform else:
def run_test(self, sessionid, test_set): """ process the execution for a test set """ if sessionid is None: return False if not "cases" in test_set: return False # start debug trace thread dlogfile = test_set['current_set_name'].replace('.xml', '.dlog') self.opts['dlog_file'] = dlogfile self.conn.start_debug(dlogfile) time.sleep(1) self.result_obj = TestSetResut( self.opts['testsuite_name'], self.opts['testset_name']) cases, exetype, ctype = test_set[ "cases"], test_set["exetype"], test_set["type"] if self.opts['test_type'] == "webapi": return self.__run_web_test(sessionid, self.opts['testset_name'], exetype, ctype, cases) elif self.opts['test_type'] == "coreapi": return self.__run_core_test(sessionid, self.opts['testset_name'], exetype, cases) elif self.opts['test_type'] == "jqunit": return self.__run_jqt_test(sessionid, self.opts['testset_name'], cases) else: LOGGER.info("[ unsupported test suite type ! ]") return False
def __prepare_result_file(self, testxmlfile, resultfile): """ write the test_xml content to resultfile""" try: parse_tree = etree.parse(testxmlfile) suiteparent = parse_tree.getroot() no_test_definition = 1 if parse_tree.getiterator('test_definition'): no_test_definition = 0 if no_test_definition: suiteparent = etree.Element('test_definition') suiteparent.tail = "\n" for suite in parse_tree.getiterator('suite'): suite.tail = "\n" suiteparent.append(suite) self.apply_filter(suiteparent) try: with open(resultfile, 'w') as output: tree = etree.ElementTree(element=suiteparent) tree.write(output) except IOError as error: LOGGER.error("[ Error: create filtered result file: %s failed,\ error: %s ]" % (resultfile, error)) except IOError as error: LOGGER.error(error) return False
def __get_test_options(self, deviceid, test_launcher, test_suite): """get test option dict """ test_opt = {} test_opt["suite_name"] = test_suite cmd = "" if test_launcher.find("WRTLauncher") != -1: test_opt["launcher"] = "wrt-launcher" # test suite need to be installed by commodule if self.__test_auto_iu: test_wgt = self.__test_wgt cmd = WRT_INSTALL_STR % (deviceid, test_suite, test_wgt) exit_code, ret = shell_command(cmd) else: test_wgt = test_suite # query the whether test widget is installed ok cmd = WRT_QUERY_STR % (deviceid, test_wgt) exit_code, ret = shell_command(cmd) if len(ret) == 0: LOGGER.info('[ test widget "%s" not installed in target ]' % test_wgt) return None else: test_opt["suite_id"] = ret[0].strip("\r\n") self.__test_wgt = test_opt["suite_id"] else: test_opt["launcher"] = test_launcher return test_opt
def prepare_run(self, testxmlfile, resultdir=None): """ testxmlfile: target testxml file execdir and resultdir: should be the absolute path since TRunner is the common lib """ # resultdir is set to current directory by default if not resultdir: resultdir = os.getcwd() ok_prepare = True if ok_prepare: try: filename = testxmlfile filename = os.path.splitext(filename)[0] if platform.system() == "Linux": filename = filename.split('/')[-2] else: filename = filename.split('\\')[-2] if self.filter_rules["execution_type"] == ["manual"]: resultfile = "%s.manual.xml" % filename else: resultfile = "%s.auto.xml" % filename resultfile = JOIN(resultdir, resultfile) if not EXISTS(resultdir): os.mkdir(resultdir) LOGGER.info("[ analysis test xml file: %s ]" % resultfile) self.__prepare_result_file(testxmlfile, resultfile) self.__split_test_xml(resultfile, resultdir) except IOError as error: LOGGER.error(error) ok_prepare &= False return ok_prepare
def finalize_test(self, sessionid): '''shut_down testkit-stub''' try: self.testworker.finalize_test(sessionid) except Exception as error: LOGGER.error("[ Error: fail to close webapi http server, " "error: %s ]" % error)
def __prepare_starup_parameters(self, testxml): """ prepare_starup_parameters """ starup_parameters = {} LOGGER.info("[ prepare_starup_parameters ]") try: parse_tree = etree.parse(testxml) tsuite = parse_tree.getroot().getiterator('suite')[0] tset = parse_tree.getroot().getiterator('set')[0] if tset.get("launcher") is not None: starup_parameters['test-launcher'] = tset.get("launcher") else: starup_parameters['test-launcher'] = tsuite.get("launcher") starup_parameters['testsuite-name'] = tsuite.get("name") starup_parameters['testset-name'] = tset.get("name") starup_parameters['stub-name'] = self.stub_name if self.external_test is not None: starup_parameters['external-test'] = self.external_test starup_parameters['debug'] = self.debug starup_parameters['test_prefix'] = self.test_prefix if self.rerun: starup_parameters['rerun'] = self.rerun if len(self.capabilities) > 0: starup_parameters['capability'] = self.capabilities except IOError as error: LOGGER.error( "[ Error: prepare starup parameters, error: %s ]" % error) return starup_parameters
def _upload_file(deviceid, remote_path, local_path): """upload file to device""" cmd = "sdb -s %s push %s %s" % (deviceid, local_path, remote_path) exit_code, result = shell_command(cmd) if exit_code != 0: LOGGER.info('[ Upload file "%s" failed,' " get error: %s ]" % (local_path, result)) return False else: return True
def _download_file(deviceid, remote_path, local_path): """download file from device""" cmd = "sdb -s %s pull %s %s" % (deviceid, remote_path, local_path) exit_code, ret = shell_command(cmd) if exit_code != 0: LOGGER.info('[ Download file "%s" from target failed, error: %s ]' % (remote_path, ret[0].strip("\r\n"))) return False else: return True
def download_file(self, remote_path, local_path): """download file from device""" cmd = "adb -s %s pull %s %s" % (self.deviceid, remote_path, local_path) exit_code, ret = shell_command(cmd) if exit_code != 0: error = ret[0].strip('\r\n') if len(ret) else "sdb shell timeout" LOGGER.info("[ Download file \"%s\" failed, error: %s ]" % (remote_path, error)) return False else: return True
def upload_file(self, remote_path, local_path): """upload file to device""" cmd = "sdb -s %s push %s %s" % (self.deviceid, local_path, remote_path) exit_code, ret = shell_command(cmd) if exit_code != 0: error = ret[0].strip('\r\n') if len(ret) else "sdb shell timeout" LOGGER.info("[ Upload file \"%s\" failed," " get error: %s ]" % (local_path, error)) return False else: return True
def get_test_result(self, sessionid): """get the test result for a test set """ result = {} if sessionid is None: return result try: global TEST_SERVER_RESULT LOCK_OBJ.acquire() result = TEST_SERVER_RESULT LOCK_OBJ.release() except OSError, error: LOGGER.error("[ Error: failed to get test result, error:%s ]\n" % error)
def write_json_result(set_result_xml, set_result): ''' fetch result form JSON''' case_results = set_result["cases"] try: parse_tree = etree.parse(set_result_xml) root_em = parse_tree.getroot() dubug_file = os.path.basename(set_result_xml) dubug_file = os.path.splitext(dubug_file)[0] + '.dlog' for tset in root_em.getiterator('set'): tset.set("set_debug_msg", dubug_file) for tcase in tset.getiterator('testcase'): for case_result in case_results: if tcase.get("id") == case_result['case_id']: tcase.set('result', case_result['result'].upper()) # Check performance test if tcase.find('measurement') is not None: for measurement in tcase.getiterator( 'measurement'): if 'measures' in case_result: m_results = case_result['measures'] for m_result in m_results: if measurement.get('name') == \ m_result['name'] and 'value' in m_result: measurement.set( 'value', m_result[ 'value']) if tcase.find("./result_info") is not None: tcase.remove(tcase.find("./result_info")) result_info = etree.SubElement(tcase, "result_info") actual_result = etree.SubElement( result_info, "actual_result") actual_result.text = case_result['result'].upper() start = etree.SubElement(result_info, "start") end = etree.SubElement(result_info, "end") stdout = etree.SubElement(result_info, "stdout") stderr = etree.SubElement(result_info, "stderr") if 'start_at' in case_result: start.text = case_result['start_at'] if 'end_at' in case_result: end.text = case_result['end_at'] if 'stdout' in case_result: stdout.text = str2xmlstr(case_result['stdout']) if 'stderr' in case_result: stderr.text = str2xmlstr(case_result['stderr']) parse_tree.write(set_result_xml) LOGGER.info("[ cases result saved to resultfile ]\n") except IOError as error: traceback.print_exc() LOGGER.error( "[ Error: fail to write cases result, error: %s ]\n" % error)
def kill_testkit_lite(pid_file): """ kill testkit lite""" try: with open(pid_file, "r") as pidfile: pid = pidfile.readline().rstrip("\n") if pid: killall(pid) except IOError, error: pattern = re.compile('No such file or directory|No such process') match = pattern.search(str(error)) if not match: LOGGER.info("[ Error: fail to kill existing testkit-lite, "\ "error: %s ]\n" % error)
def extend_result(self, cases_result=None, print_out=True): """update cases result to the result buffer""" self._mutex.acquire() if cases_result is not None: self._result["cases"].extend(cases_result) if print_out: for case_it in cases_result: LOGGER.info(self._progress % (self._suite_name, case_it['case_id'], case_it['result'])) if case_it['result'].lower() in ['fail', 'block'] and 'stdout' in case_it: LOGGER.info(case_it['stdout']) self._mutex.release()
def __run_web_test(self, sessionid, test_set_name, exetype, ctype, cases): """ process the execution for web api test may be splitted to serveral blocks, with the unit size defined by block_size """ if self.__test_self_exec: self.__test_async_shell = QUTestExecThread(deviceid=self.__device_id, sessionid=sessionid) self.__test_async_shell.start() return True if self.__test_self_repeat: global TEST_SERVER_RESULT, TEST_SERVER_STATUS result_file = os.path.expanduser("~") + os.sep + sessionid + "_uifw.xml" b_ok = _download_file(self.__device_id, UIFW_RESULT, result_file) LOGGER.info("[ web uifw test suite result splitting ...]") if b_ok: TEST_SERVER_RESULT = {"resultfile": result_file} TEST_SERVER_STATUS = {"finished": 1} else: TEST_SERVER_RESULT = {"resultfile": ""} TEST_SERVER_STATUS = {"finished": 1} return True case_count = len(cases) blknum = 0 if case_count % self.__test_set_block == 0: blknum = case_count / self.__test_set_block else: blknum = case_count / self.__test_set_block + 1 idx = 1 test_set_blocks = [] while idx <= blknum: block_data = {} block_data["exetype"] = exetype block_data["type"] = ctype block_data["totalBlk"] = str(blknum) block_data["currentBlk"] = str(idx) block_data["casecount"] = str(case_count) start = (idx - 1) * self.__test_set_block if idx == blknum: end = case_count else: end = idx * self.__test_set_block block_data["cases"] = cases[start:end] test_set_blocks.append(block_data) idx += 1 self.__test_async_http = WebTestExecThread(self.__stub_server_url, test_set_name, test_set_blocks) self.__test_async_http.start() return True
def __run_core_auto(self): """ core auto cases run""" self.core_auto_files.sort() for core_auto_file in self.core_auto_files: temp_test_xml = os.path.splitext(core_auto_file)[0] temp_test_xml = os.path.splitext(temp_test_xml)[0] temp_test_xml = os.path.splitext(temp_test_xml)[0] temp_test_xml += ".auto" # print identical xml file name if self.current_test_xml != temp_test_xml: time.sleep(3) LOGGER.info("\n[ testing xml: %s.xml ]" % temp_test_xml) self.current_test_xml = temp_test_xml self.__run_with_commodule(core_auto_file)
def __init_webtest_opt(self, params): """init the test runtime, mainly process the star up of test stub""" if params is None: return None session_id = str(uuid.uuid1()) cmdline = "" debug_opt = "" stub_app = params.get('stub-name', 'testkit-stub') stub_port = params.get('stub-port', '8000') test_launcher = params.get('external-test', '') testsuite_name = params.get('testsuite-name', '') testset_name = params.get('testset-name', '') capability_opt = params.get("capability", None) client_cmds = params.get('test-launcher', '').strip().split() wrt_tag = client_cmds[1] if len(client_cmds) > 1 else "" self.opts['fuzzy_match'] = fuzzy_match = wrt_tag.find('z') != -1 self.opts['auto_iu'] = auto_iu = wrt_tag.find('iu') != -1 self.opts['self_exec'] = wrt_tag.find('a') != -1 self.opts['self_repeat'] = wrt_tag.find('r') != -1 self.opts['debug_mode'] = params.get("debug", False) test_opt = self.conn.get_launcher_opt( test_launcher, testsuite_name, testset_name, fuzzy_match, auto_iu) if test_opt is None: LOGGER.info("[ init the test options, get failed ]") return None # to be removed in later version test_opt["suite_id"] = test_opt["test_app_id"] self.opts.update(test_opt) # uifw, this suite don't need stub if self.opts['self_exec'] or self.opts['self_repeat']: self.opts['test_type'] = "jqunit" return session_id # enable debug information if self.opts['debug_mode']: debug_opt = '--debug' if self.__init_test_stub(stub_app, stub_port, debug_opt): ret = http_request(get_url( self.server_url, "/init_test"), "POST", test_opt) if ret is None: LOGGER.info("[ init test suite failed! ]") return None elif "error_code" in ret: LOGGER.info("[ init test suite, " "get error code %d ! ]" % ret["error_code"]) return None if capability_opt is not None: ret = http_request(get_url(self.server_url, "/set_capability"), "POST", capability_opt) return session_id else: LOGGER.info("[ Init test failed ! ]") return None
def __init_com_module(self, testxml): """ send init test to com_module if webapi test,com_module will start testkit-stub else com_module send the test case to devices """ starup_prms = self.__prepare_starup_parameters(testxml) # init stub and get the session_id session_id = self.testworker.init_test(starup_prms) if session_id == None: LOGGER.error("[ Error: Initialization Error]") return False else: self.set_session_id(session_id) return True
def replace_cdata(file_name): """ replace some character""" try: abs_path = mktemp() new_file = open(abs_path, 'w') old_file = open(file_name) for line in old_file: line_temp = line.replace('<![CDATA', '<![CDATA') new_file.write(line_temp.replace(']]>', ']]>')) new_file.close() old_file.close() remove(file_name) move(abs_path, file_name) except IOError as error: LOGGER.error("[ Error: fail to replace cdata in the result file, " "error: %s ]\n" % error)
def __run_core_manual(self): """ core manual cases run """ self.core_manual_files.sort() for core_manual_file in self.core_manual_files: temp_test_xml = os.path.splitext(core_manual_file)[0] temp_test_xml = os.path.splitext(temp_test_xml)[0] temp_test_xml = os.path.splitext(temp_test_xml)[0] temp_test_xml += ".manual" # print identical xml file name if self.current_test_xml != temp_test_xml: time.sleep(3) LOGGER.info("\n[ testing xml: %s.xml ]" % temp_test_xml) self.current_test_xml = temp_test_xml if self.non_active: self.skip_all_manual = True else: self.__run_with_commodule(core_manual_file)
def get_launcher_opt(self, test_launcher, test_suite, test_set, fuzzy_match, auto_iu): """ get test option dict """ test_opt = {} test_opt["suite_name"] = test_suite test_opt["launcher"] = test_launcher test_opt["test_app_id"] = test_launcher self._wrt = False if test_launcher.find('WRTLauncher') != -1: self._wrt = True cmd = "" test_app_id = None test_opt["launcher"] = "wrt-launcher" # test suite need to be installed by commodule if auto_iu: test_wgt = test_set test_wgt_path = "/opt/usr/media/tct/opt/%s/%s.wgt" % (test_suite, test_wgt) if not self.install_app(test_wgt_path): LOGGER.info("[ failed to install widget \"%s\" in target ]" % test_wgt) return None else: test_wgt = test_suite # query the whether test widget is installed ok cmd = WRT_QUERY_STR % (self.deviceid, test_wgt) exit_code, ret = shell_command(cmd) if exit_code == -1: return None for line in ret: items = line.split(':') if len(items) < 1: continue if (fuzzy_match and items[0].find(test_wgt) != -1) or items[0] == test_wgt: test_app_id = items[1].strip('\r\n') break if test_app_id is None: LOGGER.info("[ test widget \"%s\" not found in target ]" % test_wgt) return None else: test_opt["test_app_id"] = test_app_id return test_opt
def _get_test_options(test_launcher, test_suite): """get test option dict """ test_opt = {} if test_launcher.find('WRTLauncher') != -1: test_opt["launcher"] = "wrt-launcher" cmd = "wrt-launcher -l | grep %s | awk '{print $NF}'" % test_suite exit_code, ret = shell_command(cmd) if len(ret) == 0: LOGGER.info("[ test suite \"%s\" not found in target ]" % test_suite) return None else: test_opt["suite_id"] = ret[0].strip('\r\n') else: test_opt["launcher"] = test_launcher test_opt["suite_name"] = test_suite return test_opt
def get_capability(self, file_name): """get_capability from file """ capability_xml = file_name capabilities = {} try: parse_tree = etree.parse(capability_xml) root_em = parse_tree.getroot() for tcap in root_em.getiterator('capability'): capability = get_capability_form_node(tcap) capabilities = dict(capabilities, **capability) self.set_capability(capabilities) return True except IOError as error: LOGGER.error( "[ Error: fail to parse capability xml, error: %s ]" % error) return False
def get_version_info(): """ get testkit tool version ,just read the version in VERSION file VERSION file must put in /opt/testkit/lite/ """ try: config = ConfigParser.ConfigParser() if platform.system() == "Linux": config.read('/opt/testkit/lite/VERSION') else: version_file = os.path.join(sys.path[0], 'VERSION') config.read(version_file) version = config.get('public_version', 'version') return version except KeyError as error: LOGGER.error( "[ Error: fail to parse version info, error: %s ]\n" % error) return ""
def download_file(self, remote_path, local_path): """download file from device""" local_path_dir = os.path.dirname(local_path) if not os.path.exists(local_path_dir): os.makedirs(local_path_dir) filename = os.path.basename(remote_path) cmd = "sdb -s %s pull %s %s" % ( self.deviceid, remote_path, local_path_dir) exit_code, ret = shell_command(cmd) if exit_code != 0: error = ret[0].strip('\r\n') if len(ret) else "sdb shell timeout" LOGGER.info("[ Download file \"%s\" failed, error: %s ]" % (remote_path, error)) return False else: src_path = os.path.join(local_path_dir, filename) if src_path != local_path: shutil.move(src_path, local_path) return True
def __splite_external_test(self, resultfile, test_file_name, resultdir): """select external_test""" testsuite_dict_value_list = [] testsuite_dict_add_flag = 0 filename_diff = 1 parser = etree.parse(resultfile) for tsuite in parser.getiterator('suite'): root = etree.Element('test_definition') suitefilename = os.path.splitext(resultfile)[0] suitefilename += ".suite_%s.xml" % filename_diff suitefilename = JOIN(resultdir, suitefilename) tsuite.tail = "\n" root.append(tsuite) try: with open(suitefilename, 'w') as output: tree = etree.ElementTree(element=root) tree.write(output) except IOError as error: LOGGER.error("[ Error: create filtered result file: %s failed,\ error: %s ]" % (suitefilename, error)) case_suite_find = etree.parse( suitefilename).getiterator('testcase') if case_suite_find: if tsuite.get('launcher'): if tsuite.get('launcher').find('WRTLauncher'): self.__splite_core_test(suitefilename) else: testsuite_dict_value_list.append(suitefilename) if testsuite_dict_add_flag == 0: self.exe_sequence.append(test_file_name) testsuite_dict_add_flag = 1 self.resultfiles.add(suitefilename) else: if self.filter_rules["execution_type"] == ["auto"]: self.core_auto_files.append(suitefilename) else: self.core_manual_files.append(suitefilename) self.resultfiles.add(suitefilename) filename_diff += 1 if testsuite_dict_add_flag: self.testsuite_dict[test_file_name] = testsuite_dict_value_list
def _print_dlog(dlog_file): if os.path.exists(dlog_file): LOGGER.info('[ start of dlog message ]') readbuff = file(dlog_file, "r") for line in readbuff.readlines(): LOGGER.info(line.strip('\n')) LOGGER.info('[ end of dlog message ]')