Ejemplo n.º 1
0
async def test_query_aggregate(filled_graph_db: ArangoGraphDB,
                               foo_model: Model) -> None:
    agg_query = parse_query(
        "aggregate(kind: count(identifier) as instances): is(foo)").on_section(
            "reported")
    async with await filled_graph_db.search_aggregation(
            QueryModel(agg_query, foo_model)) as gen:
        assert [x async for x in gen] == [{
            "group": {
                "kind": "foo"
            },
            "instances": 11
        }]

    agg_combined_var_query = parse_query(
        'aggregate("test_{kind}_{some_int}_{does_not_exist}" as kind: count(identifier) as instances): is("foo")'
    ).on_section("reported")

    async with await filled_graph_db.search_aggregation(
            QueryModel(agg_combined_var_query, foo_model)) as g:
        assert [x async for x in g] == [{
            "group": {
                "kind": "test_foo_0_"
            },
            "instances": 11
        }]

    agg_multi_fn_same_prop = parse_query(
        'aggregate(sum(f) as a, max(f) as b): is("bla")').on_section(
            "reported")
    async with await filled_graph_db.search_aggregation(
            QueryModel(agg_multi_fn_same_prop, foo_model)) as g:
        assert [x async for x in g] == [{"a": 2300, "b": 23}]
Ejemplo n.º 2
0
async def test_query_list(filled_graph_db: ArangoGraphDB,
                          foo_model: Model) -> None:
    blas = Query.by("foo",
                    P("identifier") == "9").traverse_out().filter(
                        "bla",
                        P("f") == 23)
    async with await filled_graph_db.search_list(
            QueryModel(blas.on_section("reported"), foo_model)) as gen:
        result = [from_js(x["reported"], Bla) async for x in gen]
        assert len(result) == 10

    foos_or_blas = parse_query("is([foo, bla])")
    async with await filled_graph_db.search_list(
            QueryModel(foos_or_blas.on_section("reported"), foo_model)) as gen:
        result = [x async for x in gen]
        assert len(result) == 111  # 113 minus 1 graph_root, minus one cloud
Ejemplo n.º 3
0
def test_ancestors_kind_lookup(foo_model: Model, graph_db: GraphDB) -> None:
    # 1234 is coerced to a string
    query = "ancestors.account.reported.name==1234"
    assert to_query(graph_db, QueryModel(parse_query(query),
                                         foo_model))[1] == {
                                             "b0": "1234"
                                         }
Ejemplo n.º 4
0
async def test_query_not(filled_graph_db: ArangoGraphDB,
                         foo_model: Model) -> None:
    # select everything that is not foo --> should be blas
    blas = Query.by(Query.mk_term("foo").not_term())
    async with await filled_graph_db.search_list(
            QueryModel(blas.on_section("reported"), foo_model)) as gen:
        result = [from_js(x["reported"], Bla) async for x in gen]
        assert len(result) == 102
Ejemplo n.º 5
0
async def load_graph(db: GraphDB,
                     model: Model,
                     base_id: str = "sub_root") -> MultiDiGraph:
    blas = Query.by("foo",
                    P("identifier") == base_id).traverse_out(
                        0, Navigation.Max)
    return await db.search_graph(QueryModel(blas.on_section("reported"),
                                            model))
def test_ip_range() -> None:
    bind_vars: Json = {}
    model = QueryModel(
        Query.by(IsTerm(["foo"])).on_section("reported"), Model.empty())
    result = in_subnet(
        "crs", bind_vars,
        FunctionTerm("in_subnet", "foo.bla", ["192.168.1.0/24"]), model)
    assert result == "BIT_AND(IPV4_TO_NUMBER(crs.foo.bla), 4294967040) == @0"
    assert bind_vars["0"] == 3232235776
Ejemplo n.º 7
0
 async def graph_query_model_from_request(
         self, request: Request) -> Tuple[GraphDB, QueryModel]:
     section = section_of(request)
     query_string = await request.text()
     graph_db = self.db.get_graph_db(
         request.match_info.get("graph_id", "resoto"))
     q = await self.query_parser.parse_query(query_string, section,
                                             **request.query)
     m = await self.model_handler.load_model()
     return graph_db, QueryModel(q, m)
