Ejemplo n.º 1
0
def test_query() -> None:
    query = (Query.by(
        "ec2",
        P("cpu") > 4, (P("mem") < 23) | (P("mem") < 59)).merge_with(
            "cloud", Navigation(1, Navigation.Max,
                                direction=Direction.inbound),
            Query.mk_term("cloud")).traverse_out().filter(
                P("some.int.value") < 1,
                P("some.other") == 23).traverse_out().filter(
                    P("active") == 12,
                    P.function("in_subnet").on(
                        "ip", "1.2.3.4/96")).filter_with(
                            WithClause(WithClauseFilter(
                                "==", 0), Navigation())).group_by([
                                    AggregateVariable(
                                        AggregateVariableName("foo"))
                                ], [AggregateFunction("sum", "cpu")]).add_sort(
                                    Sort("test", "asc")).with_limit(10))
    assert str(query) == (
        'aggregate(foo: sum(cpu)):((is("ec2") and cpu > 4) and (mem < 23 or mem < 59)) '
        '{cloud: all <-default[1:]- is("cloud")} -default-> '
        "(some.int.value < 1 and some.other == 23) -default-> "
        '(active == 12 and in_subnet(ip, "1.2.3.4/96")) '
        "with(empty, -default->) sort test asc limit 10")
    assert_round_trip(query_parser, query)
Ejemplo n.º 2
0
def test_navigation() -> None:
    for edge_type in EdgeType.all:
        # the default edge type is not rendered, so we set it explicitly to make the mapping homogeneous
        for start, until in [(0, 0), (1, 1), (5, 5), (1, 10),
                             (1, Navigation.Max), (10, Navigation.Max)]:
            assert_round_trip(
                navigation_parser,
                Navigation(start, until, [edge_type], Direction.any,
                           [edge_type]))
            for direction in Direction.all:
                assert_round_trip(
                    navigation_parser,
                    Navigation(start, until, [edge_type], direction))
Ejemplo n.º 3
0
def test_merge_query_creation() -> None:
    inbound = Navigation(1, Navigation.Max, direction=Direction.inbound)
    for_foo = Query(
        [Part(IsTerm(["foo"])),
         Part(AllTerm(), navigation=inbound)])
    merge_foo = [MergeQuery("ancestors.foo", for_foo)]

    # merge_foo is created automatically
    assert Part(AllTerm()).merge_queries_for(["ancestors.foo.reported.bla"
                                              ]) == merge_foo
    # merge_foo is already included and not added
    assert Part(MergeTerm(AllTerm(), merge_foo)).merge_queries_for(
        ["ancestors.foo.reported.bla"]) == merge_foo
    # neither ancestors/descendants
    with pytest.raises(Exception):
        Part(AllTerm()).merge_queries_for(["unknown.foo.reported.bla"])
    # no path is given
    with pytest.raises(Exception):
        Part(AllTerm()).merge_queries_for(["ancestors.foo"])

    # rewrite for ancestors/descendants also work with additional properties
    assert (str(
        Query.by("test").rewrite_for_ancestors_descendants([
            "ancestors.kind.reported.prop", "test", "a"
        ])) == 'is("test") {ancestors.kind: all <-default[1:]- is("kind")}')
    assert (
        str(
            Query.by("test").merge_with(
                "ancestors.cloud", NavigateUntilRoot,
                IsTerm(["cloud"])).rewrite_for_ancestors_descendants(
                    ["ancestors.kind.reported.prop", "test", "a"])) ==
        'is("test") {ancestors.kind: all <-default[1:]- is("kind"), ancestors.cloud: all <-default[1:]- is("cloud")}'
    )
Ejemplo n.º 4
0
def navigation(ud: UD) -> Navigation:
    d = Drawer(ud)
    start = d.draw(integers(min_value=0, max_value=1))
    length = d.draw(integers(min_value=0, max_value=100))
    ed = d.draw(edge_type)
    direction = d.draw(edge_direction)
    return Navigation(start, length + start, [ed], direction)
Ejemplo n.º 5
0
def test_part() -> None:
    assert_round_trip(part_parser, Part(P.of_kind("test")))
    assert_round_trip(
        part_parser,
        Part(P.of_kind("test"),
             navigation=Navigation(1, 10, [EdgeType.delete])))
    assert_round_trip(
        part_parser,
        Part(P.of_kind("test"),
             "red",
             navigation=Navigation(1, 10, [EdgeType.delete])))
    with_clause = WithClause(WithClauseFilter("==", 0),
                             Navigation(maybe_edge_types=[EdgeType.delete]))
    assert_round_trip(
        part_parser,
        Part(P.of_kind("test"),
             "green",
             with_clause,
             navigation=Navigation(1, 10, [EdgeType.delete])))
Ejemplo n.º 6
0
def test_with_clause() -> None:
    predicate_term.parse("foo == bla")
    wc: WithClause = with_clause_parser.parse(
        "with(empty, -delete-> foo == bla and test > 23 with(any, -delete->))")
    assert wc.with_filter == WithClauseFilter("==", 0)
    assert wc.navigation == Navigation(maybe_edge_types=["delete"])
    assert str(wc.term) == '(foo == "bla" and test > 23)'
    assert str(wc.with_clause) == "with(any, -delete->)"
    term = Query.mk_term("foo", P("test") == 23)
    clause_filter = WithClauseFilter(">", 23)
    nav = Navigation()

    def edge(wc: WithClause) -> WithClause:
        wcr = replace(wc, with_clause=edge(
            wc.with_clause)) if wc.with_clause else wc
        return replace(wcr,
                       navigation=replace(wcr.navigation,
                                          maybe_edge_types=[EdgeType.default]))

    assert_round_trip(
        with_clause_parser,
        WithClause(clause_filter, nav, term, WithClause(clause_filter, nav)),
        edge)
    assert_round_trip(with_clause_parser, WithClause(clause_filter, nav), edge)
Ejemplo n.º 7
0
def test_query() -> None:
    query = (Query.by(
        "ec2",
        P("cpu") > 4, (P("mem") < 23) | (P("mem") < 59),
        preamble={
            "merge_with_ancestors": "cloud"
        }).traverse_out().filter(
            P("some.int.value") < 1,
            P("some.other") == 23).traverse_out().filter(
                P("active") == 12,
                P.function("in_subnet").on("ip", "1.2.3.4/96")).filter_with(
                    WithClause(WithClauseFilter(
                        "==", 0), Navigation())).group_by(
                            [AggregateVariable(AggregateVariableName("foo"))],
                            [AggregateFunction("sum", "cpu")]).add_sort(
                                "test", "asc").with_limit(10))
    assert (
        str(query) == 'aggregate(foo: sum(cpu))(merge_with_ancestors="cloud"):'
        + '((is("ec2") and cpu > 4) and (mem < 23 or mem < 59)) -default-> ' +
        "(some.int.value < 1 and some.other == 23) -default-> " +
        '(active == 12 and in_subnet(ip, "1.2.3.4/96")) ' +
        "with(empty, -default->) sort test asc limit 10")
    assert_round_trip(query_parser, query)
Ejemplo n.º 8
0
    if edge_types and after_bracket_edge_types:
        raise AttributeError("Edge types can not be defined before and after the [start,until] definition.")
    return start, until, edge_types or after_bracket_edge_types


@make_parser
def two_directional_edge_definition_parser() -> Parser:
    edge_types = yield edge_type_parser
    maybe_range = yield range_parser.optional()
    outbound_edge_types = yield edge_type_parser
    start, until = maybe_range if maybe_range else (1, 1)
    return start, until, edge_types, outbound_edge_types


out_p = lexeme(string("-") >> edge_definition_parser << string("->")).map(
    lambda nav: Navigation(nav[0], nav[1], nav[2], Direction.outbound)
)
in_p = lexeme(string("<-") >> edge_definition_parser << string("-")).map(
    lambda nav: Navigation(nav[0], nav[1], nav[2], Direction.inbound)
)
in_out_p = lexeme(string("<-") >> two_directional_edge_definition_parser << string("->")).map(
    lambda nav: Navigation(nav[0], nav[1], nav[2], Direction.any, nav[3])
)
navigation_parser = in_out_p | out_p | in_p

tag_parser = lexeme(string("#") >> literal_p).optional()
with_p = lexeme(string("with"))
count_p = lexeme(string("count"))

len_empty = lexeme(string("empty")).result(WithClauseFilter("==", 0))
len_any = lexeme(string("any")).result(WithClauseFilter(">", 0))
Ejemplo n.º 9
0
def test_navigation_default() -> None:
    assert str(Navigation(1, 1)) == "-default->"
    assert str(Navigation(1, Navigation.Max)) == "-default[1:]->"