generated from coulomb/repo-seed
query parsing and diagnostics
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
"capability_group": "discovery-query",
|
||||
"tck_groups": ["QueryTestGroup"],
|
||||
"expected": "partial-pass",
|
||||
"known_gaps": ["full_cmis_sql_joins", "order_by"]
|
||||
"known_gaps": ["full_cmis_sql_joins", "custom_order_by"]
|
||||
},
|
||||
{
|
||||
"capability_group": "relationships",
|
||||
|
||||
@@ -129,6 +129,7 @@ def test_cmis_repository_info_and_type_definitions(cmis_client) -> None:
|
||||
assert repository["repositoryUrl"].endswith("/cmis/readonly-browser/browser")
|
||||
assert repository["rootFolderUrl"].endswith("/cmis/readonly-browser/browser/root")
|
||||
assert repository["capabilities"]["capabilityQuery"] == "metadataonly"
|
||||
assert repository["capabilities"]["capabilityOrderBy"] == "common"
|
||||
assert repository["capabilities"]["capabilityGetDescendants"] is False
|
||||
assert browser_types["types"][0]["id"] == "cmis:document"
|
||||
assert "propertyDefinitions" not in browser_types["types"][0]
|
||||
@@ -166,10 +167,18 @@ def test_cmis_readonly_children_object_content_query_relationships_and_changes(c
|
||||
"/cmis/readonly-browser/browser/query",
|
||||
params={"q": "SELECT * FROM cmis:document"},
|
||||
).json()
|
||||
filtered_query = cmis_client.get(
|
||||
"/cmis/readonly-browser/browser/query",
|
||||
params={"q": "SELECT * FROM cmis:document WHERE kontextual:topics IN ('cmis') ORDER BY cmis:name ASC"},
|
||||
).json()
|
||||
relationships = cmis_client.get(
|
||||
"/cmis/readonly-browser/browser/relationships",
|
||||
params={"object_id": "cmis:asset:asset-source"},
|
||||
).json()
|
||||
target_relationships = cmis_client.get(
|
||||
"/cmis/readonly-browser/browser/relationships",
|
||||
params={"object_id": "cmis:asset:asset-public", "relationshipDirection": "target"},
|
||||
).json()
|
||||
changes = cmis_client.get("/cmis/readonly-browser/browser/changes").json()
|
||||
|
||||
root_ids = {item["object_id"] for item in root_children["objects"]}
|
||||
@@ -182,8 +191,11 @@ def test_cmis_readonly_children_object_content_query_relationships_and_changes(c
|
||||
assert "get_content_stream" in object_response["allowable_actions"]
|
||||
assert content["mime_type"] == "text/markdown"
|
||||
assert query["total_num_items"] == children["total_num_items"]
|
||||
assert [item["object_id"] for item in filtered_query["results"]] == ["cmis:asset:asset-source"]
|
||||
assert relationships["count"] == 1
|
||||
assert relationships["items"][0]["properties"]["cmis:targetId"] == "cmis:asset:asset-public"
|
||||
assert relationships["items"][0]["properties"]["kontextual:relationshipId"]
|
||||
assert target_relationships["count"] == 1
|
||||
assert changes["total_num_items"] >= 3
|
||||
|
||||
|
||||
@@ -213,13 +225,24 @@ def test_cmis_query_reports_unsupported_subset_diagnostics(cmis_client) -> None:
|
||||
params={"q": "SELECT * FROM cmis:document JOIN cmis:relationship"},
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert response.json()["exception"] == "invalidArgument"
|
||||
assert response.json()["details"]["supported"] == [
|
||||
"SELECT * FROM cmis:document",
|
||||
"SELECT * FROM kontextual:document",
|
||||
assert response.status_code == 405
|
||||
assert response.json()["exception"] == "notSupported"
|
||||
assert "SELECT * FROM cmis:document" in response.json()["details"]["supported"]
|
||||
assert response.json()["details"]["orderable_fields"] == [
|
||||
"cmis:creationDate",
|
||||
"cmis:lastModificationDate",
|
||||
"cmis:name",
|
||||
"cmis:objectId",
|
||||
]
|
||||
|
||||
descendants = cmis_client.get(
|
||||
"/cmis/readonly-browser/browser/root",
|
||||
params={"cmisselector": "descendants"},
|
||||
)
|
||||
assert descendants.status_code == 405
|
||||
assert descendants.json()["exception"] == "notSupported"
|
||||
assert descendants.json()["details"]["unsupported_feature"] == "get_descendants"
|
||||
|
||||
|
||||
def test_cmis_governed_authoring_routes_allow_selected_mutations(cmis_client) -> None:
|
||||
created = cmis_client.post(
|
||||
|
||||
@@ -65,7 +65,7 @@ def test_repository_info_uses_complete_conservative_cmis_11_capability_flags() -
|
||||
assert capabilities["capability_renditions"] == "none"
|
||||
assert capabilities["capability_get_descendants"] is False
|
||||
assert capabilities["capability_get_folder_tree"] is False
|
||||
assert capabilities["capability_order_by"] == "none"
|
||||
assert capabilities["capability_order_by"] == "common"
|
||||
assert capabilities["capability_multifiling"] is False
|
||||
assert capabilities["capability_unfiling"] is False
|
||||
assert capabilities["capability_version_specific_filing"] is False
|
||||
|
||||
72
tests/cmis/test_cmis_read_side_capacity.py
Normal file
72
tests/cmis/test_cmis_read_side_capacity.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from time import perf_counter
|
||||
|
||||
import pytest
|
||||
|
||||
from kontextual_engine import Classification, ServiceRuntime, Sensitivity
|
||||
from kontextual_engine.adapters.memory import InMemoryAssetRegistryRepository
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.cmis, pytest.mark.capacity]
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
os.getenv("KONTEXTUAL_RUN_CAPACITY") != "1",
|
||||
reason="Set KONTEXTUAL_RUN_CAPACITY=1 to run CMIS read-side capacity probes.",
|
||||
)
|
||||
def test_cmis_read_side_query_and_relationship_capacity_probe() -> None:
|
||||
runtime = ServiceRuntime(repository=InMemoryAssetRegistryRepository())
|
||||
context = runtime.operation_context(actor_id="cmis-capacity", correlation_id="corr-cmis-capacity")
|
||||
asset_count = 400
|
||||
relationship_count = 250
|
||||
|
||||
for index in range(asset_count):
|
||||
runtime.asset_service().create_asset(
|
||||
f"Capacity Asset {index:04d}",
|
||||
Classification(
|
||||
asset_type="document",
|
||||
sensitivity=Sensitivity.PUBLIC if index % 5 == 0 else Sensitivity.INTERNAL,
|
||||
owner=f"capacity-owner-{index % 7}",
|
||||
topics=("capacity", f"group-{index % 11}"),
|
||||
),
|
||||
context,
|
||||
asset_id=f"asset-capacity-{index:04d}",
|
||||
)
|
||||
|
||||
for index in range(relationship_count):
|
||||
runtime.create_relationship(
|
||||
{
|
||||
"source_asset_id": f"asset-capacity-{index:04d}",
|
||||
"target_id": f"asset-capacity-{asset_count - 1:04d}",
|
||||
"predicate": "capacity-related-to",
|
||||
"target_kind": "asset",
|
||||
"confidence": 0.9,
|
||||
},
|
||||
context,
|
||||
)
|
||||
|
||||
query_started = perf_counter()
|
||||
query = runtime.cmis_query(
|
||||
"readonly-browser",
|
||||
"SELECT * FROM cmis:document WHERE kontextual:topics IN ('capacity') ORDER BY cmis:name DESC",
|
||||
context,
|
||||
max_items=25,
|
||||
)
|
||||
query_seconds = perf_counter() - query_started
|
||||
|
||||
relationships_started = perf_counter()
|
||||
relationships = runtime.cmis_relationships(
|
||||
"readonly-browser",
|
||||
context,
|
||||
object_id=f"cmis:asset:asset-capacity-{asset_count - 1:04d}",
|
||||
relationship_direction="target",
|
||||
)
|
||||
relationships_seconds = perf_counter() - relationships_started
|
||||
|
||||
assert query["total_num_items"] == asset_count
|
||||
assert query["num_items"] == 25
|
||||
assert relationships["count"] == relationship_count
|
||||
assert query_seconds < 5.0
|
||||
assert relationships_seconds < 3.0
|
||||
@@ -110,17 +110,48 @@ def test_runtime_cmis_browser_content_query_relationships_and_changes(cmis_runti
|
||||
|
||||
content = runtime.cmis_content_stream("readonly-browser", "cmis:asset:asset-runtime-source", context)
|
||||
query = runtime.cmis_query("readonly-browser", "SELECT * FROM cmis:document", context)
|
||||
filtered_query = runtime.cmis_query(
|
||||
"readonly-browser",
|
||||
"SELECT * FROM cmis:document WHERE kontextual:sensitivity = 'internal' "
|
||||
"AND kontextual:topics IN ('integration') ORDER BY cmis:name DESC",
|
||||
context,
|
||||
)
|
||||
like_query = runtime.cmis_query(
|
||||
"readonly-browser",
|
||||
"SELECT * FROM cmis:document WHERE cmis:name LIKE 'Runtime %' ORDER BY cmis:name DESC",
|
||||
context,
|
||||
)
|
||||
relationships = runtime.cmis_relationships(
|
||||
"readonly-browser",
|
||||
context,
|
||||
object_id="cmis:asset:asset-runtime-source",
|
||||
)
|
||||
target_relationships = runtime.cmis_relationships(
|
||||
"readonly-browser",
|
||||
context,
|
||||
object_id="cmis:asset:asset-runtime-public",
|
||||
relationship_direction="target",
|
||||
)
|
||||
either_relationships = runtime.cmis_relationships(
|
||||
"readonly-browser",
|
||||
context,
|
||||
object_id="cmis:asset:asset-runtime-public",
|
||||
relationship_direction="either",
|
||||
)
|
||||
changes = runtime.cmis_change_log("readonly-browser", context)
|
||||
|
||||
assert content["mime_type"] in {"text/plain", "text/markdown"}
|
||||
assert query["total_num_items"] == 2
|
||||
assert [item["object_id"] for item in filtered_query["results"]] == [
|
||||
"cmis:asset:asset-runtime-source"
|
||||
]
|
||||
assert [item["name"] for item in like_query["results"]] == ["Runtime Source", "Runtime Public"]
|
||||
assert relationships["count"] == 1
|
||||
assert relationships["items"][0]["properties"]["cmis:targetId"] == "cmis:asset:asset-runtime-public"
|
||||
assert relationships["items"][0]["properties"]["cmis:changeToken"].startswith("relationship:")
|
||||
assert relationships["items"][0]["properties"]["kontextual:direction"] == "outbound"
|
||||
assert target_relationships["count"] == 1
|
||||
assert either_relationships["count"] == 1
|
||||
assert changes["total_num_items"] >= 3
|
||||
assert all(change["object_id"] != "cmis:asset:asset-runtime-confidential" for change in changes["changes"])
|
||||
|
||||
@@ -137,6 +168,16 @@ def test_runtime_cmis_browser_rejects_unsupported_query_subset(cmis_runtime) ->
|
||||
|
||||
assert "Unsupported CMIS query subset" in str(exc_info.value)
|
||||
|
||||
with pytest.raises(Exception) as direction_exc:
|
||||
runtime.cmis_relationships(
|
||||
"readonly-browser",
|
||||
context,
|
||||
object_id="cmis:asset:asset-runtime-source",
|
||||
relationship_direction="both",
|
||||
)
|
||||
|
||||
assert "Unsupported CMIS relationship direction" in str(direction_exc.value)
|
||||
|
||||
|
||||
def test_runtime_cmis_governed_authoring_allows_selected_mutations(cmis_runtime) -> None:
|
||||
runtime, context = cmis_runtime
|
||||
@@ -335,6 +376,10 @@ def test_runtime_cmis_acl_projection_and_redaction(cmis_runtime) -> None:
|
||||
|
||||
assert public_acl["is_exact"] is True
|
||||
assert {entry["principal_id"] for entry in public_acl["aces"]} == {"cmis-runtime", "anyone"}
|
||||
assert public_acl["policy_authority"] == "kontextual-policy-gateway"
|
||||
assert public_acl["permission_mapping"]["cmis:read"] == "asset visible through profile policy"
|
||||
assert {entry["principal_kind"] for entry in public_acl["aces"]} == {"human", "well_known"}
|
||||
assert {entry["inherited"] for entry in public_acl["aces"]} == {False, True}
|
||||
assert ["cmis:read", "cmis:write", "cmis:delete"] in [
|
||||
entry["permissions"] for entry in internal_acl["aces"]
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user