Skip to content

Pipeline trait abstractions + unit tests #6

Description

@rcd27

Priority: HIGH (post-release)
Risk: HIGH — ядро приложения, может сломать timing и e2e поведение
Blocked by: ничего
Блокирует: unit тесты pipeline без root, CI без привилегий

Контекст

Сейчас execute_worker_task напрямую вызывает:

  • start_nfqws2() — spawn процесса
  • nftables::add_worker_rule() / remove_worker_rules() — shell-out в nft
  • http_test() / http_test_data() — TCP connect с SO_MARK
  • interpret_http_result() — интерпретация

Всё это требует root + Linux + nftables + nfqws2 binary. Unit тесты невозможны.

Цель

Возможность тестировать pipeline логику (батчинг, error handling, retry, scoring) без root и без реального nfqws2/nftables.

Предлагаемый подход

1. Trait WorkerBackend

#[async_trait]
trait WorkerBackend {
    async fn start_worker(&self, qnum: u16, args: &[String]) -> Result<WorkerHandle, Error>;
    async fn stop_worker(&mut self, handle: WorkerHandle);
}

Реализации:

  • Nfqws2Backend — текущая логика (spawn nfqws2)
  • MockBackend — для тестов (no-op, configurable failures)

2. Trait FirewallBackend

#[async_trait]
trait FirewallBackend {
    async fn prepare(&self) -> Result<(), Error>;
    async fn add_rules(&self, slots: &[WorkerSlot], port: u16, ips: &[String]) -> Result<(), Error>;
    async fn remove_rules(&self) -> Result<(), Error>;
    async fn cleanup(&self);
}

Реализации:

  • NftablesBackend — текущая логика
  • MockFirewall — для тестов
  • (будущее) IptablesBackend

3. Рефакторинг execute_worker_task

Разбить на:

  • setup_worker() — start nfqws2 + wait_for_ready
  • run_http_test() — HTTP request + interpret
  • cleanup_worker() — kill nfqws2

Каждая — отдельная тестируемая функция.

Что НЕ менять

  • Сигнатуры run_parallel() / run_check() — публичный API
  • Формат отчётов
  • CLI интерфейс
  • e2e тесты — они должны продолжать работать as-is

Риски

  1. Timing regression — nfqws2 spawn → sleep → nft rules → HTTP request — порядок критичен. Абстракция может скрыть timing-зависимость
  2. Performance — dynamic dispatch через trait objects добавляет vtable indirection. На 150 стр/сек может быть заметно. Замерить benchmark до/после
  3. Scope creep — соблазн переделать "ещё вот это". Строго ограничить scope: traits + mock + 5-10 unit тестов

Критерии готовности

  • cargo test проходит без root (unit тесты pipeline)
  • e2e тесты не сломаны
  • benchmark показывает ±5% от текущей производительности
  • execute_worker_task разбит на 3+ функции ≤30 строк каждая

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions