Пример #1
0
    def testLetSubexprEach(self):
        query = "each Process/children matches Process/command is 'foo'"
        expected = expression.LetEach(
            expression.Binding("Process/children"),
            expression.Equivalence(expression.Binding("Process/command"),
                                   expression.Literal("foo")))

        self.assertQueryMatches(query, expected)
Пример #2
0
    def testLetSingleAny(self):
        query = "any Process/parent->Process/command is 'init'"
        expected = expression.LetAny(
            expression.Binding("Process/parent"),
            expression.Equivalence(expression.Binding("Process/command"),
                                   expression.Literal("init")))

        self.assertQueryMatches(query, expected)
Пример #3
0
    def testTemplateReplacements(self):
        query = "Process/pid == {}"
        params = [1]
        exptected = expression.Equivalence(expression.Binding("Process/pid"),
                                           expression.Literal(1))
        self.assertQueryMatches(query, exptected, params=params)

        query = "Process/pid == {pid}"
        params = {"pid": 1}
        exptected = expression.Equivalence(expression.Binding("Process/pid"),
                                           expression.Literal(1))
        self.assertQueryMatches(query, exptected, params=params)
Пример #4
0
    def testLetSubexpr(self):
        query = ("Process/parent matches (Process/command is 'init' and "
                 "Process/pid is 1)")
        expected = expression.Let(
            expression.Binding("Process/parent"),
            expression.Intersection(
                expression.Equivalence(expression.Binding("Process/command"),
                                       expression.Literal("init")),
                expression.Equivalence(expression.Binding("Process/pid"),
                                       expression.Literal(1))))

        self.assertQueryMatches(query, expected)
Пример #5
0
    def testBigQuery(self):
        query = ("(Process/pid is 1 and Process/command in ('init', 'initd')) "
                 "or any Process/children matches (Process/command not in "
                 "('launchd', 'foo'))")
        expected = expression.Union(
            expression.Intersection(
                expression.Equivalence(expression.Binding("Process/pid"),
                                       expression.Literal(1)),
                expression.Membership(expression.Binding("Process/command"),
                                      expression.Literal(("init", "initd")))),
            expression.LetAny(
                expression.Binding("Process/children"),
                expression.Complement(
                    expression.Membership(
                        expression.Binding("Process/command"),
                        expression.Literal(("launchd", "foo"))))))

        self.assertQueryMatches(query, expected)
Пример #6
0
 def testPrecedence(self):
     query = "5 == 1 * 5 and Process/name is 'init'"
     expected = expression.Intersection(
         expression.Equivalence(
             expression.Literal(5),
             expression.Product(expression.Literal(1),
                                expression.Literal(5))),
         expression.Equivalence(expression.Binding("Process/name"),
                                expression.Literal("init")))
     self.assertQueryMatches(query, expected)
Пример #7
0
    def as_query(self):
        """A query that'll match entities with this identity."""
        union = []
        for _, keys, vals in self.indices:
            if isinstance(keys, tuple):
                intersection = []
                for idx, key in enumerate(keys):
                    intersection.append(
                        expression.Equivalence(expression.Binding(key),
                                               expression.Literal(vals[idx])))

                union.append(expression.Intersection(*intersection))
            else:
                union.append(
                    expression.Equivalence(expression.Binding(keys),
                                           expression.Literal(vals)))

        if len(union) == 1:
            return union[0]

        return expression.Union(*union)
