"""Stage 6 acceptance for the *device's own* geometry description. The review's R3 finding was that the internal-consistency check was never wired to the acquisition side: the adapter was built from the asset, so "the frame matches the scene" was a sentence the asset wrote about itself. These tests are about the other half — the description the acquisition side derives from the files the runtime actually loads, and what happens when those files and the package disagree. The bundle used here is the shipped one (``apps/studio/config/sensors/finger``); the tests that need it skip when it is absent, because the module is also imported by runs that only have the SDK. """ from __future__ import annotations import json import shutil from dataclasses import replace from pathlib import Path import numpy as np import pytest from orisys_app_shared.acquisition.geometry import ( describe_sensor_geometry, map_path_for, ) from orisys_app_shared.scene3d.contracts import ThreeDError from orisys_app_shared.scene3d.package import PackagedAssetLoader BUNDLE = ( Path(__file__).resolve().parents[2] / "apps" / "studio" / "config" / "sensors" / "finger" ) PACKAGE = BUNDLE / "scene" / "finger-display-1.0.0.oryscene" def _require_bundle() -> None: if not (BUNDLE / "sensor.json").is_file(): pytest.skip("the shipped finger bundle is not present") def _require_package() -> None: _require_bundle() if not PACKAGE.is_file(): pytest.skip("the compiled finger package is not present") def test_the_map_name_follows_the_scale_the_sdk_would_use(tmp_path): assert map_path_for(tmp_path, 0.4).name == "unroll_map_uv_s0.4.npz" assert map_path_for(tmp_path, 1.0).name == "unroll_map_uv.npz" assert map_path_for(tmp_path, None).name == "unroll_map_uv.npz" def test_the_device_description_comes_from_the_files_the_runtime_loads(): _require_bundle() device = describe_sensor_geometry("finger", BUNDLE / "sensor.json") assert device.verified, device.detail assert device.expected.sensor_model == "finger" # The metre-scaled identity needs the operator's unit statement; a device that # cannot make it must say nothing rather than echo the asset's id back. assert device.expected.geometry_id == "" assert device.expected.field_domain_id assert device.expected.source_geometry_id assert tuple(device.expected.shape_hw) == (300, 280) assert Path(device.detail["map"]).name == "unroll_map_uv_s0.4.npz" assert device.detail["shape_hw"] == "300x280" def test_the_shipped_package_passes_the_shipped_device_description(): _require_package() device = describe_sensor_geometry("finger", BUNDLE / "sensor.json") assets = PackagedAssetLoader().load(PACKAGE, device.expected) assert assets.source_geometry_id == device.expected.source_geometry_id assert assets.compatible_sensor_model == "finger" def test_a_same_size_different_mapping_is_refused(tmp_path): """The risk the review named: 300x280 is not one mapping.""" _require_package() fake = tmp_path / "finger" shutil.copytree(BUNDLE, fake) map_path = fake / "assets" / "30fps-0703" / "unroll_map_uv_s0.4.npz" with np.load(map_path, allow_pickle=False) as handle: data = {key: handle[key] for key in handle.files} # The same grid, the same valid area — a different mapping. data["map_x"] = np.asarray(data["map_x"], dtype=np.float32).copy() data["map_x"][0, 0] = float(data["map_x"][0, 0]) + 3.0 np.savez(map_path, **data) shipped = describe_sensor_geometry("finger", BUNDLE / "sensor.json") other = describe_sensor_geometry("finger", fake / "sensor.json") assert tuple(other.expected.shape_hw) == tuple(shipped.expected.shape_hw) assert other.expected.field_domain_id != shipped.expected.field_domain_id, ( "two different mappings of the same size produced the same domain id" ) with pytest.raises(ThreeDError) as excinfo: PackagedAssetLoader().load(PACKAGE, other.expected) assert excinfo.value.diagnostic.code == "field_domain_mismatch" def test_a_changed_mesh_behind_the_same_map_is_refused(tmp_path): """The other half: the map is identical, the surface behind it is not.""" _require_package() device = describe_sensor_geometry("finger", BUNDLE / "sensor.json") other_geometry = replace(device.expected, source_geometry_id="somebody-elses-surface") with pytest.raises(ThreeDError) as excinfo: PackagedAssetLoader().load(PACKAGE, other_geometry) assert excinfo.value.diagnostic.code == "geometry_mismatch" def test_a_bundle_that_cannot_be_described_is_unverified_not_a_match(tmp_path): _require_bundle() unknown = tmp_path / "nowhere" device = describe_sensor_geometry("finger", unknown) assert device.verified is False assert device.expected.geometry_id == "" assert device.expected.source_geometry_id == "" assert "could not be located" in device.detail["reason"] def test_a_bundle_whose_map_disagrees_with_the_config_is_refused(tmp_path): """``resolution_stitch`` and the map are two statements of one grid.""" _require_bundle() fake = tmp_path / "finger" shutil.copytree(BUNDLE, fake) config = json.loads((fake / "sensor.json").read_text(encoding="utf-8")) config["camera"]["resolution_stitch"] = [280, 299] (fake / "sensor.json").write_text( json.dumps(config, ensure_ascii=False), encoding="utf-8" ) with pytest.raises(ThreeDError) as excinfo: describe_sensor_geometry("finger", fake / "sensor.json") assert excinfo.value.diagnostic.code == "field_domain_mismatch" def test_a_missing_map_names_the_file_it_looked_for(tmp_path): _require_bundle() fake = tmp_path / "finger" (fake / "assets" / "30fps-0703").mkdir(parents=True) (fake / "manifest.json").write_text( json.dumps({"assets_dir": "assets/30fps-0703"}), encoding="utf-8" ) shutil.copy(BUNDLE / "sensor.json", fake / "sensor.json") with pytest.raises(ThreeDError) as excinfo: describe_sensor_geometry("finger", fake / "sensor.json") assert excinfo.value.diagnostic.code == "asset_rejected" assert "unroll_map_uv_s0.4.npz" in excinfo.value.diagnostic.message def test_a_bundle_without_an_assets_dir_is_unverified(tmp_path): fake = tmp_path / "finger" fake.mkdir() (fake / "manifest.json").write_text(json.dumps({"name": "finger"}), encoding="utf-8") (fake / "sensor.json").write_text(json.dumps({"camera": {}}), encoding="utf-8") device = describe_sensor_geometry("finger", fake / "sensor.json") assert device.verified is False assert "assets_dir" in device.detail["reason"]