def test_has_key() -> None:
    bind_vars: Json = {}
    model = QueryModel(Query.by("foo"), Model.empty())
    result = has_key("crs", bind_vars,
                     FunctionTerm("has_key", "foo.bla", [["a", "b", "c"]]),
                     model)
    assert result == "@fn0 ALL IN ATTRIBUTES(crs.foo.bla, true)"
    assert bind_vars["fn0"] == ["a", "b", "c"]
    bind_vars2: Json = {}
    result = has_key("crs", bind_vars2,
                     FunctionTerm("has_key", "foo.bla", ["a"]), model)
    assert result == "HAS(crs.foo.bla, @fn0)"
    assert bind_vars2["fn0"] == "a"
Ejemplo n.º 9
0
async def test_no_null_if_undefined(graph_db: ArangoGraphDB,
                                    foo_model: Model) -> None:
    await graph_db.wipe()
    # imported graph should not have any desired or metadata sections
    graph = create_graph("test", 0)
    for _, node in graph.nodes(True):
        del node["desired"]
        del node["metadata"]
    await graph_db.merge_graph(graph, foo_model)
    async with await graph_db.search_list(
            QueryModel(parse_query("all"), foo_model)) as cursor:
        async for elem in cursor:
            assert "reported" in elem
            assert "desired" not in elem
            assert "metadata" not in elem
Ejemplo n.º 10
0
async def test_query_graph(filled_graph_db: ArangoGraphDB,
                           foo_model: Model) -> None:
    graph = await load_graph(filled_graph_db, foo_model)
    assert len(graph.edges) == 110
    assert len(graph.nodes.values()) == 111

    # filter data and tag result, and then traverse to the end of the graph in both directions
    around_me = Query.by(
        "foo",
        P("identifier") == "9").tag("red").traverse_inout(start=0)
    graph = await filled_graph_db.search_graph(
        QueryModel(around_me.on_section("reported"), foo_model))
    assert len({x for x in graph.nodes}) == 12
    assert GraphAccess.root_id(graph) == "sub_root"
    assert list(graph.successors("sub_root"))[0] == "9"
    assert set(graph.successors("9")) == {f"9_{x}" for x in range(0, 10)}
    for from_node, to_node, data in graph.edges.data(True):
        assert from_node == "9" or to_node == "9"
        assert data == {"edge_type": "default"}

    for node_id, node in graph.nodes.data(True):
        if node_id == "9":
            assert node["metadata"]["query_tag"] == "red"
        else:
            assert "tag" not in node["metadata"]

    async def assert_result(query: str, nodes: int, edges: int) -> None:
        q = parse_query(query)
        graph = await filled_graph_db.search_graph(QueryModel(q, foo_model))
        assert len(graph.nodes) == nodes
        assert len(graph.edges) == edges

    await assert_result(
        "is(foo) and reported.identifier==9 <-delete[0:]default->", 11, 20)
    await assert_result(
        "is(foo) and reported.identifier==9 <-default[0:]delete->", 4, 3)
    await assert_result("is(foo) and reported.identifier==9 <-default[0:]->",
                        14, 13)
    await assert_result("is(foo) and reported.identifier==9 <-delete[0:]->",
                        11, 10)
    await assert_result("is(foo) and reported.identifier==9 -default[0:]->",
                        11, 10)
    await assert_result("is(foo) and reported.identifier==9 <-delete[0:]-", 11,
                        10)
    await assert_result("is(foo) and reported.identifier==9 <-default[0:]-", 4,
                        3)
    await assert_result("is(foo) and reported.identifier==9 -delete[0:]->", 1,
                        0)
