improved tests
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import pytest
|
||||
|
||||
from daglib.dag import DAG
|
||||
from daglib.operations import all_nodes
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def build_graph() -> DAG[str]:
|
||||
graph = DAG[str]()
|
||||
graph.add_edge("checkout", "compile")
|
||||
graph.add_edge("toolchain", "compile")
|
||||
graph.add_edge("compile", "package")
|
||||
graph.add_edge("package", "deploy")
|
||||
return graph
|
||||
|
||||
|
||||
def test_subgraph_reverse_mutation_preserves_parent_edge_consistency(build_graph: DAG[str]) -> None:
|
||||
assert "compile" in build_graph["toolchain"]
|
||||
assert "toolchain" in build_graph.reverse["compile"]
|
||||
|
||||
pipeline = build_graph.subgraph("checkout")
|
||||
pipeline.reverse["compile"].discard("toolchain")
|
||||
|
||||
forward_has_edge = "compile" in build_graph["toolchain"]
|
||||
reverse_has_edge = "toolchain" in build_graph.reverse["compile"]
|
||||
assert forward_has_edge == reverse_has_edge, "Subgraph mutation desynchronized the parent DAG's edge indexes"
|
||||
assert forward_has_edge
|
||||
|
||||
|
||||
def test_subgraph_reverse_mutation_preserves_parent_topological_dependencies(build_graph: DAG[str]) -> None:
|
||||
assert "toolchain" in build_graph.topo_sort()
|
||||
|
||||
pipeline = build_graph.subgraph("checkout")
|
||||
pipeline.reverse["compile"].discard("toolchain")
|
||||
|
||||
assert "compile" in build_graph["toolchain"]
|
||||
order = build_graph.topo_sort()
|
||||
assert "toolchain" in order, "Topological sorting omitted a node with an outgoing edge in the parent DAG"
|
||||
assert order.index("toolchain") < order.index("compile")
|
||||
|
||||
|
||||
def test_build_subgraph_excludes_external_dependencies(build_graph: DAG[str]) -> None:
|
||||
pipeline = build_graph.subgraph("checkout")
|
||||
|
||||
assert all_nodes(pipeline) == {"checkout", "compile", "package", "deploy"}
|
||||
assert set(pipeline.reverse["compile"]) == {"checkout"}
|
||||
assert len(pipeline) == 3
|
||||
order = pipeline.topo_sort()
|
||||
assert set(order) == all_nodes(pipeline)
|
||||
assert order.index("checkout") < order.index("compile") < order.index("package") < order.index("deploy")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mutate_parent", [False, True], ids=["child-mutation", "parent-mutation"])
|
||||
@pytest.mark.parametrize("mutation", ["add", "remove", "reverse-remove", "discard-node"])
|
||||
def test_build_subgraph_mutations_are_isolated(build_graph: DAG[str], mutate_parent: bool, mutation: str) -> None:
|
||||
pipeline = build_graph.subgraph("checkout")
|
||||
changed, protected = (build_graph, pipeline) if mutate_parent else (pipeline, build_graph)
|
||||
successors = {node: set(protected[node]) for node in protected}
|
||||
predecessors = {node: set(protected.reverse[node]) for node in protected.reverse}
|
||||
|
||||
match mutation:
|
||||
case "add":
|
||||
changed["package"].add("publish")
|
||||
case "remove":
|
||||
changed["compile"].discard("package")
|
||||
case "reverse-remove":
|
||||
changed.reverse["compile"].discard("checkout")
|
||||
case "discard-node":
|
||||
changed.discard_node("compile")
|
||||
|
||||
assert {node: set(protected[node]) for node in protected} == successors
|
||||
assert {node: set(protected.reverse[node]) for node in protected.reverse} == predecessors
|
||||
for graph in (changed, protected):
|
||||
forward_edges = {(source, target) for source in graph for target in graph[source]}
|
||||
reverse_edges = {(source, target) for target in graph.reverse for source in graph.reverse[target]}
|
||||
assert forward_edges == reverse_edges
|
||||
Reference in New Issue
Block a user