示例#1
0
    def testTuple(self):
        query = q.Query("[1, 2, 3]")
        self.assertEqual(solve.solve(query, {}).value, (1, 2, 3))

        query = q.Query("[x + 5, 1 == 1, y['foo']]")
        self.assertEqual(
            solve.solve(query, {
                "x": 2,
                "y": {
                    "foo": "bar"
                }
            }).value, ([7], True, "bar"))
示例#2
0
    def testApply(self):
        """Make sure arguments to functions are normalized."""
        original = query.Query(
            ("apply", ("var", "f"),
             ("|", ("var", "x"), ("|", ("var", "y"), ("var", "z"))), ("var",
                                                                      "w")))

        expected = query.Query(
            ("apply", ("var", "f"), ("|", ("var", "x"), ("var", "y"),
                                     ("var", "z")), ("var", "w")))

        self.assertEqual(normalize.normalize(original), expected)
示例#3
0
    def testLispDottySQLRoundtrip(self):
        lisp = syntax.Syntax.get_formatter("lisp")
        dsql = syntax.Syntax.get_formatter("dottysql")

        q = query.Query("(SELECT proc.pid FROM pslist(pid: 1)"
                        "  WHERE proc.command in ['foo', 'bar'])"
                        "OR (SELECT proc.pid FROM psxview"
                        "  WHERE proc.alive ORDER BY proc.command DESC)")

        self.assertEqual(q.root, query.Query(lisp(q)).root)
        self.assertEqual(dsql(q.root), dsql(query.Query(lisp(q)).root))
        self.assertEqual(lisp(q),
                         lisp(query.Query(dsql(query.Query(lisp(q))))))
示例#4
0
    def testEquivalence(self):
        self.assertTrue(
            solve.solve(q.Query("pid == 1"), mocks.Process(1, None,
                                                           None)).value)

        # repeated elements are expanded in the usual way.
        self.assertTrue(
            solve.solve(q.Query("[1] == 1"), mocks.Process(1, None,
                                                           None)).value)

        # Same as [1,2] == [1, None]
        self.assertFalse(
            solve.solve(q.Query("[1, 2] == [1]"), mocks.Process(1, None,
                                                                None)).value)
示例#5
0
文件: solve.py 项目: rlugojr/dotty
    def testIsInstance(self):
        with self.assertRaises(
                errors.EfilterTypeError,
                error_f=lambda e: "Cannot find type named 'FooBar'" in str(e)):
            solve.solve(q.Query("proc isa FooBar"), mocks.MockRootType())

        self.assertTrue(
            solve.solve(q.Query("proc isa Process"),
                        mocks.MockRootType()).value)

        # Builtin types should work, too.
        self.assertTrue(solve.solve(q.Query("5 isa int"), {}).value)

        # Always never forget to test for negatives.
        self.assertFalse(solve.solve(q.Query("5 isa str"), {}).value)
示例#6
0
    def testDottySQLRoundtrip(self):
        f = syntax.Syntax.get_formatter("dottysql")

        # Simple case:
        q = query.Query("(SELECT * FROM pslist WHERE pid == 1)",
                        syntax="dottysql")
        q2 = query.Query(f(q))
        self.assertEqual(q.root, q2.root)

        # ANY disambiguation:
        q = query.Query(
            "(SELECT ANY pslist WHERE pid == 1) "
            "AND (SELECT ANY netstat WHERE socket.last_pid == 1)",
            syntax="dottysql")
        q2 = query.Query(f(q))
        self.assertEqual(q.root, q2.root)
示例#7
0
def search(query, data, replacements=None):

    """Yield objects from 'data' that match the 'query'."""
    query = q.Query(query, params=replacements)
    for entry in data:
        if solve.solve(query, entry).value:
            yield entry
示例#8
0
 def testMap(self):
     self.assertEqual(
         solve.solve(q.Query("foo.bar"), {
             "foo": {
                 "bar": "baz"
             }
         }).value, "baz")
示例#9
0
    def _ParseRule(self, rule):
        """Parses a single tagging rule.

    This method attempts to detect whether the rule is written with objectfilter
    or dottysql syntax - either is acceptable.

    Example:
      _ParseRule('5 + 5')
      # Returns Sum(Literal(5), Literal(5))

    Args:
      rule (str): rule in either objectfilter or dottysql syntax.

    Returns:
      efilter.query.Query: efilter query of the rule or None.
    """
        if self._OBJECTFILTER_WORDS.search(rule):
            syntax = u'objectfilter'
        else:
            syntax = u'dottysql'

        try:
            return efilter_query.Query(rule, syntax=syntax)

        except efilter_errors.EfilterParseError as exception:
            stripped_rule = rule.rstrip()
            logging.warning(
                u'Unable to build query from rule: "{0:s}" with error: {1:s}'.
                format(stripped_rule, exception.message))
