Esempio n. 1
0
def test_content_hash() -> None:
    # the order of properties should not matter for the content hash
    g = MultiDiGraph()
    g.add_node("1", reported={"a": {"a": 1, "c": 2, "b": 3}, "c": 2, "b": 3, "d": "foo", "z": True, "kind": "a"})
    g.add_node("2", reported={"z": True, "c": 2, "b": 3, "a": {"b": 3, "c": 2, "a": 1}, "d": "foo", "kind": "a"})

    access = GraphAccess(g)
    sha1 = node(access, "1")["hash"]  # type: ignore
    sha2 = node(access, "2")["hash"]  # type: ignore
    assert sha1 == sha2
Esempio n. 2
0
def test_reassign_root(person_model: Model) -> None:
    max_m = {"id": "max", "kind": "Person", "name": "Max"}
    builder = GraphBuilder(person_model)
    builder.add_from_json({"id": "should_be_root", "reported": {"kind": "graph_root"}})
    builder.add_from_json({"id": "2", "reported": max_m})
    builder.add_from_json({"id": "3", "reported": max_m})
    builder.add_from_json({"from": "should_be_root", "to": "2"})
    builder.add_from_json({"from": "should_be_root", "to": "3"})
    builder.check_complete()
    access = GraphAccess(builder.graph)
    assert access.root() == "root"
    assert set(access.successors("root", EdgeType.default)) == {"2", "3"}
Esempio n. 3
0
def test_access_node() -> None:
    g = MultiDiGraph()
    g.add_node("1", reported=to_json(FooTuple(a="1")))
    access: GraphAccess = GraphAccess(g)
    elem: Json = node(access, "1")  # type: ignore
    assert elem["hash"] == "153c1a5c002f6213a95383f33b63aa18b8ed6939f57418fb0f27312576f0cea4"
    assert elem["reported"] == {
        "a": "1",
        "b": 0,
        "c": [],
        "d": "foo",
        "e": {"a": 12, "b": 32},
        "f": "2021-03-29",
        "g": 1.234567,
        "kind": "foo",
    }
    assert access.node("2") is None
Esempio n. 4
0
def test_ancestor_of() -> None:
    nid1 = "child_parent_region_account_cloud_gcp_1_europe_1_0"
    acc1 = "account_cloud_gcp_1"
    acc2 = "account_cloud_gcp_2"
    g = multi_cloud_graph("account")

    graph = GraphAccess(g)
    assert graph.ancestor_of(nid1, EdgeType.default, "root") is not None
    assert graph.ancestor_of(nid1, EdgeType.delete, "root") is None
    assert graph.ancestor_of(nid1, EdgeType.default, "foo") is None
    assert graph.ancestor_of(nid1, EdgeType.default, "foo") is None
    assert graph.ancestor_of(nid1, EdgeType.default, "account")["id"] == acc1  # type: ignore

    # add another "shorter" edge from acc2 -> nid1, so it is shorter that from acc1 -> nid1
    key = GraphAccess.edge_key(acc2, nid1, EdgeType.default)
    g.add_edge(acc2, nid1, key, edge_type=EdgeType.default)
    assert graph.ancestor_of(nid1, EdgeType.default, "account")["id"] == acc2  # type: ignore
Esempio n. 5
0
def test_predecessors() -> None:
    graph = GraphAccess(multi_cloud_graph("account"))
    child = "child_parent_region_account_cloud_gcp_2_europe_1_0"
    parent = "parent_region_account_cloud_gcp_2_europe_1"
    region = "region_account_cloud_gcp_2_europe"

    # default: region -> parent -> child
    assert list(graph.predecessors(child, EdgeType.default)) == [parent]
    assert list(graph.predecessors(parent, EdgeType.default)) == [region]
    assert child in list(graph.successors(parent, EdgeType.default))
    assert parent in list(graph.successors(region, EdgeType.default))

    # delete: child -> parent -> region
    assert list(graph.successors(child, EdgeType.delete)) == [parent]
    assert list(graph.successors(parent, EdgeType.delete)) == [region]
    assert parent in list(graph.successors(child, EdgeType.delete))
    assert region in list(graph.successors(parent, EdgeType.delete))
Esempio n. 6
0
def graph_access() -> GraphAccess:
    g = MultiDiGraph()

    def add_edge(from_node: str, to_node: str, edge_type: str) -> None:
        key = GraphAccess.edge_key(from_node, to_node, edge_type)
        g.add_edge(from_node, to_node, key, edge_type=edge_type)

    g.add_node("1", reported=to_json(FooTuple("1")), desired={"name": "a"}, metadata={"version": 1}, kinds=["foo"])
    g.add_node("2", reported=to_json(FooTuple("2")), desired={"name": "b"}, metadata={"version": 2}, kinds=["foo"])
    g.add_node("3", reported=to_json(FooTuple("3")), desired={"name": "c"}, metadata={"version": 3}, kinds=["foo"])
    g.add_node("4", reported=to_json(FooTuple("4")), desired={"name": "d"}, metadata={"version": 4}, kinds=["foo"])
    add_edge("1", "2", edge_type=EdgeType.default)
    add_edge("1", "3", edge_type=EdgeType.default)
    add_edge("2", "3", edge_type=EdgeType.default)
    add_edge("2", "4", edge_type=EdgeType.default)
    add_edge("3", "4", edge_type=EdgeType.default)
    add_edge("1", "2", edge_type=EdgeType.delete)
    add_edge("1", "3", edge_type=EdgeType.delete)
    add_edge("1", "4", edge_type=EdgeType.delete)
    return GraphAccess(g)
Esempio n. 7
0
def test_resolve_graph_data() -> None:
    g = multi_cloud_graph("account")
    graph = GraphAccess(g)
    graph.resolve()

    # ancestor data should be stored in metadata
    n1 = AccessJson(graph.node("child_parent_region_account_cloud_gcp_1_europe_1_0"))  # type: ignore
    assert n1.refs.region_id == "region_account_cloud_gcp_1_europe"
    assert n1.ancestors.account.reported.id == "id_account_cloud_gcp_1"
    assert n1.ancestors.account.reported.name == "name_account_cloud_gcp_1"
    assert n1.ancestors.region.reported.id == "id_region_account_cloud_gcp_1_europe"
    assert n1.ancestors.region.reported.name == "name_region_account_cloud_gcp_1_europe"
    # make sure there is no summary
    assert n1.descendant_summary == AccessNone(None)

    r1 = AccessJson(graph.node("region_account_cloud_gcp_1_europe"))  # type: ignore
    assert r1.metadata.descendant_summary == {"child": 9}
    assert r1.metadata.descendant_count == 9
    r2 = AccessJson(graph.node("account_cloud_gcp_1"))  # type: ignore
    assert r2.metadata.descendant_summary == {"child": 54, "region": 6}
    assert r2.metadata.descendant_count == 60
    r3 = AccessJson(graph.node("cloud_gcp"))  # type: ignore
    assert r3.metadata.descendant_summary == {"child": 162, "region": 18, "account": 3}
    assert r3.metadata.descendant_count == 183
Esempio n. 8
0
def test_acyclic() -> None:
    assert GraphAccess(cyclic_multi_graph(acyclic=False)).is_acyclic_per_edge_type() is False
    assert GraphAccess(cyclic_multi_graph(acyclic=True)).is_acyclic_per_edge_type() is True