Загрузка данных


#!/usr/bin/env python3
import subprocess
import datetime
import sys

# 1. ФИКСАЦИЯ ВРЕМЕНИ НАЧАЛА И СОЗДАНИЕ НАЗВАНИЯ ФАЙЛА ПО ТЗ
start_time = datetime.datetime.now()
time_str = start_time.strftime("%Y%m%d_%H%M%S")
log_filename = f"report_{time_str}.txt"

# Открываем файл для дублирования результатов
log_file = open(log_filename, "w", encoding="utf-8")

# Функция, которая пишет текст одновременно и на экран, и в файл
def print_log(text):
    print(text)
    log_file.write(text + "\n")

# 2. ОПИСАНИЕ ТЕСТОВОГО ПЛАНА И ПРИЛОЖЕНИЯ
print_log("=========================================================================")
print_log("                     ОТЧЕТ О ТЕСТИРОВАНИИ ПРОГРАММЫ                      ")
print_log("=========================================================================")
print_log("Тестируемое приложение: Консольная утилита проверки синтаксиса chown_check")
print_log("Описание плана: Проверка корректности разбора ключей, имен и ограничений Линукс")
print_log(f"Время начала тестирования: {start_time.strftime('%d.%m.%y %H:%M:%S')}")
print_log("=========================================================================")

# Матрица тестов из предыдущей ЛР (Входные данные, Ожидаемый результат, Категория/Ограничение, Вес от 1 до 5)
test_cases = [
    # Категория 1: Позитивные тесты (Базовые - легкие, сложные ключи - средние)
    ("chown root file.txt", "True", "Категория 1: Базовый корректный вызов", 1),
    ("chown root:users /var/log", "True", "Категория 1: Владелец и группа", 1),
    ("chown :group file.txt", "True", "Категория 1: Только группа", 2),
    ("chown 1000:1000 file.txt", "True", "Категория 1: Числовые UID/GID", 2),
    ("chown root: file.txt", "True", "Категория 1: Висящее двоеточие", 2),
    ("chown -R user:group /dir", "True", "Категория 1: Короткий ключ рекурсии", 1),
    ("chown -c root file.txt", "True", "Категория 1: Короткий ключ -c", 1),
    ("chown -v --dereference root file.txt", "True", "Категория 1: Длинные ключи", 2),
    ("chown -h --no-dereference symlink", "True", "Категория 1: Ключ неразыменования -h", 3),
    ("chown --from=admin:staff root file.txt", "True", "Категория 1: Ключ проверки --from", 3),
    ("chown --reference=ref.txt file.txt", "True", "Категория 1: Ссылка на файл --reference", 3),
    ("chown -R --preserve-root root /", "True", "Категория 1: Защита корня --preserve-root", 3),
    ("chown -R -L -H root /dir", "True", "Категория 1: Склейка флагов обхода ссылок", 3),
    ("chown --help", "True", "Категория 1: Флаг экстренной справки", 2),
    
    # Категория 2: Ошибки имени и ключей
    ("chovn root file.txt", "False", "Категория 2: Опечатка в имени команды", 2),
    ("Chown root file.txt", "False", "Категория 2: Ошибка регистра команды", 2),
    ("chown -z file.txt", "False", "Категория 2: Неизвестный короткий ключ", 2),
    ("chown -R -X root /dir", "False", "Категория 2: Ошибка в склейке ключей", 3),
    ("chown --unsupported root file", "False", "Категория 2: Неподдерживаемый длинный ключ", 2),
    ("chown -Rvf root file.txt", "True", "Категория 2: Корректная сложная склейка", 3),
    ("chown -Rzv file.txt", "False", "Категория 2: Брак внутри склейки ключей", 3),
    
    # Категория 3: Ошибки синтаксиса OWNER/GROUP
    ("chown 123user file.txt", "False", "Категория 3: Имя начинается с цифры", 4),
    ("chown user! file.txt", "False", "Категория 3: Запрещенный спецсимвол !", 3),
    ("chown user@group file.txt", "False", "Категория 3: Запрещенный спецсимвол @", 3),
    ("chown user:group:extra file.txt", "False", "Категория 3: Лишнее двоеточие", 3),
    ("chown :", "False", "Категория 3: Пустая спецификация", 3),
    
    # Категория 4: Ошибки файловых аргументов
    ("chown root", "False", "Категория 4: Отсутствие целевого файла", 2),
    ("chown -R user:group", "False", "Категория 4: Отсутствие файлов при ключе", 2),
    ("chown --from=admin:staff root", "False", "Категория 4: Ключ --from без файлов", 3),
    
    # Категория 5: Проверка работы счетчиков и накопления статистики
    ("resetstats", "", "Категория 5: Принудительный сброс структуры", 4),
    ("chown root file.txt", "True", "Категория 5: Накопление успешного теста 1", 2),
    ("chown user file.txt", "True", "Категория 5: Накопление успешного теста 2", 2),
    ("chown -z file.txt", "False", "Категория 5: Накопление неуспешного теста", 2),
    ("getstats", "2 1 3", "Категория 5: Запрос общей строки статистики", 5),
    ("getsuccess", "2", "Категория 5: Запрос счетчика успехов", 4),
    ("getfailed", "1", "Категория 5: Запрос счетчика ошибок", 4),
    ("resetstats", "", "Категория 5: Повторный сброс счетчиков", 4),
    ("getstats", "0 0 0", "Категория 5: Проверка нулей после сброса", 5)
]