示例#10
0
 def testSelect(self):
     self.assertEqual(
         solve.solve(q.Query("x['y']"), {
             "x": {
                 "y": 5
             }
         }).value, 5)
示例#11
0
    def _ParseEventTaggingRule(self, event_tagging_expression):
        """Parses an event tagging expression.

    This method attempts to detect whether the event tagging expression is valid
    objectfilter or dottysql syntax.

    Example:
      _ParseEventTaggingRule('5 + 5')
      # Returns Sum(Literal(5), Literal(5))

    Args:
      event_tagging_expression (str): event tagging experssion either in
          objectfilter or dottysql syntax.

    Returns:
      efilter.query.Query: efilter query of the event tagging expression.

    Raises:
      TaggingFileError: when the tagging file cannot be correctly parsed.
    """
        if self._OBJECTFILTER_WORDS.search(event_tagging_expression):
            syntax = 'objectfilter'
        else:
            syntax = 'dottysql'

        try:
            return efilter_query.Query(event_tagging_expression, syntax=syntax)

        except efilter_errors.EfilterParseError as exception:
            stripped_expression = event_tagging_expression.rstrip()
            raise errors.TaggingFileError((
                'Unable to parse event tagging expressoin: "{0:s}" with error: '
                '{1!s}').format(stripped_expression, exception))
示例#12
0
    def render_output_analysis(self, renderer):
        """Render analysis of the expression's return type and its members."""
        output_type = infer_type.infer_type(self.query, self)

        renderer.section("Type Analysis", width=140)
        renderer.table_header([
            dict(name="Name",
                 cname="name",
                 type="TreeNode",
                 max_depth=2,
                 width=60),
            dict(name="Type", cname="type", width=40)
        ])

        renderer.table_row(self.query.source, repr(output_type), depth=1)

        try:
            for member in structured.getmembers(output_type):
                subq = "(%s)[%r]" % (self.query.source, member)
                subtype = infer_type.infer_type(q.Query(subq), self)
                if isinstance(subtype, type):
                    subtype = subtype.__name__
                else:
                    subtype = repr(subtype)

                renderer.table_row(subq, subtype, depth=2)
        except (NotImplementedError, TypeError, AttributeError):
            pass
示例#13
0
 def testFormatters(self):
     """Creating a query with raw AST should generate the source."""
     q = query.Query(
         ast.Complement(
             ast.Equivalence(ast.Map(ast.Var("Process"), ast.Var("pid")),
                             ast.Literal(10))))
     self.assertEqual(q.source, "Process.pid != 10")
示例#14
0
    def testDifference(self):
        # Adding a constant to a list, adds it to each element.
        query = q.Query(
            "SELECT ages - 10 as diff FROM (bind('ages': [10, 20, 30]))")

        value = list(solve.solve(query, {}).value)
        diff = structured.resolve(value[0], "diff")
        self.assertEqual(diff, [0, 10, 20])

        # Subtracting numbers from non numbers just gives None.
        query = q.Query('SELECT ages - 10 as diff FROM '
                        '(bind("ages": ["foo", "bar", "baz"]))')

        value = list(solve.solve(query, {}).value)
        diff = structured.resolve(value[0], "diff")
        self.assertEqual(diff, [None, None, None])
示例#15
0
    def testGroup(self):
        result = api.apply(
            query=q.Query(
                (
                    "group",
                    # The input:
                    ("apply", ("var", "csv"), ("param", 0), True),
                    # The grouper expression:
                    ("var", "country"),

                    # The output reducers:
                    ("reducer", ("var", "singleton"), ("var", "country")),
                    ("reducer", ("var", "mean"), ("cast", ("var", "age"),
                                                  ("var", "int"))),
                    ("reducer", ("var", "sum"), ("cast", ("var", "age"),
                                                 ("var", "int")))),
                params=[testlib.get_fixture_path("fake_users.csv")]),
            allow_io=True)

        # Round the output means for comparison.
        actual = []
        for row in result:
            row[1] = int(row[1])
            actual.append(row)

        expected = repeated.meld(['El Salvador', 55, 1287],
                                 ['Ethiopia', 55, 1210],
                                 ['French Guiana', 47, 381],
                                 ['Germany', 42, 299], ['Haiti', 46, 610],
                                 ['Mayotte', 50, 865], ['Portugal', 48, 485])

        self.assertItemsEqual(expected, actual)
 def testCrossComponentHints(self):
     hint = self.hintQuery(
         "MemoryDescriptor/process matches (Process/command == 'Adium')"
         " and 'execute' in MemoryDescriptor/permissions"
         " and 'write' in MemoryDescriptor/permissions",
         selector="MemoryDescriptor/process")
     self.assertEqual(hint, query.Query("Process/command == 'Adium'",
                                        syntax="slashy"))
