litellm/tests/rust-python-harness/shared/reporting/strategy.py
Yujong Lee 561533c596 wip
2026-09-14 11:48:24 -07:00

100 lines
2.7 KiB
Python

from __future__ import annotations
from collections.abc import Callable, Sequence
from dataclasses import dataclass
from pathlib import Path
from typing import Annotated, Literal, Protocol, TypeAlias
from pydantic import BaseModel, ConfigDict, StringConstraints
from .models import CaseDisposition, Coverage, HarnessCase, HarnessRun, SdkFunction, Surface
from .rendering import StrategyRenderer
UpdateCallback: TypeAlias = Callable[[HarnessRun], None]
NonBlankString: TypeAlias = Annotated[str, StringConstraints(strip_whitespace=True, min_length=1)]
class SuiteCaseSpec(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
disposition: Literal[CaseDisposition.RUNNABLE] = CaseDisposition.RUNNABLE
coverage: Coverage
suite: NonBlankString
note: str = ""
class ModuleCaseSpec(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
disposition: Literal[CaseDisposition.RUNNABLE] = CaseDisposition.RUNNABLE
coverage: Coverage
module: NonBlankString
note: str = ""
class NotImplementedCaseSpec(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
disposition: Literal[CaseDisposition.NOT_IMPLEMENTED] = CaseDisposition.NOT_IMPLEMENTED
coverage: None = None
reason: NonBlankString
class SkippedCaseSpec(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
disposition: Literal[CaseDisposition.SKIPPED] = CaseDisposition.SKIPPED
coverage: None = None
reason: NonBlankString
RunnableCaseSpec: TypeAlias = SuiteCaseSpec | ModuleCaseSpec
UnavailableCaseSpec: TypeAlias = NotImplementedCaseSpec | SkippedCaseSpec
CaseSpec: TypeAlias = RunnableCaseSpec | UnavailableCaseSpec
@dataclass(frozen=True, slots=True)
class CaseDefinition:
sdk_function: SdkFunction
spec: CaseSpec
surface: Surface | None = None
@dataclass(frozen=True, slots=True)
class RunnerArgumentDefinition:
option: str
help: str
metavar: str = "ARG"
@dataclass(frozen=True, slots=True)
class RunnerOptionDefinition:
option: str
help: str
choices: tuple[str, ...]
class StrategyRunner(Protocol):
def __call__(
self,
cases: Sequence[HarnessCase],
repo_root: Path,
on_update: UpdateCallback,
runner_args: Sequence[str] = (),
) -> tuple[int, HarnessRun]: ...
@dataclass(frozen=True, slots=True)
class StrategyDefinition:
id: str
order: int
label: str
description: str
directory: Path
runnable_spec: type[SuiteCaseSpec] | type[ModuleCaseSpec]
cases: tuple[CaseDefinition, ...]
run: StrategyRunner
render: StrategyRenderer
surfaces: tuple[Surface, ...] = ()
runner_argument: RunnerArgumentDefinition | None = None
runner_options: tuple[RunnerOptionDefinition, ...] = ()