def test_weird_chars_in_lens_name(self, lens_name: str) -> None:
     """
     Roundabout way to ensure some basic properties of filter generation.
     """
     client = GraphClient()
     lens = LensView.get_or_create(
         gclient=client,
         lens_name=lens_name,
         lens_type="engagement",
     )
     requery_lens = LensQuery().with_lens_name(lens_name).query_first(
         client)
     assert requery_lens.get_lens_name() == lens_name
Exemple #2
0
def test_expected_data_in_dgraph(actix_session: str) -> None:
    # There is some unidentified, nondeterministic failure with e2e.
    # We fall into one of three buckets:
    # - No lens
    # - Lens with 3 scope
    # - Lens with 4 scope
    # - Lens with 5 scope (correct)
    query = LensQuery().with_lens_name(LENS_NAME)
    lens: LensView = wait_for_one(WaitForQuery(query),
                                  timeout_secs=TIMEOUT_SECS)
    assert lens.get_lens_name() == LENS_NAME

    # lens scope is not atomic

    def scope_has_N_items() -> bool:
        length = len(lens.get_scope())
        logging.info(f"Expected 3+ nodes in scope, currently is {length}")
        # This number can change and, rather than trying to hammer it down, we're going
        # with a lower bound
        return length >= 3

    wait_for_one(WaitForCondition(scope_has_N_items),
                 timeout_secs=TIMEOUT_SECS)

    # Now that we've confirmed that the expected data has shown up in dgraph,
    # let's see what the GraphQL endpoint says.
    # TODO: Consider using `pytest-order` to make this a separate test that
    # depends on the above test having been run.

    gql_client = GraphqlEndpointClient(actix_session=actix_session)
    wait_for_one(
        WaitForNoException(lambda: ensure_graphql_lens_scope_no_errors(
            gql_client, LENS_NAME)),
        timeout_secs=TIMEOUT_SECS,
    )
Exemple #3
0
def lens_to_dict(dgraph_client: DgraphClient,
                 lens_name: str) -> List[Dict[str, Any]]:
    current_graph = get_lens_scope(dgraph_client, lens_name)
    LOGGER.info(f"Getting lens as dict {current_graph}")
    if not current_graph or not current_graph.get("scope"):
        return []
    nodes = []
    for graph in current_graph["scope"]:
        try:
            nodes.append(BaseView.from_dict(dgraph_client, graph))
        except Exception as e:
            LOGGER.error("Failed to get NodeView from dict", e)
    if current_graph.get("scope"):
        current_graph.pop("scope")

    for node in nodes:
        node.expand()
        node.get_neighbor(
            EntityQuery,
            "expand(_all_)",
            "",
            EntityQuery().with_lenses(
                LensQuery().with_lens_name(eq=lens_name)),
        )

    results = [{"node": current_graph, "edges": []}]

    lens_risks = get_lens_risks(dgraph_client, lens_name)
    for node in lens_risks:
        edges = []
        risks = node.get("risks", [])
        if not risks:
            LOGGER.warning(
                f"Node in engagement graph has no connected risks {node}")
        for risk in risks:
            try:
                risk["node_key"] = node["node_key"] + risk["analyzer_name"]
                edge = {
                    "from": node["node_key"],
                    "edge_name": "risks",
                    "to": risk["node_key"],
                }
                edges.append(edge)
            except Exception as e:
                LOGGER.error(f"risk edge failed: {risk} {e}")

        results.append({
            "node": node,
            "edges": edges,
        })

    results.extend([n.to_dict() for n in concrete_nodes])
    results.extend(expanded_dynamic_nodes)
    return results
Exemple #4
0
    def test_expected_data_in_dgraph(self) -> None:
        query = LensQuery().with_lens_name(LENS_NAME)
        lens: LensView = wait_for_one(WaitForQuery(query), timeout_secs=120)
        assert lens.get_lens_name() == LENS_NAME

        # lens scope is not atomic
        def condition() -> bool:
            length = len(lens.get_scope())
            logging.info(f"Expected 4 nodes in scope, currently is {length}")
            return length == 4

        wait_for_one(WaitForCondition(condition), timeout_secs=240)
Exemple #5
0
 def with_lenses(self, *lenses: "LensQuery"):
     lenses = lenses or [LensQuery()]
     self.set_neighbor_filters("in_scope", [lenses])
     for lens in lenses:
         lens.set_neighbor_filters("scope", [self])
     return self
Exemple #6
0
def wait_for_lens():
    local_client = MasterGraphClient()
    query = LensQuery().with_lens_name(LENS_NAME)
    return WaitForLens(local_client, query)