From a5a7e40308b9267a3ee05cb20f7492d11083d9e9 Mon Sep 17 00:00:00 2001 From: kronecker <2026692687@qq.com> Date: Fri, 9 Oct 2026 14:15:24 +0800 Subject: [PATCH] feat(contracts): add versioned multi-runtime judging contracts --- backend/src/kf_oj/contracts/export.py | 10 + backend/src/kf_oj/contracts/judging.py | 2 +- backend/src/kf_oj/contracts/judging_v2.py | 312 +++ .../src/kf_oj/contracts/judging_versions.py | 35 + .../src/kf_oj/modules/submissions/queries.py | 10 +- .../modules/submissions/worker_access.py | 12 +- backend/tests/test_judging_v2_contracts.py | 186 ++ backend/tests/test_submission_queries.py | 15 +- .../schemas/judge-admission.v2.schema.json | 226 ++ contracts/schemas/judge-lease.v2.schema.json | 94 + .../schemas/judge-manifest.v2.schema.json | 270 +++ contracts/schemas/judge-result.v2.schema.json | 416 ++++ contracts/schemas/judge-stage.v2.schema.json | 106 + .../schemas/judge-stopped.v2.schema.json | 69 + judge/crates/contracts/src/judging.rs | 5 +- judge/crates/contracts/src/judging_v2.rs | 675 ++++++ .../crates/contracts/src/judging_versions.rs | 41 + judge/crates/contracts/src/lib.rs | 2 + .../contracts/tests/judging_v2_examples.rs | 156 ++ .../contracts-v2/canonical-manifest.c17.txt | 1 + .../contracts-v2/canonical-manifest.cpp20.txt | 1 + .../canonical-manifest.java21.txt | 1 + .../canonical-manifest.python313.txt | 1 + ...ge-admission.invalid-capability-count.json | 180 ++ ...n.invalid-semantic-duplicate-language.json | 146 ++ .../contracts-v2/judge-admission.valid.json | 146 ++ .../contracts-v2/judge-lease.valid.json | 14 + ...udge-manifest.invalid-extra-host-path.json | 81 + .../judge-manifest.invalid-extra-profile.json | 81 + ...ifest.invalid-semantic-duplicate-case.json | 91 + ...anifest.invalid-semantic-image-family.json | 80 + ...st.invalid-semantic-java-thread-floor.json | 80 + ...ifest.invalid-semantic-java-too-small.json | 80 + ...nifest.invalid-semantic-java-unpinned.json | 80 + ...est.invalid-semantic-python-too-small.json | 80 + ...ifest.invalid-semantic-python-version.json | 80 + ...e-manifest.invalid-semantic-short-job.json | 80 + ...udge-manifest.invalid-unknown-version.json | 80 + .../judge-manifest.invalid-version-bool.json | 80 + .../judge-manifest.valid-c17.json | 80 + .../judge-manifest.valid-cpp20.json | 80 + .../judge-manifest.valid-java21.json | 80 + .../judge-manifest.valid-python313.json | 80 + .../judge-result.invalid-class-count.json | 1864 +++++++++++++++++ ...e-result.invalid-semantic-attempt-c17.json | 72 + ...result.invalid-semantic-attempt-cpp20.json | 72 + ...esult.invalid-semantic-attempt-java21.json | 93 + ...lt.invalid-semantic-attempt-python313.json | 72 + ...esult.invalid-semantic-class-absolute.json | 93 + ...sult.invalid-semantic-class-duplicate.json | 100 + ...ult.invalid-semantic-class-empty-stem.json | 93 + ...dge-result.invalid-semantic-class-jar.json | 93 + ...t.invalid-semantic-class-missing-main.json | 86 + ...result.invalid-semantic-class-package.json | 93 + ...lt.invalid-semantic-class-total-bytes.json | 93 + ...sult.invalid-semantic-class-traversal.json | 93 + ...result.invalid-semantic-class-unicode.json | 93 + ...sult.invalid-semantic-class-unordered.json | 93 + ...ge-result.invalid-semantic-class-zero.json | 93 + ...nvalid-semantic-python-changed-source.json | 72 + ...ge-result.invalid-semantic-python-pyc.json | 72 + ...lt.invalid-semantic-python-wrong-kind.json | 72 + .../contracts-v2/judge-result.valid-c17.json | 72 + ...ge-result.valid-cancel-before-compile.json | 25 + ...dge-result.valid-cancel-between-cases.json | 60 + .../contracts-v2/judge-result.valid-ce.json | 25 + .../judge-result.valid-cleanup-failure.json | 72 + .../judge-result.valid-compile-limit.json | 25 + .../judge-result.valid-cpp20.json | 72 + .../judge-result.valid-java21.json | 93 + .../judge-result.valid-python313.json | 72 + .../contracts-v2/judge-stage.valid-c17.json | 14 + .../contracts-v2/judge-stage.valid-cpp20.json | 14 + .../judge-stage.valid-java21.json | 14 + .../judge-stage.valid-python313.json | 14 + .../contracts-v2/judge-stopped.valid.json | 11 + 76 files changed, 8407 insertions(+), 13 deletions(-) create mode 100644 backend/src/kf_oj/contracts/judging_v2.py create mode 100644 backend/src/kf_oj/contracts/judging_versions.py create mode 100644 backend/tests/test_judging_v2_contracts.py create mode 100644 contracts/schemas/judge-admission.v2.schema.json create mode 100644 contracts/schemas/judge-lease.v2.schema.json create mode 100644 contracts/schemas/judge-manifest.v2.schema.json create mode 100644 contracts/schemas/judge-result.v2.schema.json create mode 100644 contracts/schemas/judge-stage.v2.schema.json create mode 100644 contracts/schemas/judge-stopped.v2.schema.json create mode 100644 judge/crates/contracts/src/judging_v2.rs create mode 100644 judge/crates/contracts/src/judging_versions.rs create mode 100644 judge/crates/contracts/tests/judging_v2_examples.rs create mode 100644 tests/fixtures/contracts-v2/canonical-manifest.c17.txt create mode 100644 tests/fixtures/contracts-v2/canonical-manifest.cpp20.txt create mode 100644 tests/fixtures/contracts-v2/canonical-manifest.java21.txt create mode 100644 tests/fixtures/contracts-v2/canonical-manifest.python313.txt create mode 100644 tests/fixtures/contracts-v2/judge-admission.invalid-capability-count.json create mode 100644 tests/fixtures/contracts-v2/judge-admission.invalid-semantic-duplicate-language.json create mode 100644 tests/fixtures/contracts-v2/judge-admission.valid.json create mode 100644 tests/fixtures/contracts-v2/judge-lease.valid.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-extra-host-path.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-extra-profile.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-duplicate-case.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-image-family.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-thread-floor.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-too-small.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-unpinned.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-too-small.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-version.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-short-job.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-unknown-version.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.invalid-version-bool.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.valid-c17.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.valid-cpp20.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.valid-java21.json create mode 100644 tests/fixtures/contracts-v2/judge-manifest.valid-python313.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-class-count.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-c17.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-cpp20.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-java21.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-python313.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-absolute.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-duplicate.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-empty-stem.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-jar.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-missing-main.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-package.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-total-bytes.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-traversal.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unicode.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unordered.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-zero.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-changed-source.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-pyc.json create mode 100644 tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-wrong-kind.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-c17.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-cancel-before-compile.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-cancel-between-cases.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-ce.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-cleanup-failure.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-compile-limit.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-cpp20.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-java21.json create mode 100644 tests/fixtures/contracts-v2/judge-result.valid-python313.json create mode 100644 tests/fixtures/contracts-v2/judge-stage.valid-c17.json create mode 100644 tests/fixtures/contracts-v2/judge-stage.valid-cpp20.json create mode 100644 tests/fixtures/contracts-v2/judge-stage.valid-java21.json create mode 100644 tests/fixtures/contracts-v2/judge-stage.valid-python313.json create mode 100644 tests/fixtures/contracts-v2/judge-stopped.valid.json diff --git a/backend/src/kf_oj/contracts/export.py b/backend/src/kf_oj/contracts/export.py index f9b0aad..0215106 100644 --- a/backend/src/kf_oj/contracts/export.py +++ b/backend/src/kf_oj/contracts/export.py @@ -7,6 +7,7 @@ from pathlib import Path from kf_oj.api.app import create_app from kf_oj.contracts.judge import JudgeTaskNotification from kf_oj.contracts.judging import WIRE_MODELS +from kf_oj.contracts.judging_v2 import WIRE_MODELS as WIRE_MODELS_V2 from kf_oj.core.settings import Settings @@ -33,6 +34,15 @@ def main() -> None: "budgets, result consistency, UUID canonical form and UTF-8 byte limits." ) outputs[root / f"contracts/schemas/{name}.v1.schema.json"] = document + for name, model in WIRE_MODELS_V2.items(): + document = model.model_json_schema() + document["$schema"] = "https://json-schema.org/draft/2020-12/schema" + document["$id"] = f"urn:kf-oj:{name}:v2" + document["$comment"] = ( + "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup " + "and node budgets, canonical bounded class sets and result consistency." + ) + outputs[root / f"contracts/schemas/{name}.v2.schema.json"] = document stale = [] for path, document in outputs.items(): content = json.dumps(document, indent=2, sort_keys=True, ensure_ascii=False) + "\n" diff --git a/backend/src/kf_oj/contracts/judging.py b/backend/src/kf_oj/contracts/judging.py index 7b6aa27..7a16ccc 100644 --- a/backend/src/kf_oj/contracts/judging.py +++ b/backend/src/kf_oj/contracts/judging.py @@ -375,7 +375,7 @@ WIRE_MODELS = { } -def decode_wire[T: WireModel](model: type[T], payload: bytes) -> T: +def decode_wire[T: BaseModel](model: type[T], payload: bytes) -> T: """UTF-8, bounded size and no ambiguous duplicate members before model validation.""" if len(payload) > MAX_WIRE_BYTES: raise ValueError("wire payload exceeds byte budget") diff --git a/backend/src/kf_oj/contracts/judging_v2.py b/backend/src/kf_oj/contracts/judging_v2.py new file mode 100644 index 0000000..2723566 --- /dev/null +++ b/backend/src/kf_oj/contracts/judging_v2.py @@ -0,0 +1,312 @@ +"""Explicit multi-runtime protocol; existing v1 snapshots remain byte-for-byte stable.""" + +import re +from enum import StrEnum +from typing import Annotated, Literal, Self + +from pydantic import BeforeValidator, Field, model_validator + +from kf_oj.contracts import judging as v1 + +Version = Annotated[Literal[2], BeforeValidator(v1.integer_version)] +MAX_CLASS_FILES = 256 +JVM_NATIVE_RESERVE_BYTES = 160 * v1.MIB +JVM_THREAD_STACK_BYTES = 256 * 1024 + + +class Language(StrEnum): + C17 = "c17" + CPP20 = "cpp20" + PYTHON313 = "python313" + JAVA21 = "java21" + + +class PreparationKind(StrEnum): + COMPILE = "compile" + SYNTAX_CHECK = "syntax_check" + + +class ProgramKind(StrEnum): + NATIVE = "native_executable" + PYTHON = "python_source" + JAVA = "java_classes" + + +class RuntimeIdentity(v1.WireModel): + """An exact identity matched against trusted configuration, never a host path.""" + + toolchain_id: v1.Label + image_kind: Literal[ + "linux_gnu_cxx_x86_64_v1", "linux_cpython313_x86_64_v1", "linux_openjdk21_x86_64_v1" + ] + image_revision: Annotated[int, Field(strict=True, ge=1, le=(1 << 32) - 1)] + image_digest: v1.Digest + runtime_version: Annotated[ + str, Field(strict=True, pattern=r"^[A-Za-z0-9][A-Za-z0-9_.+-]{0,63}$") + ] + + +def runtime_contract(language: Language) -> tuple[str, str, str, ProgramKind, PreparationKind]: + """Fixed source/profile names. Runtime callers cannot introduce argv or paths.""" + return { + Language.C17: ( + "main.c", + "compile_c", + "native", + ProgramKind.NATIVE, + PreparationKind.COMPILE, + ), + Language.CPP20: ( + "main.cpp", + "compile_cpp", + "native", + ProgramKind.NATIVE, + PreparationKind.COMPILE, + ), + Language.PYTHON313: ( + "main.py", + "python_check", + "python_run", + ProgramKind.PYTHON, + PreparationKind.SYNTAX_CHECK, + ), + Language.JAVA21: ( + "Main.java", + "java_compile", + "java_run", + ProgramKind.JAVA, + PreparationKind.COMPILE, + ), + }[language] + + +def validate_runtime(language: Language, identity: RuntimeIdentity) -> None: + expected = { + Language.C17: ("gnu-cxx-v1", "linux_gnu_cxx_x86_64_v1"), + Language.CPP20: ("gnu-cxx-v1", "linux_gnu_cxx_x86_64_v1"), + Language.PYTHON313: ("cpython313-v1", "linux_cpython313_x86_64_v1"), + Language.JAVA21: ("openjdk21-v1", "linux_openjdk21_x86_64_v1"), + }[language] + if (identity.toolchain_id, identity.image_kind) != expected: + raise ValueError("runtime family differs from language contract") + if language == Language.PYTHON313 and identity.runtime_version != "3.13.16": + raise ValueError("unsupported CPython version") + if language == Language.JAVA21 and not re.fullmatch( + r"21\.[0-9]+\.[0-9]+(?:\.[0-9]+)?\+[1-9][0-9]*(?:-LTS)?", identity.runtime_version + ): + raise ValueError("JDK version must identify a fixed Java 21 build") + + +def validate_startup_budget(language: Language, limits: v1.RunLimits, *, preparing: bool) -> None: + """Admission floors, not multipliers on problem limits; real execution still required.""" + if language == Language.PYTHON313: + floor = (10_000, 50_000, 32 * v1.MIB, 1, 16) + elif language == Language.JAVA21: + floor = ( + (1_000_000, 3_000_000, 384 * v1.MIB, 16, 32) + if preparing + else (200_000, 1_000_000, 256 * v1.MIB, 16, 32) + ) + else: + return + actual = ( + limits.cpu_time_us, + limits.wall_time_us, + limits.memory_bytes, + limits.processes, + limits.open_files, + ) + if any(value < minimum for value, minimum in zip(actual, floor, strict=True)): + raise ValueError("budget below runtime startup policy") + if language == Language.JAVA21: + jvm_heap_bytes(limits) + + +def jvm_heap_bytes(limits: v1.RunLimits) -> int: + """Reserve capped metaspace/code/native and every allowed thread stack inside cgroup.""" + reserve = JVM_NATIVE_RESERVE_BYTES + limits.processes * JVM_THREAD_STACK_BYTES + heap = (limits.memory_bytes - reserve) // v1.MIB * v1.MIB + if heap < 32 * v1.MIB or limits.stack_bytes < JVM_THREAD_STACK_BYTES: + raise ValueError("budget cannot cover JVM heap and explicit non-heap reserve") + return heap + + +class LanguageConfiguration(v1.WireModel): + language: Language + toolchain: RuntimeIdentity + compile_limits: v1.RunLimits + run_limits: v1.RunLimits + job_wall_time_us: Annotated[int, Field(strict=True, ge=1000, le=v1.MAX_JOB_WALL_US)] + + @model_validator(mode="after") + def runtime_and_budget(self) -> Self: + validate_runtime(self.language, self.toolchain) + validate_startup_budget(self.language, self.compile_limits, preparing=True) + validate_startup_budget(self.language, self.run_limits, preparing=False) + if self.compile_limits.wall_time_us + self.run_limits.wall_time_us > self.job_wall_time_us: + raise ValueError("job deadline cannot cover preparation and execution") + return self + + +class JobManifest(v1.JobManifest): + schema_version: Version + language: Language + toolchain: RuntimeIdentity + + @model_validator(mode="after") + def runtime_and_budget(self) -> Self: + validate_runtime(self.language, self.toolchain) + validate_startup_budget(self.language, self.compile_limits, preparing=True) + validate_startup_budget(self.language, self.run_limits, preparing=False) + return self + + +class ProgramFile(v1.WireModel): + path: Annotated[str, Field(strict=True, min_length=1, max_length=128)] + artifact: v1.ArtifactReference + + +class CompiledProgram(v1.WireModel): + """Sealed file identities bound to a particular source, runtime and lease attempt.""" + + kind: ProgramKind + binding: v1.LeaseBinding + source: v1.ArtifactReference + toolchain: RuntimeIdentity + files: Annotated[tuple[ProgramFile, ...], Field(min_length=1, max_length=MAX_CLASS_FILES)] + + @property + def bytes(self) -> int: + return sum(file.artifact.bytes for file in self.files) + + @model_validator(mode="after") + def bounded_files(self) -> Self: + names = [file.path for file in self.files] + if names != sorted(set(names)): + raise ValueError("program files must have unique canonical order") + if not 1 <= self.source.bytes <= v1.MAX_SOURCE_BYTES: + raise ValueError("program source outside policy") + if self.bytes > v1.MAX_PACKAGE_BYTES or any( + file.artifact.bytes == 0 for file in self.files + ): + raise ValueError("program files empty or outside byte policy") + if self.kind == ProgramKind.NATIVE: + validate_runtime(Language.C17, self.toolchain) + if names != ["main"] or self.toolchain.image_kind != "linux_gnu_cxx_x86_64_v1": + raise ValueError("native program requires its fixed executable and runtime") + elif self.kind == ProgramKind.PYTHON: + validate_runtime(Language.PYTHON313, self.toolchain) + if names != ["main.py"] or self.files[0].artifact != self.source: + raise ValueError("Python program must be the exact checked source") + else: + validate_runtime(Language.JAVA21, self.toolchain) + if "Main.class" not in names or any( + not re.fullmatch(r"[A-Za-z_$][A-Za-z0-9_$]*\.class", name) for name in names + ): + raise ValueError("Java requires a bounded default-package Main class set") + return self + + +class CompilationReport(v1.CompilationReport): + program: CompiledProgram | None + + +class JudgementReport(v1.JudgementReport): + schema_version: Version + compilation: CompilationReport + + @model_validator(mode="after") + def program_attempt(self) -> Self: + if ( + self.compilation.program is not None + and self.compilation.program.binding != self.binding + ): + raise ValueError("program belongs to another attempt") + return self + + def validate_for_manifest(self, manifest: JobManifest, digest: str) -> None: + super().validate_for_manifest(manifest, digest) + program = self.compilation.program + if program is not None and ( + program.source != manifest.source + or program.toolchain != manifest.toolchain + or program.kind != runtime_contract(manifest.language)[3] + ): + raise ValueError("program differs from authorized source or runtime") + + +class LeaseGrant(v1.LeaseGrant): + schema_version: Version + + +class StageReport(v1.StageReport): + schema_version: Version + preparation_kind: PreparationKind + + def validate_for_manifest(self, manifest: JobManifest) -> None: + if self.binding.evaluation_id != manifest.evaluation_id or ( + self.preparation_kind != runtime_contract(manifest.language)[4] + ): + raise ValueError("stage differs from authorized language preparation") + + +class StoppedReport(v1.StoppedReport): + schema_version: Version + + +class RuntimeCapability(v1.WireModel): + language: Language + toolchain: RuntimeIdentity + compile_ceiling: v1.RunLimits + run_ceiling: v1.RunLimits + + @model_validator(mode="after") + def runtime_and_budget(self) -> Self: + validate_runtime(self.language, self.toolchain) + validate_startup_budget(self.language, self.compile_ceiling, preparing=True) + validate_startup_budget(self.language, self.run_ceiling, preparing=False) + return self + + +class AdmissionPolicy(v1.WireModel): + schema_version: Version + max_concurrent_jobs: Annotated[int, Field(strict=True, ge=1, le=64)] = 1 + prefetch: Annotated[int, Field(strict=True, ge=1, le=64)] = 1 + max_retries: Annotated[int, Field(strict=True, ge=0, le=4)] = 2 + max_job_wall_time_us: Annotated[int, Field(strict=True, ge=1000, le=v1.MAX_JOB_WALL_US)] + max_package_bytes: Annotated[int, Field(strict=True, ge=1, le=v1.MAX_PACKAGE_BYTES)] + capabilities: Annotated[tuple[RuntimeCapability, ...], Field(min_length=1, max_length=4)] + + @model_validator(mode="after") + def consistent(self) -> Self: + if self.prefetch > self.max_concurrent_jobs: + raise ValueError("prefetch exceeds available job slots") + if len({cap.language for cap in self.capabilities}) != len(self.capabilities): + raise ValueError("duplicate language capability") + return self + + def admit(self, manifest: JobManifest, attempt_number: int) -> None: + # Revalidate constructed/copied values as well as transport-decoded models. + manifest = JobManifest.model_validate(manifest.model_dump(mode="json")) + AdmissionPolicy.model_validate(self.model_dump(mode="json")) + if type(attempt_number) is not int or not 1 <= attempt_number <= self.max_retries + 1: + raise ValueError("attempt retry budget exhausted") + cap = next((cap for cap in self.capabilities if cap.language == manifest.language), None) + if cap is None or ( + cap.toolchain != manifest.toolchain + or not manifest.compile_limits.fits(cap.compile_ceiling) + or not manifest.run_limits.fits(cap.run_ceiling) + or manifest.job_wall_time_us > self.max_job_wall_time_us + or manifest.package_bytes() > self.max_package_bytes + ): + raise ValueError("job exceeds trusted runtime capability or budget") + + +WIRE_MODELS = { + "judge-manifest": JobManifest, + "judge-lease": LeaseGrant, + "judge-stage": StageReport, + "judge-result": JudgementReport, + "judge-admission": AdmissionPolicy, + "judge-stopped": StoppedReport, +} diff --git a/backend/src/kf_oj/contracts/judging_versions.py b/backend/src/kf_oj/contracts/judging_versions.py new file mode 100644 index 0000000..785d969 --- /dev/null +++ b/backend/src/kf_oj/contracts/judging_versions.py @@ -0,0 +1,35 @@ +"""Version dispatch at storage/transport boundaries; never rewrite legacy snapshots.""" + +from pydantic import ConfigDict, RootModel + +from kf_oj.contracts import judging as v1 +from kf_oj.contracts import judging_v2 as v2 + +Manifest = v1.JobManifest | v2.JobManifest +Report = v1.JudgementReport | v2.JudgementReport + + +class ManifestEnvelope(RootModel[Manifest]): + model_config = ConfigDict(frozen=True) + + +class ReportEnvelope(RootModel[Report]): + model_config = ConfigDict(frozen=True) + + +def decode_manifest(payload: bytes) -> Manifest: + return v1.decode_wire(ManifestEnvelope, payload).root + + +def decode_report(payload: bytes) -> Report: + return v1.decode_wire(ReportEnvelope, payload).root + + +def manifest_bytes(manifest: Manifest) -> bytes: + return v1.manifest_bytes(manifest) + + +def validate_report(report: Report, manifest: Manifest, digest: str) -> None: + if report.schema_version != manifest.schema_version: + raise ValueError("report protocol differs from authorized manifest") + report.validate_for_manifest(manifest, digest) diff --git a/backend/src/kf_oj/modules/submissions/queries.py b/backend/src/kf_oj/modules/submissions/queries.py index a8eb9bc..e254aa7 100644 --- a/backend/src/kf_oj/modules/submissions/queries.py +++ b/backend/src/kf_oj/modules/submissions/queries.py @@ -1,11 +1,13 @@ import base64 +import json from datetime import datetime from uuid import UUID from sqlalchemy import select, tuple_ from sqlalchemy.ext.asyncio import async_sessionmaker -from kf_oj.contracts.judging import MAX_SOURCE_BYTES, ArtifactReference, JudgementReport +from kf_oj.contracts.judging import MAX_SOURCE_BYTES, ArtifactReference +from kf_oj.contracts.judging_versions import decode_report from kf_oj.contracts.submissions import ( CancellationAccepted, PublicCaseResult, @@ -115,7 +117,11 @@ class SubmissionQueries: if evaluation.state in {"finished", "failed", "cancelled"} and evaluation.final_report: # A single joined snapshot, strict validation and explicit projection prevent leaking # internal bindings, artifacts, hidden case identifiers or partial attempt reports. - report = JudgementReport.model_validate(evaluation.final_report) + report = decode_report( + json.dumps( + evaluation.final_report, ensure_ascii=False, separators=(",", ":") + ).encode() + ) if str(report.binding.evaluation_id) != str(evaluation.id): raise ValueError("stored result binding invalid") if report.verdict.value != evaluation.verdict: diff --git a/backend/src/kf_oj/modules/submissions/worker_access.py b/backend/src/kf_oj/modules/submissions/worker_access.py index b6de521..1f14fc1 100644 --- a/backend/src/kf_oj/modules/submissions/worker_access.py +++ b/backend/src/kf_oj/modules/submissions/worker_access.py @@ -7,10 +7,10 @@ from contextlib import asynccontextmanager from sqlalchemy.ext.asyncio import async_sessionmaker -from kf_oj.contracts.judging import ( - JobManifest, - LeaseBinding, - decode_wire, +from kf_oj.contracts.judging import LeaseBinding +from kf_oj.contracts.judging_versions import ( + Manifest, + decode_manifest, manifest_bytes, ) from kf_oj.infra.artifacts.repository import ArtifactRepository @@ -40,7 +40,7 @@ class WorkerAccess: raise WorkerAccessDenied("worker grant rejected") return hashlib.sha256(token.encode("ascii")).hexdigest() - async def _manifest(self, session, binding: LeaseBinding, token: str) -> JobManifest: + async def _manifest(self, session, binding: LeaseBinding, token: str) -> Manifest: row = await repository.leased_submission(session, binding, self._token_hash(token)) if row is None: raise WorkerAccessDenied("worker grant rejected") @@ -49,7 +49,7 @@ class WorkerAccess: # runtime roles; use canonical bytes for both retrieval and digest verification. try: - manifest = decode_wire(JobManifest, json.dumps(attempt.manifest).encode()) + manifest = decode_manifest(json.dumps(attempt.manifest).encode()) if ( manifest.evaluation_id != evaluation.id or manifest.submission_id != submission.id diff --git a/backend/tests/test_judging_v2_contracts.py b/backend/tests/test_judging_v2_contracts.py new file mode 100644 index 0000000..1d16382 --- /dev/null +++ b/backend/tests/test_judging_v2_contracts.py @@ -0,0 +1,186 @@ +import hashlib +import json +from pathlib import Path + +import pytest +from jsonschema import Draft202012Validator, FormatChecker + +from kf_oj.contracts import judging as v1 +from kf_oj.contracts import judging_v2 as v2 +from kf_oj.contracts import judging_versions as versions + +ROOT = Path(__file__).resolve().parents[2] +FIXTURES = ROOT / "tests/fixtures/contracts-v2" +PATHS = sorted(FIXTURES.glob("*.json")) + + +def fixture(name, model): + return v1.decode_wire(model, (FIXTURES / f"{name}.json").read_bytes()) + + +@pytest.mark.parametrize("path", PATHS, ids=lambda p: p.stem) +def test_multi_runtime_examples_match_schema_and_rust(path): + name = path.name.split(".")[0] + model = v2.WIRE_MODELS[name] + schema = json.loads((ROOT / f"contracts/schemas/{name}.v2.schema.json").read_text()) + validator = Draft202012Validator(schema, format_checker=FormatChecker()) + original = json.loads(path.read_text()) + if ".invalid-" in path.name: + with pytest.raises(ValueError): + v1.decode_wire(model, path.read_bytes()) + if ".invalid-semantic-" in path.name: + assert validator.is_valid(original) + else: + assert not validator.is_valid(original) + else: + value = v1.decode_wire(model, path.read_bytes()) + validator.validate(original) + assert value.model_dump(mode="json") == original + + +@pytest.mark.parametrize("language", list(v2.Language)) +def test_explicit_version_keeps_old_consumers_closed_and_canonical_bytes_stable(language): + path = FIXTURES / f"judge-manifest.valid-{language}.json" + manifest = v1.decode_wire(v2.JobManifest, path.read_bytes()) + canonical = (FIXTURES / f"canonical-manifest.{language}.txt").read_bytes() + assert v1.manifest_bytes(manifest) == canonical + assert ( + hashlib.sha256(v1.manifest_bytes(manifest)).digest() == hashlib.sha256(canonical).digest() + ) + with pytest.raises(ValueError): + v1.decode_wire(v1.JobManifest, path.read_bytes()) + old = ROOT / "tests/fixtures/contracts/judge-manifest.valid.json" + with pytest.raises(ValueError): + v1.decode_wire(v2.JobManifest, old.read_bytes()) + old_manifest = v1.decode_wire(v1.JobManifest, old.read_bytes()) + assert ( + v1.manifest_bytes(old_manifest) + == (ROOT / "tests/fixtures/contracts/canonical-manifest.v1.txt").read_bytes() + ) + + +def test_shared_capabilities_refuse_absent_changed_runtime_and_over_budget(): + policy = fixture("judge-admission.valid", v2.AdmissionPolicy) + for language in v2.Language: + manifest = fixture(f"judge-manifest.valid-{language}", v2.JobManifest) + for attempt in (1, 2, 3): + policy.admit(manifest, attempt) + for attempt in (0, 4, True): + with pytest.raises(ValueError): + policy.admit(manifest, attempt) + for field, value in (("image_revision", 2), ("image_digest", "f" * 64)): + other = manifest.model_copy( + update={"toolchain": manifest.toolchain.model_copy(update={field: value})} + ) + with pytest.raises(ValueError): + policy.admit(other, 1) + python = fixture("judge-manifest.valid-python313", v2.JobManifest) + without_python = policy.model_copy( + update={ + "capabilities": tuple(c for c in policy.capabilities if c.language != python.language) + } + ) + with pytest.raises(ValueError): + without_python.admit(python, 1) + too_small = python.model_copy( + update={"run_limits": python.run_limits.model_copy(update={"memory_bytes": 1})} + ) + with pytest.raises(ValueError): + policy.admit(too_small, 1) + too_large = python.model_copy( + update={"run_limits": python.run_limits.model_copy(update={"memory_bytes": 128 * v1.MIB})} + ) + with pytest.raises(ValueError): + policy.admit(too_large, 1) + + +@pytest.mark.parametrize("language", list(v2.Language)) +def test_results_bind_exact_source_runtime_attempt_and_case_order(language): + manifest = fixture(f"judge-manifest.valid-{language}", v2.JobManifest) + result = fixture(f"judge-result.valid-{language}", v2.JudgementReport) + result.validate_for_manifest(manifest, result.manifest_digest) + for field, value in (("digest", "f" * 64), ("bytes", manifest.source.bytes + 1)): + other = manifest.model_copy( + update={"source": manifest.source.model_copy(update={field: value})} + ) + with pytest.raises(ValueError): + result.validate_for_manifest(other, result.manifest_digest) + with pytest.raises(ValueError): + result.validate_for_manifest(manifest, "f" * 64) + changed_runtime = manifest.model_copy( + update={"toolchain": manifest.toolchain.model_copy(update={"image_digest": "e" * 64})} + ) + with pytest.raises(ValueError): + result.validate_for_manifest(changed_runtime, result.manifest_digest) + short = result.model_dump(mode="json") + short.update(cases=short["cases"][:1], run_cpu_time_us=100, run_memory_peak_bytes=256 * 1024) + valid_partial = v2.JudgementReport.model_validate(short) + with pytest.raises(ValueError): + valid_partial.validate_for_manifest(manifest, result.manifest_digest) + + +def test_python_check_is_not_an_accepted_result_and_stage_kind_is_bound(): + manifest = fixture("judge-manifest.valid-python313", v2.JobManifest) + stage = fixture("judge-stage.valid-python313", v2.StageReport) + stage.validate_for_manifest(manifest) + with pytest.raises(ValueError): + stage.model_copy( + update={"preparation_kind": v2.PreparationKind.COMPILE} + ).validate_for_manifest(manifest) + result = fixture("judge-result.valid-python313", v2.JudgementReport).model_dump(mode="json") + result.update(cases=[], run_cpu_time_us=None, run_memory_peak_bytes=None) + with pytest.raises(ValueError): + v2.JudgementReport.model_validate(result) + + +def test_jvm_heap_is_smaller_than_total_memory_and_threads_share_the_budget(): + manifest = fixture("judge-manifest.valid-java21", v2.JobManifest) + limits = manifest.run_limits + assert 32 * v1.MIB <= v2.jvm_heap_bytes(limits) < limits.memory_bytes + more_threads = limits.model_copy(update={"processes": 32}) + assert v2.jvm_heap_bytes(more_threads) < v2.jvm_heap_bytes(limits) + with pytest.raises(ValueError): + v2.jvm_heap_bytes(limits.model_copy(update={"memory_bytes": 128 * v1.MIB})) + # Ordinary RuntimeError has no infrastructure failure code or trusted memory-limit claim. + result = fixture("judge-result.valid-java21", v2.JudgementReport).model_dump(mode="json") + result["cases"][0]["verdict"] = "runtime_error" + result["verdict"] = "runtime_error" + v2.JudgementReport.model_validate(result) + + +def test_v2_wire_rejects_ambiguous_private_values_without_echoing_them(): + data = (FIXTURES / "judge-lease.valid.json").read_bytes() + duplicate = data.replace(b'"schema_version": 2', b'"schema_version": 2, "schema_version": 2') + for invalid in (duplicate, b" " * (v1.MAX_WIRE_BYTES + 1), data.decode().encode("utf-16")): + with pytest.raises(ValueError): + v1.decode_wire(v2.LeaseGrant, invalid) + secret = "private-placeholder-never-echo" + value = json.loads(data) + value["lease_token"] = secret + with pytest.raises(ValueError) as error: + v1.decode_wire(v2.LeaseGrant, json.dumps(value).encode()) + assert secret not in str(error.value) + + +def test_storage_boundary_reads_both_versions_without_rewriting_or_cross_version_reports(): + old = ROOT / "tests/fixtures/contracts" + old_manifest = versions.decode_manifest((old / "judge-manifest.valid.json").read_bytes()) + old_report = versions.decode_report((old / "judge-result.valid.json").read_bytes()) + versions.validate_report(old_report, old_manifest, old_report.manifest_digest) + assert versions.manifest_bytes(old_manifest) == (old / "canonical-manifest.v1.txt").read_bytes() + manifest = versions.decode_manifest( + (FIXTURES / "judge-manifest.valid-python313.json").read_bytes() + ) + report = versions.decode_report((FIXTURES / "judge-result.valid-python313.json").read_bytes()) + versions.validate_report(report, manifest, report.manifest_digest) + for result, task in ((old_report, manifest), (report, old_manifest)): + with pytest.raises(ValueError): + versions.validate_report(result, task, result.manifest_digest) + payload = (FIXTURES / "judge-manifest.valid-python313.json").read_bytes() + for invalid in ( + payload.replace(b'"schema_version": 2', b'"schema_version": 3'), + payload.replace(b'"schema_version": 2', b'"schema_version": true'), + payload.replace(b'"schema_version": 2', b'"schema_version": 2, "schema_version": 2'), + ): + with pytest.raises(ValueError): + versions.decode_manifest(invalid) diff --git a/backend/tests/test_submission_queries.py b/backend/tests/test_submission_queries.py index 106306c..46977a4 100644 --- a/backend/tests/test_submission_queries.py +++ b/backend/tests/test_submission_queries.py @@ -27,7 +27,10 @@ def test_cursor_and_control_configuration_fail_closed(): Settings(_env_file=None, coordinator_url="http://127.0.0.1:8100", coordinator_token="a" * 64) -def test_actual_owned_history_source_result_and_cancel(postgres_url, tmp_path, monkeypatch): +@pytest.mark.parametrize("wire_version", [1, 2]) +def test_actual_owned_history_source_result_and_cancel( + postgres_url, tmp_path, monkeypatch, wire_version +): async def run(): app, engine, mod = await setup_app(postgres_url, tmp_path) monkeypatch.setattr(mod, "build_engine", lambda _: engine) @@ -52,9 +55,17 @@ def test_actual_owned_history_source_result_and_cancel(postgres_url, tmp_path, m ) ) # Synthetic contract projection only, never claimed as a real judgement. - fixture = Path(__file__).parents[2] / "tests/fixtures/contracts/judge-result.valid.json" + fixture = Path(__file__).parents[2] / ( + "tests/fixtures/contracts/judge-result.valid.json" + if wire_version == 1 + else "tests/fixtures/contracts-v2/judge-result.valid-c17.json" + ) report = json.loads(fixture.read_text()) report["binding"]["evaluation_id"] = str(records[0].evaluation_id) + if wire_version == 2: + report["compilation"]["program"]["binding"]["evaluation_id"] = str( + records[0].evaluation_id + ) admin = create_async_engine(postgres_url) async with admin.begin() as conn: await conn.execute(text("SET LOCAL ROLE kf_oj_coordinator")) diff --git a/contracts/schemas/judge-admission.v2.schema.json b/contracts/schemas/judge-admission.v2.schema.json new file mode 100644 index 0000000..3c0770f --- /dev/null +++ b/contracts/schemas/judge-admission.v2.schema.json @@ -0,0 +1,226 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "Language": { + "enum": [ + "c17", + "cpp20", + "python313", + "java21" + ], + "title": "Language", + "type": "string" + }, + "RunLimits": { + "additionalProperties": false, + "properties": { + "cpu_time_us": { + "maximum": 60000000, + "minimum": 1000, + "title": "Cpu Time Us", + "type": "integer" + }, + "file_bytes": { + "maximum": 67108864, + "minimum": 1, + "title": "File Bytes", + "type": "integer" + }, + "memory_bytes": { + "maximum": 2147483648, + "minimum": 1, + "title": "Memory Bytes", + "type": "integer" + }, + "open_files": { + "maximum": 1024, + "minimum": 3, + "title": "Open Files", + "type": "integer" + }, + "processes": { + "maximum": 128, + "minimum": 1, + "title": "Processes", + "type": "integer" + }, + "stack_bytes": { + "maximum": 268435456, + "minimum": 1, + "title": "Stack Bytes", + "type": "integer" + }, + "stderr_bytes": { + "maximum": 16777216, + "minimum": 1, + "title": "Stderr Bytes", + "type": "integer" + }, + "stdout_bytes": { + "maximum": 16777216, + "minimum": 1, + "title": "Stdout Bytes", + "type": "integer" + }, + "wall_time_us": { + "maximum": 120000000, + "minimum": 1000, + "title": "Wall Time Us", + "type": "integer" + }, + "workdir_bytes": { + "maximum": 268435456, + "minimum": 1, + "title": "Workdir Bytes", + "type": "integer" + } + }, + "required": [ + "cpu_time_us", + "wall_time_us", + "memory_bytes", + "stack_bytes", + "processes", + "open_files", + "stdout_bytes", + "stderr_bytes", + "file_bytes", + "workdir_bytes" + ], + "title": "RunLimits", + "type": "object" + }, + "RuntimeCapability": { + "additionalProperties": false, + "properties": { + "compile_ceiling": { + "$ref": "#/$defs/RunLimits" + }, + "language": { + "$ref": "#/$defs/Language" + }, + "run_ceiling": { + "$ref": "#/$defs/RunLimits" + }, + "toolchain": { + "$ref": "#/$defs/RuntimeIdentity" + } + }, + "required": [ + "language", + "toolchain", + "compile_ceiling", + "run_ceiling" + ], + "title": "RuntimeCapability", + "type": "object" + }, + "RuntimeIdentity": { + "additionalProperties": false, + "description": "An exact identity matched against trusted configuration, never a host path.", + "properties": { + "image_digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Image Digest", + "type": "string" + }, + "image_kind": { + "enum": [ + "linux_gnu_cxx_x86_64_v1", + "linux_cpython313_x86_64_v1", + "linux_openjdk21_x86_64_v1" + ], + "title": "Image Kind", + "type": "string" + }, + "image_revision": { + "maximum": 4294967295, + "minimum": 1, + "title": "Image Revision", + "type": "integer" + }, + "runtime_version": { + "pattern": "^[A-Za-z0-9][A-Za-z0-9_.+-]{0,63}$", + "title": "Runtime Version", + "type": "string" + }, + "toolchain_id": { + "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$", + "title": "Toolchain Id", + "type": "string" + } + }, + "required": [ + "toolchain_id", + "image_kind", + "image_revision", + "image_digest", + "runtime_version" + ], + "title": "RuntimeIdentity", + "type": "object" + } + }, + "$id": "urn:kf-oj:judge-admission:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "capabilities": { + "items": { + "$ref": "#/$defs/RuntimeCapability" + }, + "maxItems": 4, + "minItems": 1, + "title": "Capabilities", + "type": "array" + }, + "max_concurrent_jobs": { + "default": 1, + "maximum": 64, + "minimum": 1, + "title": "Max Concurrent Jobs", + "type": "integer" + }, + "max_job_wall_time_us": { + "maximum": 3600000000, + "minimum": 1000, + "title": "Max Job Wall Time Us", + "type": "integer" + }, + "max_package_bytes": { + "maximum": 67108864, + "minimum": 1, + "title": "Max Package Bytes", + "type": "integer" + }, + "max_retries": { + "default": 2, + "maximum": 4, + "minimum": 0, + "title": "Max Retries", + "type": "integer" + }, + "prefetch": { + "default": 1, + "maximum": 64, + "minimum": 1, + "title": "Prefetch", + "type": "integer" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + } + }, + "required": [ + "schema_version", + "max_job_wall_time_us", + "max_package_bytes", + "capabilities" + ], + "title": "AdmissionPolicy", + "type": "object" +} diff --git a/contracts/schemas/judge-lease.v2.schema.json b/contracts/schemas/judge-lease.v2.schema.json new file mode 100644 index 0000000..4392db6 --- /dev/null +++ b/contracts/schemas/judge-lease.v2.schema.json @@ -0,0 +1,94 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "LeaseBinding": { + "additionalProperties": false, + "properties": { + "attempt_id": { + "format": "uuid", + "title": "Attempt Id", + "type": "string" + }, + "evaluation_id": { + "format": "uuid", + "title": "Evaluation Id", + "type": "string" + }, + "fencing_version": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Fencing Version", + "type": "integer" + }, + "worker_id": { + "format": "uuid", + "title": "Worker Id", + "type": "string" + } + }, + "required": [ + "evaluation_id", + "attempt_id", + "worker_id", + "fencing_version" + ], + "title": "LeaseBinding", + "type": "object" + } + }, + "$id": "urn:kf-oj:judge-lease:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "attempt_number": { + "maximum": 5, + "minimum": 1, + "title": "Attempt Number", + "type": "integer" + }, + "binding": { + "$ref": "#/$defs/LeaseBinding" + }, + "expires_at_unix_ms": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Expires At Unix Ms", + "type": "integer" + }, + "kind": { + "const": "judge.lease", + "title": "Kind", + "type": "string" + }, + "lease_token": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Lease Token", + "type": "string" + }, + "manifest_digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Manifest Digest", + "type": "string" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + } + }, + "required": [ + "schema_version", + "kind", + "binding", + "lease_token", + "attempt_number", + "expires_at_unix_ms", + "manifest_digest" + ], + "title": "LeaseGrant", + "type": "object" +} diff --git a/contracts/schemas/judge-manifest.v2.schema.json b/contracts/schemas/judge-manifest.v2.schema.json new file mode 100644 index 0000000..c486056 --- /dev/null +++ b/contracts/schemas/judge-manifest.v2.schema.json @@ -0,0 +1,270 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "ArtifactReference": { + "additionalProperties": false, + "properties": { + "bytes": { + "maximum": 67108864, + "minimum": 0, + "title": "Bytes", + "type": "integer" + }, + "digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Digest", + "type": "string" + } + }, + "required": [ + "digest", + "bytes" + ], + "title": "ArtifactReference", + "type": "object" + }, + "Language": { + "enum": [ + "c17", + "cpp20", + "python313", + "java21" + ], + "title": "Language", + "type": "string" + }, + "RunLimits": { + "additionalProperties": false, + "properties": { + "cpu_time_us": { + "maximum": 60000000, + "minimum": 1000, + "title": "Cpu Time Us", + "type": "integer" + }, + "file_bytes": { + "maximum": 67108864, + "minimum": 1, + "title": "File Bytes", + "type": "integer" + }, + "memory_bytes": { + "maximum": 2147483648, + "minimum": 1, + "title": "Memory Bytes", + "type": "integer" + }, + "open_files": { + "maximum": 1024, + "minimum": 3, + "title": "Open Files", + "type": "integer" + }, + "processes": { + "maximum": 128, + "minimum": 1, + "title": "Processes", + "type": "integer" + }, + "stack_bytes": { + "maximum": 268435456, + "minimum": 1, + "title": "Stack Bytes", + "type": "integer" + }, + "stderr_bytes": { + "maximum": 16777216, + "minimum": 1, + "title": "Stderr Bytes", + "type": "integer" + }, + "stdout_bytes": { + "maximum": 16777216, + "minimum": 1, + "title": "Stdout Bytes", + "type": "integer" + }, + "wall_time_us": { + "maximum": 120000000, + "minimum": 1000, + "title": "Wall Time Us", + "type": "integer" + }, + "workdir_bytes": { + "maximum": 268435456, + "minimum": 1, + "title": "Workdir Bytes", + "type": "integer" + } + }, + "required": [ + "cpu_time_us", + "wall_time_us", + "memory_bytes", + "stack_bytes", + "processes", + "open_files", + "stdout_bytes", + "stderr_bytes", + "file_bytes", + "workdir_bytes" + ], + "title": "RunLimits", + "type": "object" + }, + "RuntimeIdentity": { + "additionalProperties": false, + "description": "An exact identity matched against trusted configuration, never a host path.", + "properties": { + "image_digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Image Digest", + "type": "string" + }, + "image_kind": { + "enum": [ + "linux_gnu_cxx_x86_64_v1", + "linux_cpython313_x86_64_v1", + "linux_openjdk21_x86_64_v1" + ], + "title": "Image Kind", + "type": "string" + }, + "image_revision": { + "maximum": 4294967295, + "minimum": 1, + "title": "Image Revision", + "type": "integer" + }, + "runtime_version": { + "pattern": "^[A-Za-z0-9][A-Za-z0-9_.+-]{0,63}$", + "title": "Runtime Version", + "type": "string" + }, + "toolchain_id": { + "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$", + "title": "Toolchain Id", + "type": "string" + } + }, + "required": [ + "toolchain_id", + "image_kind", + "image_revision", + "image_digest", + "runtime_version" + ], + "title": "RuntimeIdentity", + "type": "object" + }, + "TestCase": { + "additionalProperties": false, + "properties": { + "case_id": { + "format": "uuid", + "title": "Case Id", + "type": "string" + }, + "expected": { + "$ref": "#/$defs/ArtifactReference" + }, + "input": { + "$ref": "#/$defs/ArtifactReference" + } + }, + "required": [ + "case_id", + "input", + "expected" + ], + "title": "TestCase", + "type": "object" + } + }, + "$id": "urn:kf-oj:judge-manifest:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "cases": { + "items": { + "$ref": "#/$defs/TestCase" + }, + "maxItems": 256, + "minItems": 1, + "title": "Cases", + "type": "array" + }, + "comparison": { + "const": "exact_bytes", + "title": "Comparison", + "type": "string" + }, + "compile_limits": { + "$ref": "#/$defs/RunLimits" + }, + "evaluation_id": { + "format": "uuid", + "title": "Evaluation Id", + "type": "string" + }, + "job_wall_time_us": { + "maximum": 3600000000, + "minimum": 1000, + "title": "Job Wall Time Us", + "type": "integer" + }, + "kind": { + "const": "judge.manifest", + "title": "Kind", + "type": "string" + }, + "language": { + "$ref": "#/$defs/Language" + }, + "problem_version_id": { + "format": "uuid", + "title": "Problem Version Id", + "type": "string" + }, + "run_limits": { + "$ref": "#/$defs/RunLimits" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + }, + "source": { + "$ref": "#/$defs/ArtifactReference" + }, + "submission_id": { + "format": "uuid", + "title": "Submission Id", + "type": "string" + }, + "toolchain": { + "$ref": "#/$defs/RuntimeIdentity" + } + }, + "required": [ + "schema_version", + "kind", + "evaluation_id", + "submission_id", + "problem_version_id", + "language", + "toolchain", + "source", + "cases", + "comparison", + "compile_limits", + "run_limits", + "job_wall_time_us" + ], + "title": "JobManifest", + "type": "object" +} diff --git a/contracts/schemas/judge-result.v2.schema.json b/contracts/schemas/judge-result.v2.schema.json new file mode 100644 index 0000000..44c224b --- /dev/null +++ b/contracts/schemas/judge-result.v2.schema.json @@ -0,0 +1,416 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "ArtifactReference": { + "additionalProperties": false, + "properties": { + "bytes": { + "maximum": 67108864, + "minimum": 0, + "title": "Bytes", + "type": "integer" + }, + "digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Digest", + "type": "string" + } + }, + "required": [ + "digest", + "bytes" + ], + "title": "ArtifactReference", + "type": "object" + }, + "CaseReport": { + "additionalProperties": false, + "properties": { + "case_id": { + "format": "uuid", + "title": "Case Id", + "type": "string" + }, + "cpu_time_us": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Cpu Time Us" + }, + "memory_peak_bytes": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Memory Peak Bytes" + }, + "verdict": { + "$ref": "#/$defs/Verdict" + } + }, + "required": [ + "case_id", + "verdict", + "cpu_time_us", + "memory_peak_bytes" + ], + "title": "CaseReport", + "type": "object" + }, + "CompilationReport": { + "additionalProperties": false, + "properties": { + "cpu_time_us": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Cpu Time Us" + }, + "diagnostics": { + "maxLength": 65536, + "title": "Diagnostics", + "type": "string" + }, + "diagnostics_truncated": { + "title": "Diagnostics Truncated", + "type": "boolean" + }, + "memory_peak_bytes": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Memory Peak Bytes" + }, + "program": { + "anyOf": [ + { + "$ref": "#/$defs/CompiledProgram" + }, + { + "type": "null" + } + ] + }, + "status": { + "$ref": "#/$defs/CompilationStatus" + } + }, + "required": [ + "status", + "program", + "diagnostics", + "diagnostics_truncated", + "cpu_time_us", + "memory_peak_bytes" + ], + "title": "CompilationReport", + "type": "object" + }, + "CompilationStatus": { + "enum": [ + "succeeded", + "compilation_error", + "compilation_limit", + "cancelled", + "system_error" + ], + "title": "CompilationStatus", + "type": "string" + }, + "CompiledProgram": { + "additionalProperties": false, + "description": "Sealed file identities bound to a particular source, runtime and lease attempt.", + "properties": { + "binding": { + "$ref": "#/$defs/LeaseBinding" + }, + "files": { + "items": { + "$ref": "#/$defs/ProgramFile" + }, + "maxItems": 256, + "minItems": 1, + "title": "Files", + "type": "array" + }, + "kind": { + "$ref": "#/$defs/ProgramKind" + }, + "source": { + "$ref": "#/$defs/ArtifactReference" + }, + "toolchain": { + "$ref": "#/$defs/RuntimeIdentity" + } + }, + "required": [ + "kind", + "binding", + "source", + "toolchain", + "files" + ], + "title": "CompiledProgram", + "type": "object" + }, + "FailureCode": { + "enum": [ + "artifact_unavailable", + "sandbox_unavailable", + "cleanup_failed", + "lease_lost", + "job_deadline" + ], + "title": "FailureCode", + "type": "string" + }, + "LeaseBinding": { + "additionalProperties": false, + "properties": { + "attempt_id": { + "format": "uuid", + "title": "Attempt Id", + "type": "string" + }, + "evaluation_id": { + "format": "uuid", + "title": "Evaluation Id", + "type": "string" + }, + "fencing_version": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Fencing Version", + "type": "integer" + }, + "worker_id": { + "format": "uuid", + "title": "Worker Id", + "type": "string" + } + }, + "required": [ + "evaluation_id", + "attempt_id", + "worker_id", + "fencing_version" + ], + "title": "LeaseBinding", + "type": "object" + }, + "ProgramFile": { + "additionalProperties": false, + "properties": { + "artifact": { + "$ref": "#/$defs/ArtifactReference" + }, + "path": { + "maxLength": 128, + "minLength": 1, + "title": "Path", + "type": "string" + } + }, + "required": [ + "path", + "artifact" + ], + "title": "ProgramFile", + "type": "object" + }, + "ProgramKind": { + "enum": [ + "native_executable", + "python_source", + "java_classes" + ], + "title": "ProgramKind", + "type": "string" + }, + "RuntimeIdentity": { + "additionalProperties": false, + "description": "An exact identity matched against trusted configuration, never a host path.", + "properties": { + "image_digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Image Digest", + "type": "string" + }, + "image_kind": { + "enum": [ + "linux_gnu_cxx_x86_64_v1", + "linux_cpython313_x86_64_v1", + "linux_openjdk21_x86_64_v1" + ], + "title": "Image Kind", + "type": "string" + }, + "image_revision": { + "maximum": 4294967295, + "minimum": 1, + "title": "Image Revision", + "type": "integer" + }, + "runtime_version": { + "pattern": "^[A-Za-z0-9][A-Za-z0-9_.+-]{0,63}$", + "title": "Runtime Version", + "type": "string" + }, + "toolchain_id": { + "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$", + "title": "Toolchain Id", + "type": "string" + } + }, + "required": [ + "toolchain_id", + "image_kind", + "image_revision", + "image_digest", + "runtime_version" + ], + "title": "RuntimeIdentity", + "type": "object" + }, + "Verdict": { + "enum": [ + "accepted", + "wrong_answer", + "compilation_error", + "runtime_error", + "time_limit_exceeded", + "memory_limit_exceeded", + "output_limit_exceeded", + "cancelled", + "system_error" + ], + "title": "Verdict", + "type": "string" + } + }, + "$id": "urn:kf-oj:judge-result:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "binding": { + "$ref": "#/$defs/LeaseBinding" + }, + "cases": { + "items": { + "$ref": "#/$defs/CaseReport" + }, + "maxItems": 256, + "title": "Cases", + "type": "array" + }, + "cleanup_complete": { + "title": "Cleanup Complete", + "type": "boolean" + }, + "compilation": { + "$ref": "#/$defs/CompilationReport" + }, + "failure_code": { + "anyOf": [ + { + "$ref": "#/$defs/FailureCode" + }, + { + "type": "null" + } + ] + }, + "kind": { + "const": "judge.result", + "title": "Kind", + "type": "string" + }, + "manifest_digest": { + "maxLength": 64, + "minLength": 64, + "pattern": "^[0-9a-f]{64}$", + "title": "Manifest Digest", + "type": "string" + }, + "run_cpu_time_us": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Run Cpu Time Us" + }, + "run_memory_peak_bytes": { + "anyOf": [ + { + "maximum": 9223372036854775807, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Run Memory Peak Bytes" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + }, + "verdict": { + "$ref": "#/$defs/Verdict" + } + }, + "required": [ + "schema_version", + "kind", + "binding", + "manifest_digest", + "compilation", + "cases", + "verdict", + "cleanup_complete", + "failure_code", + "run_cpu_time_us", + "run_memory_peak_bytes" + ], + "title": "JudgementReport", + "type": "object" +} diff --git a/contracts/schemas/judge-stage.v2.schema.json b/contracts/schemas/judge-stage.v2.schema.json new file mode 100644 index 0000000..2daeece --- /dev/null +++ b/contracts/schemas/judge-stage.v2.schema.json @@ -0,0 +1,106 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "LeaseBinding": { + "additionalProperties": false, + "properties": { + "attempt_id": { + "format": "uuid", + "title": "Attempt Id", + "type": "string" + }, + "evaluation_id": { + "format": "uuid", + "title": "Evaluation Id", + "type": "string" + }, + "fencing_version": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Fencing Version", + "type": "integer" + }, + "worker_id": { + "format": "uuid", + "title": "Worker Id", + "type": "string" + } + }, + "required": [ + "evaluation_id", + "attempt_id", + "worker_id", + "fencing_version" + ], + "title": "LeaseBinding", + "type": "object" + }, + "PreparationKind": { + "enum": [ + "compile", + "syntax_check" + ], + "title": "PreparationKind", + "type": "string" + } + }, + "$id": "urn:kf-oj:judge-stage:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "binding": { + "$ref": "#/$defs/LeaseBinding" + }, + "case_index": { + "anyOf": [ + { + "exclusiveMaximum": 256, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Case Index" + }, + "kind": { + "const": "judge.stage", + "title": "Kind", + "type": "string" + }, + "preparation_kind": { + "$ref": "#/$defs/PreparationKind" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + }, + "sequence": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Sequence", + "type": "integer" + }, + "stage": { + "enum": [ + "compiling", + "running" + ], + "title": "Stage", + "type": "string" + } + }, + "required": [ + "schema_version", + "kind", + "binding", + "sequence", + "stage", + "case_index", + "preparation_kind" + ], + "title": "StageReport", + "type": "object" +} diff --git a/contracts/schemas/judge-stopped.v2.schema.json b/contracts/schemas/judge-stopped.v2.schema.json new file mode 100644 index 0000000..c6d7f11 --- /dev/null +++ b/contracts/schemas/judge-stopped.v2.schema.json @@ -0,0 +1,69 @@ +{ + "$comment": "Multi-runtime protocol. Also validate runtime/source/attempt bindings, startup and node budgets, canonical bounded class sets and result consistency.", + "$defs": { + "LeaseBinding": { + "additionalProperties": false, + "properties": { + "attempt_id": { + "format": "uuid", + "title": "Attempt Id", + "type": "string" + }, + "evaluation_id": { + "format": "uuid", + "title": "Evaluation Id", + "type": "string" + }, + "fencing_version": { + "maximum": 9223372036854775807, + "minimum": 1, + "title": "Fencing Version", + "type": "integer" + }, + "worker_id": { + "format": "uuid", + "title": "Worker Id", + "type": "string" + } + }, + "required": [ + "evaluation_id", + "attempt_id", + "worker_id", + "fencing_version" + ], + "title": "LeaseBinding", + "type": "object" + } + }, + "$id": "urn:kf-oj:judge-stopped:v2", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "binding": { + "$ref": "#/$defs/LeaseBinding" + }, + "cleanup_complete": { + "title": "Cleanup Complete", + "type": "boolean" + }, + "kind": { + "const": "judge.stopped", + "title": "Kind", + "type": "string" + }, + "schema_version": { + "const": 2, + "title": "Schema Version", + "type": "integer" + } + }, + "required": [ + "schema_version", + "kind", + "binding", + "cleanup_complete" + ], + "title": "StoppedReport", + "type": "object" +} diff --git a/judge/crates/contracts/src/judging.rs b/judge/crates/contracts/src/judging.rs index 44784aa..ecf7062 100644 --- a/judge/crates/contracts/src/judging.rs +++ b/judge/crates/contracts/src/judging.rs @@ -42,7 +42,7 @@ pub fn manifest_bytes(manifest: &JobManifest) -> Result, &'static str> { serde_json::to_vec(&value).map_err(|_| "invalid manifest") } -fn bounded(value: u64, min: u64, max: u64) -> Validation { +pub(crate) fn bounded(value: u64, min: u64, max: u64) -> Validation { if (min..=max).contains(&value) { Ok(()) } else { @@ -52,7 +52,7 @@ fn bounded(value: u64, min: u64, max: u64) -> Validation { fn measure(value: Option) -> Validation { value.map_or(Ok(()), |v| bounded(v, 0, I64_MAX)) } -fn required_option<'de, D, T>(deserializer: D) -> Result, D::Error> +pub(crate) fn required_option<'de, D, T>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, T: Deserialize<'de>, @@ -78,6 +78,7 @@ macro_rules! validated_struct { } }; } +pub(crate) use validated_struct; macro_rules! kind { ($name:ident, $wire:literal) => { #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/judge/crates/contracts/src/judging_v2.rs b/judge/crates/contracts/src/judging_v2.rs new file mode 100644 index 0000000..ad2d107 --- /dev/null +++ b/judge/crates/contracts/src/judging_v2.rs @@ -0,0 +1,675 @@ +//! Explicit multi-runtime protocol. Version 1 remains an independent wire contract. +use super::judging as v1; +use serde::{Deserialize, Serialize, de::Error}; +pub use v1::{ + ArtifactReference, CaseReport, Comparison, CompilationStatus, CompilerDiagnostics, Digest, + FailureCode, Identifier, Label, LeaseBinding, LeaseToken, ManifestKind, ResultKind, RunLimits, + Stage, StageKind, StoppedKind, TestCase, Validation, Verdict, +}; +use v1::{bounded, validated_struct}; + +pub const MAX_CLASS_FILES: usize = 256; +pub const JVM_NATIVE_RESERVE_BYTES: u64 = 160 * v1::MIB; +pub const JVM_THREAD_STACK_BYTES: u64 = 256 * 1024; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(try_from = "u16", into = "u16")] +pub struct SchemaVersion; +impl TryFrom for SchemaVersion { + type Error = &'static str; + fn try_from(value: u16) -> Result { + if value == 2 { + Ok(Self) + } else { + Err("unsupported multi-runtime version") + } + } +} +impl From for u16 { + fn from(_: SchemaVersion) -> Self { + 2 + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Language { + #[serde(rename = "c17")] + C17, + #[serde(rename = "cpp20")] + Cpp20, + #[serde(rename = "python313")] + Python313, + #[serde(rename = "java21")] + Java21, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub enum ImageKind { + #[serde(rename = "linux_gnu_cxx_x86_64_v1")] + GnuCxx, + #[serde(rename = "linux_cpython313_x86_64_v1")] + CPython313, + #[serde(rename = "linux_openjdk21_x86_64_v1")] + OpenJdk21, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum PreparationKind { + Compile, + SyntaxCheck, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum ProgramKind { + NativeExecutable, + PythonSource, + JavaClasses, +} + +pub struct RuntimeContract { + pub source_name: &'static str, + pub preparation_profile: &'static str, + pub run_profile: &'static str, + pub program_kind: ProgramKind, + pub preparation_kind: PreparationKind, +} +impl Language { + pub fn contract(self) -> RuntimeContract { + let (source_name, preparation_profile, run_profile, program_kind, preparation_kind) = + match self { + Self::C17 => ( + "main.c", + "compile_c", + "native", + ProgramKind::NativeExecutable, + PreparationKind::Compile, + ), + Self::Cpp20 => ( + "main.cpp", + "compile_cpp", + "native", + ProgramKind::NativeExecutable, + PreparationKind::Compile, + ), + Self::Python313 => ( + "main.py", + "python_check", + "python_run", + ProgramKind::PythonSource, + PreparationKind::SyntaxCheck, + ), + Self::Java21 => ( + "Main.java", + "java_compile", + "java_run", + ProgramKind::JavaClasses, + PreparationKind::Compile, + ), + }; + RuntimeContract { + source_name, + preparation_profile, + run_profile, + program_kind, + preparation_kind, + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(try_from = "String")] +pub struct RuntimeVersion(String); +impl TryFrom for RuntimeVersion { + type Error = &'static str; + fn try_from(value: String) -> Result { + if value.is_empty() + || value.len() > 64 + || !value.as_bytes()[0].is_ascii_alphanumeric() + || !value + .bytes() + .all(|b| b.is_ascii_alphanumeric() || b"_.+-".contains(&b)) + { + return Err("invalid runtime build version"); + } + Ok(Self(value)) + } +} +impl RuntimeVersion { + pub fn as_str(&self) -> &str { + &self.0 + } + fn is_java21_build(&self) -> bool { + let value = self.0.strip_suffix("-LTS").unwrap_or(&self.0); + let Some((version, build)) = value.split_once('+') else { + return false; + }; + let parts: Vec<_> = version.split('.').collect(); + (parts.len() == 3 || parts.len() == 4) + && parts[0] == "21" + && parts + .iter() + .all(|p| !p.is_empty() && p.bytes().all(|b| b.is_ascii_digit())) + && !build.is_empty() + && build.as_bytes()[0] != b'0' + && build.bytes().all(|b| b.is_ascii_digit()) + } +} +validated_struct!(RuntimeIdentity { + toolchain_id: Label, + image_kind: ImageKind, + image_revision: u32, + image_digest: Digest, + runtime_version: RuntimeVersion, +}); +impl RuntimeIdentity { + pub fn validate(&self) -> Validation { + bounded(u64::from(self.image_revision), 1, u64::from(u32::MAX)) + } + pub fn validate_for_language(&self, language: Language) -> Validation { + self.validate()?; + let (id, kind) = match language { + Language::C17 | Language::Cpp20 => ("gnu-cxx-v1", ImageKind::GnuCxx), + Language::Python313 => ("cpython313-v1", ImageKind::CPython313), + Language::Java21 => ("openjdk21-v1", ImageKind::OpenJdk21), + }; + if self.toolchain_id.as_str() != id || self.image_kind != kind { + return Err("runtime family differs from language contract"); + } + if language == Language::Python313 && self.runtime_version.as_str() != "3.13.16" { + return Err("unsupported CPython version"); + } + if language == Language::Java21 && !self.runtime_version.is_java21_build() { + return Err("JDK version must identify a fixed Java 21 build"); + } + Ok(()) + } +} + +pub fn jvm_heap_bytes(limits: &RunLimits) -> Result { + let reserve = JVM_NATIVE_RESERVE_BYTES + u64::from(limits.processes) * JVM_THREAD_STACK_BYTES; + let heap = limits.memory_bytes.saturating_sub(reserve) / v1::MIB * v1::MIB; + if heap < 32 * v1::MIB || limits.stack_bytes < JVM_THREAD_STACK_BYTES { + return Err("budget cannot cover JVM heap and explicit non-heap reserve"); + } + Ok(heap) +} +pub fn validate_startup_budget( + language: Language, + limits: &RunLimits, + preparing: bool, +) -> Validation { + limits.validate()?; + let floor = match (language, preparing) { + (Language::Python313, _) => (10_000, 50_000, 32 * v1::MIB, 1, 16), + (Language::Java21, true) => (1_000_000, 3_000_000, 384 * v1::MIB, 16, 32), + (Language::Java21, false) => (200_000, 1_000_000, 256 * v1::MIB, 16, 32), + _ => return Ok(()), + }; + if limits.cpu_time_us < floor.0 + || limits.wall_time_us < floor.1 + || limits.memory_bytes < floor.2 + || limits.processes < floor.3 + || limits.open_files < floor.4 + { + return Err("budget below runtime startup policy"); + } + if language == Language::Java21 { + jvm_heap_bytes(limits)?; + } + Ok(()) +} +validated_struct!(LanguageConfiguration { + language: Language, + toolchain: RuntimeIdentity, + compile_limits: RunLimits, + run_limits: RunLimits, + job_wall_time_us: u64, +}); +impl LanguageConfiguration { + pub fn validate(&self) -> Validation { + self.toolchain.validate_for_language(self.language)?; + validate_startup_budget(self.language, &self.compile_limits, true)?; + validate_startup_budget(self.language, &self.run_limits, false)?; + bounded(self.job_wall_time_us, 1000, v1::MAX_JOB_WALL_US)?; + if self.compile_limits.wall_time_us + self.run_limits.wall_time_us > self.job_wall_time_us { + return Err("job deadline cannot cover preparation and execution"); + } + Ok(()) + } +} +validated_struct!(JobManifest { + schema_version: SchemaVersion, kind: ManifestKind, evaluation_id: Identifier, + submission_id: Identifier, problem_version_id: Identifier, language: Language, + toolchain: RuntimeIdentity, source: ArtifactReference, cases: Vec, + comparison: Comparison, compile_limits: RunLimits, run_limits: RunLimits, job_wall_time_us: u64, +}); + +validated_struct!(ProgramFile { + path: String, + artifact: ArtifactReference +}); +impl ProgramFile { + pub fn validate(&self) -> Validation { + self.artifact.validate()?; + if self.path.is_empty() || self.path.len() > 128 { + return Err("invalid program file path"); + } + Ok(()) + } +} +validated_struct!(CompiledProgram { + kind: ProgramKind, binding: LeaseBinding, source: ArtifactReference, + toolchain: RuntimeIdentity, files: Vec, +}); +impl CompiledProgram { + pub fn bytes(&self) -> u64 { + self.files.iter().map(|f| f.artifact.bytes).sum() + } + pub fn validate(&self) -> Validation { + self.binding.validate()?; + self.source.validate()?; + self.toolchain.validate()?; + bounded(self.source.bytes, 1, v1::MAX_SOURCE_BYTES)?; + if self.files.is_empty() || self.files.len() > MAX_CLASS_FILES { + return Err("program file count outside policy"); + } + let mut last: Option<&str> = None; + for file in &self.files { + file.validate()?; + if file.artifact.bytes == 0 || last.is_some_and(|v| v >= file.path.as_str()) { + return Err("program files empty, duplicated or not in canonical order"); + } + last = Some(&file.path); + } + if self.bytes() > v1::MAX_PACKAGE_BYTES { + return Err("program byte count outside policy"); + } + match self.kind { + ProgramKind::NativeExecutable => { + self.toolchain.validate_for_language(Language::C17)?; + if self.files.len() != 1 || self.files[0].path != "main" { + return Err("invalid native program"); + } + } + ProgramKind::PythonSource => { + self.toolchain.validate_for_language(Language::Python313)?; + if self.files.len() != 1 + || self.files[0].path != "main.py" + || self.files[0].artifact != self.source + { + return Err("Python program must be the exact checked source"); + } + } + ProgramKind::JavaClasses => { + self.toolchain.validate_for_language(Language::Java21)?; + if !self.files.iter().any(|f| f.path == "Main.class") + || self.files.iter().any(|f| !class_name(&f.path)) + { + return Err("Java requires a bounded default-package Main class set"); + } + } + } + Ok(()) + } +} +fn class_name(path: &str) -> bool { + let Some(stem) = path.strip_suffix(".class") else { + return false; + }; + !stem.is_empty() + && (stem.as_bytes()[0].is_ascii_alphabetic() || b"_$".contains(&stem.as_bytes()[0])) + && stem + .bytes() + .all(|b| b.is_ascii_alphanumeric() || b"_$".contains(&b)) +} +validated_struct!(CompilationReport { + status: CompilationStatus, + #[serde(deserialize_with = "v1::required_option")] program: Option, + diagnostics: CompilerDiagnostics, diagnostics_truncated: bool, + #[serde(deserialize_with = "v1::required_option")] cpu_time_us: Option, + #[serde(deserialize_with = "v1::required_option")] memory_peak_bytes: Option, +}); +impl CompilationReport { + pub fn validate(&self) -> Validation { + for value in [self.cpu_time_us, self.memory_peak_bytes] + .into_iter() + .flatten() + { + bounded(value, 0, v1::I64_MAX)?; + } + if (self.status == CompilationStatus::Succeeded) != self.program.is_some() { + return Err("compiled artifact only belongs to successful compilation"); + } + if let Some(program) = &self.program { + program.validate()?; + } + Ok(()) + } +} +validated_struct!(JudgementReport { + schema_version: SchemaVersion, kind: ResultKind, binding: LeaseBinding, manifest_digest: Digest, + compilation: CompilationReport, cases: Vec, verdict: Verdict, cleanup_complete: bool, + #[serde(deserialize_with = "v1::required_option")] failure_code: Option, + #[serde(deserialize_with = "v1::required_option")] run_cpu_time_us: Option, + #[serde(deserialize_with = "v1::required_option")] run_memory_peak_bytes: Option, +}); +validated_struct!(LeaseGrant { + schema_version: SchemaVersion, + kind: v1::LeaseKind, + binding: LeaseBinding, + lease_token: LeaseToken, + attempt_number: u32, + expires_at_unix_ms: u64, + manifest_digest: Digest, +}); +impl LeaseGrant { + pub fn validate(&self) -> Validation { + self.binding.validate()?; + bounded(u64::from(self.attempt_number), 1, 5)?; + bounded(self.expires_at_unix_ms, 1, v1::I64_MAX) + } +} +validated_struct!(StageReport { + schema_version: SchemaVersion, kind: StageKind, binding: LeaseBinding, sequence: u64, + stage: Stage, preparation_kind: PreparationKind, + #[serde(deserialize_with = "v1::required_option")] case_index: Option, +}); +impl StageReport { + pub fn validate(&self) -> Validation { + self.binding.validate()?; + bounded(self.sequence, 1, v1::I64_MAX)?; + if (self.stage == Stage::Running) != self.case_index.is_some() + || self + .case_index + .is_some_and(|i| usize::from(i) >= v1::MAX_CASES) + { + return Err("testcase index only belongs to running phase"); + } + Ok(()) + } + pub fn validate_for_manifest(&self, manifest: &JobManifest) -> Validation { + self.validate()?; + manifest.validate()?; + if self.binding.evaluation_id != manifest.evaluation_id + || self.preparation_kind != manifest.language.contract().preparation_kind + { + return Err("stage differs from authorized language preparation"); + } + Ok(()) + } +} +validated_struct!(StoppedReport { + schema_version: SchemaVersion, + kind: StoppedKind, + binding: LeaseBinding, + cleanup_complete: bool +}); +impl StoppedReport { + pub fn validate(&self) -> Validation { + self.binding.validate() + } +} +validated_struct!(RuntimeCapability { + language: Language, + toolchain: RuntimeIdentity, + compile_ceiling: RunLimits, + run_ceiling: RunLimits +}); +impl RuntimeCapability { + pub fn validate(&self) -> Validation { + self.toolchain.validate_for_language(self.language)?; + validate_startup_budget(self.language, &self.compile_ceiling, true)?; + validate_startup_budget(self.language, &self.run_ceiling, false) + } +} +validated_struct!(AdmissionPolicy { + schema_version: SchemaVersion, + #[serde(default = "one")] max_concurrent_jobs: u32, + #[serde(default = "one")] prefetch: u32, + #[serde(default = "two")] max_retries: u32, + max_job_wall_time_us: u64, max_package_bytes: u64, capabilities: Vec, +}); +fn one() -> u32 { + 1 +} +fn two() -> u32 { + 2 +} +impl AdmissionPolicy { + pub fn validate(&self) -> Validation { + bounded(u64::from(self.max_concurrent_jobs), 1, 64)?; + bounded(u64::from(self.prefetch), 1, 64)?; + bounded(u64::from(self.max_retries), 0, 4)?; + bounded(self.max_job_wall_time_us, 1000, v1::MAX_JOB_WALL_US)?; + bounded(self.max_package_bytes, 1, v1::MAX_PACKAGE_BYTES)?; + if self.prefetch > self.max_concurrent_jobs + || self.capabilities.is_empty() + || self.capabilities.len() > 4 + { + return Err("runtime admission capacity outside policy"); + } + let mut seen = std::collections::HashSet::new(); + for cap in &self.capabilities { + cap.validate()?; + if !seen.insert(cap.language) { + return Err("duplicate language capability"); + } + } + Ok(()) + } + pub fn admit(&self, manifest: &JobManifest, attempt_number: u32) -> Validation { + self.validate()?; + manifest.validate()?; + bounded( + u64::from(attempt_number), + 1, + u64::from(self.max_retries) + 1, + )?; + let cap = self + .capabilities + .iter() + .find(|c| c.language == manifest.language) + .ok_or("unsupported runtime capability")?; + if cap.toolchain != manifest.toolchain + || !manifest.compile_limits.fits(&cap.compile_ceiling) + || !manifest.run_limits.fits(&cap.run_ceiling) + || manifest.job_wall_time_us > self.max_job_wall_time_us + || manifest.package_bytes() > self.max_package_bytes + { + return Err("job exceeds trusted runtime capability or budget"); + } + Ok(()) + } +} + +fn measure(value: Option) -> Validation { + value.map_or(Ok(()), |v| bounded(v, 0, v1::I64_MAX)) +} + +impl JobManifest { + pub fn package_bytes(&self) -> u64 { + self.source.bytes + + self + .cases + .iter() + .map(|c| c.input.bytes + c.expected.bytes) + .sum::() + } + pub fn validate(&self) -> Validation { + self.source.validate()?; + self.toolchain.validate_for_language(self.language)?; + validate_startup_budget(self.language, &self.compile_limits, true)?; + validate_startup_budget(self.language, &self.run_limits, false)?; + self.compile_limits.validate()?; + self.run_limits.validate()?; + bounded(self.source.bytes, 1, v1::MAX_SOURCE_BYTES)?; + bounded(self.job_wall_time_us, 1000, v1::MAX_JOB_WALL_US)?; + if self.cases.is_empty() || self.cases.len() > v1::MAX_CASES { + return Err("testcase count outside policy"); + } + let mut seen = std::collections::HashSet::new(); + for c in &self.cases { + c.validate()?; + if !seen.insert(c.case_id) { + return Err("duplicate testcase identifiers"); + } + if c.expected.bytes > self.run_limits.stdout_bytes { + return Err("expected output exceeds output budget"); + } + } + if self.package_bytes() > v1::MAX_PACKAGE_BYTES { + return Err("test package outside policy"); + } + let required = self.compile_limits.wall_time_us + + self.cases.len() as u64 * self.run_limits.wall_time_us; + if required > self.job_wall_time_us { + return Err("job deadline cannot cover execution budgets"); + } + Ok(()) + } +} + +impl JudgementReport { + pub fn validate(&self) -> Validation { + self.binding.validate()?; + self.compilation.validate()?; + if self + .compilation + .program + .as_ref() + .is_some_and(|p| p.binding != self.binding) + { + return Err("program belongs to another attempt"); + } + measure(self.run_cpu_time_us)?; + measure(self.run_memory_peak_bytes)?; + if self.cases.len() > v1::MAX_CASES { + return Err("testcase count outside policy"); + } + let mut seen = std::collections::HashSet::new(); + for (i, c) in self.cases.iter().enumerate() { + c.validate()?; + if !seen.insert(c.case_id) { + return Err("duplicate testcase results"); + } + if matches!(c.verdict, Verdict::SystemError | Verdict::Cancelled) + && i != self.cases.len() - 1 + { + return Err("results after fatal testcase outcome"); + } + } + if !self.cleanup_complete && self.failure_code != Some(FailureCode::CleanupFailed) { + return Err("incomplete cleanup requires its own failure evidence"); + } + if self.cleanup_complete && self.failure_code == Some(FailureCode::CleanupFailed) { + return Err("cleanup failure cannot claim completed cleanup"); + } + if (self.verdict == Verdict::SystemError) != self.failure_code.is_some() { + return Err("infrastructure failure and verdict must agree"); + } + if self.compilation.status != CompilationStatus::Succeeded { + let mapped = match self.compilation.status { + CompilationStatus::CompilationError | CompilationStatus::CompilationLimit => { + Verdict::CompilationError + } + CompilationStatus::Cancelled => Verdict::Cancelled, + CompilationStatus::SystemError => Verdict::SystemError, + CompilationStatus::Succeeded => unreachable!(), + }; + if !self.cases.is_empty() || self.verdict != mapped { + return Err("failed compilation cannot have runtime results"); + } + } else if self.failure_code.is_none() { + if self.cases.iter().any(|c| c.verdict == Verdict::SystemError) { + return Err("infrastructure failure requires failure code"); + } + if self.cases.is_empty() && self.verdict != Verdict::Cancelled { + return Err("missing testcase results cannot be a completed judgement"); + } + if self.verdict != Verdict::Cancelled && !self.cases.is_empty() { + let summary = self + .cases + .iter() + .find(|c| c.verdict == Verdict::Cancelled) + .or_else(|| self.cases.iter().find(|c| c.verdict != Verdict::Accepted)) + .map_or(Verdict::Accepted, |c| c.verdict); + if self.verdict != summary { + return Err("testcase summary disagrees"); + } + } + } + let cpu = if !self.cases.is_empty() && self.cases.iter().all(|c| c.cpu_time_us.is_some()) { + Some( + self.cases + .iter() + .try_fold(0_u64, |total, c| { + total.checked_add(c.cpu_time_us.unwrap_or(0)) + }) + .ok_or("measurement sum overflow")?, + ) + } else { + None + }; + let memory = + if !self.cases.is_empty() && self.cases.iter().all(|c| c.memory_peak_bytes.is_some()) { + self.cases.iter().filter_map(|c| c.memory_peak_bytes).max() + } else { + None + }; + if self.run_cpu_time_us != cpu || self.run_memory_peak_bytes != memory { + return Err("runtime measurement summary disagrees"); + } + Ok(()) + } + pub fn validate_for_manifest(&self, manifest: &JobManifest, digest: &Digest) -> Validation { + self.validate()?; + manifest.validate()?; + if self.compilation.program.as_ref().is_some_and(|p| { + p.source != manifest.source + || p.toolchain != manifest.toolchain + || p.kind != manifest.language.contract().program_kind + }) { + return Err("program differs from authorized source or runtime"); + } + if self.binding.evaluation_id != manifest.evaluation_id || &self.manifest_digest != digest { + return Err("report does not belong to authorized manifest"); + } + if self.cases.len() > manifest.cases.len() + || !self + .cases + .iter() + .zip(&manifest.cases) + .all(|(a, b)| a.case_id == b.case_id) + { + return Err("testcase results differ from authorized order"); + } + if !matches!( + self.verdict, + Verdict::CompilationError | Verdict::Cancelled | Verdict::SystemError + ) && self.cases.len() != manifest.cases.len() + { + return Err("incomplete ordinary judgement"); + } + Ok(()) + } +} + +pub fn manifest_bytes(manifest: &JobManifest) -> Result, &'static str> { + manifest.validate()?; + let mut value = serde_json::to_value(manifest).map_err(|_| "invalid manifest")?; + fn sorted(value: &mut serde_json::Value) { + match value { + serde_json::Value::Object(map) => { + let mut entries: Vec<_> = std::mem::take(map).into_iter().collect(); + entries.sort_by(|a, b| a.0.cmp(&b.0)); + for (_, nested) in &mut entries { + sorted(nested); + } + *map = entries.into_iter().collect(); + } + serde_json::Value::Array(values) => values.iter_mut().for_each(sorted), + _ => {} + } + } + sorted(&mut value); + serde_json::to_vec(&value).map_err(|_| "invalid manifest") +} diff --git a/judge/crates/contracts/src/judging_versions.rs b/judge/crates/contracts/src/judging_versions.rs new file mode 100644 index 0000000..a8e2dce --- /dev/null +++ b/judge/crates/contracts/src/judging_versions.rs @@ -0,0 +1,41 @@ +//! Version dispatch without changing legacy canonical snapshots or result identities. +use super::{judging as v1, judging_v2 as v2}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum JobManifest { + V1(v1::JobManifest), + V2(v2::JobManifest), +} +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum JudgementReport { + V1(v1::JudgementReport), + V2(v2::JudgementReport), +} +impl JobManifest { + pub fn canonical_bytes(&self) -> Result, &'static str> { + match self { + Self::V1(manifest) => v1::manifest_bytes(manifest), + Self::V2(manifest) => v2::manifest_bytes(manifest), + } + } +} +impl JudgementReport { + pub fn validate_for_manifest( + &self, + manifest: &JobManifest, + digest: &v1::Digest, + ) -> v1::Validation { + match (self, manifest) { + (Self::V1(report), JobManifest::V1(manifest)) => { + report.validate_for_manifest(manifest, digest) + } + (Self::V2(report), JobManifest::V2(manifest)) => { + report.validate_for_manifest(manifest, digest) + } + _ => Err("report protocol differs from authorized manifest"), + } + } +} diff --git a/judge/crates/contracts/src/lib.rs b/judge/crates/contracts/src/lib.rs index eb0bf40..b68d60b 100644 --- a/judge/crates/contracts/src/lib.rs +++ b/judge/crates/contracts/src/lib.rs @@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; pub mod judging; +pub mod judging_v2; +pub mod judging_versions; pub mod state; pub const SCHEMA_VERSION: u16 = 1; diff --git a/judge/crates/contracts/tests/judging_v2_examples.rs b/judge/crates/contracts/tests/judging_v2_examples.rs new file mode 100644 index 0000000..4c522c1 --- /dev/null +++ b/judge/crates/contracts/tests/judging_v2_examples.rs @@ -0,0 +1,156 @@ +use kf_contracts::judging_versions as versions; +use kf_contracts::{judging as v1, judging_v2 as v2}; +use serde::{Serialize, de::DeserializeOwned}; +use std::{fs, path::PathBuf}; + +fn fixtures() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../../tests/fixtures/contracts-v2") +} +fn fixture(name: &str) -> T { + v1::decode_wire(&fs::read(fixtures().join(format!("{name}.json"))).unwrap()).unwrap() +} +fn roundtrip(data: &[u8], invalid: bool, name: &str) { + let result = v1::decode_wire::(data); + if invalid { + assert!(result.is_err(), "must reject {name}"); + } else { + assert_eq!( + serde_json::to_value(result.unwrap_or_else(|e| panic!("{name}: {e}"))).unwrap(), + serde_json::from_slice::(data).unwrap(), + "roundtrip {name}" + ); + } +} +#[test] +fn shared_v2_acceptance_rejection_and_canonical_bytes_match_python() { + let mut count = 0; + for entry in fs::read_dir(fixtures()).unwrap() { + let path = entry.unwrap().path(); + if path.extension().is_none_or(|e| e != "json") { + continue; + } + let name = path.file_name().unwrap().to_string_lossy(); + let data = fs::read(&path).unwrap(); + let invalid = name.contains(".invalid-"); + match name.split('.').next().unwrap() { + "judge-manifest" => roundtrip::(&data, invalid, &name), + "judge-lease" => roundtrip::(&data, invalid, &name), + "judge-stage" => roundtrip::(&data, invalid, &name), + "judge-result" => roundtrip::(&data, invalid, &name), + "judge-admission" => roundtrip::(&data, invalid, &name), + "judge-stopped" => roundtrip::(&data, invalid, &name), + _ => panic!("unrecognized fixture {name}"), + } + count += 1; + } + assert!(count >= 53); + for language in ["c17", "cpp20", "python313", "java21"] { + let manifest: v2::JobManifest = fixture(&format!("judge-manifest.valid-{language}")); + assert_eq!( + v2::manifest_bytes(&manifest).unwrap(), + fs::read(fixtures().join(format!("canonical-manifest.{language}.txt"))).unwrap() + ); + let data = + fs::read(fixtures().join(format!("judge-manifest.valid-{language}.json"))).unwrap(); + assert!(v1::decode_wire::(&data).is_err()); + } +} +#[test] +fn runtime_identity_admission_and_program_binding_are_exact() { + let policy: v2::AdmissionPolicy = fixture("judge-admission.valid"); + for language in ["c17", "cpp20", "python313", "java21"] { + let manifest: v2::JobManifest = fixture(&format!("judge-manifest.valid-{language}")); + for attempt in [1, 2, 3] { + policy.admit(&manifest, attempt).unwrap(); + } + for attempt in [0, 4] { + assert!(policy.admit(&manifest, attempt).is_err()); + } + let mut wrong = manifest.clone(); + wrong.toolchain.image_revision += 1; + assert!(policy.admit(&wrong, 1).is_err()); + wrong = manifest.clone(); + wrong.toolchain.image_digest = "f".repeat(64).try_into().unwrap(); + assert!(policy.admit(&wrong, 1).is_err()); + let result: v2::JudgementReport = fixture(&format!("judge-result.valid-{language}")); + result + .validate_for_manifest(&manifest, &result.manifest_digest) + .unwrap(); + let mut wrong = manifest.clone(); + wrong.source.bytes += 1; + assert!( + result + .validate_for_manifest(&wrong, &result.manifest_digest) + .is_err() + ); + let stage: v2::StageReport = fixture(&format!("judge-stage.valid-{language}")); + stage.validate_for_manifest(&manifest).unwrap(); + } + let mut restricted = policy; + restricted + .capabilities + .retain(|c| c.language != v2::Language::Python313); + let manifest: v2::JobManifest = fixture("judge-manifest.valid-python313"); + assert!(restricted.admit(&manifest, 1).is_err()); +} +#[test] +fn runtime_entry_profiles_and_jvm_nonheap_memory_are_fixed() { + let python = v2::Language::Python313.contract(); + assert_eq!(python.source_name, "main.py"); + assert_eq!(python.preparation_profile, "python_check"); + assert_eq!(python.preparation_kind, v2::PreparationKind::SyntaxCheck); + let java = v2::Language::Java21.contract(); + assert_eq!(java.source_name, "Main.java"); + assert_eq!(java.run_profile, "java_run"); + let manifest: v2::JobManifest = fixture("judge-manifest.valid-java21"); + let heap = v2::jvm_heap_bytes(&manifest.run_limits).unwrap(); + assert!(heap >= 32 * v1::MIB && heap < manifest.run_limits.memory_bytes); + let mut more = manifest.run_limits.clone(); + more.processes = 32; + assert!(v2::jvm_heap_bytes(&more).unwrap() < heap); + more.memory_bytes = 128 * v1::MIB; + assert!(v2::jvm_heap_bytes(&more).is_err()); +} + +#[test] +fn storage_boundary_retains_version_identity_and_rejects_mismatched_results() { + let original = fixtures().parent().unwrap().join("contracts"); + let old_manifest: versions::JobManifest = + v1::decode_wire(&fs::read(original.join("judge-manifest.valid.json")).unwrap()).unwrap(); + let old_report: versions::JudgementReport = + v1::decode_wire(&fs::read(original.join("judge-result.valid.json")).unwrap()).unwrap(); + let manifest: versions::JobManifest = fixture("judge-manifest.valid-python313"); + let report: versions::JudgementReport = fixture("judge-result.valid-python313"); + let digest: v1::Digest = match &old_report { + versions::JudgementReport::V1(r) => r.manifest_digest.clone(), + _ => unreachable!(), + }; + old_report + .validate_for_manifest(&old_manifest, &digest) + .unwrap(); + report.validate_for_manifest(&manifest, &digest).unwrap(); + assert!( + old_report + .validate_for_manifest(&manifest, &digest) + .is_err() + ); + assert!( + report + .validate_for_manifest(&old_manifest, &digest) + .is_err() + ); + assert_eq!( + old_manifest.canonical_bytes().unwrap(), + fs::read(original.join("canonical-manifest.v1.txt")).unwrap() + ); + let data = fs::read(fixtures().join("judge-manifest.valid-python313.json")).unwrap(); + let text = String::from_utf8(data).unwrap(); + for replacement in [ + "\"schema_version\": 3", + "\"schema_version\": true", + "\"schema_version\": 2, \"schema_version\": 2", + ] { + let invalid = text.replace("\"schema_version\": 2", replacement); + assert!(v1::decode_wire::(invalid.as_bytes()).is_err()); + } +} diff --git a/tests/fixtures/contracts-v2/canonical-manifest.c17.txt b/tests/fixtures/contracts-v2/canonical-manifest.c17.txt new file mode 100644 index 0000000..80815dc --- /dev/null +++ b/tests/fixtures/contracts-v2/canonical-manifest.c17.txt @@ -0,0 +1 @@ +{"cases":[{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000004","expected":{"bytes":0,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":0,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000005","expected":{"bytes":1,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":1,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000006","expected":{"bytes":2,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":2,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}}],"comparison":"exact_bytes","compile_limits":{"cpu_time_us":10000000,"file_bytes":67108864,"memory_bytes":536870912,"open_files":128,"processes":32,"stack_bytes":16777216,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":30000000,"workdir_bytes":268435456},"evaluation_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","job_wall_time_us":60000000,"kind":"judge.manifest","language":"c17","problem_version_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000003","run_limits":{"cpu_time_us":1000000,"file_bytes":16777216,"memory_bytes":67108864,"open_files":64,"processes":8,"stack_bytes":8388608,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":3000000,"workdir_bytes":67108864},"schema_version":2,"source":{"bytes":124,"digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"submission_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000002","toolchain":{"image_digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","image_kind":"linux_gnu_cxx_x86_64_v1","image_revision":1,"runtime_version":"gnu-cxx-v1","toolchain_id":"gnu-cxx-v1"}} \ No newline at end of file diff --git a/tests/fixtures/contracts-v2/canonical-manifest.cpp20.txt b/tests/fixtures/contracts-v2/canonical-manifest.cpp20.txt new file mode 100644 index 0000000..4708e59 --- /dev/null +++ b/tests/fixtures/contracts-v2/canonical-manifest.cpp20.txt @@ -0,0 +1 @@ +{"cases":[{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000004","expected":{"bytes":0,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":0,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000005","expected":{"bytes":1,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":1,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000006","expected":{"bytes":2,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":2,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}}],"comparison":"exact_bytes","compile_limits":{"cpu_time_us":10000000,"file_bytes":67108864,"memory_bytes":536870912,"open_files":128,"processes":32,"stack_bytes":16777216,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":30000000,"workdir_bytes":268435456},"evaluation_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","job_wall_time_us":60000000,"kind":"judge.manifest","language":"cpp20","problem_version_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000003","run_limits":{"cpu_time_us":1000000,"file_bytes":16777216,"memory_bytes":67108864,"open_files":64,"processes":8,"stack_bytes":8388608,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":3000000,"workdir_bytes":67108864},"schema_version":2,"source":{"bytes":124,"digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"submission_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000002","toolchain":{"image_digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","image_kind":"linux_gnu_cxx_x86_64_v1","image_revision":1,"runtime_version":"gnu-cxx-v1","toolchain_id":"gnu-cxx-v1"}} \ No newline at end of file diff --git a/tests/fixtures/contracts-v2/canonical-manifest.java21.txt b/tests/fixtures/contracts-v2/canonical-manifest.java21.txt new file mode 100644 index 0000000..9fad162 --- /dev/null +++ b/tests/fixtures/contracts-v2/canonical-manifest.java21.txt @@ -0,0 +1 @@ +{"cases":[{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000004","expected":{"bytes":0,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":0,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000005","expected":{"bytes":1,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":1,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000006","expected":{"bytes":2,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":2,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}}],"comparison":"exact_bytes","compile_limits":{"cpu_time_us":10000000,"file_bytes":67108864,"memory_bytes":536870912,"open_files":128,"processes":32,"stack_bytes":16777216,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":30000000,"workdir_bytes":268435456},"evaluation_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","job_wall_time_us":60000000,"kind":"judge.manifest","language":"java21","problem_version_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000003","run_limits":{"cpu_time_us":1000000,"file_bytes":16777216,"memory_bytes":268435456,"open_files":64,"processes":16,"stack_bytes":8388608,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":3000000,"workdir_bytes":67108864},"schema_version":2,"source":{"bytes":124,"digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"submission_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000002","toolchain":{"image_digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","image_kind":"linux_openjdk21_x86_64_v1","image_revision":1,"runtime_version":"21.0.12.1+1-LTS","toolchain_id":"openjdk21-v1"}} \ No newline at end of file diff --git a/tests/fixtures/contracts-v2/canonical-manifest.python313.txt b/tests/fixtures/contracts-v2/canonical-manifest.python313.txt new file mode 100644 index 0000000..469d6ae --- /dev/null +++ b/tests/fixtures/contracts-v2/canonical-manifest.python313.txt @@ -0,0 +1 @@ +{"cases":[{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000004","expected":{"bytes":0,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":0,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000005","expected":{"bytes":1,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":1,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}},{"case_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000006","expected":{"bytes":2,"digest":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"input":{"bytes":2,"digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}}],"comparison":"exact_bytes","compile_limits":{"cpu_time_us":10000000,"file_bytes":67108864,"memory_bytes":536870912,"open_files":128,"processes":32,"stack_bytes":16777216,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":30000000,"workdir_bytes":268435456},"evaluation_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000001","job_wall_time_us":60000000,"kind":"judge.manifest","language":"python313","problem_version_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000003","run_limits":{"cpu_time_us":1000000,"file_bytes":16777216,"memory_bytes":67108864,"open_files":64,"processes":8,"stack_bytes":8388608,"stderr_bytes":1048576,"stdout_bytes":1048576,"wall_time_us":3000000,"workdir_bytes":67108864},"schema_version":2,"source":{"bytes":124,"digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"submission_id":"aaaaaaaa-aaaa-4aaa-8aaa-000000000002","toolchain":{"image_digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","image_kind":"linux_cpython313_x86_64_v1","image_revision":1,"runtime_version":"3.13.16","toolchain_id":"cpython313-v1"}} \ No newline at end of file diff --git a/tests/fixtures/contracts-v2/judge-admission.invalid-capability-count.json b/tests/fixtures/contracts-v2/judge-admission.invalid-capability-count.json new file mode 100644 index 0000000..ffbc904 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-admission.invalid-capability-count.json @@ -0,0 +1,180 @@ +{ + "max_concurrent_jobs": 1, + "prefetch": 1, + "max_retries": 2, + "max_job_wall_time_us": 60000000, + "max_package_bytes": 67108864, + "schema_version": 2, + "capabilities": [ + { + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "cpp20", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 268435456, + "stack_bytes": 8388608, + "processes": 16, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + } + ] +} diff --git a/tests/fixtures/contracts-v2/judge-admission.invalid-semantic-duplicate-language.json b/tests/fixtures/contracts-v2/judge-admission.invalid-semantic-duplicate-language.json new file mode 100644 index 0000000..7ec2495 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-admission.invalid-semantic-duplicate-language.json @@ -0,0 +1,146 @@ +{ + "max_concurrent_jobs": 1, + "prefetch": 1, + "max_retries": 2, + "max_job_wall_time_us": 60000000, + "max_package_bytes": 67108864, + "schema_version": 2, + "capabilities": [ + { + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "cpp20", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + } + ] +} diff --git a/tests/fixtures/contracts-v2/judge-admission.valid.json b/tests/fixtures/contracts-v2/judge-admission.valid.json new file mode 100644 index 0000000..ded5487 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-admission.valid.json @@ -0,0 +1,146 @@ +{ + "max_concurrent_jobs": 1, + "prefetch": 1, + "max_retries": 2, + "max_job_wall_time_us": 60000000, + "max_package_bytes": 67108864, + "schema_version": 2, + "capabilities": [ + { + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "cpp20", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + }, + { + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "compile_ceiling": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_ceiling": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 268435456, + "stack_bytes": 8388608, + "processes": 16, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + } + } + ] +} diff --git a/tests/fixtures/contracts-v2/judge-lease.valid.json b/tests/fixtures/contracts-v2/judge-lease.valid.json new file mode 100644 index 0000000..8670a0b --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-lease.valid.json @@ -0,0 +1,14 @@ +{ + "schema_version": 2, + "kind": "judge.lease", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "lease_token": "0000000000000000000000000000000000000000000000000000000000000000", + "attempt_number": 1, + "expires_at_unix_ms": 1800000000000, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-host-path.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-host-path.json new file mode 100644 index 0000000..2aa74a2 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-host-path.json @@ -0,0 +1,81 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000, + "image_root": "/host/credentials" +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-profile.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-profile.json new file mode 100644 index 0000000..b3ba74d --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-extra-profile.json @@ -0,0 +1,81 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000, + "run_profile": "shell" +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-duplicate-case.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-duplicate-case.json new file mode 100644 index 0000000..2305861 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-duplicate-case.json @@ -0,0 +1,91 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-image-family.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-image-family.json new file mode 100644 index 0000000..8679ebf --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-image-family.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-thread-floor.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-thread-floor.json new file mode 100644 index 0000000..678af9d --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-thread-floor.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 268435456, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-too-small.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-too-small.json new file mode 100644 index 0000000..89c0153 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-too-small.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 16, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-unpinned.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-unpinned.json new file mode 100644 index 0000000..2b80d8e --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-java-unpinned.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 268435456, + "stack_bytes": 8388608, + "processes": 16, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-too-small.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-too-small.json new file mode 100644 index 0000000..856a28d --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-too-small.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 16777216, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-version.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-version.json new file mode 100644 index 0000000..ebd0ac7 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-python-version.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.14.0" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-short-job.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-short-job.json new file mode 100644 index 0000000..9f53ed4 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-semantic-short-job.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 1000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-unknown-version.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-unknown-version.json new file mode 100644 index 0000000..a83d3ed --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-unknown-version.json @@ -0,0 +1,80 @@ +{ + "schema_version": 3, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.invalid-version-bool.json b/tests/fixtures/contracts-v2/judge-manifest.invalid-version-bool.json new file mode 100644 index 0000000..2c691b6 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.invalid-version-bool.json @@ -0,0 +1,80 @@ +{ + "schema_version": true, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.valid-c17.json b/tests/fixtures/contracts-v2/judge-manifest.valid-c17.json new file mode 100644 index 0000000..3273fff --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.valid-c17.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "c17", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.valid-cpp20.json b/tests/fixtures/contracts-v2/judge-manifest.valid-cpp20.json new file mode 100644 index 0000000..4a42b54 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.valid-cpp20.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "cpp20", + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.valid-java21.json b/tests/fixtures/contracts-v2/judge-manifest.valid-java21.json new file mode 100644 index 0000000..e569c8f --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.valid-java21.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "java21", + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 268435456, + "stack_bytes": 8388608, + "processes": 16, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-manifest.valid-python313.json b/tests/fixtures/contracts-v2/judge-manifest.valid-python313.json new file mode 100644 index 0000000..23c07e2 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-manifest.valid-python313.json @@ -0,0 +1,80 @@ +{ + "schema_version": 2, + "kind": "judge.manifest", + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "submission_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000002", + "problem_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000003", + "language": "python313", + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 0 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 1 + } + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "input": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 2 + }, + "expected": { + "digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "bytes": 2 + } + } + ], + "comparison": "exact_bytes", + "compile_limits": { + "cpu_time_us": 10000000, + "wall_time_us": 30000000, + "memory_bytes": 536870912, + "stack_bytes": 16777216, + "processes": 32, + "open_files": 128, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 67108864, + "workdir_bytes": 268435456 + }, + "run_limits": { + "cpu_time_us": 1000000, + "wall_time_us": 3000000, + "memory_bytes": 67108864, + "stack_bytes": 8388608, + "processes": 8, + "open_files": 64, + "stdout_bytes": 1048576, + "stderr_bytes": 1048576, + "file_bytes": 16777216, + "workdir_bytes": 67108864 + }, + "job_wall_time_us": 60000000 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-class-count.json b/tests/fixtures/contracts-v2/judge-result.invalid-class-count.json new file mode 100644 index 0000000..35e6dcf --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-class-count.json @@ -0,0 +1,1864 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Class000.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class001.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class002.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class003.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class004.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class005.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class006.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class007.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class008.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class009.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class010.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class011.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class012.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class013.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class014.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class015.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class016.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class017.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class018.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class019.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class020.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class021.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class022.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class023.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class024.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class025.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class026.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class027.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class028.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class029.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class030.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class031.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class032.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class033.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class034.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class035.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class036.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class037.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class038.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class039.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class040.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class041.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class042.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class043.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class044.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class045.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class046.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class047.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class048.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class049.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class050.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class051.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class052.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class053.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class054.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class055.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class056.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class057.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class058.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class059.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class060.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class061.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class062.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class063.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class064.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class065.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class066.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class067.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class068.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class069.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class070.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class071.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class072.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class073.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class074.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class075.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class076.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class077.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class078.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class079.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class080.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class081.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class082.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class083.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class084.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class085.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class086.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class087.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class088.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class089.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class090.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class091.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class092.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class093.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class094.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class095.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class096.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class097.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class098.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class099.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class100.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class101.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class102.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class103.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class104.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class105.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class106.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class107.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class108.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class109.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class110.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class111.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class112.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class113.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class114.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class115.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class116.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class117.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class118.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class119.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class120.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class121.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class122.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class123.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class124.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class125.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class126.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class127.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class128.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class129.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class130.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class131.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class132.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class133.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class134.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class135.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class136.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class137.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class138.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class139.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class140.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class141.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class142.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class143.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class144.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class145.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class146.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class147.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class148.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class149.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class150.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class151.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class152.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class153.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class154.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class155.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class156.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class157.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class158.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class159.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class160.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class161.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class162.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class163.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class164.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class165.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class166.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class167.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class168.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class169.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class170.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class171.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class172.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class173.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class174.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class175.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class176.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class177.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class178.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class179.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class180.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class181.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class182.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class183.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class184.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class185.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class186.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class187.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class188.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class189.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class190.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class191.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class192.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class193.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class194.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class195.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class196.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class197.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class198.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class199.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class200.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class201.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class202.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class203.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class204.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class205.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class206.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class207.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class208.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class209.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class210.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class211.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class212.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class213.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class214.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class215.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class216.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class217.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class218.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class219.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class220.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class221.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class222.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class223.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class224.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class225.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class226.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class227.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class228.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class229.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class230.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class231.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class232.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class233.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class234.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class235.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class236.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class237.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class238.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class239.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class240.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class241.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class242.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class243.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class244.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class245.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class246.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class247.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class248.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class249.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class250.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class251.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class252.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class253.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class254.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Class255.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 1 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-c17.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-c17.json new file mode 100644 index 0000000..c943749 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-c17.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "native_executable", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 2 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "files": [ + { + "path": "main", + "artifact": { + "digest": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "bytes": 4096 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-cpp20.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-cpp20.json new file mode 100644 index 0000000..c943749 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-cpp20.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "native_executable", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 2 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "files": [ + { + "path": "main", + "artifact": { + "digest": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "bytes": 4096 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-java21.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-java21.json new file mode 100644 index 0000000..b7b15fd --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-java21.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 2 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-python313.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-python313.json new file mode 100644 index 0000000..8176a85 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-attempt-python313.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 2 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-absolute.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-absolute.json new file mode 100644 index 0000000..0e9db79 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-absolute.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "/work/Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-duplicate.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-duplicate.json new file mode 100644 index 0000000..382875e --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-duplicate.json @@ -0,0 +1,100 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-empty-stem.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-empty-stem.json new file mode 100644 index 0000000..f5bc494 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-empty-stem.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": ".class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-jar.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-jar.json new file mode 100644 index 0000000..9a4e9bf --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-jar.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.jar", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-missing-main.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-missing-main.json new file mode 100644 index 0000000..d8f1adc --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-missing-main.json @@ -0,0 +1,86 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-package.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-package.json new file mode 100644 index 0000000..9992402 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-package.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "pkg/Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-total-bytes.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-total-bytes.json new file mode 100644 index 0000000..a158678 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-total-bytes.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 67108864 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 67108864 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 67108864 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 67108864 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-traversal.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-traversal.json new file mode 100644 index 0000000..8d9548e --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-traversal.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "../Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unicode.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unicode.json new file mode 100644 index 0000000..1a8bb78 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unicode.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "类.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unordered.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unordered.json new file mode 100644 index 0000000..3a10f85 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-unordered.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-zero.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-zero.json new file mode 100644 index 0000000..f8a90fa --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-class-zero.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 0 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-changed-source.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-changed-source.json new file mode 100644 index 0000000..a102c76 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-changed-source.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-pyc.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-pyc.json new file mode 100644 index 0000000..86c30a9 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-pyc.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.pyc", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-wrong-kind.json b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-wrong-kind.json new file mode 100644 index 0000000..897be44 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.invalid-semantic-python-wrong-kind.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "native_executable", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-c17.json b/tests/fixtures/contracts-v2/judge-result.valid-c17.json new file mode 100644 index 0000000..8c7167d --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-c17.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "native_executable", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "files": [ + { + "path": "main", + "artifact": { + "digest": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "bytes": 4096 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-cancel-before-compile.json b/tests/fixtures/contracts-v2/judge-result.valid-cancel-before-compile.json new file mode 100644 index 0000000..0cced79 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-cancel-before-compile.json @@ -0,0 +1,25 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "cancelled", + "program": null, + "diagnostics": "synthetic compiler diagnostic\n", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [], + "verdict": "cancelled", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": null, + "run_memory_peak_bytes": null +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-cancel-between-cases.json b/tests/fixtures/contracts-v2/judge-result.valid-cancel-between-cases.json new file mode 100644 index 0000000..4da9ec5 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-cancel-between-cases.json @@ -0,0 +1,60 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + } + ], + "verdict": "cancelled", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 100, + "run_memory_peak_bytes": 262144 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-ce.json b/tests/fixtures/contracts-v2/judge-result.valid-ce.json new file mode 100644 index 0000000..8019287 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-ce.json @@ -0,0 +1,25 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "compilation_error", + "program": null, + "diagnostics": "synthetic compiler diagnostic\n", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [], + "verdict": "compilation_error", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": null, + "run_memory_peak_bytes": null +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-cleanup-failure.json b/tests/fixtures/contracts-v2/judge-result.valid-cleanup-failure.json new file mode 100644 index 0000000..04b0191 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-cleanup-failure.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "system_error", + "cleanup_complete": false, + "failure_code": "cleanup_failed", + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-compile-limit.json b/tests/fixtures/contracts-v2/judge-result.valid-compile-limit.json new file mode 100644 index 0000000..7e59e3e --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-compile-limit.json @@ -0,0 +1,25 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "compilation_limit", + "program": null, + "diagnostics": "synthetic compiler diagnostic\n", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [], + "verdict": "compilation_error", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": null, + "run_memory_peak_bytes": null +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-cpp20.json b/tests/fixtures/contracts-v2/judge-result.valid-cpp20.json new file mode 100644 index 0000000..8c7167d --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-cpp20.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "native_executable", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "gnu-cxx-v1", + "image_kind": "linux_gnu_cxx_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "gnu-cxx-v1" + }, + "files": [ + { + "path": "main", + "artifact": { + "digest": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + "bytes": 4096 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-java21.json b/tests/fixtures/contracts-v2/judge-result.valid-java21.json new file mode 100644 index 0000000..c82fd6a --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-java21.json @@ -0,0 +1,93 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "java_classes", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "openjdk21-v1", + "image_kind": "linux_openjdk21_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "21.0.12.1+1-LTS" + }, + "files": [ + { + "path": "Helper.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$1.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main$Inner.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + }, + { + "path": "Main.class", + "artifact": { + "digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "bytes": 64 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-result.valid-python313.json b/tests/fixtures/contracts-v2/judge-result.valid-python313.json new file mode 100644 index 0000000..ae85867 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-result.valid-python313.json @@ -0,0 +1,72 @@ +{ + "schema_version": 2, + "kind": "judge.result", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "manifest_digest": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "compilation": { + "status": "succeeded", + "program": { + "kind": "python_source", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "source": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + }, + "toolchain": { + "toolchain_id": "cpython313-v1", + "image_kind": "linux_cpython313_x86_64_v1", + "image_revision": 1, + "image_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "runtime_version": "3.13.16" + }, + "files": [ + { + "path": "main.py", + "artifact": { + "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "bytes": 124 + } + } + ] + }, + "diagnostics": "", + "diagnostics_truncated": false, + "cpu_time_us": 100000, + "memory_peak_bytes": 16777216 + }, + "cases": [ + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000004", + "verdict": "accepted", + "cpu_time_us": 100, + "memory_peak_bytes": 262144 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000005", + "verdict": "accepted", + "cpu_time_us": 200, + "memory_peak_bytes": 524288 + }, + { + "case_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000006", + "verdict": "accepted", + "cpu_time_us": 300, + "memory_peak_bytes": 524288 + } + ], + "verdict": "accepted", + "cleanup_complete": true, + "failure_code": null, + "run_cpu_time_us": 600, + "run_memory_peak_bytes": 524288 +} diff --git a/tests/fixtures/contracts-v2/judge-stage.valid-c17.json b/tests/fixtures/contracts-v2/judge-stage.valid-c17.json new file mode 100644 index 0000000..7a4c4b1 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-stage.valid-c17.json @@ -0,0 +1,14 @@ +{ + "schema_version": 2, + "kind": "judge.stage", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "sequence": 1, + "stage": "compiling", + "case_index": null, + "preparation_kind": "compile" +} diff --git a/tests/fixtures/contracts-v2/judge-stage.valid-cpp20.json b/tests/fixtures/contracts-v2/judge-stage.valid-cpp20.json new file mode 100644 index 0000000..7a4c4b1 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-stage.valid-cpp20.json @@ -0,0 +1,14 @@ +{ + "schema_version": 2, + "kind": "judge.stage", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "sequence": 1, + "stage": "compiling", + "case_index": null, + "preparation_kind": "compile" +} diff --git a/tests/fixtures/contracts-v2/judge-stage.valid-java21.json b/tests/fixtures/contracts-v2/judge-stage.valid-java21.json new file mode 100644 index 0000000..7a4c4b1 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-stage.valid-java21.json @@ -0,0 +1,14 @@ +{ + "schema_version": 2, + "kind": "judge.stage", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "sequence": 1, + "stage": "compiling", + "case_index": null, + "preparation_kind": "compile" +} diff --git a/tests/fixtures/contracts-v2/judge-stage.valid-python313.json b/tests/fixtures/contracts-v2/judge-stage.valid-python313.json new file mode 100644 index 0000000..3813cfb --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-stage.valid-python313.json @@ -0,0 +1,14 @@ +{ + "schema_version": 2, + "kind": "judge.stage", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "sequence": 1, + "stage": "compiling", + "case_index": null, + "preparation_kind": "syntax_check" +} diff --git a/tests/fixtures/contracts-v2/judge-stopped.valid.json b/tests/fixtures/contracts-v2/judge-stopped.valid.json new file mode 100644 index 0000000..a17c2b2 --- /dev/null +++ b/tests/fixtures/contracts-v2/judge-stopped.valid.json @@ -0,0 +1,11 @@ +{ + "schema_version": 2, + "kind": "judge.stopped", + "binding": { + "evaluation_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000001", + "attempt_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000007", + "worker_id": "aaaaaaaa-aaaa-4aaa-8aaa-000000000008", + "fencing_version": 1 + }, + "cleanup_complete": true +}