# Шапка таблицы в консоли
print_log(f"{'№':<3} | {'Входные данные':<38} | {'Вес':<3} | {'Статус':<5} | {'Ограничение / Характеристика'}")
print_log("-" * 110)

# Подготовка текстового потока для передачи в дочерний процесс
input_stream = "\n".join([case[0] for case in test_cases]) + "\n"

# ЗАПУСК ИСПЫТАНИЙ (ЧЕРНЫЙ ЯЩИК)
process = subprocess.run(
    ["python", "chown_check.py"],
    input=input_stream,
    text=True,
    capture_output=True
)

# Чтение реальных ответов тестируемой программы
actual_outputs = process.stdout.splitlines()

# Переменные для финальных расчетов по примеру
total_tests = len(test_cases)
success_count = 0
fail_count = 0

total_weight = 0
success_weight = 0

# ПРОВЕРКА РЕЗУЛЬТАТОВ
for idx, (command, expected, description, weight) in enumerate(test_cases):
    actual = actual_outputs[idx] if idx < len(actual_outputs) else "НЕТ ОТВЕТА"
    total_weight += weight
    
    if actual == expected:
        status = "OK"
        success_count += 1
        success_weight += weight
    else:
        status = "FAIL"
        fail_count += 1
        
    # Форматированный вывод строки теста
    print_log(f"{idx+1:<3} | {command:<38} | {weight:<3} | {status:<5} | {description}")

# 3. ОПИСАНИЕ ИТОГОВОГО РЕЗУЛЬТАТА ТЕСТИРОВАНИЯ
end_time = datetime.datetime.now()
success_percent = (success_count / total_tests) * 100
relevance_percent = (success_weight / total_weight) * 100

print_log("=========================================================================")
print_log(f"Время завершения тестирования: {end_time.strftime('%d.%m.%y %H:%M:%S')}")
[span_4](start_span)print_log(f"Всего тестовых примеров:       {total_tests} шт.")[span_4](end_span)
print_log(f"Успешно пройденных тестов:     {success_count} шт.")
print_log(f"Неуспешных тестов (сбоев):     {fail_count} шт.")
print_log(f"Процент успешности:            {success_percent:.2f}% (по количеству тестов)")
print_log(f"Процент результативности:      {relevance_percent:.2f}% (отношение суммы весов успешных к общей)")
print_log("=========================================================================")

# Закрываем файл отчета
log_file.close()
print(f"\n[INFO] Результаты тестирования успешно сдублированы в файл: {log_filename}")