yams/tools/fuzzing/fuzz_startup.cpp
Trevon 6248c87bcc
Some checks are pending
Fuzz Smoke / libFuzzer smoke (push) Waiting to run
test(daemon): replay startup schedules under a fuzzer (#335)
Startup ordering defects were only observable by waiting minutes on a live
daemon, and the one that aborted it took a live restart loop to find. Give the
startup contracts a deterministic harness that runs in milliseconds.

+ startup_fuzz_support.h drives the real ServiceManagerFsm and the real
  DeferralGate with virtual time: legal phase advances, injected failure,
  shutdown and terminal reset, idle/busy, pressure/calm, starvation deadlines
  and cancellation
+ oracles fail closed on shutdown resurrection without reset, failure-to-ready,
  eligibility disagreeing with fsm.isReady(), admission outside the virtual
  deadline, and ineligible work touching the admission gate; fuzzed IEEE-754
  components must never yield non-finite or out-of-range scores
+ catch2_startup_replay runs named regressions plus 1024 seeded traces per run
  and reports the root seed and action offset for replay
+ fuzz_startup builds the same harness for libFuzzer/AFL, with a seed generator
  that refuses to overwrite different existing files
- the fuzzing lane no longer defaults to TSan: harnesses link
  -fsanitize=fuzzer,address,undefined and the two runtimes cannot share a
  process; combining them now fails with an explanation instead of producing a
  binary that cannot start
- documented the lane invocation, target naming and the coverage limits,
  including that governor call ordering inside the poller is not covered

Scope: contract-valid single-owner schedules. Executor interleavings, late
callbacks, concurrent FSM instances and filesystem/model faults are not modeled.

Signed-off-by: trvon <git@trevon.dev>
2026-10-22 16:48:50 -06:00

28 lines
919 B
C++

// Copyright (c) 2026 YAMS Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <span>
#include <spdlog/spdlog.h>
#include "startup_fuzz_support.h"
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size) {
// A standalone fuzz process owns its logger and the process-global tinyfsm.
spdlog::set_level(spdlog::level::off);
const auto bytes = std::span<const std::uint8_t>{data, size};
const auto replay = yams::fuzz::replayStartup(bytes);
if (!replay.ok()) {
std::fprintf(stderr, "startup replay failed at byte %zu: %s\n", replay.offset,
replay.error);
std::abort();
}
if (!yams::fuzz::semanticScoresBounded(bytes)) {
std::fprintf(stderr, "startup semantic-score invariant failed\n");
std::abort();
}
return 0;
}