예제 #1
0
    def test_engine_builtins(self):
        builtins = engine.Builtins.from_defaults(
            {'test': {
                'one': 1.0,
                'two': 2.0
            }})
        self.assertIsInstance(builtins, engine.Builtins)
        self.assertIsNone(builtins.namespace)
        self.assertRegex(
            repr(builtins),
            r'<Builtins namespace=None keys=\(\'\S+\'(, \'\S+\')*\)')

        self.assertIn('test', builtins)
        test_builtins = builtins['test']
        self.assertIsInstance(test_builtins, engine.Builtins)
        self.assertEqual(test_builtins.namespace, 'test')

        self.assertIn('today', builtins)
        today = builtins['today']
        self.assertIsInstance(today, datetime.date)

        # test that builtins have correct type hints
        builtins = engine.Builtins.from_defaults(
            {'name': 'Alice'}, value_types={'name': ast.DataType.STRING})
        self.assertEqual(builtins.resolve_type('name'), ast.DataType.STRING)
        self.assertEqual(builtins.resolve_type('missing'),
                         ast.DataType.UNDEFINED)
        context = engine.Context()
        context.builtins = builtins
        engine.Rule('$name =~ ""')
        with self.assertRaises(errors.EvaluationError):
            engine.Rule('$name + 1', context=context)
예제 #2
0
	def test_engine_resolve_item_with_defaults(self):
		thing = {'name': 'Alice'}
		context = engine.Context(resolver=engine.resolve_item, default_value=None)
		self.assertEqual(engine.Rule('name', context=context).evaluate(thing), thing['name'])
		self.assertIsNone(engine.Rule('name.first', context=context).evaluate(thing))
		self.assertIsNone(engine.Rule('address', context=context).evaluate(thing))
		self.assertIsNone(engine.Rule('address.city', context=context).evaluate(thing))
예제 #3
0
	def test_engine_resolve_attribute_with_defaults(self):
		thing = collections.namedtuple('Person', ('name',))(name='alice')
		context = engine.Context(resolver=engine.resolve_attribute, default_value=None)
		self.assertEqual(engine.Rule('name', context=context).evaluate(thing), thing.name)
		self.assertIsNone(engine.Rule('name.first', context=context).evaluate(thing))
		self.assertIsNone(engine.Rule('address', context=context).evaluate(thing))
		self.assertIsNone(engine.Rule('address.city', context=context).evaluate(thing))
예제 #4
0
	def test_number_10(self):
		value = random.randint(1, 10000)
		thing = {
			'c': {
				'c1': value,
			}
		}
		rule_text = 'c.c1 == ' + str(value)
		rule1 = engine.Rule(rule_text, context=engine.Context())
		rule2 = engine.Rule(rule_text, context=engine.Context(default_value=None))
		self.assertEqual(rule1.evaluate(thing), rule2.evaluate(thing))
예제 #5
0
 def test_engine_rule_filter(self, rule=None):
     rule = rule or engine.Rule(self.rule_text)
     result = rule.filter([self.true_item, self.false_item])
     self.assertIsInstance(result, types.GeneratorType)
     result = tuple(result)
     self.assertIn(self.true_item, result)
     self.assertNotIn(self.false_item, result)
예제 #6
0
 def test_tls_for_comprehension(self):
     context = engine.Context()
     rule = engine.Rule('[word for word in words][0]', context=context)
     rule.evaluate({'words': ('MainThread', 'Test')})
     # this isn't exactly a thread test since the assignment scope should be cleared after the comprehension is
     # complete
     self.assertEqual(len(context._tls.assignment_scopes), 0)
예제 #7
0
 def test_tls_for_regex1(self):
     context = engine.Context()
     rule = engine.Rule('words =~ "(\w+) \w+"', context=context)
     rule.evaluate({'words': 'MainThread Test'})
     self.assertEqual(context._tls.regex_groups, ('MainThread', ))
     RuleThread(rule, {'words': 'AlternateThread Test'}).join()
     self.assertEqual(context._tls.regex_groups, ('MainThread', ))
예제 #8
0
    def test_engine_builtins_re_groups(self):
        context = engine.Context()
        rule = engine.Rule(
            'words =~ "(\\w+) (\\w+) (\\w+)" and $re_groups[0] == word0',
            context=context)
        self.assertIsNone(context._tls.regex_groups)
        words = (''.join(
            random.choice(string.ascii_letters)
            for _ in range(random.randint(4, 12))), ''.join(
                random.choice(string.ascii_letters)
                for _ in range(random.randint(4, 12))), ''.join(
                    random.choice(string.ascii_letters)
                    for _ in range(random.randint(4, 12))))
        self.assertTrue(
            rule.matches({
                'words': ' '.join(words),
                'word0': words[0]
            }))
        self.assertEqual(context._tls.regex_groups, words)

        self.assertFalse(
            rule.matches({
                'words': ''.join(words),
                'word0': words[0]
            }))
        self.assertIsNone(context._tls.regex_groups)
