31 lines
4.9 KiB
Python
31 lines
4.9 KiB
Python
"""Проверка точности и масштабируемости нативного индекса кривой PWM.""" # Тест компилирует фактическую реализацию DSView без подключения прибора.
|
||
import os # Изолированное окружение содержит DLL выбранного MSYS2 SDK.
|
||
from pathlib import Path # Пути вычисляются относительно теста и настроенного SDK.
|
||
import subprocess # Нативный тест запускается отдельным процессом с проверкой кода возврата.
|
||
import tempfile # Исполняемый файл создаётся вне исходников и автоматически удаляется.
|
||
import unittest # Проверка входит в существующий набор unittest discover.
|
||
|
||
|
||
class PwmEnvelopeTests(unittest.TestCase): # Функциональные и нагрузочные сценарии используют реальный заголовок C++.
|
||
def test_native_extrema_zoom_gaps_and_million_periods(self): # Один запуск проверяет данные и ограниченную геометрию длинного захвата.
|
||
candidates = [Path(os.environ.get('SETGUI_MSYS_ROOT', 'C:/msys64')), Path('C:/setcorp/tools/msys64')] # Учитываем явную настройку и оба поддерживаемых расположения SDK.
|
||
prefix = next((root / 'ucrt64' for root in candidates if (root / 'ucrt64/bin/g++.exe').is_file()), None) # Компилятор должен принадлежать тому же SDK, что заголовки и DLL Qt.
|
||
if os.name != 'nt' or prefix is None: # Переносимые Python-тесты продолжают работать без необязательного нативного SDK.
|
||
self.skipTest('Для нативного теста необходим Windows MSYS2 UCRT64 с Qt 5.') # Причина пропуска видна в отчёте unittest.
|
||
recipe = Path(__file__).resolve().parents[1] # Заголовок и тест берутся из одного рецепта DSView.
|
||
env = dict(os.environ) # Сохраняем стандартные системные настройки процесса компилятора.
|
||
env['PATH'] = str(prefix / 'bin') + os.pathsep + env.get('PATH', '') # Компилятор и тест находят DLL UCRT64 без глобального изменения PATH.
|
||
with tempfile.TemporaryDirectory(prefix='pwm-envelope-') as temporary: # Все создаваемые бинарные файлы принадлежат только текущему тесту.
|
||
executable = Path(temporary) / 'pwm-envelope.exe' # Результат компиляции не меняет установленный DSView.
|
||
includes = [recipe / 'native', prefix / 'include', prefix / 'include/QtCore', prefix / 'include/QtGui'] # QtGui предоставляет используемые заголовком типы QPainter и QLineF.
|
||
command = [str(prefix / 'bin/g++.exe'), '-std=c++11', '-O2', *('-I' + str(path) for path in includes), str(recipe / 'tests/pwm_envelope.cpp'), '-L' + str(prefix / 'lib'), '-lQt5Gui', '-lQt5Core', '-o', str(executable)] # Стандарт C++11 совпадает с нативной сборкой DSView, оптимизация моделирует рабочий компонент.
|
||
compiled = subprocess.run(command, env=env, capture_output=True, text=True, errors='replace', timeout=60) # Ограничение времени выявляет зависший компилятор без бесконечного ожидания.
|
||
self.assertEqual(compiled.returncode, 0, compiled.stdout + compiled.stderr) # Ошибки компиляции сообщаются вместе с диагностикой SDK.
|
||
checked = subprocess.run([str(executable)], env=env, capture_output=True, text=True, errors='replace', timeout=30) # Миллион периодов должен обрабатываться в ограниченное время.
|
||
self.assertEqual(checked.returncode, 0, checked.stdout + checked.stderr) # Сам C++-тест независимо проверяет экстремумы, разрывы, очистку и точный крупный масштаб.
|
||
print(checked.stdout.strip()) # Измеренная задержка кадра сохраняется в отчёте для сравнения производительности.
|
||
|
||
|
||
if __name__ == '__main__': # Файл можно запустить отдельно или через общий unittest discover.
|
||
unittest.main() # Стандартный запуск возвращает ненулевой код при нарушении проверяемых свойств.
|