Ejemplo n.º 11
0
async def test_query_merge(filled_graph_db: ArangoGraphDB,
                           foo_model: Model) -> None:
    q = parse_query("is(foo) --> is(bla) { "
                    "foo.bar.parents[]: <-[1:]-, "
                    "foo.child: -->, "
                    "walk: <-- -->, "
                    "bla.agg: aggregate(sum(1) as count): <-[0:]- "
                    "}")
    async with await filled_graph_db.search_list(QueryModel(q, foo_model),
                                                 with_count=True) as cursor:
        assert cursor.count() == 100
        async for bla in cursor:
            b = AccessJson(bla)
            assert b.reported.kind == "bla"
            assert len(b.foo.bar.parents) == 4
            for parent in b.foo.bar.parents:
                assert parent.reported.kind in ["foo", "cloud", "graph_root"]
            assert b.walk.reported.kind == "bla"
            assert b.foo.child == AccessNone()
            assert b.bla.agg == [{"count": 5}]
Ejemplo n.º 12
0
async def test_query_with_merge(filled_graph_db: ArangoGraphDB,
                                foo_model: Model) -> None:
    query = parse_query(
        '(merge_with_ancestors="foo as foobar,bar"): is("bla")')
    async with await filled_graph_db.search_list(QueryModel(query, foo_model)
                                                 ) as cursor:
        async for bla in cursor:
            js = AccessJson(bla)
            assert "bar" in js.reported  # key exists
            assert "bar" in js.desired  # key exists
            assert "bar" in js.metadata  # key exists
            assert js.reported.bar.is_none  # bla is not a parent of this node
            assert js.desired.bar.is_none  # bla is not a parent of this node
            assert js.metadata.bar.is_none  # bla is not a parent of this node
            assert js.reported.foobar is not None  # foobar is merged into reported
            assert js.desired.foobar is not None  # foobar is merged into reported
            assert js.metadata.foobar is not None  # foobar is merged into reported
            # make sure the correct parent is merged (foobar(1) -> bla(1_xxx))
            assert js.reported.identifier.startswith(
                js.reported.foobar.identifier)
            assert js.reported.identifier.startswith(js.desired.foobar.node_id)
            assert js.reported.identifier.startswith(
                js.metadata.foobar.node_id)
Ejemplo n.º 13
0
 async def query(q: str) -> List[Json]:
     agg_query = parse_query(q)
     async with await filled_graph_db.search_list(
             QueryModel(agg_query.on_section("reported"),
                        foo_model)) as cursor:
         return [bla async for bla in cursor]
Ejemplo n.º 14
0
 async def search(query: str) -> List[JsonElement]:
     async with await filled_graph_db.search_list(
             QueryModel(parse_query(query), foo_model)) as cursor:
         return [elem async for elem in cursor]
Ejemplo n.º 15
0
 def check_sort_in_query(q: Query, expected_sort: str) -> None:
     query_str, _ = to_query(graph_db, QueryModel(q, foo_model))
     assert f"SORT {expected_sort}" in query_str, f"Expected {expected_sort} in {query_str}"
Ejemplo n.º 16
0
 async def assert_result(query: str, nodes: int, edges: int) -> None:
     q = parse_query(query)
     graph = await filled_graph_db.search_graph(QueryModel(q, foo_model))
     assert len(graph.nodes) == nodes
     assert len(graph.edges) == edges
Ejemplo n.º 17
0
 async def cost(query_str: str) -> EstimatedSearchCost:
     query = parse_query(query_str)
     return await query_cost(graph_db, QueryModel(query, foo_model), False)
Ejemplo n.º 18
0
 def query_string(query: str) -> str:
     query_str, _ = to_query(graph_db,
                             QueryModel(parse_query(query), foo_model))
     return query_str
Ejemplo n.º 19
0
def test_escape_property_path(foo_model: Model, graph_db: GraphDB) -> None:
    raw = "metadata.replace.with.filter.sort.bla==true"
    query = to_query(graph_db, QueryModel(parse_query(raw), foo_model))[0]
    # aql keywords are escaped with backslashes
    assert "m0.metadata.`replace`.`with`.`filter`.`sort`.bla" in query