import pytest from viano_bug_analysis.package import PackageReader, PackageReadError def test_open_reader_uses_immutable_snapshot(make_package): path=make_package(entries={"data":b"original"}) with PackageReader(path) as reader: path.write_bytes(b"damaged after opening") assert reader.read_bytes("data")==b"original" with pytest.raises(PackageReadError): with PackageReader(path):pass def test_cached_validation_is_detached_and_limits_are_part_of_key(make_package): from viano_bug_analysis.package import PackageLimits path=make_package(entries={"data":b"original"}) with PackageReader(path) as reader: reader._result.manifest["case_id"]="mutated-private-result" with PackageReader(path) as reader:assert reader.manifest["case_id"]=="case-A" with pytest.raises(PackageReadError): with PackageReader(path,PackageLimits(max_file_bytes=1)):pass def test_cached_reader_rejects_changed_bytes_even_when_mtime_and_size_match(make_package): import os path=make_package(entries={"data":b"original"}) with PackageReader(path):pass stat=path.stat();path.write_bytes(b"x"*stat.st_size) os.utime(path,ns=(stat.st_atime_ns,stat.st_mtime_ns)) with pytest.raises(PackageReadError): with PackageReader(path):pass def test_read_only_and_filename_independent(make_package): path = make_package(entries={"unknown/data.bin": b"\x00\xff"}) before = path.read_bytes() renamed = path.with_name("different.name") path.rename(renamed) with PackageReader(renamed) as reader: assert reader.manifest["package_id"] == "stable-package" assert reader.read_bytes("unknown/data.bin") == b"\x00\xff" modified = reader.manifest modified["case_id"] = "changed" assert reader.manifest["case_id"] == "case-A" with pytest.raises(PackageReadError): reader.read_bytes("../outside") assert renamed.read_bytes() == before with pytest.raises(RuntimeError): reader.read_bytes("manifest.json") def test_reader_rejection_and_cleanup(make_package): reader = PackageReader(make_package(raw=b"{}")) with pytest.raises(PackageReadError) as error: with reader: pytest.fail("Invalid package opened") assert not error.value.result.valid assert reader._source is None def test_reader_missing_file(tmp_path): with pytest.raises(PackageReadError): with PackageReader(tmp_path / "absent"): pass