kvs/тесты/тест_бнд/тест_бнд.py

193 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import subprocess
import sys
import os
import re
from pathlib import Path
SCRIPT_DIR = Path(__file__).parent.absolute()
PROJECT_ROOT = SCRIPT_DIR.parent.parent
SOURCE_REL = SCRIPT_DIR / "тест_бнд.квс"
def clean():
files = [
"тест_бнд.elf",
"тест_бнд.csv",
"тест_бнд.аст",
"тест_бнд.токены",
"тест_бнд.константа",
"тест_бнд_pass4.log"
]
for f in files:
f_path = SCRIPT_DIR / f
if f_path.exists():
f_path.unlink()
def build():
os.chdir(PROJECT_ROOT)
build = subprocess.run(["python3", "kvs_build.py", str(SOURCE_REL)],
capture_output=True, text=True)
if build.returncode != 0:
print(f"❌ Ошибка сборки: {build.returncode}", file=sys.stderr)
print(build.stderr, file=sys.stderr)
return False
return True
def test_file_size():
"""Проверка: файл должен быть маленьким (BSS не в файле)"""
print("DEBUG: Проверка размера файла", file=sys.stderr)
elf_path = SCRIPT_DIR / "тест_бнд.elf"
size = elf_path.stat().st_size
max_size = 100 * 1024 # 100 КБ
if size >= max_size:
print(f"❌ Размер файла {size} байт (ожидалось < {max_size})", file=sys.stderr)
return False
print(f"DEBUG: Размер файла {size} байт (OK)", file=sys.stderr)
return True
def test_bss_section():
"""Проверка секции .bss через readelf -S"""
print("DEBUG: Проверка секции .bss", file=sys.stderr)
os.chdir(SCRIPT_DIR)
result = subprocess.run(["readelf", "-S", "тест_бнд.elf"],
capture_output=True, text=True)
lines = result.stdout.split('\n')
expected_size = 1048576 # 1 МБ = 0x100000
for i, line in enumerate(lines):
if '.bss' in line and 'NOBITS' in line:
if i + 1 < len(lines):
size_line = lines[i + 1].strip()
match = re.search(r'^([0-9a-fA-F]+)', size_line)
if match:
size = int(match.group(1), 16)
if size == expected_size:
print(f"DEBUG: Размер .bss = {size} (OK)", file=sys.stderr)
return True
else:
print(f"❌ Размер .bss = {size} (ожидался {expected_size})", file=sys.stderr)
return False
print("❌ Секция .bss не найдена или имеет неверный формат", file=sys.stderr)
return False
def test_load_segment():
"""Проверка сегмента LOAD с BSS"""
print("DEBUG: Проверка сегмента LOAD", file=sys.stderr)
os.chdir(SCRIPT_DIR)
result = subprocess.run(["readelf", "-l", "тест_бнд.elf"],
capture_output=True, text=True)
print("DEBUG: Вывод readelf -l:", file=sys.stderr)
print(result.stdout, file=sys.stderr)
lines = result.stdout.split('\n')
expected_min = 1048576
# Поиск LOAD сегмента с RW
for i, line in enumerate(lines):
print(f"DEBUG: Строка {i}: {repr(line)}", file=sys.stderr)
if 'LOAD' in line and 'RW' in line:
print(f"DEBUG: Найден LOAD RW на строке {i}: {line}", file=sys.stderr)
# Ищем в следующих строках p_memsz
for j in range(i + 1, min(i + 5, len(lines))):
print(f"DEBUG: Строка {j}: {repr(lines[j])}", file=sys.stderr)
# Формат: 0x0000000000000001 0x0000000000101000 RW 0x1000
matches = re.findall(r'0x([0-9a-fA-F]+)', lines[j])
print(f"DEBUG: Найдено hex: {matches}", file=sys.stderr)
if len(matches) >= 2:
filesz = int(matches[0], 16)
memsz = int(matches[1], 16)
print(f"DEBUG: p_filesz = {filesz}, p_memsz = {memsz}", file=sys.stderr)
if memsz >= expected_min:
print(f"DEBUG: p_memsz = {memsz} (OK)", file=sys.stderr)
return True
else:
print(f"❌ p_memsz = {memsz} (ожидалось >= {expected_min})", file=sys.stderr)
return False
break
else:
# Альтернативный поиск: ищем по соответствию с .bss
print("DEBUG: LOAD RW не найден, ищем по соответствию с .bss", file=sys.stderr)
in_mapping = False
for i, line in enumerate(lines):
if 'Соответствие раздел-сегмент' in line:
in_mapping = True
print(f"DEBUG: Найдено 'Соответствие раздел-сегмент' на строке {i}", file=sys.stderr)
continue
if in_mapping and '.bss' in line:
print(f"DEBUG: Найдена строка с .bss: {line}", file=sys.stderr)
# Находим номер сегмента
seg_match = re.search(r'(\d+)', line)
if seg_match:
seg_num = int(seg_match.group(1))
print(f"DEBUG: Сегмент {seg_num} содержит .bss", file=sys.stderr)
# Теперь ищем этот сегмент в заголовках
for k, l in enumerate(lines):
if f'LOAD' in l and k < i:
print(f"DEBUG: Найден LOAD на строке {k}: {l}", file=sys.stderr)
# Проверяем его размер
for m in range(k + 1, min(k + 5, len(lines))):
matches = re.findall(r'0x([0-9a-fA-F]+)', lines[m])
if len(matches) >= 2:
memsz = int(matches[1], 16)
if memsz >= expected_min:
print(f"DEBUG: p_memsz = {memsz} (OK)", file=sys.stderr)
return True
break
print("Не найден LOAD сегмент с BSS", file=sys.stderr)
return False
def test_execution():
"""Проверка: программа должна выполниться и вернуть 0"""
print("DEBUG: Проверка выполнения", file=sys.stderr)
os.chdir(SCRIPT_DIR)
elf_path = SCRIPT_DIR / "тест_бнд.elf"
run = subprocess.run([str(elf_path)], capture_output=True, text=True)
if run.returncode != 0:
print(f"❌ Код возврата {run.returncode} (ожидался 0)", file=sys.stderr)
return False
print("DEBUG: Выполнение успешно", file=sys.stderr)
return True
def main():
print("DEBUG: Начало теста тест_бнд", file=sys.stderr)
if not build():
clean()
sys.exit(1)
tests = [
("Размер файла", test_file_size),
("Секция .bss", test_bss_section),
("Сегмент LOAD", test_load_segment),
("Выполнение", test_execution),
]
all_passed = True
for name, test_func in tests:
if not test_func():
print(f"❌ Провалена проверка: {name}", file=sys.stderr)
all_passed = False
break
clean()
if all_passed:
print("", file=sys.stderr)
sys.exit(0)
else:
print("", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()