示例#17
0
文件: solve.py 项目: rlugojr/dotty
 def testFilter(self):
     self.assertValuesEqual(
         solve.solve(
             q.Query("select * from Process where (pid == 1)"), {
                 "Process":
                 repeated.meld(mocks.Process(2, None, None),
                               mocks.Process(1, None, None))
             }).value, mocks.Process(1, None, None))
示例#18
0
    def testSourceCache(self):
        """Creating the query with valid source should preserve it."""
        q = query.Query("Process.pid    != 10")  # Extra whitespace.
        self.assertEqual(q.source, "Process.pid    != 10")

        # Normalization shouldn't mess up the code (because it's 1:1).
        q = normalize.normalize(q)
        self.assertEqual(q.source, "Process.pid    != 10")
示例#19
0
    def testIfElse(self):
        # Missing else:
        q = query.Query(
            ast.IfElse(
                ast.Pair(ast.Literal(True), ast.Literal("foo")),
                ast.Pair(ast.Literal(True), ast.Literal("bar"))))

        with self.assertRaises(errors.EfilterLogicError):
            validate.validate(q)
示例#20
0
 def testEach(self):
     self.assertFalse(
         solve.solve(
             q.Query("each(Process.parent, (pid == 1))"), {
                 "Process": {
                     "parent":
                     repeated.meld(mocks.Process(1, None, None),
                                   mocks.Process(2, None, None))
                 }
             }).value)
示例#21
0
    def testAny(self):
        self.assertTrue(
            solve.solve(
                q.Query("any Process.parent where (pid == 1)"), {
                    "Process": {
                        "parent":
                        repeated.meld(mocks.Process(1, None, None),
                                      mocks.Process(2, None, None))
                    }
                }).value)

        # Test that unary ANY works as expected.
        query = q.Query(ast.Any(ast.Var("x")))
        self.assertFalse(solve.solve(query, {"x": None}).value)
        self.assertTrue(solve.solve(query, {"x": 1}).value)
        self.assertTrue(
            solve.solve(query, {
                "x": repeated.meld(1, 2, 3)
            }).value)
示例#22
0
    def find_by_component(self, component, complete=True):
        """Finds all entities that have the component.

        Arguments:
            complete: If True, will attempt to collect the component.
        """
        query = entity_query.Query(expression.ComponentLiteral(component))
        if complete:
            self.collect_for(query)

        return list(self.lookup_tables["components"].lookup(component))
示例#23
0
def infer(query,
          replacements=None,
          root_type=None,
          libs=("stdcore", "stdmath")):
    """Determine the type of the query's output without actually running it.

    Arguments:
        query: A query object or string with the query.
        replacements: Built-time parameters to the query, either as dict or as
            an array (for positional interpolation).
        root_type: The types of variables to be supplied to the query inference.
        libs: What standard libraries should be taken into account for the
            inference.

    Returns:
        The type of the query's output, if it can be determined. If undecidable,
        returns efilter.protocol.AnyType.

        NOTE: The inference returns the type of a row in the results, not of the
        actual Python object returned by 'apply'. For example, if a query
        returns multiple rows, each one of which is an integer, the type of the
        output is considered to be int, not a collection of rows.

    Examples:
        infer("5 + 5") # -> INumber

        infer("SELECT * FROM people WHERE age > 10") # -> AnyType

        # If root_type implements the IStructured reflection API:
        infer("SELECT * FROM people WHERE age > 10", root_type=...) # -> dict
    """
    # Always make the scope stack start with stdcore.
    if root_type:
        type_scope = scope.ScopeStack(std_core.MODULE, root_type)
    else:
        type_scope = scope.ScopeStack(std_core.MODULE)

    stdcore_included = False
    for lib in libs:
        if lib == "stdcore":
            stdcore_included = True
            continue

        module = std_core.LibraryModule.ALL_MODULES.get(lib)
        if not module:
            raise TypeError("No standard library module %r." % lib)

        type_scope = scope.ScopeStack(module, type_scope)

    if not stdcore_included:
        raise TypeError("'stdcore' must always be included.")

    query = q.Query(query, params=replacements)
    return infer_type.infer_type(query, type_scope)
