Files
Andrey a5e46d4627 Расширить обмен по шинам, CAN-адаптеры и обработку графиков
Добавить очереди операций PBUS/SBUS, общую консоль, настройки Candle и SLCAN, декодеры DSView и обработку плотных графиков. Обновить протокол Бальзам и проверки общих компонентов.
2026-10-17 14:36:14 +03:00

65 lines
4.6 KiB
Python

# Проверки runtime: фиксируют ожидаемое поведение на воспроизводимых входных данных.
# Сценарии для навигации по файлу:
# test_legacy_runtime_and_mismatched_binary_or_recipe_require_rebuild
# test_patch_adapters_and_shared_cores_all_invalidate_runtime
# Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
# настройками рабочего устройства.
"""Prevent packaging a new GUI with a stale native DSView component."""
import hashlib
import importlib.util
import json
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
RECIPE = Path(__file__).resolve().parents[1] / 'build.py'
SPEC = importlib.util.spec_from_file_location('dsview_runtime_build', RECIPE)
BUILD = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(BUILD)
class RuntimeTests(unittest.TestCase):
def test_legacy_runtime_and_mismatched_binary_or_recipe_require_rebuild(self):
with tempfile.TemporaryDirectory() as temporary:
output = Path(temporary)
(output / 'DSView.exe').write_bytes(b'native fixture')
(output / 'host-protocol-1').write_text('DSView host protocol 1\n')
self.assertFalse(BUILD.runtime_is_current(output))
stamp = {'recipe': 'new', 'executable': hashlib.sha256(b'native fixture').hexdigest()}
(output / 'host-build.json').write_text(json.dumps(stamp))
with patch.object(BUILD, 'recipe_digest', return_value='new'):
self.assertTrue(BUILD.runtime_is_current(output))
(output / 'DSView.exe').write_bytes(b'old native fixture')
self.assertFalse(BUILD.runtime_is_current(output))
(output / 'DSView.exe').write_bytes(b'native fixture')
with patch.object(BUILD, 'recipe_digest', return_value='changed'):
self.assertFalse(BUILD.runtime_is_current(output))
(output / 'host-build.json').write_text('partial JSON')
self.assertFalse(BUILD.runtime_is_current(output))
def test_patch_adapters_and_shared_cores_all_invalidate_runtime(self):
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
recipe = root / 'tools/dsview'
recipe.mkdir(parents=True) # Временный рецепт воспроизводит относительную структуру закреплённого templates.
(recipe / 'protocol-files.json').write_bytes(RECIPE.with_name('protocol-files.json').read_bytes()) # Реальная ведомость гарантирует включение новых зависимостей и карт.
files = [recipe / 'build.py', recipe / 'setgui-host.patch', recipe / 'gate-pair-checkbox.patch', recipe / 'decoder-panel.patch', recipe / 'driver-summary.patch', recipe / 'windows-usb-events.patch', recipe / 'native/gate_summary.h',
recipe / 'decoders/gate_driver_timing/pd.py']
files += [root / item.relative_to(RECIPE.parents[2]) for item, _ in BUILD.protocol_payload()] # Проверка охватывает все канонические модули и JSON-карты, перечисленные в поставке.
for item in files:
item.parent.mkdir(parents=True, exist_ok=True) # Для каждого переносимого пакета создаются вложенные каталоги.
item.write_text('initial')
with patch.object(BUILD, '__file__', str(recipe / 'build.py')):
initial = BUILD.recipe_digest()
for item in files:
with self.subTest(file=item.name):
item.write_text('changed')
self.assertNotEqual(initial, BUILD.recipe_digest())
item.write_text('initial')
self.assertEqual(initial, BUILD.recipe_digest())
with (recipe / 'protocol-files.json').open('a', encoding='utf-8') as output: # Пробел меняет хеш, сохраняя корректность JSON-ведомости.
output.write('\n') # Изменение самого состава поставки также должно требовать обновления runtime.
self.assertNotEqual(initial, BUILD.recipe_digest()) # Устаревшая ведомость не допускается к упаковке незаметно.