Добавить очереди операций PBUS/SBUS, общую консоль, настройки Candle и SLCAN, декодеры DSView и обработку плотных графиков. Обновить протокол Бальзам и проверки общих компонентов.
65 lines
4.6 KiB
Python
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()) # Устаревшая ведомость не допускается к упаковке незаметно.
|