def replace_region_values_on_cam_json(json_detector: dict, region_name: str, new_region: dict, force: bool, statistic: Statistic) -> dict: """Замена зоны по ключам (только существующие ключи). :param json_detector: json с секцией детектора; :param region_name: имя зоны; :param new_region: словарь с новым регионом; :param force: вставить принудительно настройку, если ее нет в json; :param statistic: объект класса Statistic. :return: json с измененной секцией детектора в зоне """ logger = statistic.get_log().get_logger("scripts/common/graph") logger.info("was called (json_detector: dict, region_name: str, new_region: dict, statistic: Statistic") logger.debug("with params (" + str(json_detector) + ", " + region_name + ", " + str(new_region) + ")") detector_name = get_plugin_type(json_detector, statistic) data = get_region_from_detector_json(json_detector, region_name, statistic) index_region = data[0] region = data[1] if index_region == -1: statistic.append_error(region_name, "НЕТ ЗОНЫ") return {} region_json = json_detector[detector_name]['detection_regions']['square']['_value'][index_region] for first_lvl_key in new_region.keys(): if tools.check_keys_exist(region, [first_lvl_key], region_name, False, statistic) is False: if force: region_json[first_lvl_key] = new_region[first_lvl_key] txt_msg = first_lvl_key + " в зоне '" + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_success(txt_msg, "ПРИНУДИТЕЛЬНАЯ ВСТАВКА КЛЮЧА В ЗОНЕ") continue # если данный ключ является отрисовкой зоны _points, то содержимое меняем # немного по другому if first_lvl_key == '_points': region_json['_points'] = new_region['_points'] txt_msg = "_ points в зоне " + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_info(txt_msg, "ЗАМЕНА КЛЮЧЕЙ В ЗОНЕ") continue # для остальных ключей делаем замену в _value if tools.check_keys_exist(region[first_lvl_key], ['_value'], region_name + "[" + str(index_region) + "]", False, statistic) is False: continue if tools.check_keys_exist(new_region[first_lvl_key], ['_value'], first_lvl_key + " в новом регионе!", False, statistic) is False: continue region_json[first_lvl_key]['_value'] = new_region[first_lvl_key]['_value'] txt_msg = first_lvl_key + "[_value] в зоне '" + region_name + " выполнена успешно!" logger.info(txt_msg) statistic.append_success(txt_msg, "ЗАМЕНА КЛЮЧА В ЗОНЕ") return json_detector
class TestRunner(threading.Thread): """Класс для запуска тесте из тест кейса в отдельном потоке. """ def __init__(self, thread_id: int, module: str, test: str, input_data: dict, config: dict, log: Log): threading.Thread.__init__(self) self._statistic = Statistic(test, thread_id, config, log) self._test_class = test_classes[module](input_data, config, self._statistic) self._test = test self._id = str(thread_id) def get_statistic(self): """Метод-геттер получения объекта статистики. :return: """ return self._statistic def run(self): """Переопределенный метод запуска потока. """ full_test_name = self._test + "[Поток #" + self._id + "]" test_method = getattr(self._test_class, self._test) error_msg = "" try: self._test_class.setup() test_method() except SystemExit as e: error_msg = e.args[0] self._test_class.teardown() if error_msg: self._statistic.append_error( "Тест " + full_test_name + " завершился с критической ошибкой: " + error_msg, "КРИТ") else: self._statistic.append_success( "Тест " + full_test_name + " завершился без критических ошибок!", "УСПЕХ")
def _check_event_comment(event_info: dict, event: dict, statistic: Statistic) -> None: """Функция проверки вхождений значений ключей из event_info в event['evtcomment']. То есть есть ли указанные значения в комментарии события. :param event_info: ключи со значениями, которые надо искать в комментарии; :param event: событие (ответ ws); :param statistic: объект класса Statistic. """ logger = statistic.get_log().get_logger("scripts/tools/analytics") logger.info("was called (event_info: dict, event: dict, statistic: Statistic)") logger.debug("params (client_obj, " + str(event_info) + ", " + str(event) + ", stat_obj)") for key, value in event_info.items(): index = event['evtcomment'].find(value) if index == -1: statistic.append_error("Ожидалось: " + value + ". Получено: " + event['evtcomment'] + "!", "НЕВАЛИД " + key, False) else: statistic.append_success("Получено: '" + event['evtcomment'] + "'", "ВАЛИД " + key)
def run(self): """Запуск тест кейса. :return: """ test_case_statistic = Statistic("Тест-кейс", 1, self._runner_config, self._log) test_threads: list = [] for test in self._tests_config: test_case_statistic.append_success( "----------------------------------ТЕСТ " + test['module'] + "." + test['test'] + "------------------------------------", "ЗАПУСК") for thread in range(test['threads']): test_threads.append( self.TestRunner(thread + 1, test['module'], test['test'], test['input_data'], self._runner_config, self._log)) for thread in test_threads: thread.start() for thread in test_threads: thread.join() test_case_statistic.append_success( "----------------------------------ТЕСТ " + test['module'] + "." + test['test'] + "------------------------------------", "ЗАВЕРШЕНИЕ") for thread in test_threads: statistic = thread.get_statistic() statistic.show_errors_statistic() statistic.show_warns_statistic() if self._runner_config['settings']['create_report']: statistic.create_report() test_threads.clear() time.sleep(test['wait_time']) return True
def run_events_test(ws_client: SoapClient, token: str, cam_info: dict, events: tuple, inaccuracy: int, event_type: int, video_source: str, statistic: Statistic) -> None: """Функция запуска проверки наличия событий по детектору. Каждое событие появляется через определенное время от начала видео. Функция, учитывая погрешность, вычисляет интервал времени, в котором должно быть событие и уходит в sleep на это время. После пробуждения проверяет наличие события в этом интервале, используя ws метод ewriter:exec с командой select и нужными фильтрами. :param ws_client: объект класса SoapClient; :param token: токен авторизации; :param cam_info: информация по камере (сервер, имя, профиль); :param events: список событий из входных данных вида: [ { "time": 15, "info": {...} } ] см. подробное описание в тестах по аналитике, которые используют данную функцию; :param inaccuracy: погрешность для вычисления грациц интервала, в которых должно быть событие; :param event_type: номер события; :param video_source: путь к видеоисточнику (нужен для удобства вывода сообщений); :param statistic: объект класса Statistic. """ if _video_start_expecting(ws_client, token, cam_info, statistic) is False: statistic.append_error("Источник: " + video_source + "!", "НЕТ ВИДЕО") return # Заранее высчитываются временные интервалы, # в которых должны находиться события start_server_time: str = ws_common.get_current_server_time(ws_client, token, statistic) date_start_server_time = tools.get_date_from_str(start_server_time, statistic) for event in events: event_time = tools.increment_time(date_start_server_time, event['time']) left_interval_time_utc = tools.decrement_time(event_time, inaccuracy) right_interval_time_utc = tools.increment_time(event_time, inaccuracy) left_interval_time = str(tools.convert_time_from_gtc(left_interval_time_utc))[:-9] right_interval_time = str(tools.convert_time_from_gtc(right_interval_time_utc))[:-9] left_interval_time_utc = str(left_interval_time_utc) right_interval_time_utc = str(right_interval_time_utc) event.update({ "start": left_interval_time_utc, "end": right_interval_time_utc }) previous_sleep = 0 for index, event in enumerate(events): time.sleep(event['time'] - previous_sleep + inaccuracy) result = _check_event_existing(ws_client, token, event['start'], event['end'], event_type, cam_info, statistic) if result[0] == 0: statistic.append_success("#" + str(index + 1) + " по источнику " + video_source + " в интервале с " + left_interval_time + " по " + right_interval_time + "!", "ПОЛУЧЕНО СОБЫТИЕ") _check_event_comment(event['info'], result[1][0], statistic) elif result[0] == -1: statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " + left_interval_time + " по " + right_interval_time + "!", "НЕТ СОБЫТИЯ") time.sleep(inaccuracy / 2) current_server_time: str = ws_common.get_current_server_time(ws_client, token, statistic) event.update({ "start": start_server_time, "end": current_server_time }) result = _check_event_existing(ws_client, token, event['start'], event['end'], event_type, cam_info, statistic) if result[0] == 0: statistic.append_warn("#" + str(index + 1) + " по источнику " + video_source + " в интервале с " + start_server_time + " по " + current_server_time + "!", "ПОЛУЧЕНО СОБЫТИЕ") _check_event_comment(event['info'], result[1][0], statistic) elif result[0] > 1: statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " + start_server_time + " по " + current_server_time + "!", "МНОГО СОБЫТИй") else: statistic.append_error( "Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " + start_server_time + " по " + current_server_time + "!", "НЕТ СОБЫТИЯ") else: statistic.append_error("Событие #" + str(index + 1) + " по источнику " + video_source + " в интервале с " + left_interval_time + " по " + right_interval_time + "!", "МНОГО СОБЫТИй") previous_sleep = event['time']