def _check_alerts(*, log=None): if log is None: with Log.open(encoding='utf-8') as f: log = f.read() found = False alerts = re.findall(r'.+\[alert\].+', log) if alerts: print('\nAll alerts/sanitizer errors found in log:') [print(alert) for alert in alerts] found = True if option.skip_alerts: for skip in option.skip_alerts: alerts = [al for al in alerts if re.search(skip, al) is None] assert not alerts, 'alert(s)' if not option.skip_sanitizer: sanitizer_errors = re.findall('.+Sanitizer.+', log) assert not sanitizer_errors, 'sanitizer error(s)' if found: print('skipped.')
def pytest_sessionfinish(session): if not option.restart and option.save_log: print('Path to unit.log:\n' + Log.get_path() + '\n') option.restart = True unit_stop() shutil.rmtree(option.cache_dir)
def test_usr1_unit_log(self, temp_dir, unit_pid): self.load('log_body') log_new = 'new.log' log_path = temp_dir + '/unit.log' log_path_new = temp_dir + '/' + log_new os.rename(log_path, log_path_new) Log.swap(log_new) try: body = 'body_for_a_log_new\n' assert self.post(body=body)['status'] == 200 assert (self.wait_for_record(body, log_new) is not None), 'rename new' assert not os.path.isfile(log_path), 'rename old' os.kill(unit_pid, signal.SIGUSR1) assert waitforfiles(log_path), 'reopen' body = 'body_for_a_log_unit\n' assert self.post(body=body)['status'] == 200 assert self.wait_for_record(body) is not None, 'rename new' assert self.search_in_log(body, log_new) is None, 'rename new 2' finally: # merge two log files into unit.log to check alerts with open(log_path, 'r', errors='ignore') as unit_log: log = unit_log.read() with open(log_path, 'w') as unit_log, open(log_path_new, 'r', errors='ignore') as unit_log_new: unit_log.write(unit_log_new.read()) unit_log.write(log) Log.swap(log_new)
def pytest_sessionstart(session): option.available = {'modules': {}, 'features': {}} unit = unit_run() # read unit.log for i in range(50): with open(Log.get_path(), 'r') as f: log = f.read() m = re.search('controller started', log) if m is None: time.sleep(0.1) else: break if m is None: _print_log(log) exit("Unit is writing log too long") # discover available modules from unit.log for module in re.findall(r'module: ([a-zA-Z]+) (.*) ".*"$', log, re.M): versions = option.available['modules'].setdefault(module[0], []) if module[1] not in versions: versions.append(module[1]) # discover modules from check option.available['modules']['openssl'] = check_openssl(unit['unitd']) option.available['modules']['go'] = check_go(option.current_dir, unit['temp_dir'], option.test_dir) option.available['modules']['node'] = check_node(option.current_dir) option.available['modules']['regex'] = check_regex(unit['unitd']) # remove None values option.available['modules'] = { k: v for k, v in option.available['modules'].items() if v is not None } check_chroot() check_isolation() _clear_conf(unit['temp_dir'] + '/control.unit.sock') unit_stop() _check_alerts() if option.restart: shutil.rmtree(unit_instance['temp_dir'])
def wait_for_record(self, pattern, name='unit.log', wait=150): with Log.open(name) as f: for i in range(wait): found = re.search(pattern, f.read()) if found is not None: break time.sleep(0.1) return found
def _print_log(log=None): path = Log.get_path() print('Path to unit.log:\n' + path + '\n') if option.print_log: os.set_blocking(sys.stdout.fileno(), True) sys.stdout.flush() if log is None: with open(path, 'r', encoding='utf-8', errors='ignore') as f: shutil.copyfileobj(f, sys.stdout) else: sys.stdout.write(log)
def run(request): unit = unit_run() option.skip_alerts = [ r'read signalfd\(4\) failed', r'sendmsg.+failed', r'recvmsg.+failed', ] option.skip_sanitizer = False _fds_info['main']['skip'] = False _fds_info['router']['skip'] = False _fds_info['controller']['skip'] = False yield # stop unit error_stop_unit = unit_stop() error_stop_processes = stop_processes() # prepare log with Log.open(encoding='utf-8') as f: log = f.read() Log.set_pos(f.tell()) if not option.save_log and option.restart: shutil.rmtree(unit['temp_dir']) Log.set_pos(0) # clean temp_dir before the next test if not option.restart: _clear_conf(unit['temp_dir'] + '/control.unit.sock', log=log) for item in os.listdir(unit['temp_dir']): if item not in [ 'control.unit.sock', 'state', 'unit.pid', 'unit.log', ]: path = os.path.join(unit['temp_dir'], item) public_dir(path) if os.path.isfile(path) or stat.S_ISSOCK( os.stat(path).st_mode): os.remove(path) else: for attempt in range(10): try: shutil.rmtree(path) break except OSError as err: if err.errno != 16: raise time.sleep(1) # check descriptors _check_fds(log=log) # print unit.log in case of error if hasattr(request.node, 'rep_call') and request.node.rep_call.failed: _print_log(log) if error_stop_unit or error_stop_processes: _print_log(log) # check unit.log for errors assert error_stop_unit is None, 'stop unit' assert error_stop_processes is None, 'stop processes' _check_alerts(log=log)
def search_in_log(self, pattern, name='unit.log'): with Log.open(name) as f: return re.search(pattern, f.read())
def findall(self, pattern, name='unit.log'): with Log.open(name) as f: return re.findall(pattern, f.read())
def run(request): unit = unit_run() option.skip_alerts = [ r'read signalfd\(4\) failed', r'sendmsg.+failed', r'recvmsg.+failed', ] option.skip_sanitizer = False _fds_check['main']['skip'] = False _fds_check['router']['skip'] = False _fds_check['controller']['skip'] = False yield # stop unit error_stop_unit = unit_stop() error_stop_processes = stop_processes() # prepare log with Log.open(encoding='utf-8') as f: log = f.read() Log.set_pos(f.tell()) if not option.save_log and option.restart: shutil.rmtree(unit['temp_dir']) Log.set_pos(0) # clean temp_dir before the next test if not option.restart: _clear_conf(unit['temp_dir'] + '/control.unit.sock', log) for item in os.listdir(unit['temp_dir']): if item not in [ 'control.unit.sock', 'state', 'unit.pid', 'unit.log', ]: path = os.path.join(unit['temp_dir'], item) public_dir(path) if os.path.isfile(path) or stat.S_ISSOCK( os.stat(path).st_mode): os.remove(path) else: shutil.rmtree(path) # check descriptors (wait for some time before check) def waitforfds(diff): for i in range(600): fds_diff = diff() if fds_diff <= option.fds_threshold: break time.sleep(0.1) return fds_diff ps = _fds_check['main'] if not ps['skip']: fds_diff = waitforfds( lambda: _count_fds(unit_instance['pid']) - ps['fds']) ps['fds'] += fds_diff assert (fds_diff <= option.fds_threshold), 'descriptors leak main process' else: ps['fds'] = _count_fds(unit_instance['pid']) for name in ['controller', 'router']: ps = _fds_check[name] ps_pid = ps['pid'] ps['pid'] = pid_by_name(ps['name']) if not ps['skip']: fds_diff = waitforfds(lambda: _count_fds(ps['pid']) - ps['fds']) ps['fds'] += fds_diff assert ps['pid'] == ps_pid, 'same pid %s' % name assert fds_diff <= option.fds_threshold, ('descriptors leak %s' % name) else: ps['fds'] = _count_fds(ps['pid']) # print unit.log in case of error if hasattr(request.node, 'rep_call') and request.node.rep_call.failed: _print_log(log) if error_stop_unit or error_stop_processes: _print_log(log) # check unit.log for errors assert error_stop_unit is None, 'stop unit' assert error_stop_processes is None, 'stop processes' _check_alerts(log=log)