def getUniqueId(self): """ This function is not used any more :return: returns the local pc unique ID """ try: node_id_file_path = Path( os.path.abspath(__file__).split("Framework")[0]) / Path( "node_id.conf") if os.path.isfile(node_id_file_path): unique_id = ConfigModule.get_config_value( "UniqueID", "id", node_id_file_path) if unique_id == "": ConfigModule.clean_config_file(node_id_file_path) ConfigModule.add_section("UniqueID", node_id_file_path) unique_id = uuid.uuid4() unique_id = str(unique_id)[:10] ConfigModule.add_config_value("UniqueID", "id", unique_id, node_id_file_path) machine_name = str(unique_id) return machine_name[:100] machine_name = str(unique_id) else: # create the file name f = open(node_id_file_path, "w") f.close() unique_id = uuid.uuid4() unique_id = str(unique_id)[:10] ConfigModule.add_section("UniqueID", node_id_file_path) ConfigModule.add_config_value("UniqueID", "id", unique_id, node_id_file_path) machine_name = str(unique_id) return machine_name[:100] except Exception: ErrorMessage = "Unable to set create a Node key. Please check class MachineInfo() in commonutil" return Exception_Handler(sys.exc_info(), None, ErrorMessage)
def update_machine(dependency, default_team_and_project_dict): try: # Get Local Info object oLocalInfo = CommonUtil.MachineInfo() local_ip = oLocalInfo.getLocalIP() testerid = (oLocalInfo.getLocalUser()).lower() project = default_team_and_project_dict["project_name"] team = default_team_and_project_dict["team_name"] if not dependency: dependency = "" _d = {} for x in dependency: t = [] for i in x[1]: _t = ["name", "bit", "version"] __t = {} for index, _i in enumerate(i): __t.update({_t[index]: _i}) if __t: t.append(__t) _d.update({x[0]: t}) dependency = _d available_to_all_project = ConfigModule.get_config_value( "Advanced Options", "available_to_all_project") allProject = "no" if str(available_to_all_project).lower() == "true": allProject = "yes" update_object = { "machine_name": testerid, "local_ip": local_ip, "dependency": dependency, "project": project, "team": team, "device": device_dict, "allProject": allProject, } r = RequestFormatter.Get("update_automation_machine_api", update_object) if r["registered"]: CommonUtil.ExecLog( "", "Zeuz Node is online: %s" % (r["name"]), 4, False, ) else: if r["license"]: CommonUtil.ExecLog("", "Machine is not registered as online", 4, False) else: if "message" in r: CommonUtil.ExecLog("", r["message"], 4, False) CommonUtil.ExecLog("", "Machine is not registered as online", 4, False) else: CommonUtil.ExecLog("", "Machine is not registered as online", 4, False) return r except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] Error_Detail = ((str(exc_type).replace("type ", "Error Type: ")) + ";" + "Error Message: " + str(exc_obj) + ";" + "File Name: " + fname + ";" + "Line: " + str(exc_tb.tb_lineno)) CommonUtil.ExecLog("", Error_Detail, 4, False)
def Login(cli=False, run_once=False, log_dir=None): username = ConfigModule.get_config_value(AUTHENTICATION_TAG, USERNAME_TAG) password = ConfigModule.get_config_value(AUTHENTICATION_TAG, PASSWORD_TAG) server_name = ConfigModule.get_config_value(AUTHENTICATION_TAG, "server_address") api = ConfigModule.get_config_value(AUTHENTICATION_TAG, "api-key") api_flag = True if not api or not server_name: zeuz_authentication_prompts_for_cli() for i in range( 30): # it takes time to save in the file. so lets wait 15 sec time.sleep(0.5) api = ConfigModule.get_config_value(AUTHENTICATION_TAG, "api-key") server_name = ConfigModule.get_config_value( AUTHENTICATION_TAG, "server_address") if api and server_name: break while api and server_name: url = '/api/auth/token/verify?api_key=%s' % (api) r = RequestFormatter.Get(url) if r: try: token = r['token'] res = RequestFormatter.Get( "/api/user", headers={'Authorization': "Bearer %s" % token}) info = res[0] username = info['username'] api_flag = False ConfigModule.add_config_value(AUTHENTICATION_TAG, "username", username) break except: print("Incorrect API key...") server_name, api = zeuz_authentication_prompts_for_cli() continue else: print("Server down. Trying again after 30 seconds") time.sleep(30) if password == "YourUserNameGoesHere": password = password else: password = pass_decode("zeuz", password) # form payload object user_info_object = { "username": username, "password": password, "project": "", "team": "", } # Iniitalize GUI Offline call CommonUtil.set_exit_mode(False) global exit_script global processing_test_case exit_script = False # Reset exit variable while True: if exit_script: break # if not user_info_object["username"] or not user_info_object["password"]: # break # Test to ensure server is up before attempting to login r = check_server_online() # Login to server if r: # Server is up try: default_team_and_project = RequestFormatter.UpdatedGet( "get_default_team_and_project_api", {"username": username}) if not default_team_and_project: CommonUtil.ExecLog( "AUTH FAILED", "Failed to get TEAM and PROJECT information. Incorrect username or password.", 3, False, ) break user_info_object["project"] = default_team_and_project[ "project_name"] user_info_object["team"] = default_team_and_project[ "team_name"] CommonUtil.ExecLog("", f"Authenticating user: {username}", 4, False) if api_flag: r = RequestFormatter.Post("login_api", user_info_object) if r or (isinstance(r, dict) and r['status'] == 200): CommonUtil.ExecLog( "", f"Authentication successful: USER='******', " f"PROJECT='{user_info_object['project']}', TEAM='{user_info_object['team']}', SERVER='{server_name}'", 4) ConfigModule.add_config_value("sectionOne", PROJECT_TAG, user_info_object['project'], temp_ini_file) ConfigModule.add_config_value("sectionOne", TEAM_TAG, user_info_object['team'], temp_ini_file) global device_dict device_dict = All_Device_Info.get_all_connected_device_info( ) machine_object = update_machine( dependency_collection(default_team_and_project), default_team_and_project, ) if machine_object["registered"]: tester_id = machine_object["name"] try: # send machine's time zone local_tz = str(get_localzone()) time_zone_object = { "time_zone": local_tz, "machine": tester_id, } executor = CommonUtil.GetExecutor() executor.submit(RequestFormatter.Get, "send_machine_time_zone_api", time_zone_object) # RequestFormatter.Get("send_machine_time_zone_api", time_zone_object) # end except Exception as e: CommonUtil.ExecLog( "", "Time zone settings failed {}".format(e), 4, False) # Telling the node_manager that the node is ready to deploy CommonUtil.node_manager_json({ "state": "idle", "report": { "zip": None, "directory": None, } }) run_again = RunProcess(tester_id, user_info_object, run_once=run_once, log_dir=log_dir) if not run_again: break # Exit login else: return False elif not r: # Server should send "False" when user/pass is wrong CommonUtil.ExecLog( "", f"Authentication Failed. Username or password incorrect. SERVER='{server_name}'", 4, False, ) if cli: zeuz_authentication_prompts_for_cli() Login(cli=True) break else: # Server likely sent nothing back or RequestFormatter.Get() caught an exception CommonUtil.ExecLog( "", "Login attempt failed, retrying in 60 seconds...", 4, False, ) if cli: zeuz_authentication_prompts_for_cli() Login(cli=True) time.sleep(60) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] Error_Detail = ( (str(exc_type).replace("type ", "Error Type: ")) + ";" + "Error Message: " + str(exc_obj) + ";" + "File Name: " + fname + ";" + "Line: " + str(exc_tb.tb_lineno)) CommonUtil.ExecLog("", Error_Detail, 4, False) CommonUtil.ExecLog( "", "Error logging in, waiting 60 seconds before trying again", 4, False, ) time.sleep(60) # Server down, wait and retry else: CommonUtil.ExecLog( "", "Server down or verify the server address, waiting 60 seconds before trying again", 4, False, ) # if cli: # zeuz_authentication_prompts_for_cli() # Login(cli=True) time.sleep(60) if run_once: print( "[OFFLINE]", "Zeuz Node is going offline after running one session, since `--once` or `-o` flag is specified." ) else: CommonUtil.ExecLog( "[OFFLINE]", "Zeuz Node Offline", 3 ) # GUI relies on this exact text. GUI must be updated if this is changed processing_test_case = False
)) # Tells node whether it should run a test set/deployment only once and quit. RUN_ONCE = False local_run = False # Move to Framework directory, so all modules can be seen os.chdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), "Framework")) sys.path.append("..") from Framework.Utilities import (RequestFormatter, CommonUtil, FileUtilities as FL, All_Device_Info, self_updater) from Framework import MainDriverApi temp_ini_file = (Path(PROJECT_ROOT) / "AutomationLog" / ConfigModule.get_config_value("Advanced Options", "_file")) import subprocess def signal_handler(sig, frame): CommonUtil.run_cancelled = True print("Disconnecting from server...") disconnect_from_server() sys.exit(0) def password_hash(encrypt, key, pw): """ Encrypt, decrypt password and encode in plaintext """ # This is just an obfuscation technique, so the password is not immediately seen by users # Zeuz_Node.py has a similar function that will need to be updated if this is changed
def ExecLog(sModuleInfo, sDetails, iLogLevel=1, _local_run="", sStatus="", force_write=False, variable=None): # Do not log anything if load testing is going on and we're not forced to write logs if load_testing and not force_write: return if not print_execlog: return # For bypass_bug() function dont print logs # Read from settings file debug_mode = ConfigModule.get_config_value("RunDefinition", "debug_mode") # ";" is not supported for logging. So replacing them sDetails = sDetails.replace(";", ":").replace("%22", "'") # Terminal output color line_color = "" # Convert logLevel from int to string for clarity if iLogLevel == 0: if debug_mode.lower() == "true": status = ( "Debug" # This is not displayed on the server log, just in the console ) else: # Do not display this log line anywhere return elif iLogLevel == 1: status = "Passed" line_color = Fore.GREEN elif iLogLevel == 2: status = "Warning" line_color = Fore.YELLOW elif iLogLevel == 3: status = "Error" line_color = Fore.RED elif iLogLevel == 4: status = "Console" elif iLogLevel == 5: status = "Info" iLogLevel = 1 line_color = Fore.CYAN elif iLogLevel == 6: status = "BrowserConsole" else: print("*** Unknown log level - Set to Info ***") status = "Info" iLogLevel = 5 line_color = Fore.CYAN if not sModuleInfo: sModuleInfo = "" info = "" else: info = f"{sModuleInfo}\t\n" # Display on console # Change the format for console, mainly leave out the status level if "saved variable" not in sDetails.lower(): if status == "Console": msg = f"{info}{sDetails}" if sModuleInfo else sDetails print(line_color + msg) else: print(line_color + f"{status.upper()} - {info}{sDetails}") current_log_line = f"{status.upper()} - {sModuleInfo} - {sDetails}" global previous_log_line # Skip duplicate logs if previous_log_line and previous_log_line.strip( ) == current_log_line.strip(): return # Set current log as the next previous log previous_log_line = current_log_line ws.log(sModuleInfo, iLogLevel, sDetails) if iLogLevel > 0: if iLogLevel == 6: FWLogFolder = ConfigModule.get_config_value( "sectionOne", "log_folder", temp_config) if os.path.exists(FWLogFolder) == False: FL.CreateFolder(FWLogFolder) # Create log directory if missing if FWLogFolder == "": BrowserConsoleLogFile = (ConfigModule.get_config_value( "sectionOne", "temp_run_file_path", temp_config) + os.sep + "BrowserLog.log") else: BrowserConsoleLogFile = FWLogFolder + os.sep + "BrowserLog.log" logger = logging.getLogger(__name__) browser_log_handler = None if os.name == "posix": try: browser_log_handler = logging.FileHandler( BrowserConsoleLogFile) except: pass elif os.name == "nt": browser_log_handler = logging.FileHandler( BrowserConsoleLogFile) formatter = logging.Formatter( "%(asctime)s - %(levelname)s - %(message)s") if browser_log_handler: browser_log_handler.setFormatter(formatter) logger.addHandler(browser_log_handler) logger.setLevel(logging.DEBUG) logger.info(sModuleInfo + " - " + sDetails + "" + sStatus) logger.removeHandler(browser_log_handler) else: # Except the browser logs global all_logs, all_logs_count, all_logs_list log_id = ConfigModule.get_config_value("sectionOne", "sTestStepExecLogId", temp_config) if not log_id: return now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") if variable and variable["key"] not in skip_list: sDetails = "%s\nVariable value: %s" % (sDetails, variable["val"]) if upload_on_fail and rerun_on_fail and not rerunning_on_fail: pass else: CreateJsonReport(logs=(log_id, now, iLogLevel, status, sModuleInfo, sDetails)) all_logs[all_logs_count] = { "logid": log_id, "modulename": sModuleInfo, "details": sDetails, "status": status, "loglevel": iLogLevel, "tstamp": str(now), } if len(all_logs_list) >= 1: # start logging to the log file instead of logging to the server try: # filepath = Path(ConfigModule.get_config_value('sectionOne', 'log_folder', temp_config)) / 'execution.log' filepath = (Path( ConfigModule.get_config_value( "sectionOne", "temp_run_file_path", temp_config)) / "execution.log") with open(filepath, "a+") as f: print("[%s] %s" % (now, current_log_line), file=f) except FileNotFoundError: pass # log warnings and errors if iLogLevel in (2, 3) or len(all_logs_list) < 1: # log to server in case of logs less than 2k all_logs_count += 1 if all_logs_count > 2000: all_logs_list.append(all_logs) all_logs_count = 0 all_logs = {}
def CreateJsonReport(logs=None, stepInfo=None, TCInfo=None, setInfo=None): try: if debug_status: return elif upload_on_fail and rerun_on_fail and not rerunning_on_fail and logs: return global all_logs_json, report_json_time, tc_error_logs, passed_after_rerun start = time.perf_counter() if logs or stepInfo or TCInfo or setInfo: log_id = ConfigModule.get_config_value("sectionOne", "sTestStepExecLogId", temp_config) if not log_id: return log_id_vals = log_id.split("|") if logs: log_id, now, iLogLevel, status, sModuleInfo, sDetails = logs if len(log_id_vals) == 4: # these loops can be optimized by saving the previous log_id_vals and comparing it with current one runID, testcase_no, step_id, step_no = log_id_vals run_id_info = all_logs_json[runid_index] if setInfo: run_id_info["execution_detail"] = setInfo return all_testcases_info = run_id_info["test_cases"] testcase_info = all_testcases_info[tc_index] if TCInfo: testcase_info["execution_detail"] = TCInfo fail_reason_str = "" if TCInfo["status"] in ("Failed", "Blocked"): count = -min(len(tc_error_logs), 3) while count <= -1: fail_reason_str += tc_error_logs[count] if count != -1: fail_reason_str += "\n---------------------------------------------\n" count += 1 elif passed_after_rerun: fail_reason_str = "** Test case Failed on first run but Passed when Rerun **" passed_after_rerun = False testcase_info["execution_detail"][ "failreason"] = fail_reason_str return if step_id == "none": return all_step_info = testcase_info["steps"] step_info = all_step_info[step_index] if stepInfo: step_info["execution_detail"] = stepInfo step_error_logs = [] if stepInfo["status"].lower( ) == "failed" and "log" in step_info: count, err_count, max_count = -1, 0, -len( step_info["log"]) # Can be optimized by taking error when occurs and append it if the step fails only while count >= max_count and err_count < 3: each_log = step_info["log"][count] if each_log["status"].lower() == "error": step_error_logs.append(each_log["details"]) err_count += 1 count -= 1 step_error_logs.reverse() tc_error_logs += step_error_logs return log_info = { "status": status, "modulename": sModuleInfo, "details": sDetails, "tstamp": now, "loglevel": iLogLevel, "logid": log_id } if "log" in step_info: step_info["log"].append(log_info) else: step_info["log"] = [log_info] elif stepInfo: pass report_json_time += (time.perf_counter() - start) except: debug_code_error(sys.exc_info())