def generate_high_light(doc_dir): ''' This is new fun, Invoked by project.get ,then loaded in editor.html. ''' log.info("生成高亮显示 js ...") project = get_projectnamefromkey(doc_dir) kwd = os.getcwd() + "/keyword/" + project jsd = os.getcwd() + "/auto/www/static/js/" + project if not os.path.exists(jsd): mk_dirs(jsd) if not os.path.exists(kwd): mk_dirs(kwd) ff = codecs.open(jsd + "/highlight.js", "w", "utf-8") keyword_list = [] keys = os.listdir(kwd) for k in keys: if not k.endswith('.xml'): continue path = kwd + "/" + k tree = ET.parse(path) root = tree.getroot() name = root.attrib["name"] for kw in root.iter("kw"): # 关键字 keyword_list.append("'" + kw.attrib["name"] + "'") keyword_list = list(set(keyword_list)) keyword_list.sort(key=len, reverse=True) keywords = "var high_light=" + "[" + ",".join(keyword_list) + "];" ff.write(keywords) ff.close()
def run(self): #lock = threading.Lock() # self.lock.acquire() if not exists_path(self.output): mk_dirs(self.output) self.suite = TestSuiteBuilder().build(self.project) (output, index) = self.reset_next_build_numb() self.setName(output) self.result = self.suite.run(output_directory=output, output=output + "/output.xml", debugfile=output + "/debug.txt", loglevel="TRACE") # self.reset_last_status(index) # Report and xUnit files can be generated based on the result object. # ResultWriter(self.result).write_results(report=output + '/report.html', log=output + '/log.html') # self.lock.release() # Generating log files requires processing the earlier generated output XML. # ResultWriter(self.output + '/output.xml').write_results() self.result = ExecutionResult(out + "/output.xml") self.reset_last_status(self.result, output, index) # Report and xUnit files can be generated based on the result object. ResultWriter(self.result).write_results(report=out + '/report.html', log=out + '/log.html')
def robot_run(username, name, project, output): if not exists_path(output): mk_dirs(output) suite = TestSuiteBuilder().build(project) (out, index) = reset_next_build_numb(output) result = suite.run(output_directory=out, output=out + "/output.xml", debugfile=out + "/debug.txt", loglevel="TRACE") # reset_last_status(result, output, index) # Report and xUnit files can be generated based on the result object. # ResultWriter(result).write_results(report=out + '/report.html', log=out + '/log.html') detail_result = ExecutionResult(out + "/output.xml") # detail_result.save(out + "/output_new.xml") reset_last_status(detail_result, output, index) # Report and xUnit files can be generated based on the result object. ResultWriter(detail_result).write_results(report=out + '/report.html', log=out + '/log.html') send_robot_report(username, name, index, detail_result, out)
def get_robotcase_res(casefile): project = get_projectnamefromkey(casefile) projectdir = get_projectdirfromkey(casefile) os.environ["ROBOT_DIR"] = projectdir os.environ["PROJECT_DIR"] = projectdir cwd = os.getcwd() + "/keyword/" + project if not os.path.exists(cwd): mk_dirs(cwd) try: suite = TestSuiteBuilder().build(casefile) except SyntaxError as e: log.error("Exception:TestSuiteBuilder().build:{} {}".format( casefile, e)) return [] except Exception as e: log.error("Exception:TestSuiteBuilder().build:{} {}".format( casefile, e)) return [] resources = [] for i in suite.resource.imports: rsfile = i.name # Full path of file if rsfile.find("%{ROBOT_DIR}") != -1: rsfile = rsfile.replace("%{ROBOT_DIR}", projectdir) if rsfile.find("%{PROJECT_DIR}") != -1: rsfile = rsfile.replace("%{PROJECT_DIR}", projectdir) if rsfile.startswith('.'): dir = os.path.dirname(casefile) rsfile = os.path.join(dir, rsfile) basename = os.path.basename(rsfile) # Lib name without path fpre = basename.split('.')[ 0] # BuildIn or UserRes without '.resource' or '.robot' xmlfile = cwd + "/%s.xml" % fpre if not os.path.exists(rsfile) and (rsfile.find('/') != -1 or rsfile.find('.robot') != -1 or rsfile.find('.resource') != -1): log.error("找不到资源文件:{} !".format(rsfile)) continue if os.path.exists(rsfile): res = generate_resource_xml( rsfile, xmlfile) if not os.path.exists(xmlfile) else None resources.append(fpre) if os.path.exists(xmlfile) else log.error( "生成资源文件失败 XML:{},INFO:{}".format(xmlfile, res)) else: res = generate_resource_xml( fpre, xmlfile) if not os.path.exists(xmlfile) else None resources.append(fpre) if os.path.exists(xmlfile) else log.error( "生成资源文件失败 XML:{},INFO:{}".format(xmlfile, res)) if rsfile.endswith('.robot') or rsfile.endswith('.resource'): resources += get_robotress_res(rsfile) return resources
def robot_run(app, case_key, args='', user='', driver='USER'): username = user if user != '' else session['username'] project = get_projectnamefromkey(case_key) output = app.config["AUTO_HOME"] + "/jobs/%s/%s" % (username, project) if not exists_path(output): mk_dirs(output) (out, index) = reset_next_build_numb(output) mk_dirs(out) if not exists_path(out) else None cmd = 'robot ' + args + ' --outputdir=' + out + ' ' + case_key log.info("Robot_run CMD:{}".format(cmd)) with open(out + "/cmd.txt", 'w') as f: f.write("{}|robot|{}|--outputdir={}|{}\n".format( driver, args, out, case_key)) cp = subRun(cmd, shell=True, stdout=PIPE, stderr=STDOUT, text=True, timeout=7200) # timeout: sec 2hrs with open(out + "/debug.txt", 'w') as f: f.write(cp.stdout) app.config['DB'].insert_loginfo(username, 'task', 'run', case_key, 'OK') # Report and xUnit files can be generated based on the result object. # ResultWriter(result).write_results(report=out + '/report.html', log=out + '/log.html') try: detail_result = ExecutionResult(out + "/output.xml") except Exception as e: log.error( "Open output.xml Exception:{},\n May robot run fail, console:{}". format(e, cp.stdout)) return # detail_result.save(out + "/output_new.xml") reset_last_status(detail_result, output, index) # Report and xUnit files can be generated based on the result object. ResultWriter(detail_result).write_results(report=out + '/report.html', log=out + '/log.html') s = detail_result.suite dealwith_source(app, username, s)
def __create(self, args): result = {"status": "success", "msg": "创建目录成功"} user_path = self.app.config["AUTO_HOME"] + "/workspace/%s/%s/%s" % ( session["username"], args["project_name"], args["name"]) if not exists_path(user_path): mk_dirs(user_path) else: result["status"] = "fail" result["msg"] = "目录名称重复,创建失败" return result
def remote_clone(app, url): """ git.colone_from return True/False and info """ newdir = url.split('/')[-1].split('.')[0] to_path = os.path.join(app.config['AUTO_TEMP'], newdir) remove_dir(to_path) if os.path.exists(to_path) else None mk_dirs(to_path) try: repo = git.Repo.clone_from(url, to_path) except git.exc.GitError as e: log.error("Git clone 从 {} 到目录 {} 异常:{}".format(url, to_path, e)) log.info("{}".format(e)) return (False, "{}".format(e)) log.info("Clone 从 {} 到路径:{} 成功".format(url, to_path)) projectfile = os.path.join(to_path, 'platforminterface/project.conf') log.info("读取 Project file: {}".format(projectfile)) if os.path.exists(projectfile): with open(projectfile, 'r') as f: for l in f: if l.startswith('#'): continue if len(l.strip()) == 0: continue splits = l.strip().split('|') if len(splits) != 4: log.error("错误的 project.conf 行 " + l) return (False, "错误的 project.conf 行 " + l) (projectname, owner, users, cron) = splits project_path = os.path.join(app.config['AUTO_HOME'], 'workspace', owner, projectname) if os.path.exists(project_path): msg = '目标目录存在:{}'.format(project_path) log.error(msg) return (False, msg) log.info("复制文件从 {} 到 {} ".format(to_path, project_path)) try: shutil.copytree(to_path, project_path) except Exception as e: return (False, "{}".format(e)) else: msg = "Load Project Fail: 找不到 project.conf:{} ".format(projectfile) log.error(msg) return (False, msg) return (True, project_path) if repo else (False, "Git clone fail!")
def __create(self, args): result = {"status": "success", "msg": "成功:创建目录."} user_path = args['key'] + '/' + args['name'] if not exists_path(user_path): mk_dirs(user_path) else: result["status"] = "fail" result["msg"] = "失败:目录已存在!" try: res = self.app.config['DB'].insert_loginfo(session['username'], 'dir', 'create', user_path, result['status']) except Exception as e: self.log.error("创建目录 {} 异常: {}".format(user_path,e)) return result
def reset_next_build_numb(output): next_build_number = output + "/nextBuildNumber" index = 1 data = "%d" % (index + 1) if not exists_path(next_build_number): make_nod(next_build_number) else: index = int(read_file(next_build_number)["data"]) data = "%d" % (index + 1) write_file(next_build_number, data) out = output + "/%d" % index if not exists_path(output): mk_dirs(output) return (out, index)
def robot_run(name, output): if not exists_path(output): mk_dirs(output) suite = TestSuiteBuilder().build(name) (out, index) = reset_next_build_numb(output) result = suite.run(output_directory=out, output=out + "/output.xml", log_level="TRACE") reset_last_status(result, output, index) # Report and xUnit files can be generated based on the result object. ResultWriter(result).write_results(report=out + '/report.html', log=out + '/log.html')
def robot_debugrun(app, cases): out = app.config['AUTO_TEMP'] if not exists_path(out): mk_dirs(out) cmd = 'robot --outputdir=' + out + ' ' + cases cp = subRun(cmd, shell=True, stdout=PIPE, stderr=STDOUT, text=True, timeout=60) # timeout: sec app.config['DB'].insert_loginfo(session['username'], 'case', 'debug', cases, 'OK') return cp.stdout
def generate_auto_complete( doc_dir ): # This is new fun, Invoked by project.get ,then loaded in editor.html. log.info("生成自动完成 js ...") project = get_projectnamefromkey(doc_dir) kwd = os.getcwd() + "/keyword/" + project jsd = os.getcwd() + "/auto/www/static/js/" + project if not os.path.exists(jsd): mk_dirs(jsd) if not os.path.exists(kwd): mk_dirs(kwd) ff = codecs.open(jsd + "/autocomplete.js", "w", "utf-8") keyword_list = [] keys = os.listdir(kwd) for k in keys: if not k.endswith('.xml'): continue path = kwd + "/" + k tree = ET.parse(path) root = tree.getroot() name = root.attrib["name"] for kw in root.iter("kw"): # 关键字 word = "'" + kw.attrib["name"] # 关键字参数 for arg in kw.iter("arg"): word += "\t[" + arg.text.replace("'", "") + "]" word += "'" keyword_list.append(word) keyword_list = list(set(keyword_list)) keyword_list.sort(key=len, reverse=False) keyword_list = ROBOT_BUILTIN_KEYWORDS + keyword_list kewords = "var auto_complete=" + "[" + ",".join(keyword_list) + "];" ff.write(kewords) ff.close()
def __create(self, args): name = args["name"] manager = args["manager"] passwd = generate_password_hash("123") result = {"status": "success", "msg": "成功:创建项目{}.".format(name)} if args["name"] in self.reserved_names: result = {"status": "fail", "msg": "请换一个用户名."} return result if not self.app.config['DB'].add_user( manager, manager, passwd, manager + "@qq.com", 'User', name): result = { "status": "fail", "msg": "失败:创建项目管理员{}失败.".format(manager) } return result project_path = self.app.config["AUTO_HOME"] + \ "/workspace/%s/%s" % (manager, name) if not exists_path(project_path): mk_dirs(project_path) mk_dirs(os.path.join(project_path, 'platforminterface')) if not self.app.config['DB'].add_project(name, manager, ''): result["status"] = "fail" result["msg"] = "失败: 创建项目失败(?名称存在)" self.app.config['DB'].del_user(manager) return result self.save_project(project_path) self.save_user(project_path) self.save_settings(project_path) self.app.config['DB'].insert_loginfo(session['username'], 'project', 'create', project_path, result['status']) return result
def __create(self, args): result = {"status": "success", "msg": "创建项目成功"} user_path = self.app.config["AUTO_HOME"] + "/workspace/%s/%s" % ( session["username"], args["name"]) if not exists_path(user_path): mk_dirs(user_path) create_project( self.app, session["username"], { "name": args["name"], "description": args["description"], "boolean": args["boolean"], "enable": args["enable"], "cron": args["cron"] }) else: result["status"] = "fail" result["msg"] = "项目名称重复,创建失败" return result
def robot_runOLD(app, username, project, case_key, output): if not exists_path(output): mk_dirs(output) suite = TestSuiteBuilder().build(case_key) (out, index) = reset_next_build_numb(output) result = suite.run(output_directory=out, output=out + "/output.xml", debugfile=out + "/debug.txt", loglevel="TRACE") try: totalcases = result.statistics.total.all.total passed = result.statistics.total.all.passed failed = result.statistics.total.all.failed elapsedtime = result.suite.elapsedtime logres = "total:{},pass:{},fail:{},elapsedtime:{}".format( totalcases, passed, failed, elapsedtime) app.config['DB'].insert_loginfo(username, 'task', 'run', case_key, logres) except Exception as e: log.error("robot_run Exception: {}".format(e)) # Report and xUnit files can be generated based on the result object. # ResultWriter(result).write_results(report=out + '/report.html', log=out + '/log.html') detail_result = ExecutionResult(out + "/output.xml") # detail_result.save(out + "/output_new.xml") reset_last_status(detail_result, output, index) # Report and xUnit files can be generated based on the result object. ResultWriter(detail_result).write_results(report=out + '/report.html', log=out + '/log.html') s = detail_result.suite dealwith_source(app, username, s) send_robot_report(username, project, index, detail_result, out)
def __create(self, args): result = {"status": "success", "msg": "创建用户成功"} user_path = self.app.config["AUTO_HOME"] + "/users/%s" % ( args["username"]) if not exists_path(user_path): mk_dirs(user_path) make_nod(user_path + "/config.json") user = { "fullname": args["fullname"], "email": args["email"], "passwordHash": generate_password_hash(args["password"]), "data": [] } json.dump(user, codecs.open(user_path + '/config.json', 'w', 'utf-8')) else: result["status"] = "fail" result["msg"] = "用户名称重复,创建失败" return result
def run(self): #lock = threading.Lock() # self.lock.acquire() if not exists_path(self.output): mk_dirs(self.output) self.suite = TestSuiteBuilder().build(self.project) (output, index) = self.reset_next_build_numb() self.setName(output) self.result = self.suite.run(output_directory=output, output=output + "/output.xml", log_level="DEBUG") self.reset_last_status(index) # Report and xUnit files can be generated based on the result object. ResultWriter(self.result).write_results(report=output + '/report.html', log=output + '/log.html')
def __gitclone_caserecord(self, args): url = args['name'] if len(url) < 4: url = self.app.config['DB'].get_setting('history_git') if not url.startswith('http'): result = { "status": "fail", "msg": "Fail:没有配置历史结果git或配置有误!url:" + url } return result path = self.app.config['AUTO_TEMP'] + '/caserecordgit' remove_dir(path) if os.path.exists(path) else None mk_dirs(path) (ok, info) = remote_clone(url, path) if not ok: result = {"status": "fail", "msg": info} self.app.config['DB'].insert_loginfo(session['username'], 'case', 'gitclonecaserecord', url, result['status']) return result (gitname, extf) = os.path.splitext(os.path.basename(url)) gitpath = os.path.join(path, gitname, '.git') remove_dir(gitpath) if os.path.exists(gitpath) else None total = 0 success = 0 formaterror = 0 exits = 0 totalfile = 0 omitfile = 0 for root, dirs, files in os.walk(os.path.join(path, gitname), topdown=False): for name in files: ff = os.path.join(root, name) (_, f_ext) = os.path.splitext(ff) totalfile += 1 if not f_ext == '.his': self.log.warning("Gitclone caserecord 忽略文件:" + ff) omitfile += 1 continue with open(ff, 'r') as f: for l in f: l = l.strip() if len(l) != 0: total += 1 else: continue splits = l.split('|') if len(splits) != 8: formaterror += 1 self.log.error("uploadcaserecord 错误行:" + l) continue (info_key, info_name, info_testproject, info_projectversion, ontime, run_status, run_elapsedtime, run_user) = splits sql = ''' INSERT into caserecord (info_key,info_name,info_testproject,info_projectversion,ontime,run_status,run_elapsedtime,run_user) VALUES ('{}','{}','{}','{}','{}','{}','{}','{}'); '''.format(info_key, info_name, info_testproject, info_projectversion, ontime, run_status, run_elapsedtime, run_user) res = self.app.config['DB'].runsql(sql) if res: success += 1 else: exits += 1 self.log.error("uploadcaserecord 失败,记录存在:" + l) remove_dir(path) if os.path.exists(path) else None info = 'Finished with totalfile:{}, omitfile:{}, total:{}, sucess:{}, error:{}, exists:{}'.format( totalfile, omitfile, total, success, formaterror, exits) result = {"status": "success", "msg": info} return result