示例#24
0
    def __init__(self, query, query_parameters=None, **kwargs):
        super(EfilterPlugin, self).__init__(**kwargs)
        self.query_source = query

        try:
            self.query = q.Query(query, params=query_parameters)
        except errors.EfilterError as error:
            self.query_error = error
            self.query = None

        self.query_parameters = query_parameters
示例#25
0
    def testDestructuring(self):
        result = solve.solve(q.Query("Process.pid == 1"),
                             {"Process": {
                                 "pid": 1
                             }})
        self.assertTrue(result.value)

        # Using a let-any form should succeed even if there is only one linked
        # object.
        result = solve.solve(
            q.Query("any Process.parent where (Process.pid == 1 or "
                    "Process.command == 'foo')"),
            {"Process": {
                "parent": {
                    "Process": {
                        "pid": 1
                    }
                }
            }})
        self.assertTrue(result.value)
示例#26
0
    def testRepeat(self):
        query = q.Query("(1, 2, 3, 4)")
        self.assertEqual(
            solve.solve(query, {}).value, repeated.meld(1, 2, 3, 4))

        # Repeated values do not flatten automatically.
        query = q.Query("(1, (2, 3), 4)")
        self.assertEqual(
            solve.solve(query, {}).value, repeated.meld(1, [2, 3], 4))

        # Expressions work.
        query = q.Query("(1, (2 + 2), 3, 4)")
        self.assertEqual(
            solve.solve(query, {}).value,
            # Operators always return a list.
            repeated.meld(1, [4], 3, 4))

        # None should be skipped.
        query = q.Query(
            ast.Repeat(ast.Literal(None), ast.Literal(2), ast.Literal(None),
                       ast.Literal(4)))
        self.assertEqual(solve.solve(query, {}).value, repeated.meld(2, 4))
示例#27
0
    def __init__(self,
                 query=None,
                 explain=None,
                 columns=None,
                 sort=None,
                 width=None,
                 filter=None,
                 stream_results=False,
                 complete_results=True,
                 **kwargs):
        super(EntityFind, self).__init__(**kwargs)
        if query:
            self.query = entity_query.Query(query)
        else:
            self.query = entity_query.Query(self.search)

        if columns is not None:
            self.columns = columns

        if sort is not None:
            self.sort = sort

        if width is not None:
            self.width = width

        if filter is not None:
            self.display_filter = entity_query.Query(filter)

        if stream_results is not None:
            if sort:
                raise ValueError(
                    "Can't stream results and sort at the same time.")
            self.stream_results = stream_results

        if complete_results is not None:
            self.complete_results = complete_results

        self.explain = explain
示例#28
0
    def stream(self, query, handler, query_params=None):
        query = entity_query.Query(query, params=query_params)
        seen = set()

        def _deduplicator(entity):
            if entity in seen:
                return

            seen.add(entity)
            handler(entity)

        self.collect_for(query, result_stream_handler=_deduplicator)
        for entity in self.find(query, complete=False, keep_cache=True):
            _deduplicator(entity)
示例#29
0
    def __init__(self, *args, **kwargs):
        super(EfilterPlugin, self).__init__(*args, **kwargs)

        try:
            self.query = q.Query(self.plugin_args.query,
                                 params=self.plugin_args.query_parameters)
        except errors.EfilterError as error:
            self.query_error = error
            self.query = None
        except Exception:
            # I am using a broad except here to make sure we always display a
            # friendly error message. EFILTER will usually raise a friendly
            # error, but we might get a non-EfilterError exception if the user
            # gets creative (e.g. passing a custom object as query, instead of a
            # string).
            raise plugin.PluginError("Could not parse your query %r." %
                                     (self.plugin_args.query, ))
示例#30
0
文件: aslisp.py 项目: rlugojr/dotty
    def testQuery(self):
        query = q.Query(
            "SELECT proc.pid, proc.parent.pid FROM pslist() "
            "WHERE proc.command == 'init'",
            syntax="dottysql")
        expected = \
            ("map",
                ("filter",
                    ("apply", ("var", "pslist")),
                    ("==",
                        (".", ("var", "proc"), "command"), "init")),
                ("bind",
                    (":", "pid", (".", ("var", "proc"), "pid")),
                    (":", "column_1",
                        (".", (".", ("var", "proc"), "parent"), "pid"))))

        self.assertEqual(aslisp.aslisp(query), expected)