def test_literal_set(self): inp = "{true false 1.0 \"quote\"}" lexer = parser.get_lexer() p = parser.get_parser() res = p.parse(inp, lexer=lexer) assert isinstance(res, ast.LiteralSet) assert res.value == set([ ast.Constant(True), ast.Constant(False), ast.Number(1.0), ast.Literal("\"quote\"") ])
def test_branch_true_dead(self): "Test branch with the false branch being dead" t = ast.Constant(True) f = ast.Constant(False) l = ast.Literal('foo') v = ast.Number(42) cmp = ast.CompareOperator('=', l, v) n = ast.Branch(f, t, cmp) # Should reduce to to the compare c, r = optimizer.optimization_pass(n) assert c == 1 assert r is cmp
def test_branch(self): l = ast.Literal('a') r = ast.Literal('b') check = ast.CompareOperator('>', l, r) true = ast.Constant(True) false = ast.Constant(False) b = ast.Branch(check, true, false) assert b.evaluate(MockPred(), {'a': 2, 'b':1}) res, ctx = b.analyze(MockPred(), {'a': 1, 'b':2}) assert not res assert ctx.literals["a"] == 1 assert ctx.literals["b"] == 2 assert ctx.failed[-1].startswith("Right hand side")
def test_both_dead(self): "Test removing a both node when one side is dead" t = ast.Constant(True) f = ast.Constant(False) # Should reduce to left n = ast.Both(t, f) c, r = optimizer.optimization_pass(n) assert c == 1 assert r is t # Should reduce to right n = ast.Both(f, t) c, r = optimizer.optimization_pass(n) assert c == 1 assert r is t
def test_simple_pattern_value(self): l = ast.Literal('foo') r = ast.Constant(True) n = ast.CompareOperator('=', l, r) p = tiler.SimplePattern('types:CompareOperator AND ops:=', 'types:Literal', 'types:Constant AND value:True') assert p.matches(n)
def test_min_change(self): t = ast.Constant(True) f = ast.Constant(False) left = ast.LogicalOperator('or', t, f) right = ast.LogicalOperator('and', t, f) r = ast.LogicalOperator('or', left, right) # First pass will only replace the left and right # with constants, but will not cause 3 changes. r = optimizer.optimize(r, max_pass=10, min_change=3) assert isinstance(r, ast.LogicalOperator) assert isinstance(r.left, ast.Constant) assert r.left.value == True assert isinstance(r.right, ast.Constant) assert r.right.value == False
def test_litset_eval(self): s = ast.LiteralSet([ast.Constant(True), ast.Literal('a'), ast.Literal('b')]) ctx = ast.EvalContext(MockPred(), {'a': 2, 'b': False}) res = s.eval(ctx) assert isinstance(res, frozenset) assert True in res assert False in res assert 2 in res
def test_cached_node_sets_cache(self): c = ast.Constant(False) n = ast.CachedNode(c, 0) ctx = ast.EvalContext(MockPred(), {}) assert not n.eval(ctx) assert not ctx.cached_res[0]
def test_and_replace(self): "Test AND -> False" t = ast.Constant(True) f = ast.Constant(False) n = ast.LogicalOperator('and', t, f) # Should reduce to False c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False # Should reduce to False n = ast.LogicalOperator('and', f, t) c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False
def test_negate(self): "Test negation static analysis" t = ast.Constant(True) f = ast.Constant(False) n = ast.NegateOperator(t) # Should reduce to False c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False # Should reduce to True n = ast.NegateOperator(f) c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == True
def test_or_replace(self): "Test OR -> True" t = ast.Constant(True) f = ast.Constant(False) n = ast.LogicalOperator('or', t, f) # Should reduce to True c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == True # Should reduce to True n = ast.LogicalOperator('or', f, t) c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == True
def test_both_all_false(self): "Test removing a both node when both sides are false" f = ast.Constant(False) n = ast.Both(f, f) # Should reduce to False c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False
def test_push_result(self): "Test false push result" f = ast.Constant(False) n = ast.PushResult(None, f) # Should reduce to False c, r = optimizer.optimization_pass(n) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False
def test_litset_static(self): s = ast.LiteralSet([ast.Constant(True), ast.Literal('\"a\"')]) pred = MockPred() s.static_resolve(pred) ctx = ast.EvalContext(pred, {'a': 2, 'b': False}) res = s.eval(ctx) assert s.static assert isinstance(res, set) assert True in res assert "a" in res
def test_push(self): p = ast.PushResult(True, ast.Constant(True)) class TestSet(object): def __init__(self): self.res = [] def push_match(self, m): self.res.append(m) testset = TestSet() assert p.evaluate(testset, {}) assert testset.res == [True]
def test_or_dead(self): "Tests removing OR with dead branch" f = ast.Constant(False) l = ast.Literal('foo') v = ast.Number(42) cmp = ast.CompareOperator('=', l, v) n = ast.LogicalOperator('or', f, cmp) # Should reduce to to the compare c, r = optimizer.optimization_pass(n) assert c == 1 assert r is cmp
def test_and_dead_right(self): "Tests removing AND with dead branch, right side" t = ast.Constant(True) l = ast.Literal('foo') v = ast.Number(42) cmp = ast.CompareOperator('=', l, v) n = ast.LogicalOperator('and', cmp, t) # Should reduce to to the compare c, r = optimizer.optimization_pass(n) assert c == 1 assert r is cmp
def test_names(self): n1 = ast.Literal("foo") assert ("Literal", "foo") == merge.node_name(n1) n2 = ast.Number(12) assert ("Number", 12) == merge.node_name(n2) n3 = ast.Constant(True) assert ("Constant", True) == merge.node_name(n3) n4 = ast.Regex("^tubez$") assert ("Regex", "^tubez$") == merge.node_name(n4) n5 = ast.Undefined() assert "Undefined" == merge.node_name(n5) n6 = ast.Empty() assert "Empty" == merge.node_name(n6) # Negate does not emit the operator! n7 = ast.NegateOperator(n3) assert ("Constant", True) == merge.node_name(n7) n8 = ast.CompareOperator('=', n1, n2) n8_name = merge.node_name(n8) assert ("CompareOperator", "=", ("Literal", "foo"), ("Number", 12)) == n8_name n8_static = merge.node_name(n8, True) assert ("CompareOperator", "equality", ("Literal", "foo"), ("Number", "static")) == n8_static n9 = ast.MatchOperator(n1, n4) n9_name = merge.node_name(n9) assert ("MatchOperator", ("Literal", "foo"), ("Regex", "^tubez$")) == n9_name n10 = ast.ContainsOperator(n1, n2) n10_name = merge.node_name(n10) assert ("ContainsOperator", ("Literal", "foo"), ("Number", 12.0)) == n10_name # Logical operator returns literal! n11 = ast.LogicalOperator('and', n1, n3) n11_name = merge.node_name(n11) assert ("Literal", "foo") == n11_name # Literal set just uses name n12 = ast.LiteralSet([n1, n2]) n12_name = merge.node_name(n12) assert "LiteralSet" == n12_name
def test_names(self): n1 = ast.Literal("foo") assert ("Literal", "foo") == compact.node_name(n1) n2 = ast.Number(12) assert ("Number", 12) == compact.node_name(n2) n3 = ast.Constant(True) assert ("Constant", True) == compact.node_name(n3) n4 = ast.Regex("^tubez$") assert ("Regex", "^tubez$") == compact.node_name(n4) n5 = ast.Undefined() assert "Undefined" == compact.node_name(n5) n6 = ast.Empty() assert "Empty" == compact.node_name(n6) n7 = ast.NegateOperator(n3) assert ("NegateOperator", ("Constant", True)) == compact.node_name(n7) n8 = ast.CompareOperator('=', n1, n2) n8_name = compact.node_name(n8) assert ("CompareOperator", "=", ("Literal", "foo"), ("Number", 12)) == n8_name n9 = ast.MatchOperator(n1, n4) n9_name = compact.node_name(n9) assert ("MatchOperator", ("Literal", "foo"), ("Regex", "^tubez$")) == n9_name n10 = ast.ContainsOperator(n1, n2) n10_name = compact.node_name(n10) assert ("ContainsOperator", ("Literal", "foo"), ("Number", 12.0)) == n10_name n11 = ast.LogicalOperator('and', n1, n3) n11_name = compact.node_name(n11) assert ("LogicalOperator", "and", ("Literal", "foo"), ("Constant", True)) == n11_name
def test_iterall_true(self): c1 = ast.Constant(False) c2 = ast.Constant(True) n = ast.Both(c1, c2) assert n.evaluate(MockPred(), {}) == True
def test_both_false(self): c1 = ast.Constant(False) c2 = ast.Constant(False) n = ast.Both(c1, c2) assert n.evaluate(MockPred(), {}) == False
def test_bad_constant(self): a = ast.Constant(42) valid, info = a.validate() assert not valid assert "Invalid Constant" in info["errors"][0]