Fastfill-test / code /fastfill /v2 /tests /test_asset_attribute_contract.py
XXXpilar's picture
FastFill v4 base (step 6552): LoRA adapter, geometry heads, tokenizer, training code, predict.py
e6f80f3 verified
Raw History Blame Contribute Delete
5.14 kB
"""Unverified typed attributes cannot be satisfied by a reference catalog."""
from copy import deepcopy
import pytest
from fastfill.v2.runtime import Asset, AtomicMemoryHost, CatalogResolver, run_pipeline
from fastfill.v2.schema import validate_condition
from fastfill.v2.tests.test_runtime import condition, desk, layout
from fastfill.v2.validation import validate_scene
def attribute_condition(attributes):
return condition([{"id": "desk", "category": "desk", "support_parent": "floor",
"attributes": attributes, "description": "a red wooden work desk"}])
@pytest.mark.parametrize("attributes", [
{"color": "red"}, {"material": "wood"}, {"has_drawers": False},
{"finish": {"coating": "matte"}}, {"color": None},
])
def test_reference_catalog_requires_evidence_for_every_nonempty_typed_attribute_request(attributes):
request = attribute_condition(attributes)
validate_condition(request)
asset = desk(description="a red wooden work desk", capabilities=("work_surface",))
before = deepcopy((request, layout()))
resolver = CatalogResolver((asset,))
assert resolver.resolve(request["objects"][0], layout()["objects"][0]) is None
assert (request, layout()) == before
@pytest.mark.parametrize("claimed_metadata", [{}, {"attributes": {"color": "red", "material": "wood"}},
{"verified_attributes": {"color": "red", "material": "wood"}}])
def test_direct_actual_validator_has_hard_unknown_without_an_attribute_evidence_contract(claimed_metadata):
request = attribute_condition({"color": "red", "material": "wood"})
actual = {**layout()["objects"][0], "actual_size_local_m": [.9, 1., .7],
"capabilities": ["work_surface"], **claimed_metadata}
before = deepcopy((request, actual))
report = validate_scene(request, [actual], stage="actual")
assert not report["ok"]
check = next(check for check in report["checks"] if check["code"] == "attributes_unverified")
assert check["hard"] is True and check["status"] == "unknown"
assert check["object_ids"] == ["desk"]
assert "attributes_unverified" in report["unknown_checks"]
assert (request, actual) == before
def test_external_resolver_cannot_bypass_required_attributes_or_partially_commit():
request = condition([
{"id": "plain", "category": "desk", "support_parent": "floor"},
{"id": "required", "category": "desk", "support_parent": "floor",
"attributes": {"color": "red", "material": "wood"}},
])
prediction = layout([{**layout()["objects"][0], "id": "plain", "bottom_center_m": [1, 2, 0]},
{**layout()["objects"][0], "id": "required", "bottom_center_m": [3, 2, 0]}])
before = deepcopy((request, prediction))
class IgnoringResolver:
def resolve(self, request_object, _prediction, *, excluded_refs=()):
return Asset(request_object["id"], "desk", (.9, 1., .7), description="blue plastic desk")
host = AtomicMemoryHost()
report = run_pipeline(request, prediction, IgnoringResolver(), host=host,
expected_world_version=0, idempotency_key="attribute-request")
assert not report["ok"] and not report["committed"]
assert report["metrics"]["model"]["schema_success"] is True
assert report["diagnostics"][0]["code"] == "asset_unavailable"
assert report["diagnostics"][0]["object_id"] == "required"
assert host.snapshot() == {"version": 0, "objects": [], "commits": 0}
assert report["raw_model_output"] == prediction
assert (request, prediction) == before
@pytest.mark.parametrize("attributes", [None, {}])
def test_plain_or_empty_attributes_keep_existing_size_and_capability_contract(attributes):
request_object = {"id": "desk", "category": "desk", "support_parent": "floor",
"required_capabilities": ["work_surface"],
"fixed_size_local_m": [None, 1., None]}
if attributes is not None:
request_object = {**request_object, "attributes": attributes}
request, prediction = condition([request_object]), layout()
resolver = CatalogResolver((desk("no_capability"),
desk("eligible", (.9, 1., .7), capabilities=("work_surface",))))
host = AtomicMemoryHost()
report = run_pipeline(request, prediction, resolver, host=host,
expected_world_version=0, idempotency_key="plain-request")
assert report["ok"] and report["committed"]
assert report["final_objects"][0]["asset_ref"] == "eligible"
assert report["final_objects"][0]["target_size_local_m"] == [1., 1., .75]
assert report["final_objects"][0]["actual_size_local_m"] == [.9, 1., .7]
assert "attributes_unverified" not in report["validation"]["final"]["unknown_checks"]
assert host.snapshot()["commits"] == 1
def test_target_geometry_stage_does_not_claim_asset_attribute_verification():
report = validate_scene(attribute_condition({"color": "red"}), layout()["objects"])
assert report["ok"]
assert report["stage"] == "target" and report["geometry_level"] == "bbox"