Trace complete directed graph lineage in Flow view
This commit is contained in:
parent
984a4fd993
commit
e405326334
3 changed files with 139 additions and 61 deletions
|
|
@ -177,47 +177,34 @@ if (centered.width !== 500 || centered.height !== 300) fail("center preserves zo
|
|||
if (centered.x !== positions.get("child-two").x - 250) fail("center x");
|
||||
if (centered.y !== positions.get("child-two").y - 150) fail("center y");
|
||||
if (relationStyle("calls").family !== "Execution") fail("calls family");
|
||||
if (relationStyle("contains").flow !== "forward") fail("contains flow direction");
|
||||
if (relationStyle("reads").flow !== "reverse") fail("reads flow direction");
|
||||
if (relationStyle("documents").flow !== null) fail("documents excluded from flow");
|
||||
if (relationStyle("unknown_relation").family !== "Other") fail("fallback relation family");
|
||||
const flowData = {
|
||||
root: "primary",
|
||||
depth: 2,
|
||||
nodes: [
|
||||
{node_id: "primary"},
|
||||
{node_id: "caller"},
|
||||
{node_id: "dependency"},
|
||||
{node_id: "reader"},
|
||||
{node_id: "package"},
|
||||
{node_id: "module"},
|
||||
{node_id: "test-class"},
|
||||
{node_id: "test-file"},
|
||||
{node_id: "document"},
|
||||
{node_id: "evidence"},
|
||||
],
|
||||
edges: [
|
||||
{source_id: "caller", relation: "calls", target_id: "primary"},
|
||||
{source_id: "primary", relation: "depends_on", target_id: "dependency"},
|
||||
{source_id: "primary", relation: "reads", target_id: "reader"},
|
||||
{source_id: "test-class", relation: "contains", target_id: "primary"},
|
||||
{source_id: "test-file", relation: "contains", target_id: "test-class"},
|
||||
{source_id: "document", relation: "documents", target_id: "primary"},
|
||||
{source_id: "module", relation: "contains", target_id: "test-file"},
|
||||
{source_id: "package", relation: "contains", target_id: "module"},
|
||||
{source_id: "evidence", relation: "verifies", target_id: "primary"},
|
||||
],
|
||||
};
|
||||
const flow = buildFlowGraph(flowData);
|
||||
const flowIds = new Set(flow.nodes.map((node) => node.node_id));
|
||||
if (!flowIds.has("caller") || !flowIds.has("dependency") || !flowIds.has("reader")
|
||||
|| !flowIds.has("test-class") || !flowIds.has("test-file")) {
|
||||
fail("upstream flow membership");
|
||||
}
|
||||
if (flowIds.has("document")) fail("evidence leaked into flow");
|
||||
if (!flowIds.has("package") || !flowIds.has("module") || !flowIds.has("test-class")
|
||||
|| !flowIds.has("test-file") || !flowIds.has("evidence")) fail("full lineage membership");
|
||||
const flowPositions = layoutFlow(flow.nodes, flow.root, flow.topology);
|
||||
if (flowPositions.get("primary").x !== 0) fail("flow destination position");
|
||||
if (flowPositions.get("caller").x >= flowPositions.get("primary").x) {
|
||||
if (flowPositions.get("package").x >= flowPositions.get("primary").x) {
|
||||
fail("flow upstream direction");
|
||||
}
|
||||
const dependencyEdge = flow.edges.find((edge) => edge.relation === "depends_on");
|
||||
if (dependencyEdge.source_id !== "dependency" || dependencyEdge.target_id !== "primary") {
|
||||
fail("dependency semantic reversal");
|
||||
}
|
||||
const containmentEdge = flow.edges.find((edge) => edge.relation === "contains"
|
||||
&& edge.source_id === "test-class");
|
||||
if (!containmentEdge || containmentEdge.target_id !== "primary") {
|
||||
|
|
@ -307,9 +294,9 @@ if (!containmentEdge || containmentEdge.target_id !== "primary") {
|
|||
self.assertIn("relationStyles", html)
|
||||
self.assertIn("appendRelationMarker", html)
|
||||
self.assertIn("renderRelationshipKey", html)
|
||||
self.assertIn("semanticFlowEdge", html)
|
||||
self.assertIn("buildFlowGraph", html)
|
||||
self.assertIn("layoutFlow", html)
|
||||
self.assertIn('api(`${showingFlow ? "lineage" : "node"}?${params}`)', html)
|
||||
self.assertIn("filterByDescriptor", html)
|
||||
self.assertIn("api(`filter?${params}`)", html)
|
||||
self.assertIn('setViewMode("flow")', html)
|
||||
|
|
@ -371,6 +358,22 @@ if (!containmentEdge || containmentEdge.target_id !== "primary") {
|
|||
self.assertEqual("guide.workflow", node["node"]["node_id"])
|
||||
self.assertEqual("guide.workflow", node["root"])
|
||||
|
||||
lineage_query = urllib.parse.urlencode({"id": "guide.workflow", "limit": 1000})
|
||||
with urllib.request.urlopen(
|
||||
f"{base}api/lineage?{lineage_query}", timeout=2
|
||||
) as response:
|
||||
lineage = json.load(response)
|
||||
self.assertTrue(lineage["lineage"])
|
||||
self.assertEqual("guide.workflow", lineage["root"])
|
||||
self.assertIn(
|
||||
{
|
||||
"source_id": "proof.validation",
|
||||
"relation": "proves",
|
||||
"target_id": "guide.workflow",
|
||||
},
|
||||
lineage["edges"],
|
||||
)
|
||||
|
||||
wrong_token = f"{first_url.scheme}://{first_url.netloc}/wrong-token/api/overview"
|
||||
with self.assertRaises(urllib.error.HTTPError) as missing:
|
||||
urllib.request.urlopen(wrong_token, timeout=2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue