Загрузка данных
сцен ини
"""
Модуль сценариев тестов.
Содержит функции-обёртки для каждого типа теста.
Функции называются так же, как тесты, но без префикса test_.
Для добавления нового теста необходимо добавить в список __all__ название этого теста scenarios.your_new_test
"""
import test_scenarios.smoke_scenarios as scenarios
from test_scenarios import (
lds_configurator_scenarios,
lds_status_scenarios,
rejected_scenarios,
stationary_status_scenarios,
)
__all__ = [
scenarios.basic_info,
scenarios.messages_exist_in_journal,
scenarios.imitate_sensor_signal,
scenarios.lds_status_initialization,
scenarios.lds_status_init_in_journal,
scenarios.main_page_info,
scenarios.main_page_info_signals,
scenarios.mask_info_in_journal,
scenarios.mask_signal_test,
scenarios.lds_status_initialization_out,
scenarios.lds_status_init_out_in_journal,
scenarios.all_leaks_info,
scenarios.leak_info_in_journal,
scenarios.possible_leak_in_journal,
scenarios.tu_leaks_info,
scenarios.lds_status_during_leak,
scenarios.acknowledge_leak_info,
scenarios.acknowledge_leak_in_journal,
scenarios.output_signals,
scenarios.balance_algorithm_leak_completed,
scenarios.completed_leak_info_in_journal,
scenarios.stationary_status_in_journal,
rejected_scenarios.rejection_input_signals,
rejected_scenarios.rejection_journal,
rejected_scenarios.rejection_main_page,
rejected_scenarios.rejection_scheme_signals_state,
lds_status_scenarios.lds_status_check_with_reasons,
scenarios.export_leaks_report,
scenarios.export_lds_status_report,
scenarios.export_mt_mode_report,
lds_configurator_scenarios.lds_configurator_admin_setup,
lds_configurator_scenarios.lds_configurator_verify_after_core,
lds_configurator_scenarios.lds_configurator_teardown,
stationary_status_scenarios.stationary_status_check_with_reasons,
stationary_status_scenarios.stationary_status_in_journal,
]
лдс конф сцен
"""
Сценарии setup/teardown СОУ через раздел Администрирование (LDS Configurator).
"""
from __future__ import annotations
import asyncio
import logging
from typing import Any, Dict, Optional
from pytest import fail
from clients.http_client import StandHttpClient
from clients.websocket_client import WebSocketClient
from constants.architecture_constants import HTTPClientConstants as HttpConst
from constants.enums import SouAdminStatus
from constants.test_constants import LdsConfiguratorConstants as LdsCfgConst
from test_config.models_for_tests import BaseSuiteConfig
from utils.helpers import lds_configurator_utils as lds_utils
from utils.helpers import ws_test_utils as t_utils
from utils.helpers.ws_message_parser import ws_message_parser as parser
logger = logging.getLogger(__name__)
def _save_group_state(group_state: Optional[Dict[str, Any]], cfg: BaseSuiteConfig, tu_id: int) -> None:
"""
Сохраняет resolved tu_id и флаги в group_state для teardown в conftest.
"""
if group_state is None:
return
group_state["use_lds_configurator"] = cfg.use_lds_configurator
group_state["resolved_tu_id"] = tu_id
group_state["admin_tu_name"] = cfg.admin_tu_name
def _save_pre_run_running_tus(
group_state: Optional[Dict[str, Any]],
snapshot: list[Dict[str, Any]],
) -> None:
"""Сохраняет список включённых ТУ стенда до запуска автотестов."""
if group_state is None:
return
group_state["pre_run_running_tus"] = snapshot
async def lds_configurator_admin_setup(
http_client: StandHttpClient,
cfg: BaseSuiteConfig,
group_state: Optional[Dict[str, Any]] = None,
) -> None:
"""
Холодный запуск СОУ через Администрирование до старта имитатора.
1. Получить tu_id по admin_tu_name из GetBasicInfoAdmin.
2. Снять слепок всех RUNNING ТУ и остановить их на стенде.
3. LaunchLdsRequest и ожидание status=включена.
4. Подтвердить launchedAt в GetTusInformation.
"""
tu_id: int
logger.info("[SETUP] Получение ТУ '%s' из Администрирования", cfg.admin_tu_name)
admin_reply = lds_utils.get_basic_info_admin_with_retry(http_client, parser)
admin_tu = lds_utils.find_tu_by_name(admin_reply, cfg.admin_tu_name)
lds_utils.validate_admin_tu(admin_tu)
tu_id = admin_tu.tuId
cfg.resolved_tu_id = tu_id
_save_group_state(group_state, cfg, tu_id)
logger.info(
"[SETUP] Найден ТУ: tuId=%s, tuName=%r, status=%s (%s)",
tu_id,
admin_tu.tuName,
SouAdminStatus(admin_tu.status),
SouAdminStatus.report_text_by_value(admin_tu.status),
)
running_tus = lds_utils.extract_running_tus(admin_reply)
pre_run_snapshot = lds_utils.running_tus_to_snapshot(running_tus)
_save_pre_run_running_tus(group_state, pre_run_snapshot)
logger.info(
"[SETUP] Список включённых ТУ на стенде: %s шт. %s",
len(pre_run_snapshot),
pre_run_snapshot,
)
await lds_utils.stop_all_running_tus(http_client, parser, running_tus)
logger.info("[SETUP] ТЕСТ УСПЕХ await lds_utils.stop_all_running_tus")
launch_checkpoint = t_utils.moscow_now()
logger.info(
"[SETUP] Момент фиксации времени перед LaunchLds: %s",
t_utils.format_datetime_moscow(launch_checkpoint),
)
logger.info("[SETUP] Холодный запуск СОУ (LaunchLdsRequest) для tuId=%s", tu_id)
lds_utils.run_lds_command(http_client, HttpConst.LAUNCH_LDS_URL_PATH, tu_id)
logger.info("[SETUP] Ожидание включения СОУ в Администрировании")
if not await lds_utils.poll_admin_tu_status(http_client, parser, tu_id, SouAdminStatus.RUNNING):
fail(
"Не удалось запустить СОУ: статус в Администрировании не стал 'включена' за 2 минуты",
pytrace=False,
)
logger.info("[SETUP] Подтверждение времени запуска (GetTusInformation)")
lds_utils.verify_launched_at(http_client, parser, tu_id, launch_checkpoint)
async def lds_configurator_verify_after_core(
ws_client: WebSocketClient,
http_client: StandHttpClient,
cfg: BaseSuiteConfig,
) -> None:
"""
Проверка готовности стенда после запуска lds-core.
1. Актуальный статус СОУ из Администрирования.
2. Ожидание согласованного состояния ТУ на Состоянии МТ в BasicInfo из общего запаса времени.
3. Ожидание согласованного состояния ТУ на Состоянии МТ в MainPageInfoContent - остаток от общего запаса времени.
4. Сверка статуса СОУ: Администрирование vs Состояние МТ.
"""
tu_id = cfg.tu_id
tu_name = cfg.tu_name
logger.info("[SETUP] Получение актуального статуса СОУ для tuId=%s", tu_id)
admin_reply = lds_utils.get_basic_info_admin_with_retry(http_client, parser)
sou_status = lds_utils.get_admin_tu_status(admin_reply, tu_id)
if sou_status is None:
fail(
f"ТУ tuId={tu_id} ('{tu_name}') не найден в GetBasicInfoAdminResponse",
pytrace=False,
)
expect_enabled = sou_status == SouAdminStatus.RUNNING
action = "появления" if expect_enabled else "отсутствия"
loop = asyncio.get_running_loop()
if expect_enabled:
ui_sync_time_total = LdsCfgConst.VERIFY_UI_SYNC_TIME_SECONDS
admin_label = "Admin=RUNNING"
else:
ui_sync_time_total = LdsCfgConst.POLL_TIMEOUT_SECONDS
admin_label = "Admin=STOPPED"
ui_sync_time_seconds = int(ui_sync_time_total)
ui_sync_deadline = loop.time() + ui_sync_time_total
basic_timeout = ui_sync_deadline - loop.time()
logger.info(
"[SETUP] %s, запас времени %s с, ожидание %s ТУ в BasicInfo (до %s с)",
admin_label,
ui_sync_time_seconds,
action,
int(basic_timeout),
)
basic_info_poll_ok = await lds_utils.poll_basic_info_tu_presence(
http_client, parser, tu_id, tu_name, expect_present=expect_enabled, total_wait_seconds=basic_timeout
)
if not basic_info_poll_ok:
if expect_enabled:
fail(
f"СОУ не отображается на Состоянии МТ в BasicInfo: ТУ не появилась за {ui_sync_time_seconds} c "
f"после запуска core",
pytrace=False,
)
fail(
"СОУ отображается на Состоянии МТ в BasicInfo при статусе 'выключена' в Администрировании",
pytrace=False,
)
main_timeout = ui_sync_deadline - loop.time()
if main_timeout <= 0:
fail(
f"Весь запас времени {ui_sync_time_seconds} для синхронизации подписок израсходован на ожидание BasicInfo"
"на MainPage времени не осталось"
)
logger.info(
"[SETUP] Ожидание %s ТУ в Состоянии МТ (остаток запаса времени %s с)",
action,
int(main_timeout),
)
main_page_poll_ok = await lds_utils.poll_main_page_tu_presence(
ws_client, tu_id, expect_present=expect_enabled, total_wait_seconds=main_timeout
)
if not main_page_poll_ok:
if expect_enabled:
fail(
"СОУ не отображается в Состоянии МТ: ТУ не появилась за оставшееся время запаса для синхронизации"
f"({ui_sync_time_seconds} c после запуска core)",
pytrace=False,
)
fail(
"СОУ отображается в Состоянии МТ при статусе 'выключена' в Администрировании",
pytrace=False,
)
logger.info("[SETUP] Сверка статуса СОУ: Администрирование vs Состояние МТ")
lds_utils.check_sou_status_sync(sou_status, expect_enabled, expect_enabled, tu_id, tu_name)
async def lds_configurator_teardown(
ws_client: WebSocketClient,
http_client: StandHttpClient,
tu_id: int,
admin_tu_name: str,
pre_run_running_tus: Optional[list[Dict[str, Any]]] = None,
) -> None:
"""
Teardown набора: остановка СОУ автотестов и восстановление ТУ стенда из снимка.
Некритичные отклонения логируются без падения прогона.
"""
snapshot = pre_run_running_tus or []
try:
logger.info("[TEARDOWN] Проверка статуса СОУ (tuId=%s, «%s»)", tu_id, admin_tu_name)
ws_client.clear_queue()
admin_reply = lds_utils.get_basic_info_admin_with_retry(http_client, parser)
sou_status = lds_utils.get_admin_tu_status(admin_reply, tu_id)
if sou_status == SouAdminStatus.RUNNING:
logger.info("[TEARDOWN] Остановка СОУ (StopLdsRequest) для tuId=%s", tu_id)
lds_utils.run_lds_command(http_client, HttpConst.STOP_LDS_URL_PATH, tu_id)
logger.info("[TEARDOWN] Ожидание выключения СОУ в Администрировании")
if not await lds_utils.poll_admin_tu_status(http_client, parser, tu_id, SouAdminStatus.STOPPED):
lds_utils.attach_allure_alert(
f"СОУ не выключилась за 2 минуты после StopLdsRequest. "
f"tuId={tu_id}, adminTuName={admin_tu_name!r}. Проверить вручную."
)
else:
lds_utils.attach_allure_alert(
f"СОУ не в статусе 'включена' при teardown (status={sou_status}), остановка пропущена. "
f"tuId={tu_id}, adminTuName='{admin_tu_name}'"
)
await lds_utils.restore_pre_run_tus(http_client, parser, snapshot, exclude_tu_id=tu_id)
except BaseException as error:
logger.warning(
"[TEARDOWN] [ALERT] LDS Configurator teardown: %s: %r. tuId=%s, adminTuName=%r",
type(error).__name__,
error,
tu_id,
admin_tu_name,
)
lds_utils.attach_allure_alert(
f"Ошибка LDS Configurator teardown: {type(error).__name__}: {error!r}. "
f"tuId={tu_id}, adminTuName={admin_tu_name!r}"
)
лдс статус сцен
"""
Сценарии тестов по режимам СОУ - функции-обёртки без pytest маркеров.
Каждая функция содержит логику одного теста.
Pytest маркеры и allure декораторы применяются в тестовых файлах.
"""
import time
from datetime import datetime
import allure
from constants.architecture_constants import HTTPClientConstants as HttpConst
from constants.enums import Direction, LdsStatus, MessageType, ReplyStatus, StationaryStatus
from constants.test_constants import BaseTN3Constants as TestConst
from models.get_messages_model import Filtering, FilteringObjects, Pagination
from test_config.models_for_tests import CaseData, LDSStatusConfig, SmokeSuiteConfig
from utils.helpers import ws_test_utils as t_utils
from utils.helpers.asserts import SoftAssertions, StepCheck
from utils.helpers.ws_message_parser import ws_message_parser as parser
async def lds_status_check_on_longest_flow_area(ws_client, cfg: LDSStatusConfig, test_data: CaseData):
"""
Проверка Инициализации и причины инициализации СОУ на самом протяженном участке карты течений
"""
# Распаковка данных для теста
expected_lds_status, expected_lds_status_reasons = test_data.expected_result
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
# Получает список участков карты течения
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
# Получает самый протяженный участок карты течения
longest_flow_area = t_utils.get_longest_flow_area(flow_areas)
# Получает список ДУ
diagnostic_areas = getattr(longest_flow_area, 'diagnosticAreas', [])
StepCheck("Проверка наличия данных диагностических участков", "diagnosticAreas").actual(
diagnostic_areas
).is_not_empty()
with SoftAssertions() as soft_failures:
for diagnostic_area in diagnostic_areas:
diagnostic_area_lds_status = LdsStatus(diagnostic_area.ldsStatus) if diagnostic_area.ldsStatus else None
StepCheck(f"Проверка режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatus", soft_failures).actual(
diagnostic_area_lds_status
).expected(expected_lds_status).equal_to()
lds_status_reasons = t_utils.parse_lds_status_reasons(
diagnostic_area.ldsStatus, diagnostic_area.ldsStatusReasons, soft_failures
)
StepCheck(
f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons", soft_failures
).contains(lds_status_reasons, expected_lds_status_reasons)
async def lds_status_check_with_reasons(ws_client, cfg: SmokeSuiteConfig | LDSStatusConfig, test_data: CaseData):
"""
Проверка режима работы и причины режима СОУ на заданном ДУ
"""
# Распаковка данных для теста
pipe_id = test_data.params.get("pipe_id")
expected_lds_status, expected_lds_status_reasons = test_data.expected_result
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
# Получает список участков карты течения
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
# Получает ДУ
diagnostic_area = t_utils.find_diagnostic_area_by_pipe_id(flow_areas, pipe_id)
StepCheck("Проверка наличия данных диагностического участка", "diagnosticAreas").actual(
diagnostic_area
).is_not_none()
diagnostic_area_lds_status = LdsStatus(diagnostic_area.ldsStatus) if diagnostic_area.ldsStatus else None
StepCheck(f"Проверка режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatus").actual(
diagnostic_area_lds_status
).expected(expected_lds_status).equal_to()
if diagnostic_area_lds_status != LdsStatus.SERVICEABLE:
lds_status_reasons = t_utils.parse_lds_status_reasons(
diagnostic_area.ldsStatus, diagnostic_area.ldsStatusReasons
)
StepCheck(f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons").contains(
lds_status_reasons, expected_lds_status_reasons
)
async def lds_status_check_with_2_reasons(ws_client, cfg: SmokeSuiteConfig | LDSStatusConfig, test_data: CaseData):
"""
Проверка режима работы СОУ и двух причин режима работы СОУ на заданном ДУ
"""
# Распаковка данных для теста
pipe_id = test_data.params.get("pipe_id")
expected_lds_status, expected_lds_status_reason_1, expected_lds_status_reason_2 = test_data.expected_result
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
# Получает список участков карты течения
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
# Получает ДУ
diagnostic_area = t_utils.find_diagnostic_area_by_pipe_id(flow_areas, pipe_id)
StepCheck("Проверка наличия данных диагностического участка", "diagnosticAreas").actual(
diagnostic_area
).is_not_none()
diagnostic_area_lds_status = LdsStatus(diagnostic_area.ldsStatus) if diagnostic_area.ldsStatus else None
StepCheck(f"Проверка режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatus").actual(
diagnostic_area_lds_status
).expected(expected_lds_status).equal_to()
if diagnostic_area_lds_status != LdsStatus.SERVICEABLE:
with SoftAssertions() as soft_failures:
lds_status_reasons = t_utils.parse_lds_status_reasons(
diagnostic_area.ldsStatus, diagnostic_area.ldsStatusReasons, soft_failures
)
StepCheck(
f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons", soft_failures
).contains(lds_status_reasons, expected_lds_status_reason_1)
StepCheck(
f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons", soft_failures
).contains(lds_status_reasons, expected_lds_status_reason_2)
async def lds_status_check_on_multiple_diagnostic_areas(
ws_client, cfg: SmokeSuiteConfig | LDSStatusConfig, test_data: CaseData
):
"""
Проверка режима работы и причины режима СОУ на заданных ДУ
"""
# Распаковка данных для теста
pipe_ids = test_data.params.get("pipe_ids")
expected_result = test_data.expected_result
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
diagnostic_areas = t_utils.find_diagnostic_areas_by_pipe_ids(flow_areas, pipe_ids)
StepCheck("Проверка наличия данных диагностических участков", "diagnosticAreas").actual(
diagnostic_areas
).is_not_empty()
lds_status_set = {diagnostic_area.ldsStatus for diagnostic_area in diagnostic_areas}
lds_status_int = t_utils.determine_lds_status_by_priority(lds_status_set)
lds_status = LdsStatus(lds_status_int) if lds_status_int else None
StepCheck(
"Проверка режима работы СОУ на заданных ДУ",
"ldsStatus",
).actual(
lds_status
).expected(expected_result).equal_to()
async def lds_and_stationary_status_check_with_reasons(
ws_client, cfg: SmokeSuiteConfig | LDSStatusConfig, test_data: CaseData
):
"""
Проверка режима работы и причины режима СОУ и МТ на заданном ДУ
"""
# Распаковка данных для теста
pipe_id = test_data.params.get("pipe_id")
(
expected_lds_status,
expected_lds_status_reasons,
expected_stationary_status,
expected_stationary_status_reasons,
) = test_data.expected_result
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
# Получает список участков карты течения
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
# Получает ДУ
diagnostic_area = t_utils.find_diagnostic_area_by_pipe_id(flow_areas, pipe_id)
StepCheck("Проверка наличия данных диагностического участка", "diagnosticAreas").actual(
diagnostic_area
).is_not_none()
diagnostic_area_lds_status = LdsStatus(diagnostic_area.ldsStatus) if diagnostic_area.ldsStatus else None
diagnostic_area_stationary_status = (
StationaryStatus(diagnostic_area.stationaryStatus) if diagnostic_area.stationaryStatus else None
)
StepCheck(f"Проверка режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatus").actual(
diagnostic_area_lds_status
).expected(expected_lds_status).equal_to()
StepCheck(f"Проверка режима работы МТ на ДУ с id:{diagnostic_area.id}", "stationaryStatus").actual(
diagnostic_area_stationary_status
).expected(expected_stationary_status).equal_to()
with SoftAssertions() as soft_failures:
lds_status_reasons = t_utils.parse_lds_status_reasons(
diagnostic_area.ldsStatus, diagnostic_area.ldsStatusReasons, soft_failures
)
stationary_status_reasons = t_utils.parse_stationary_status_reasons(
diagnostic_area.stationaryStatus, diagnostic_area.stationaryStatusReasons, soft_failures
)
StepCheck(
f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons", soft_failures
).contains(lds_status_reasons, expected_lds_status_reasons)
StepCheck(
f"Проверка причины режима работы МТ на ДУ с id:{diagnostic_area.id}",
"stationaryStatusReasons",
soft_failures,
).contains(stationary_status_reasons, expected_stationary_status_reasons)
async def lds_status_check_degradation_pig_sensor_passage(
ws_client, cfg: SmokeSuiteConfig | LDSStatusConfig, test_data: CaseData
):
"""
Проверка режима работы и причины режима СОУ на заданном ДУ, с командой на включение СОД
"""
# Распаковка данных для теста
pipe_id = test_data.params.get("pipe_id")
pig_trap_id = test_data.params.get("pig_trap_id")
expected_lds_status, expected_lds_status_reasons = test_data.expected_result
with allure.step("Подключение по ws, отправка сообщения и обработка ответа о запуске СОД: LaunchPigRequest"):
payload = await t_utils.connect_and_get_msg(
ws_client,
"LaunchPigRequest",
{'pigTrapId': pig_trap_id, 'tuId': cfg.tu_id, 'timeToLaunch': 0, 'additionalProperties': None},
)
parsed_payload = parser.parse_launch_pig_msg(payload)
launch_pig_reply_status = parsed_payload.replyStatus
time.sleep(cfg.basic_message_timeout)
with allure.step("Подключение по ws, получение и обработка сообщения типа: CommonSchemeContent"):
payload = await t_utils.connect_and_subscribe_msg(
ws_client,
"CommonSchemeContent",
"SubscribeCommonSchemeRequest",
{'tuId': cfg.tu_id, 'additionalProperties': None},
)
parsed_payload = parser.parse_common_scheme_info_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
# Получает список участков карты течения
flow_areas = getattr(parsed_payload.replyContent, 'flowAreas', [])
# Получает ДУ
diagnostic_area = t_utils.find_diagnostic_area_by_pipe_id(flow_areas, pipe_id)
StepCheck("Проверка наличия данных диагностического участка", "diagnosticAreas").actual(
diagnostic_area
).is_not_none()
diagnostic_area_lds_status = LdsStatus(diagnostic_area.ldsStatus) if diagnostic_area.ldsStatus else None
StepCheck(f"Проверка режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatus").actual(
diagnostic_area_lds_status
).expected(expected_lds_status).equal_to()
lds_status_reasons = t_utils.parse_lds_status_reasons(diagnostic_area.ldsStatus, diagnostic_area.ldsStatusReasons)
StepCheck(f"Проверка причины режима работы СОУ на ДУ с id:{diagnostic_area.id}", "ldsStatusReasons").contains(
lds_status_reasons, expected_lds_status_reasons
)
StepCheck("Проверка кода ответа на запрос о запуске СОД", "replyStatus").actual(launch_pig_reply_status).expected(
ReplyStatus.OK.value
).equal_to()
def lds_status_in_journal(http_client, cfg: LDSStatusConfig, test_data: CaseData):
"""
Проверка наличия записи в журнале о выходе СОУ из режима Инициализация.
"""
# Распаковка данных для теста
control_points = test_data.params.get("control_points")
if isinstance(test_data.expected_result, tuple):
expected_lds_status, expected_lds_status_reasons = test_data.expected_result
else:
expected_lds_status, expected_lds_status_reasons = test_data.expected_result, None
with allure.step("Http запрос сообщений журнала с фильтром messageTypes=MASKING_LDS"):
end_time = datetime.now()
start_time = t_utils.datetime_minus_seconds(end_time, TestConst.JOURNAL_STATUS_TOTAL_WAIT)
request_body = t_utils.create_journal_req_body(
pagination=Pagination(limit=TestConst.JOURNAL_PAGINATION_STATUS_LIMIT, direction=Direction.FIRST.value),
filtering=Filtering(messageTypes=int(MessageType.LDS_STATUS), objects=FilteringObjects(tuId=cfg.tu_id)),
)
response = http_client.post_request(HttpConst.GET_MESSAGES_URL_PATH, request_body)
payload = t_utils.get_json_from_http_response(response)
parsed_payload = parser.parse_journal_msg(payload)
with allure.step("Извлечение и подготовка данных для проверки"):
messages_info = getattr(parsed_payload.replyContent, 'messagesInfo', [])
StepCheck("Проверка наличия сообщений в журнале", "messagesInfo").actual(messages_info).is_not_empty()
with allure.step("Фильтрация сообщений по времени и controlPoint"):
filter_start_msk = t_utils.localize_as_moscow(start_time)
filter_end_msk = t_utils.localize_as_moscow(end_time)
lds_msg_by_control_points = []
time_filtered = [
msg
for msg in messages_info
if filter_start_msk <= t_utils.ensure_moscow_timezone(msg.time) <= filter_end_msk
]
time_filtered.sort(key=lambda msg: t_utils.ensure_moscow_timezone(msg.time), reverse=True)
# Поиск нужных сообщений по КП
for control_point in control_points:
lds_msg = next(
(msg for msg in time_filtered if msg.controlPoint == control_point),
None,
)
if lds_msg:
lds_msg_by_control_points.append(lds_msg)
StepCheck(
f"Проверка наличия сообщений c controlPoint из списка {control_points} в журнале", "messagesInfo"
).actual(lds_msg_by_control_points).is_not_empty()
with SoftAssertions() as soft_failures:
for msg in lds_msg_by_control_points:
msg_event = getattr(msg, 'event', None)
cp_lds_status, cp_lds_status_reasons = t_utils.parse_event(msg_event)
StepCheck(f"Проверка режима работы СОУ на КП:{msg.controlPoint}", "event", soft_failures).actual(
cp_lds_status
).expected(expected_lds_status).equal_to()
if cp_lds_status != LdsStatus.SERVICEABLE.report_text:
StepCheck(
f"Проверка причины режима работы СОУ на КП:{msg.controlPoint}", "event", soft_failures
).contains(cp_lds_status_reasons, expected_lds_status_reasons)