def __init__(self, table, task_id, key_word): super().__init__(table) sys_logger.debug('实例初始化开始') self._continue = True # 将测试任务基础数据转换为多个变量 # 基础数据校验在server接收数据的时候就要做好,本处无需再做 self.task_id = task_id self.key_word = key_word sys_logger.debug('实例初始化结束')
def kill_task(assign_data): """ :param assign_data: 测试任务下发数据 :return: 无返回 """ # 获取已下发测试任务的所有有效的worker信息 good_workers = [] # 轮询assign_data中的worker,判断是否可用 for ad in assign_data: # 根据ad的workerId查询workerInfo try: worker_info = model_mysql_workerinfo.query.filter( model_mysql_workerinfo.workerId == ad.workerId).first() except Exception as e: db_logger.error("worker:" + str(ad.workerId) + " 信息查询失败,失败原因:" + repr(e)) else: db_logger.debug("worker:" + str(ad.workerId) + " 信息查询成功") # 判断数据是否存在 if worker_info is None: # 如果worker的条目没有了,则将对应下发记录的finishTime直接赋上 update_finishtime(ad.assignId) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) r = s.connect_ex((worker_info.ip, worker_info.port)) if r != 0: # 将worker的状态置为异常 worker_info.status = 0 # 如果worker的状态为异常,则将对应下发记录的finishTime直接赋上 update_finishtime(ad.assignId) else: # 将worker的状态置为正常 worker_info.status = 1 good_workers.append(ad) try: mysqlpool.session.commit() except Exception as e: sys_logger.error("worker:" + str(ad.workerId) + " 信息更新失败,失败原因:" + repr(e)) else: sys_logger.debug("worker:" + str(ad.workerId) + " 信息更新成功") s.close() # 如果缺少可用worker if len(good_workers) < 1: pass else: # 开启线程池 pool = ThreadPool(len(good_workers)) pool.map(kill, good_workers) pool.close() pool.join()
def __init__(self, table, task_id, key_word): super().__init__(table) sys_logger.debug('实例初始化开始') self._continue = True # 将测试任务基础数据转换为多个变量 # 基础数据校验在server接收数据的时候就要做好,本处无需再做 self.task_id = task_id self.key_word = key_word """ 日志控制器内部维护 1.异步的、定时(根据配置文件)检查日志暂存条目数、定量(根据配置文件)地将日志条目发送给日志存储服务 2.一个队列,用来暂存日志条目。队列线程安全 """ self.log_temporary_storage = [] self.log_check_time_interval = app_config.getint("log", "interval") self.log_send_item_num = app_config.getint("log", "every") self.log_trans_timer = None sys_logger.debug('实例初始化结束') # 异步开启日志同步线程 self.trans()
def __send(self, to, msg): error_flag = True # -1 接收邮件地址或校验码填写非法 # 0 公共邮件发送成功 # 1 SMTP服务器连接失败 # 2 公共邮箱登陆失败 # 3 公共邮件发送失败 error_type = 0 logmsg = "准备发送邮件" sys_logger.info(logmsg) # 尝试连接服务器 try: # 根据SMTP服务器SSL状态连接 if self.smtp_ssl is True: smtp_server = smtplib.SMTP_SSL(self.smtp_host, self.smtp_port) else: smtp_server = smtplib.SMTP(self.smtp_host, self.smtp_port) # 打印日志 logmsg = "SMTP服务器连接成功" sys_logger.debug(logmsg) except Exception as A: logmsg = "SMTP服务器连接失败,失败信息:" + repr(A) error_flag = False error_type = 1 sys_logger.error(logmsg) else: try: smtp_server.login(self.send_address, self.send_password) logmsg = "公共邮件箱登陆成功" sys_logger.debug(logmsg) except Exception as B: logmsg = "公共邮件箱登陆失败,失败信息:" + repr(B) error_flag = False error_type = 2 sys_logger.error(logmsg) else: try: smtp_server.sendmail(self.send_address, to, msg.as_string()) smtp_server.quit() logmsg = "公共邮件发送成功" sys_logger.debug(logmsg) except Exception as C: logmsg = "公共邮件发送失败,失败信息:" + repr(C) error_flag = False error_type = 3 sys_logger.warn(logmsg) logmsg = "邮件发送结束" sys_logger.info(logmsg) return error_flag, error_type
# -*- coding: utf-8 -*- import configparser from handler.log import sys_logger app_config = configparser.ConfigParser() msg = "准备读取环境配置文件生成配置对象" sys_logger.info(msg) try: app_config.read(filenames="config/app.ini", encoding="utf-8") msg = "环境配置文件读取成功,成功生成配置对象" sys_logger.debug(msg) except Exception as e: msg = "环境配置文件读取失败,失败原因:" + repr(e) sys_logger.error(msg) raise e else: """ 检查app.ini内各项内容是否符合填写要求 log: interval/every """ try: app_config.getint('log', 'interval') app_config.getint('log', 'every') except Exception as e: sys_logger.error(repr(e)) raise e
# -*- coding: utf-8 -*- from configparser import ConfigParser from handler.log import sys_logger appconfig = ConfigParser() logmsg = "系统初始化|准备读取环境配置文件生成配置对象" sys_logger.info(logmsg) try: appconfig.read(filenames="config/app.ini", encoding="utf-8") logmsg = "系统初始化|环境配置文件读取成功,成功生成配置对象" sys_logger.debug(logmsg) except Exception as e: logmsg = "系统初始化|环境配置文件读取失败,失败原因:" + repr(e) sys_logger.error(logmsg) raise RuntimeError(logmsg) logmsg = "系统初始化|环境配置对象生成结束" sys_logger.info(logmsg)
def kill(assign_data): assign_id, task_id, worker_id, worker_ip, worker_port = assign_data # 打包action struct_action_data = struct.pack(dataFormat['action'], 'stopTestTask'.encode()) # 初始化并发送第一个请求 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sys_logger.debug(str(worker_id) + '|prepare to send action...') try: s.connect((worker_ip, worker_port)) s.send(struct_action_data) except Exception as e: sys_logger.error(str(worker_id) + '|send action failed:' + repr(e)) else: sys_logger.debug(str(worker_id) + '|send action succeeded') sys_logger.debug( str(worker_id) + '|listen action response from worker...') worker_response = s.recv(1024) sys_logger.debug(str(worker_id) + '|get action response from worker') worker_response = worker_response.decode() if worker_response == 'Success': # 打包base_data struct_base_data = struct.pack(dataFormat['stopTestTask'], task_id) sys_logger.debug(str(worker_id) + '|prepare to send base data...') try: s.send(struct_base_data) except Exception as e: sys_logger.error( str(worker_id) + '|send base data failed:' + repr(e)) else: sys_logger.debug(str(worker_id) + '|send base data succeeded') sys_logger.debug( str(worker_id) + '|listen base response from worker...') worker_response = s.recv(1024) sys_logger.debug( str(worker_id) + '|get base response from worker') if worker_response.decode() == 'Success': pass
def multi_deploy(base, file): """ :param base: 接收测试任务基础信息 :param file: 接收测试任务文件 :return: True/False """ # 获取当前所有有效的worker信息 try: all_workers = model_mysql_workerinfo.query.filter( model_mysql_workerinfo.status == 1).all() except Exception as e: sys_logger.debug("获取执行应用列表失败,失败原因:" + repr(e)) return False # 检查worker good_workers = [] if not all_workers: sys_logger.debug("当前系统无可用worker") return False else: # 轮询可用worker,判断是否确实可用 for aw in all_workers: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) r = s.connect_ex((aw.ip, aw.port)) if r != 0: # 将worker的状态置为异常 aw.status = 0 try: mysqlpool.session.commit() except Exception as e: sys_logger.error("worker:" + str(aw.workerId) + " 信息更新失败,失败原因:" + repr(e)) else: sys_logger.debug("worker:" + str(aw.workerId) + " 信息更新成功") else: good_workers.append(aw) s.send(struct.pack(dataFormat['action'], 'test'.encode())) s.close() # 如果缺少可用worker,则报错 if len(good_workers) < 1: sys_logger.error("当前系统无可用worker") return False # 根据worker数量拆分base中的vUser if len(good_workers) >= base.vUser: sys_logger.debug("虚拟用户数量较少,仅选择单机运行") # 如果vUser数量小于等于worker数量,则随机取一个worker the_worker = random.sample(good_workers, 1)[0] # 调用deploy deploy_result = deploy([the_worker, base, file]) return deploy_result # 如果vUser数量大于worker数量,则均分 else: sys_logger.debug("虚拟用户数量较多,选择多机运行") u1 = base.vUser // len(good_workers) # 判断能否整除 if base.vUser % len(good_workers) == 0: users = [u1] * len(good_workers) else: users = [u1] * (len(good_workers) - 1) users.append(base.vUser - u1 * (len(good_workers) - 1)) # 开启线程池 pool = ThreadPool(len(good_workers)) worker_base_list = [] i = 0 for gw in good_workers: base.vUser = users[i] worker_base_list.append([gw, base, file]) i += 1 pool.map(deploy, worker_base_list) pool.close() pool.join() return True
def single_deploy(base, file): """ :param base: 接收测试任务基础信息 :param file: 接收测试任务文件 :return: True/False """ # 获取当前所有有效的worker信息 try: all_workers = model_mysql_workerinfo.query.filter( model_mysql_workerinfo.status == 1).all() except Exception as e: msg = "获取执行应用列表失败,失败原因:" + repr(e) sys_logger.debug(msg) return False, msg # 检查worker good_workers = [] if not all_workers: msg = "当前系统无可用worker" sys_logger.warn(msg) return False, msg else: # 轮询可用worker,判断是否确实可用 for aw in all_workers: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(2) r = s.connect_ex((aw.ip, aw.port)) if r != 0: # 将worker的状态置为异常 aw.status = 0 try: mysqlpool.session.commit() except Exception as e: sys_logger.error("worker:" + str(aw.workerId) + " 信息更新失败,失败原因:" + repr(e)) else: sys_logger.debug("worker:" + str(aw.workerId) + " 信息更新成功") else: good_workers.append(aw) s.close() # 如果缺少可用worker,则报错 if len(good_workers) < 1: msg = "当前系统无可用worker" sys_logger.error(msg) return False, msg else: # 从可用worker列表中任取一个进行下发操作 # 如果失败,则把错误返回累计起来以便写warn日志,并继续尝试,直到下发成功 deploy_msg = '' deploy_result = False while len(good_workers) > 0 and not deploy_result: i = random.randint(0, len(good_workers) - 1) # 调用deploy deploy_result, msg = deploy([good_workers[i], base, file]) deploy_msg += msg + ';' good_workers.pop(i) if deploy_result: sys_logger.debug(deploy_msg) else: sys_logger.warn(deploy_msg) return deploy_result, deploy_msg
def deploy(worker_base_file): the_worker, base, file = worker_base_file the_worker_id = the_worker.workerId msg = '' the_date = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) # 新增下发测试任务记录 new_task_assign = model_mysql_taskassign(taskId=base.taskId, workerId=the_worker_id, vuser=base.vUser, status=0, createTime=the_date, updateTime=the_date) try: # 下发记录入库 mysqlpool.session.add(new_task_assign) mysqlpool.session.commit() except Exception as e: msg = "测试任务下发记录新增失败,失败原因:" + repr(e) sys_logger.debug(msg) return False, msg else: sys_logger.debug("测试任务下发记录新增成功") # 打包action # 初始化并发送第一个请求 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sys_logger.debug('workerId:%d,准备发送action...' % the_worker_id) try: s.connect((the_worker.ip, the_worker.port)) s.send(struct.pack(dataFormat['action'], 'newTestTask'.encode())) except Exception as e: msg = 'workerId:%d,发送action失败:%s' % (the_worker_id, repr(e)) sys_logger.error(msg) return False, msg else: msg = 'workerId:%d,发送action成功' % the_worker_id sys_logger.debug(msg) msg = 'workerId:%d,准备接收action返回...' % the_worker_id sys_logger.debug(msg) worker_response = s.recv(1024) msg = 'workerId:%d,接收到action返回' % the_worker_id sys_logger.debug(msg) worker_response = worker_response.decode() if worker_response == 'Success': msg = 'workerId:%d,准备发送basedata...' % the_worker_id sys_logger.debug(msg) try: # 打包并发送base_data s.send( struct.pack( dataFormat['newTestTask'], base.taskId, base.vUser, base.rampUpPeriod, base.startType, base.endType, base.errorType, base.excuteTimes if base.excuteTimes else 0, os.stat(file).st_size, str(base.startTime).encode() if base.startTime else ''.encode(), str(base.endTime).encode() if base.endTime else ''.encode())) except Exception as e: msg = 'workerId:%d,发送basedata失败:%s' % (the_worker_id, repr(e)) sys_logger.error(msg) return False, msg else: msg = 'workerId:%d,发送basedata成功' % the_worker_id sys_logger.debug(msg) msg = 'workerId:%d,准备接收basedata返回...' % the_worker_id sys_logger.debug(msg) worker_response = s.recv(1024) msg = 'workerId:%d,接收到basedata返回' % the_worker_id sys_logger.debug(msg) worker_response = worker_response.decode() if worker_response == 'Success': task_file = open(file, 'rb') msg = 'workerId:%d,准备发送测试任务数据及文件的压缩包...' % the_worker_id sys_logger.debug(msg) try: while True: file_data = task_file.read(1024) if not file_data: break s.send(file_data) except Exception as e: msg = 'workerId:%d,发送压缩包失败:%s' % (the_worker_id, repr(e)) sys_logger.error(msg) return False, msg else: task_file.close() msg = 'workerId:%d,发送压缩包成功' % the_worker_id sys_logger.debug(msg) msg = 'workerId:%d,准备接收压缩包返回...' % the_worker_id sys_logger.debug(msg) worker_response = s.recv(1024) msg = 'workerId:%d,接收到压缩包返回' % the_worker_id sys_logger.debug(msg) worker_response = worker_response.decode() if worker_response == 'Success': # 下发结果入库 new_task_assign.status = 1 new_task_assign.updateTime = str( datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S")) msg = 'workerId:%d,压缩包处理成功' % the_worker_id sys_logger.debug(msg) try: mysqlpool.session.commit() except Exception as e: msg = '测试任务下发记录更新失败,失败原因:%s' % repr(e) sys_logger.debug(msg) return False, msg else: msg = '测试任务下发记录更新成功' sys_logger.debug(msg) return True, '测试任务下发成功' else: # 下发结果入库 new_task_assign.status = -1 new_task_assign.updateTime = str( datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S")) msg = 'workerId:%d,压缩包处理失败:%s' % ( the_worker_id, worker_response.split('.') [1] if len(worker_response.split('.')) > 1 else '原因未知') sys_logger.error(msg) try: mysqlpool.session.commit() except Exception as e: msg = '测试任务下发记录更新失败,失败原因:%s' % repr(e) sys_logger.debug(msg) return False, msg else: msg = '测试任务下发记录更新成功' sys_logger.debug(msg) return False, 'workerId:%d,压缩包处理失败:%s' % ( the_worker_id, worker_response.split('.')[1] if len(worker_response.split('.')) > 1 else '原因未知') else: # 下发结果入库 new_task_assign.status = -1 new_task_assign.updateTime = str( datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S")) msg = 'workerId:%d,basedata处理失败:%s' % ( the_worker_id, worker_response.split('.')[1] if len(worker_response.split('.')) > 1 else '原因未知') sys_logger.error(msg) try: mysqlpool.session.commit() except Exception as e: msg = '测试任务下发记录更新失败,失败原因:%s' % repr(e) sys_logger.debug(msg) return False, msg else: msg = '测试任务下发记录更新成功' sys_logger.debug(msg) return False, 'workerId:%d,basedata处理失败:%s' % ( the_worker_id, worker_response.split('.')[1] if len(worker_response.split('.')) > 1 else '原因未知') else: # 下发结果入库 new_task_assign.status = -1 new_task_assign.updateTime = str( datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) msg = 'workerId:%d,action处理失败:%s' % ( the_worker_id, worker_response.split('.')[1] if len(worker_response.split('.')) > 1 else '原因未知') sys_logger.error(msg) try: mysqlpool.session.commit() except Exception as e: msg = '测试任务下发记录更新失败,失败原因:%s' % repr(e) sys_logger.debug(msg) return False, msg else: msg = '测试任务下发记录更新成功' sys_logger.debug(msg) return False, 'workerId:%d,action处理失败:%s' % ( the_worker_id, worker_response.split('.')[1] if len(worker_response.split('.')) > 1 else '原因未知')