Пример #8
0
    def render(self, renderer):
        renderer.table_header([("User", "user", "15"),
                               ("Session", "session", "15"),
                               ("Terminal vnode", "vnode", "30"),
                               ("Recovered input", "input", "75"),
                               ("Recovered output", "output", "75")])

        for terminal in self.session.entities.find("has component Terminal"):

            buffer_in = self.session.entities.find_first(
                expression.Intersection(
                    expression.Equivalence(
                        expression.Binding("Buffer/purpose"),
                        expression.Literal("terminal_input")),
                    expression.Equivalence(
                        expression.Binding("Buffer/context"),
                        expression.Literal(terminal.identity))))

            buffer_out = self.session.entities.find_first(
                expression.Intersection(
                    expression.Equivalence(
                        expression.Binding("Buffer/purpose"),
                        expression.Literal("terminal_output")),
                    expression.Equivalence(
                        expression.Binding("Buffer/context"),
                        expression.Literal(terminal.identity))))

            renderer.table_row(
                terminal["Terminal/session"]["Session/user"]["User/username"],
                terminal["Terminal/session"]["Session/sid"],
                terminal.get("Terminal/file", complete=True)["File/path"],
                repr(
                    self.SHORTENER.sub("<whitespace>",
                                       buffer_in["Buffer/contents"])),
                repr(
                    self.SHORTENER.sub("<whitespace>",
                                       buffer_out["Buffer/contents"])))
Пример #9
0
 def testNestedParens(self):
     query = "Process/pid in ((1,2))"
     expected = expression.Membership(expression.Binding("Process/pid"),
                                      expression.Literal((1, 2)))
     self.assertQueryMatches(query, expected)
Пример #10
0
    def next_atom(self):
        token = self.tokenizer.next_token()

        if token is None:
            return self.error("Unexpected end of input.")

        if token.name == "infix":
            if token.value == "-":
                # As it turns out, minus signs can be prefix operators! Who
                # knew? Certainly not the tokenizer.
                token.name = "prefix"
            else:
                return self.error("Unexpected infix operator.", token)

        if token.name == "prefix":
            operator = PREFIX[token.value]
            lhs = self.next_atom()
            rhs = self.next_expression(lhs, operator.precedence)
            return self._handle_expr(operator,
                                     rhs,
                                     start=token.start,
                                     end=rhs.end)

        if token.name == "literal":
            return expression.Literal(token.value,
                                      start=token.start,
                                      end=token.end)

        if token.name == "param":
            return expression.Literal(self._replace_param(token),
                                      start=token.start,
                                      end=token.end)

        if token.name == "symbol":
            return expression.Binding(token.value,
                                      start=token.start,
                                      end=token.end)

        if token.name == "lparen":
            # Parentheses can denote subexpressions or lists. Lists have at
            # least one comma before rparen (just like Python).
            lhs = self.next_atom()
            expr = self.next_expression(lhs, 0)
            if self.tokenizer.current_token is None:
                return self.error("End of input before closing parenthesis.",
                                  token)

            if self.tokenizer.peek().name == "comma":
                # It's a list, not an expression. Build it out as a literal.
                if not isinstance(lhs, expression.Literal):
                    return self.error("Non-literal value in list.", lhs)

                self.tokenizer.next_token()
                vals = [lhs.value]

                while (self.tokenizer.current_token
                       and self.tokenizer.current_token.name == "comma"):
                    atom = self.next_atom()
                    if not isinstance(atom, expression.Literal):
                        return self.error("Non-literal value in list", atom)
                    vals.append(atom.value)
                    self.tokenizer.next_token()

                if (self.tokenizer.current_token is None
                        or self.tokenizer.current_token.name != "rparen"):
                    self.error("Lists must end with a closing paren.",
                               self.tokenizer.current_token)

                return expression.Literal(tuple(vals),
                                          start=token.start,
                                          end=self.tokenizer.position)

            elif self.tokenizer.peek().name != "rparen":
                # We got here because there's still some stuff left to parse
                # and the next token is not an rparen. That can mean that an
                # infix operator is missing or that the parens are unmatched.
                # Decide which is more likely and raise the appropriate error.
                lparens = 1
                rparens = 0
                lookahead = 2
                while self.tokenizer.peek(lookahead):
                    if self.tokenizer.peek(lookahead).name == "lparen":
                        lparens += 1
                    elif self.tokenizer.peek(lookahead).name == "rparen":
                        rparens += 1

                    lookahead += 1

                if lparens > rparens:
                    return self.error("Ummatched left parenthesis.", token)
                else:
                    next_token = self.tokenizer.peek()
                    return self.error(
                        "Was not expecting %s here." % next_token.value,
                        next_token)

            self.tokenizer.next_token()
            return expr

        return self.error("Cannot handle token %s." % token, token)