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
12 changes: 10 additions & 2 deletions cognite_toolkit/_cdf_tk/storageio/_applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def _populate_id_cache(self, data_chunk: Sequence[IndustrialCanvas]) -> None:
self.client.lookup.files.external_id(list(file_ids))

def _dump_resource(self, canvas: IndustrialCanvas) -> dict[str, JsonVal]:
dumped = canvas.as_write().dump()
dumped = canvas.as_write().dump(keep_existing_version=False)
references = dumped.get("containerReferences", [])
if not isinstance(references, list):
return dumped
Expand All @@ -230,10 +230,18 @@ def _dump_resource(self, canvas: IndustrialCanvas) -> dict[str, JsonVal]:
properties = source["properties"]
if not isinstance(properties, dict):
continue
reference_type = properties.get("containerReferenceType")
if (
reference_type
in {
"charts",
"dataGrid",
}
): # These container reference types are special cases with a resourceId statically set to -1, which is why we skip them
continue
resource_id = properties.pop("resourceId", None)
if not isinstance(resource_id, int):
continue
reference_type = properties.get("containerReferenceType")
if reference_type == "asset":
external_id = self.client.lookup.assets.external_id(resource_id)
elif reference_type == "timeseries":
Expand Down
58 changes: 58 additions & 0 deletions tests/test_unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ def asset_centric_canvas() -> tuple[IndustrialCanvas, NodeList[InstanceSource]]:
},
"space": "IndustrialCanvasInstanceSpace",
"version": 14,
"existingVersion": 14,
}
],
"containerReferences": [
Expand Down Expand Up @@ -270,6 +271,7 @@ def asset_centric_canvas() -> tuple[IndustrialCanvas, NodeList[InstanceSource]]:
},
"space": "IndustrialCanvasInstanceSpace",
"version": 1,
"existingVersion": 1,
},
{
"createdTime": 1751540275336,
Expand All @@ -296,6 +298,7 @@ def asset_centric_canvas() -> tuple[IndustrialCanvas, NodeList[InstanceSource]]:
},
"space": "IndustrialCanvasInstanceSpace",
"version": 1,
"existingVersion": 1,
},
{
"createdTime": 1751540544349,
Expand All @@ -322,6 +325,61 @@ def asset_centric_canvas() -> tuple[IndustrialCanvas, NodeList[InstanceSource]]:
},
"space": "IndustrialCanvasInstanceSpace",
"version": 4,
"existingVersion": 4,
},
{
"createdTime": 1751540600000,
"externalId": "495af88f-fe1d-403d-91b1-76ef9f80f265_chart-ref-1",
"instanceType": "node",
"lastUpdatedTime": 1751540600000,
"properties": {
"cdf_industrial_canvas": {
"ContainerReference/v2": {
"chartsId": "my-chart-id",
"containerReferenceType": "charts",
"height": 400,
"id": "chart-ref-1",
"label": "My Chart",
"maxHeight": None,
"maxWidth": None,
"resourceId": -1,
"resourceSubId": None,
"width": 600,
"x": 100,
"y": 100,
}
}
},
"space": "IndustrialCanvasInstanceSpace",
"version": 1,
"existingVersion": 1,
},
{
"createdTime": 1751540700000,
"externalId": "495af88f-fe1d-403d-91b1-76ef9f80f265_datagrid-ref-1",
"instanceType": "node",
"lastUpdatedTime": 1751540700000,
"properties": {
"cdf_industrial_canvas": {
"ContainerReference/v2": {
"chartsId": None,
"containerReferenceType": "dataGrid",
"height": 300,
"id": "datagrid-ref-1",
"label": "My Data Grid",
"maxHeight": None,
"maxWidth": None,
"resourceId": -1,
"resourceSubId": None,
"width": 800,
"x": 200,
"y": 200,
}
}
},
"space": "IndustrialCanvasInstanceSpace",
"version": 1,
"existingVersion": 1,
},
],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ def test_migrate_canvas_happy_path(
backup = client.canvas.industrial.create.call_args[0][0]
assert isinstance(backup, IndustrialCanvasApply)

assert len(update.fdm_instance_container_references) == len(canvas.container_references)
# Only asset-centric container references should be migrated (not charts/dataGrid)
migratable_refs = [
ref for ref in canvas.container_references if ref.container_reference_type not in {"charts", "dataGrid"}
]
assert len(update.fdm_instance_container_references) == len(migratable_refs)
assert len(backup.fdm_instance_container_references) == 0

def test_migrate_canvas_missing(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,12 @@ def test_download_iterable(
class TestCanvasIO:
def test_download_iterable(self, asset_centric_canvas: tuple[IndustrialCanvas, NodeList[InstanceSource]]) -> None:
canvas, _ = asset_centric_canvas
ids = [container_ref.resource_id for container_ref in canvas.container_references or []]
# Exclude charts/dataGrid types which have resourceId=-1 by design
ids = [
container_ref.resource_id
for container_ref in canvas.container_references or []
if container_ref.container_reference_type not in {"charts", "dataGrid"}
]
assert len(ids) > 0, "Test canvas must have container references for this test to be valid."
mapping = {id_: f"external_id_{no}" for no, id_ in enumerate(ids)}
reverse = {v: k for k, v in mapping.items()}
Expand Down Expand Up @@ -186,8 +191,10 @@ def lookup(external_id: str | list[str]) -> int | list[int]:
json_str = json.dumps(json_format)
internal_id_in_json = [id_ for id_ in ids if str(id_) in json_str]
assert len(internal_id_in_json) == 0, "Internal IDs should not be present in the JSON export."
assert "existingVersion" not in json_str, "existingVersion should not be present in the JSON export."
restored_canvases = io.json_chunk_to_data([("line 1", item) for item in json_format])

assert len(restored_canvases) == 1
restored_canvas = restored_canvases[0]
assert restored_canvas.item.dump() == canvas.as_write().dump()
# The restored canvas should match the original without existingVersion fields
assert restored_canvas.item.dump() == canvas.as_write().dump(keep_existing_version=False)
Loading