Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions datalab/tests/features/common/provenance_capture_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import sigima.proc.image as sipi
import sigima.proc.signal as sips
from sigima.objects import create_image, create_signal
from sigima.proc import contracts
from sigima.tests.data import create_peak_image

from datalab.env import execenv
Expand Down Expand Up @@ -542,6 +543,11 @@ def test_replaced_analysis_result_is_not_attributed() -> None:
# from Pyodide (Playwright, ``DLW_WRITE_PROVENANCE_FIXTURE=1``).

HDF5_DIR = osp.join(osp.dirname(osp.dirname(__file__)), "hdf5")
#: Contract versions of the local Sigima, by operation identifier
LOCAL_VERSIONS = {
contract.operation_id: contract.contract_version
for contract in contracts.build_contract_registry().contracts
}
CAPTURE_SHAPE = [
("image", None, "geometry"),
("image", "image", None),
Expand Down Expand Up @@ -709,6 +715,13 @@ def check_families_reference(win, edition: str) -> list[dict]:
reports = []
for activity in activities:
report = win.verify_provenance_activity(activity["activity_id"])
operation = activity["call"]["operation"]
if operation["contract_version"] != LOCAL_VERSIONS[operation["id"]]:
# Recorded with another version of the contract (e.g. before Sigima
# 1.4): refused explicitly, never compared
assert report["eligibility"] == "unsupported_contract", report
reports.append(report)
continue
accepted = ("exact",) if edition == "desktop" else ("exact", "within_tolerance")
assert report["verdict"] in accepted, report
reports.append(report)
Expand All @@ -724,12 +737,15 @@ def test_families_reference_round_trip() -> None:
win.save_h5_workspace(path)
with app() as win:
win.load_h5_workspace([path], reset_all=True)
check_families_reference(win, "desktop")
reports = check_families_reference(win, "desktop")
# Recorded with the local contracts: every activity is replayed
assert all(report["eligibility"] == "ready" for report in reports)


@pytest.mark.parametrize("edition", ["desktop", "web"])
def test_families_reference_files(edition: str) -> None:
"""Families files of both editions are replayed here under the declared rule."""
"""Families files of both editions are replayed here under the declared rule,
except the activities recorded with an earlier contract version (refused)."""
path = osp.join(HDF5_DIR, f"provenance_{edition}_families.h5")
with app() as win:
win.load_h5_workspace([path], reset_all=True)
Expand Down
32 changes: 24 additions & 8 deletions datalab/tests/features/common/provenance_difference_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import pytest
import sigima.proc.signal as sips
from sigima.objects import SignalObj, create_signal
from sigima.proc import contracts

from datalab.env import execenv
from datalab.objectmodel import get_uuid
Expand All @@ -25,6 +26,8 @@
)

HDF5_DIR = osp.join(osp.dirname(osp.dirname(__file__)), "hdf5")
#: Version of the difference contract of the local Sigima
DIFFERENCE_VERSION = contracts.contract_for_function(sips.difference).contract_version


def add(win, x, y, title: str, units=("s", "V")) -> SignalObj:
Expand Down Expand Up @@ -89,8 +92,14 @@ def build_differences(win) -> tuple[SignalObj, ...]:
return a, b, a_b, b_a


def check_differences(win, edition: str = "desktop") -> None:
"""Check the two recorded differences of a workspace and replay them."""
def check_differences(
win, edition: str = "desktop", contract_version: int = DIFFERENCE_VERSION
) -> None:
"""Check the two recorded differences of a workspace and replay them.

Activities recorded with another version of the difference contract (files
written before Sigima 1.4) are refused explicitly, without computation.
"""
ledger = win.provenance.ledger
ledger.validate()
act_ab, act_ba = ledger.activities
Expand All @@ -99,7 +108,7 @@ def check_differences(win, edition: str = "desktop") -> None:
assert activity["edition"] == edition
assert activity["call"]["operation"] == {
"id": "sigima.signal.difference",
"contract_version": 1,
"contract_version": contract_version,
}
assert activity["call"]["parameters"] == {}
assert activity["context"]["x_alignment"] == RULE
Expand All @@ -111,11 +120,17 @@ def check_differences(win, edition: str = "desktop") -> None:
result = win.find_object_by_uuid(state["object_uuid"])
assert np.array_equal(result.y, expected)
computations = win.signalpanel.processor.execution.computations
replayable = contract_version == DIFFERENCE_VERSION
for activity in (act_ab, act_ba):
report = win.verify_provenance_activity(activity["activity_id"])
assert report["verdict"] == "exact", report
assert report["context"]["x_alignment"] == RULE
assert win.signalpanel.processor.execution.computations == computations + 2
if replayable:
assert report["verdict"] == "exact", report
assert report["context"]["x_alignment"] == RULE
else:
assert report["eligibility"] == "unsupported_contract", report
assert report["verdict"] == "not_verified", report
expected = computations + (2 if replayable else 0)
assert win.signalpanel.processor.execution.computations == expected


def test_capture_and_verification() -> None:
Expand Down Expand Up @@ -148,11 +163,12 @@ def test_desktop_round_trip() -> None:

@pytest.mark.parametrize("edition", ["desktop", "web"])
def test_reference_files(edition: str) -> None:
"""Reference files of both editions reopen and replay exactly on Desktop."""
"""Reference files of both editions reopen on Desktop; recorded with version 1
of the difference contract (before Sigima 1.4), they are refused explicitly."""
path = osp.join(HDF5_DIR, f"provenance_{edition}_difference.h5")
with app() as win:
win.load_h5_workspace([path], reset_all=True)
check_differences(win, edition)
check_differences(win, edition, contract_version=1)


def test_swapped_roles_give_a_different_result() -> None:
Expand Down
21 changes: 10 additions & 11 deletions datalab/tests/features/common/provenance_processing_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ def test_one_output_of_a_grouped_command(method: str) -> None:


def test_web_files_are_described_and_applied_again() -> None:
"""Reference files written by DataLab-Web: consulted, restored, reapplied."""
"""Reference files written by DataLab-Web: consulted, restored, reapplied when
their contract version is still supported."""
hdf5 = osp.join(osp.dirname(osp.dirname(__file__)), "hdf5")
with app() as win:
win.load_h5_workspace(
Expand Down Expand Up @@ -497,17 +498,15 @@ def test_web_files_are_described_and_applied_again() -> None:
[osp.join(hdf5, "provenance_web_difference.h5")], reset_all=True
)
act_ab, _act_ba = win.provenance.ledger.activities
# Recorded with version 1 of the difference contract (before Sigima 1.4):
# described, but not applied again with the current contract
assert act_ab["call"]["operation"]["contract_version"] == 1
a_b = win.find_object_by_uuid(output_uuid(win, act_ab))
call = resolve_processing_call(win, a_b)
assert call.pattern == "2-to-1" and call.can_reapply
assert call.pattern == "2-to-1" and not call.can_reapply
assert "sigima.signal.difference" in call.reason
assert [(i.role, i.object_uuid) for i in call.inputs] == inputs_of(win, act_ab)
a_b.y[:] = 0.0
count = len(win.provenance.ledger.activities)
report = win.signalpanel.processor.recompute_processing(a_b, interactive=False)
assert report.success, report.message
assert np.array_equal(a_b.y, A_MINUS_B)
activity = win.provenance.ledger.activities[-1]
assert activity["context"]["x_alignment"] == RULE
assert (
win.verify_provenance_activity(activity["activity_id"])["verdict"]
== "exact"
)
assert not report.success
assert len(win.provenance.ledger.activities) == count
Loading