예제 #9
0
 def test_engine_rule_matches(self, rule=None):
     rule = rule or engine.Rule(self.rule_text)
     result = rule.matches(self.true_item)
     self.assertIsInstance(result, bool)
     self.assertTrue(result)
     result = rule.matches(self.false_item)
     self.assertIsInstance(result, bool)
     self.assertFalse(result)
예제 #10
0
 def test_number_19(self):
     context = engine.Context(type_resolver=engine.type_resolver_from_dict({
         'facts':
         ast.DataType.MAPPING(key_type=ast.DataType.STRING,
                              value_type=ast.DataType.STRING)
     }))
     rule = engine.Rule('facts.abc == "def"', context=context)
     self.assertTrue(rule.matches({'facts': {'abc': 'def'}}))
예제 #11
0
 def test_number_14(self):
     context = engine.Context(type_resolver=engine.type_resolver_from_dict({
         'TEST_FLOAT':
         ast.DataType.FLOAT,
     }))
     rule = engine.Rule('(TEST_FLOAT == null ? 0 : TEST_FLOAT) < 42',
                        context=context)
     rule.matches({'TEST_FLOAT': None})
예제 #12
0
 def test_tls_for_regex2(self):
     lock = threading.RLock()
     context = engine.Context(
         resolver=functools.partial(testing_resolver, lock))
     rule = engine.Rule(
         'words =~ "(\w+) \w+" and lock and $re_groups[0] == "MainThread"',
         context=context)
     self.assertTrue(rule.evaluate({'words': 'MainThread Test'}))
     lock.release()
     with lock:
         thread = RuleThread(rule, {'words': 'AlternateThread Test'})
         self.assertTrue(rule.evaluate({'words': 'MainThread Test'}))
         lock.release()
     self.assertFalse(thread.join())
예제 #13
0
    def test_engine_rule_evaluate_attributes(self):
        # ensure that multiple levels can be evaluated as attributes
        rule = engine.Rule('a.b.c')
        self.assertTrue(rule.evaluate({'a': {'b': {'c': True}}}))

        value = rule.evaluate({'a': {'b': {'c': 1}}})
        self.assertIsInstance(value, float)
        self.assertEqual(value, 1.0)

        value = rule.evaluate({'a': {'b': {'c': {'d': None}}}})
        self.assertIsInstance(value, dict)
        self.assertIn('d', value)

        with self.assertRaises(errors.AttributeResolutionError):
            rule.evaluate({'a': {}})
예제 #14
0
 def test_engine_rule_to_graphviz_3(self):
     rule = engine.Rule('[member for member in iterable if member]')
     digraph = rule.to_graphviz()
     self.assertIsInstance(digraph, graphviz.Digraph)
예제 #15
0
 def test_engine_rule_raises(self):
     with self.assertRaises(errors.RuleSyntaxError):
         engine.Rule('test ==')
예제 #16
0
	def test_number_20(self):
		rule = engine.Rule('a / b ** 2')
		self.assertEqual(rule.evaluate({'a': 8, 'b': 4}), 0.5)
예제 #17
0
 def test_engine_rule_to_graphviz_1(self):
     rule = engine.Rule(self.rule_text)
     digraph = rule.to_graphviz()
     self.assertIsInstance(digraph, graphviz.Digraph)
     self.assertEqual(digraph.comment, self.rule_text)
예제 #18
0
 def test_engine_rule_evaluate(self):
     rule = engine.Rule('"string"')
     self.assertEqual(rule.evaluate(None), 'string')
예제 #19
0
 def test_engine_rule_to_graphviz_2(self):
     rule = engine.Rule(
         'null in [foo.length % [2, 4, 6][boz] ? (bar > baz) : (bar < -baz)]'
     )
     digraph = rule.to_graphviz()
     self.assertIsInstance(digraph, graphviz.Digraph)
예제 #20
0
 def test_engine_rule_to_strings(self):
     rule = engine.Rule(self.rule_text)
     self.assertEqual(str(rule), self.rule_text)
     self.assertRegex(
         repr(rule), "<Rule text='{0}' >".format(re.escape(self.rule_text)))