mirror of
https://github.com/FuzzingLabs/fuzzforge_ai.git
synced 2026-09-30 19:50:09 +02:00
chore(modules): remove redundant harness-validator module
This commit is contained in:
1 parent
d786c6dab1
commit
f099bd018d
12 files changed
-582
No files matched your search
@@ -1,23 +0,0 @@
|
|||||||
FROM localhost/fuzzforge-modules-sdk:0.1.0
|
|
||||||
|
|
||||||
# Install build tools and Rust nightly for compiling fuzz harnesses
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
curl \
|
|
||||||
build-essential \
|
|
||||||
pkg-config \
|
|
||||||
libssl-dev \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly
|
|
||||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
|
||||||
|
|
||||||
# Install cargo-fuzz for validation
|
|
||||||
RUN cargo install cargo-fuzz --locked || true
|
|
||||||
|
|
||||||
COPY ./src /app/src
|
|
||||||
COPY ./pyproject.toml /app/pyproject.toml
|
|
||||||
|
|
||||||
# Remove workspace reference since we're using wheels
|
|
||||||
RUN sed -i '/\[tool\.uv\.sources\]/,/^$/d' /app/pyproject.toml
|
|
||||||
|
|
||||||
RUN uv sync --find-links /wheels
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
PACKAGE=$(word 1, $(shell uv version))
|
|
||||||
VERSION=$(word 2, $(shell uv version))
|
|
||||||
|
|
||||||
PODMAN?=/usr/bin/podman
|
|
||||||
|
|
||||||
SOURCES=./src
|
|
||||||
TESTS=./tests
|
|
||||||
|
|
||||||
.PHONY: bandit build clean format mypy pytest ruff version
|
|
||||||
|
|
||||||
bandit:
|
|
||||||
uv run bandit --recursive $(SOURCES)
|
|
||||||
|
|
||||||
build:
|
|
||||||
$(PODMAN) build --file ./Dockerfile --no-cache --tag $(PACKAGE):$(VERSION)
|
|
||||||
|
|
||||||
save: build
|
|
||||||
$(PODMAN) save --format oci-archive --output /tmp/$(PACKAGE)-$(VERSION).oci $(PACKAGE):$(VERSION)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@find . -type d \( \
|
|
||||||
-name '*.egg-info' \
|
|
||||||
-o -name '.mypy_cache' \
|
|
||||||
-o -name '.pytest_cache' \
|
|
||||||
-o -name '.ruff_cache' \
|
|
||||||
-o -name '__pycache__' \
|
|
||||||
\) -printf 'removing directory %p\n' -exec rm -rf {} +
|
|
||||||
|
|
||||||
cloc:
|
|
||||||
cloc $(SOURCES)
|
|
||||||
|
|
||||||
format:
|
|
||||||
uv run ruff format $(SOURCES) $(TESTS)
|
|
||||||
|
|
||||||
mypy:
|
|
||||||
uv run mypy $(SOURCES)
|
|
||||||
|
|
||||||
pytest:
|
|
||||||
uv run pytest $(TESTS)
|
|
||||||
|
|
||||||
ruff:
|
|
||||||
uv run ruff check --fix $(SOURCES) $(TESTS)
|
|
||||||
|
|
||||||
version:
|
|
||||||
@echo '$(PACKAGE)@$(VERSION)'
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# FuzzForge Modules - FIXME
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Python
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# install the package (users)
|
|
||||||
uv sync
|
|
||||||
# install the package and all development dependencies (developers)
|
|
||||||
uv sync --all-extras
|
|
||||||
```
|
|
||||||
|
|
||||||
### Container
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# build the image
|
|
||||||
make build
|
|
||||||
# run the container
|
|
||||||
mkdir -p "${PWD}/data" "${PWD}/data/input" "${PWD}/data/output"
|
|
||||||
echo '{"settings":{},"resources":[]}' > "${PWD}/data/input/input.json"
|
|
||||||
podman run --rm \
|
|
||||||
--volume "${PWD}/data:/data" \
|
|
||||||
'<name>:<version>' 'uv run module'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```shell
|
|
||||||
uv run module
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development tools
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# run ruff (formatter)
|
|
||||||
make format
|
|
||||||
# run mypy (type checker)
|
|
||||||
make mypy
|
|
||||||
# run tests (pytest)
|
|
||||||
make pytest
|
|
||||||
# run ruff (linter)
|
|
||||||
make ruff
|
|
||||||
```
|
|
||||||
|
|
||||||
See the file `Makefile` at the root of this directory for more tools.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[mypy]
|
|
||||||
plugins = pydantic.mypy
|
|
||||||
strict = True
|
|
||||||
warn_unused_ignores = True
|
|
||||||
warn_redundant_casts = True
|
|
||||||
warn_return_any = True
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
[project]
|
|
||||||
name = "harness-validator"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "FuzzForge module that validates fuzz harnesses compile correctly"
|
|
||||||
authors = []
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.14"
|
|
||||||
dependencies = [
|
|
||||||
"fuzzforge-modules-sdk==0.0.1",
|
|
||||||
"pydantic==2.12.4",
|
|
||||||
"structlog==25.5.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
lints = [
|
|
||||||
"bandit==1.8.6",
|
|
||||||
"mypy==1.18.2",
|
|
||||||
"ruff==0.14.4",
|
|
||||||
]
|
|
||||||
tests = [
|
|
||||||
"pytest==9.0.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
module = "module.__main__:main"
|
|
||||||
|
|
||||||
[tool.uv.sources]
|
|
||||||
fuzzforge-modules-sdk = { workspace = true }
|
|
||||||
|
|
||||||
[tool.uv]
|
|
||||||
package = true
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
line-length = 120
|
|
||||||
|
|
||||||
[lint]
|
|
||||||
select = [ "ALL" ]
|
|
||||||
ignore = [
|
|
||||||
"COM812", # conflicts with the formatter
|
|
||||||
"D100", # ignoring missing docstrings in public modules
|
|
||||||
"D104", # ignoring missing docstrings in public packages
|
|
||||||
"D203", # conflicts with 'D211'
|
|
||||||
"D213", # conflicts with 'D212'
|
|
||||||
"TD002", # ignoring missing author in 'TODO' statements
|
|
||||||
"TD003", # ignoring missing issue link in 'TODO' statements
|
|
||||||
]
|
|
||||||
|
|
||||||
[lint.per-file-ignores]
|
|
||||||
"tests/*" = [
|
|
||||||
"PLR2004", # allowing comparisons using unamed numerical constants in tests
|
|
||||||
"S101", # allowing 'assert' statements in tests
|
|
||||||
]
|
|
||||||
Whitespace-only changes.
@@ -1,19 +0,0 @@
|
|||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from fuzzforge_modules_sdk.api import logs
|
|
||||||
|
|
||||||
from module.mod import Module
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from fuzzforge_modules_sdk.api.modules.base import FuzzForgeModule
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
"""TODO."""
|
|
||||||
logs.configure()
|
|
||||||
module: FuzzForgeModule = Module()
|
|
||||||
module.main()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,309 +0,0 @@
|
|||||||
"""Harness Validator module for FuzzForge.
|
|
||||||
|
|
||||||
This module validates that fuzz harnesses compile correctly.
|
|
||||||
It takes a Rust project with a fuzz directory containing harnesses
|
|
||||||
and runs cargo build to verify they compile.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
import structlog
|
|
||||||
|
|
||||||
from fuzzforge_modules_sdk.api.constants import PATH_TO_INPUTS, PATH_TO_OUTPUTS
|
|
||||||
from fuzzforge_modules_sdk.api.models import FuzzForgeModuleResults
|
|
||||||
from fuzzforge_modules_sdk.api.modules.base import FuzzForgeModule
|
|
||||||
|
|
||||||
from module.models import Input, Output, ValidationResult, HarnessStatus
|
|
||||||
from module.settings import Settings
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from fuzzforge_modules_sdk.api.models import FuzzForgeModuleResource
|
|
||||||
|
|
||||||
logger = structlog.get_logger()
|
|
||||||
|
|
||||||
|
|
||||||
class Module(FuzzForgeModule):
|
|
||||||
"""Harness Validator module - validates that fuzz harnesses compile."""
|
|
||||||
|
|
||||||
_settings: Settings | None
|
|
||||||
_results: list[ValidationResult]
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
"""Initialize an instance of the class."""
|
|
||||||
name: str = "harness-validator"
|
|
||||||
version: str = "0.1.0"
|
|
||||||
FuzzForgeModule.__init__(self, name=name, version=version)
|
|
||||||
self._settings = None
|
|
||||||
self._results = []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _get_input_type(cls) -> type[Input]:
|
|
||||||
"""Return the input type."""
|
|
||||||
return Input
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _get_output_type(cls) -> type[Output]:
|
|
||||||
"""Return the output type."""
|
|
||||||
return Output
|
|
||||||
|
|
||||||
def _prepare(self, settings: Settings) -> None: # type: ignore[override]
|
|
||||||
"""Prepare the module.
|
|
||||||
|
|
||||||
:param settings: Module settings.
|
|
||||||
|
|
||||||
"""
|
|
||||||
self._settings = settings
|
|
||||||
logger.info("harness-validator preparing", settings=settings.model_dump() if settings else {})
|
|
||||||
|
|
||||||
def _run(self, resources: list[FuzzForgeModuleResource]) -> FuzzForgeModuleResults:
|
|
||||||
"""Run the harness validator.
|
|
||||||
|
|
||||||
:param resources: Input resources (fuzz project directory).
|
|
||||||
:returns: Module execution result.
|
|
||||||
|
|
||||||
"""
|
|
||||||
logger.info("harness-validator starting", resource_count=len(resources))
|
|
||||||
|
|
||||||
# Find the fuzz project directory
|
|
||||||
fuzz_project_src = self._find_fuzz_project(resources)
|
|
||||||
if fuzz_project_src is None:
|
|
||||||
logger.error("No fuzz project found in resources")
|
|
||||||
return FuzzForgeModuleResults.FAILURE
|
|
||||||
|
|
||||||
logger.info("Found fuzz project", path=str(fuzz_project_src))
|
|
||||||
|
|
||||||
# Copy the project to a writable location since /data/input is read-only
|
|
||||||
# and cargo needs to write Cargo.lock and build artifacts
|
|
||||||
import shutil
|
|
||||||
work_dir = Path("/tmp/fuzz-build")
|
|
||||||
if work_dir.exists():
|
|
||||||
shutil.rmtree(work_dir)
|
|
||||||
|
|
||||||
# Copy entire project root (parent of fuzz directory)
|
|
||||||
project_root = fuzz_project_src.parent
|
|
||||||
work_project = work_dir / project_root.name
|
|
||||||
shutil.copytree(project_root, work_project, dirs_exist_ok=True)
|
|
||||||
|
|
||||||
# Adjust fuzz_project to point to the copied location
|
|
||||||
fuzz_project = work_dir / project_root.name / fuzz_project_src.name
|
|
||||||
logger.info("Copied project to writable location", work_dir=str(fuzz_project))
|
|
||||||
|
|
||||||
# Find all harness targets
|
|
||||||
targets = self._find_harness_targets(fuzz_project)
|
|
||||||
if not targets:
|
|
||||||
logger.error("No harness targets found")
|
|
||||||
return FuzzForgeModuleResults.FAILURE
|
|
||||||
|
|
||||||
logger.info("Found harness targets", count=len(targets))
|
|
||||||
|
|
||||||
# Validate each harness
|
|
||||||
all_valid = True
|
|
||||||
for target in targets:
|
|
||||||
result = self._validate_harness(fuzz_project, target)
|
|
||||||
self._results.append(result)
|
|
||||||
if result.status != HarnessStatus.VALID:
|
|
||||||
all_valid = False
|
|
||||||
logger.warning("Harness validation failed",
|
|
||||||
target=target,
|
|
||||||
status=result.status.value,
|
|
||||||
errors=result.errors)
|
|
||||||
else:
|
|
||||||
logger.info("Harness valid", target=target)
|
|
||||||
|
|
||||||
# Set output data for results.json
|
|
||||||
valid_targets = [r.target for r in self._results if r.status == HarnessStatus.VALID]
|
|
||||||
invalid_targets = [r.target for r in self._results if r.status != HarnessStatus.VALID]
|
|
||||||
|
|
||||||
self.set_output(
|
|
||||||
fuzz_project=str(fuzz_project),
|
|
||||||
total_targets=len(self._results),
|
|
||||||
valid_count=len(valid_targets),
|
|
||||||
invalid_count=len(invalid_targets),
|
|
||||||
valid_targets=valid_targets,
|
|
||||||
invalid_targets=invalid_targets,
|
|
||||||
results=[r.model_dump() for r in self._results],
|
|
||||||
)
|
|
||||||
|
|
||||||
valid_count = sum(1 for r in self._results if r.status == HarnessStatus.VALID)
|
|
||||||
logger.info("harness-validator completed",
|
|
||||||
total=len(self._results),
|
|
||||||
valid=valid_count,
|
|
||||||
invalid=len(self._results) - valid_count)
|
|
||||||
|
|
||||||
return FuzzForgeModuleResults.SUCCESS
|
|
||||||
|
|
||||||
def _cleanup(self, settings: Settings) -> None: # type: ignore[override]
|
|
||||||
"""Clean up after execution.
|
|
||||||
|
|
||||||
:param settings: Module settings.
|
|
||||||
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _find_fuzz_project(self, resources: list[FuzzForgeModuleResource]) -> Path | None:
|
|
||||||
"""Find the fuzz project directory in the resources.
|
|
||||||
|
|
||||||
:param resources: List of input resources.
|
|
||||||
:returns: Path to fuzz project or None.
|
|
||||||
|
|
||||||
"""
|
|
||||||
for resource in resources:
|
|
||||||
path = Path(resource.path)
|
|
||||||
|
|
||||||
# Check if it's a fuzz directory with Cargo.toml
|
|
||||||
if path.is_dir():
|
|
||||||
cargo_toml = path / "Cargo.toml"
|
|
||||||
if cargo_toml.exists():
|
|
||||||
# Check if it has fuzz_targets directory
|
|
||||||
fuzz_targets = path / "fuzz_targets"
|
|
||||||
if fuzz_targets.is_dir():
|
|
||||||
return path
|
|
||||||
|
|
||||||
# Check for fuzz subdirectory
|
|
||||||
fuzz_dir = path / "fuzz"
|
|
||||||
if fuzz_dir.is_dir():
|
|
||||||
cargo_toml = fuzz_dir / "Cargo.toml"
|
|
||||||
if cargo_toml.exists():
|
|
||||||
return fuzz_dir
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _find_harness_targets(self, fuzz_project: Path) -> list[str]:
|
|
||||||
"""Find all harness target names in the fuzz project.
|
|
||||||
|
|
||||||
:param fuzz_project: Path to the fuzz project.
|
|
||||||
:returns: List of target names.
|
|
||||||
|
|
||||||
"""
|
|
||||||
targets = []
|
|
||||||
fuzz_targets_dir = fuzz_project / "fuzz_targets"
|
|
||||||
|
|
||||||
if fuzz_targets_dir.is_dir():
|
|
||||||
for rs_file in fuzz_targets_dir.glob("*.rs"):
|
|
||||||
# Target name is the file name without extension
|
|
||||||
target_name = rs_file.stem
|
|
||||||
targets.append(target_name)
|
|
||||||
|
|
||||||
return targets
|
|
||||||
|
|
||||||
def _validate_harness(self, fuzz_project: Path, target: str) -> ValidationResult:
|
|
||||||
"""Validate a single harness by compiling it.
|
|
||||||
|
|
||||||
:param fuzz_project: Path to the fuzz project.
|
|
||||||
:param target: Name of the harness target.
|
|
||||||
:returns: Validation result.
|
|
||||||
|
|
||||||
"""
|
|
||||||
harness_file = fuzz_project / "fuzz_targets" / f"{target}.rs"
|
|
||||||
|
|
||||||
if not harness_file.exists():
|
|
||||||
return ValidationResult(
|
|
||||||
target=target,
|
|
||||||
file_path=str(harness_file),
|
|
||||||
status=HarnessStatus.NOT_FOUND,
|
|
||||||
errors=["Harness file not found"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Try to compile just this target
|
|
||||||
try:
|
|
||||||
env = os.environ.copy()
|
|
||||||
env["CARGO_INCREMENTAL"] = "0"
|
|
||||||
|
|
||||||
result = subprocess.run(
|
|
||||||
[
|
|
||||||
"cargo", "build",
|
|
||||||
"--bin", target,
|
|
||||||
"--message-format=json",
|
|
||||||
],
|
|
||||||
cwd=fuzz_project,
|
|
||||||
capture_output=True,
|
|
||||||
text=True,
|
|
||||||
timeout=self._settings.compile_timeout if self._settings else 120,
|
|
||||||
env=env,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Parse cargo output for errors
|
|
||||||
errors = []
|
|
||||||
warnings = []
|
|
||||||
|
|
||||||
for line in result.stdout.splitlines():
|
|
||||||
try:
|
|
||||||
msg = json.loads(line)
|
|
||||||
if msg.get("reason") == "compiler-message":
|
|
||||||
message = msg.get("message", {})
|
|
||||||
level = message.get("level", "")
|
|
||||||
rendered = message.get("rendered", "")
|
|
||||||
|
|
||||||
if level == "error":
|
|
||||||
errors.append(rendered.strip())
|
|
||||||
elif level == "warning":
|
|
||||||
warnings.append(rendered.strip())
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Also check stderr for any cargo errors
|
|
||||||
if result.returncode != 0 and not errors:
|
|
||||||
errors.append(result.stderr.strip() if result.stderr else "Build failed with unknown error")
|
|
||||||
|
|
||||||
if result.returncode == 0:
|
|
||||||
return ValidationResult(
|
|
||||||
target=target,
|
|
||||||
file_path=str(harness_file),
|
|
||||||
status=HarnessStatus.VALID,
|
|
||||||
errors=[],
|
|
||||||
warnings=warnings,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return ValidationResult(
|
|
||||||
target=target,
|
|
||||||
file_path=str(harness_file),
|
|
||||||
status=HarnessStatus.COMPILE_ERROR,
|
|
||||||
errors=errors,
|
|
||||||
warnings=warnings,
|
|
||||||
)
|
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
return ValidationResult(
|
|
||||||
target=target,
|
|
||||||
file_path=str(harness_file),
|
|
||||||
status=HarnessStatus.TIMEOUT,
|
|
||||||
errors=["Compilation timed out"],
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
return ValidationResult(
|
|
||||||
target=target,
|
|
||||||
file_path=str(harness_file),
|
|
||||||
status=HarnessStatus.ERROR,
|
|
||||||
errors=[str(e)],
|
|
||||||
)
|
|
||||||
|
|
||||||
def _write_output(self, fuzz_project: Path) -> None:
|
|
||||||
"""Write the validation results to output.
|
|
||||||
|
|
||||||
:param fuzz_project: Path to the fuzz project.
|
|
||||||
|
|
||||||
"""
|
|
||||||
output_path = PATH_TO_OUTPUTS / "validation.json"
|
|
||||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
valid_targets = [r.target for r in self._results if r.status == HarnessStatus.VALID]
|
|
||||||
invalid_targets = [r.target for r in self._results if r.status != HarnessStatus.VALID]
|
|
||||||
|
|
||||||
output_data = {
|
|
||||||
"fuzz_project": str(fuzz_project),
|
|
||||||
"total_targets": len(self._results),
|
|
||||||
"valid_count": len(valid_targets),
|
|
||||||
"invalid_count": len(invalid_targets),
|
|
||||||
"valid_targets": valid_targets,
|
|
||||||
"invalid_targets": invalid_targets,
|
|
||||||
"results": [r.model_dump() for r in self._results],
|
|
||||||
}
|
|
||||||
|
|
||||||
output_path.write_text(json.dumps(output_data, indent=2))
|
|
||||||
logger.info("wrote validation results", path=str(output_path))
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
"""Models for the harness-validator module."""
|
|
||||||
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
|
||||||
from fuzzforge_modules_sdk.api.models import FuzzForgeModuleInputBase, FuzzForgeModuleOutputBase
|
|
||||||
|
|
||||||
from module.settings import Settings
|
|
||||||
|
|
||||||
|
|
||||||
class HarnessStatus(str, Enum):
|
|
||||||
"""Status of harness validation."""
|
|
||||||
|
|
||||||
VALID = "valid"
|
|
||||||
COMPILE_ERROR = "compile_error"
|
|
||||||
NOT_FOUND = "not_found"
|
|
||||||
TIMEOUT = "timeout"
|
|
||||||
ERROR = "error"
|
|
||||||
|
|
||||||
|
|
||||||
class ValidationResult(BaseModel):
|
|
||||||
"""Result of validating a single harness."""
|
|
||||||
|
|
||||||
#: Name of the harness target
|
|
||||||
target: str
|
|
||||||
|
|
||||||
#: Path to the harness file
|
|
||||||
file_path: str
|
|
||||||
|
|
||||||
#: Validation status
|
|
||||||
status: HarnessStatus
|
|
||||||
|
|
||||||
#: Compilation errors (if any)
|
|
||||||
errors: list[str] = Field(default_factory=list)
|
|
||||||
|
|
||||||
#: Compilation warnings (if any)
|
|
||||||
warnings: list[str] = Field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class Input(FuzzForgeModuleInputBase[Settings]):
|
|
||||||
"""Input for the harness-validator module.
|
|
||||||
|
|
||||||
Expects a fuzz project directory with:
|
|
||||||
- Cargo.toml
|
|
||||||
- fuzz_targets/ directory with .rs harness files
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class Output(FuzzForgeModuleOutputBase):
|
|
||||||
"""Output from the harness-validator module."""
|
|
||||||
|
|
||||||
#: Path to the fuzz project
|
|
||||||
fuzz_project: str = ""
|
|
||||||
|
|
||||||
#: Total number of harness targets
|
|
||||||
total_targets: int = 0
|
|
||||||
|
|
||||||
#: Number of valid (compilable) harnesses
|
|
||||||
valid_count: int = 0
|
|
||||||
|
|
||||||
#: Number of invalid harnesses
|
|
||||||
invalid_count: int = 0
|
|
||||||
|
|
||||||
#: List of valid target names (ready for fuzzing)
|
|
||||||
valid_targets: list[str] = Field(default_factory=list)
|
|
||||||
|
|
||||||
#: List of invalid target names (need fixes)
|
|
||||||
invalid_targets: list[str] = Field(default_factory=list)
|
|
||||||
|
|
||||||
#: Detailed validation results per target
|
|
||||||
results: list[ValidationResult] = Field(default_factory=list)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
"""Settings for the harness-validator module."""
|
|
||||||
|
|
||||||
from fuzzforge_modules_sdk.api.models import FuzzForgeModulesSettingsBase
|
|
||||||
|
|
||||||
|
|
||||||
class Settings(FuzzForgeModulesSettingsBase):
|
|
||||||
"""Settings for the harness-validator module."""
|
|
||||||
|
|
||||||
#: Timeout for compiling each harness (seconds)
|
|
||||||
compile_timeout: int = 120
|
|
||||||
|
|
||||||
#: Whether to stop on first error
|
|
||||||
fail_fast: bool = False
|
|
||||||
Whitespace-only changes.
Reference in new issue
Block a user