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_select_expr_negate(self): "Checks that a negate operation is not selected" l = ast.Literal('foo') n = ast.NegateOperator(l) name = merge.node_name(n) expr = merge.select_rewrite_expression(DEEP, name, [n]) assert expr == l
def test_canonical_static_order(self): "Test canonicalization, static ordering" static = ast.Literal("'string'") static.static = True static.static_val = 'string' static2 = ast.Literal("'foo'") static2.static = True static2.static_val = 'foo' cmp = ast.CompareOperator('<', static, static2) compare.canonicalize(cmp) assert cmp.left is static2 assert cmp.right is static assert cmp.type == ">"
def test_compare_empty(self, type): l = ast.Literal("l") r = ast.Literal("r") a = ast.CompareOperator(type, l, r) d = {"l": 1, "r": ast.Empty()} res, ctx = a.analyze(MockPred(), d) # Determine the expected result if type == "!=": assert res else: assert not res if not res: assert ("%s comparison at" % type.upper()) in ctx.failed[0] assert ctx.literals["l"] == d["l"] assert ctx.literals["r"] == ast.Empty()
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_simple_pattern_type(self): l = ast.Literal('foo') r = ast.Regex('^tubez$') n = ast.MatchOperator(l, r) p = tiler.SimplePattern('types:MatchOperator', 'types:Literal', 'types:Regex') assert p.matches(n)
def test_equality_rewrite_non_static(self): "Test an equality rewrite with non-static values" l = ast.Literal('foo') v = ast.Literal('bar') cmp1 = ast.CompareOperator('=', l, v) cmp2 = ast.CompareOperator('!=', l, v) or1 = ast.LogicalOperator('or', cmp1, cmp2) # Rewrite foo = bar as True # Left should be True, right should be False name = merge.node_name(cmp1, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp1, True) assert isinstance(r.left, ast.Constant) assert r.left.value == True assert isinstance(r.right, ast.Constant) assert r.right.value == False # Rewrite foo = bar as False # Left should be False, right should be True name = merge.node_name(cmp1, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp1, False) assert isinstance(r.left, ast.Constant) assert r.left.value == False assert isinstance(r.right, ast.Constant) assert r.right.value == True # Rewrite foo != bar as True # Left should be False, right should be True name = merge.node_name(cmp2, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp2, True) assert isinstance(r.left, ast.Constant) assert r.left.value == False assert isinstance(r.right, ast.Constant) assert r.right.value == True # Rewrite foo != bar as False # Left should be False, right should be True name = merge.node_name(cmp2, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp2, False) assert isinstance(r.left, ast.Constant) assert r.left.value == True assert isinstance(r.right, ast.Constant) assert r.right.value == False
def test_undef_contains(self): "Tests removing an Empty contains X" u = ast.Undefined() v = ast.Literal('foo') cn = ast.ContainsOperator(u, v) c, r = optimizer.optimization_pass(cn) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False
def test_rewrite_contains(self): "Checks that a contain rewrite uses contains module" l = ast.LiteralSet([ast.Number(1), ast.Number(2)]) r = ast.Literal('bar') c = ast.ContainsOperator(l, r) name = merge.node_name(c) with patch('pypred.merge.contains.contains_rewrite') as cr: merge.rewrite_ast(c, name, c, True) assert cr.called
def test_canonical_non_literal(self): "Test canonicalization, literals on left" v = ast.Number(42) l = ast.Literal('foo') cmp = ast.CompareOperator('=', v, l) compare.canonicalize(cmp) assert cmp.left is l assert cmp.right is v
def test_empty_contains(self, type): "Tests removing an Empty contains X" e = ast.Empty() v = ast.Literal('foo') cn = ast.SetComparisonOperator(type, e, v) c, r = optimizer.optimization_pass(cn) assert c == 1 assert isinstance(r, ast.Constant) assert r.value == False
def test_equality_rewrite_literals(self): "Test an equality rewrite with different literals" l = ast.Literal('foo') v = ast.Literal('bar') v2 = ast.Literal('baz') cmp1 = ast.CompareOperator('=', l, v) cmp2 = ast.CompareOperator('=', l, v2) or1 = ast.LogicalOperator('or', cmp1, cmp2) # Rewrite foo = bar as True # Left should be True, right should be unchanged name = merge.node_name(cmp1, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp1, True) assert isinstance(r.left, ast.Constant) assert r.left.value == True assert ASTPattern(cmp2).matches(r.right) # Rewrite foo = bar as False # Left should be False, right should be same name = merge.node_name(cmp1, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp1, False) assert isinstance(r.left, ast.Constant) assert r.left.value == False assert ASTPattern(cmp2).matches(r.right) # Rewrite foo = baz as True # Left should be same, right should be True name = merge.node_name(cmp2, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp2, True) assert ASTPattern(cmp1).matches(r.left) assert isinstance(r.right, ast.Constant) assert r.right.value == True # Rewrite foo = baz as False # Left should be same, right should be False name = merge.node_name(cmp2, True) r = compare.equality_rewrite(ast.dup(or1), name, cmp2, False) assert ASTPattern(cmp1).matches(r.left) assert isinstance(r.right, ast.Constant) assert r.right.value == False
def test_select_expr_contains(self): "Checks that a contains operation uses contains module" l = ast.LiteralSet([ast.Number(1), ast.Number(2)]) r = ast.Literal('bar') c = ast.ContainsOperator(l, r) name = merge.node_name(c) with patch('pypred.merge.contains.select_rewrite_expression') as cr: merge.select_rewrite_expression(DEEP, name, [c]) assert cr.called
def test_compare(self, type): l = ast.Literal("l") r = ast.Literal("r") a = ast.CompareOperator(type, l, r) d = {"l": 1, "r": 5} res, ctx = a.analyze(MockPred(), d) # Determine the expected result if type == "=": s = '%d %s %d' % (d["l"], "==", d["r"]) else: s = '%d %s %d' % (d["l"], type, d["r"]) expected = eval(s) assert res == expected if not res: assert ("%s comparison at" % type.upper()) in ctx.failed[0] assert ctx.literals["l"] == d["l"] assert ctx.literals["r"] == d["r"]
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_contains_rewrite(self): s1 = ast.LiteralSet([ast.Number(1), ast.Number(2), ast.Number(3)]) s2 = ast.LiteralSet([ast.Number(1)]) s3 = ast.LiteralSet([ ast.Number(1), ast.Number(2), ast.Number(3), ast.Number(4), ast.Number(5) ]) s4 = ast.LiteralSet([ast.Number(6)]) s5 = ast.LiteralSet([ast.Number(2), ast.Number(3), ast.Number(4)]) l = ast.Literal('foo') c1 = ast.ContainsOperator(s1, l) c2 = ast.ContainsOperator(s2, l) c3 = ast.ContainsOperator(s3, l) c4 = ast.ContainsOperator(s4, l) c5 = ast.ContainsOperator(s5, l) # Rewrite set1 as True, s3 is super set, should be True name = merge.node_name(c1, True) r = contains.contains_rewrite(c3, name, c1, True) assert isinstance(r, ast.Constant) and r.value == True # Rewrite set1 as False, s3 is super set, should be trimed name = merge.node_name(c1, True) r = contains.contains_rewrite(c3, name, c1, False) assert len(r.left.value) == 2 assert ast.Number(4) in r.left.value assert ast.Number(5) in r.left.value # Rewrite set1 as True, s2 is sub set, should check value r = contains.contains_rewrite(c2, name, c1, True) assert len(r.left.value) == 1 # Rewrite set1 as False, s2 is subset, should be false r = contains.contains_rewrite(c2, name, c1, False) assert isinstance(r, ast.Constant) and r.value == False # Rewrite set1 as True, s4 has no overlap, should be false r = contains.contains_rewrite(c4, name, c1, True) assert isinstance(r, ast.Constant) and r.value == False # Rewrite set1 as False, s4 is no overlap, should check r = contains.contains_rewrite(c4, name, c1, False) assert len(r.left.value) == 1 assert ast.Number(6) in r.left.value # Rewrite set1 as True, s5 is has mostly overlap, should check # the negation of s1 - s5 r = contains.contains_rewrite(c5, name, c1, True) assert isinstance(r, ast.NegateOperator) assert isinstance(r.left, ast.ContainsOperator) assert len(r.left.left.value) assert ast.Number(1) in r.left.left.value
def test_select_rewrite_eq(self): "Test rewrite selection for equality" l = ast.Literal('foo') v = ast.Number(42) v2 = ast.Number(11) cmp1 = ast.CompareOperator('=', l, v2) cmp2 = ast.CompareOperator('=', l, v) cmp3 = ast.CompareOperator('=', l, v) name = merge.node_name(cmp1, True) select = compare.select_rewrite_expression(name, [cmp1, cmp2, cmp3]) assert select is cmp2
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_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_select_rewrite_ord_numeric(self): "Test rewrite selection for ordered with numerics" l = ast.Literal('foo') v = ast.Number(42) v2 = ast.Number(11) v3 = ast.Number(100) cmp1 = ast.CompareOperator('>', l, v) cmp2 = ast.CompareOperator('<', l, v2) cmp3 = ast.CompareOperator('>', l, v3) name = merge.node_name(cmp1, True) select = compare.select_rewrite_expression(name, [cmp1, cmp2, cmp3]) assert select is cmp1
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_select_rewrite(self): "Test rewrite selection" settings = merge.RefactorSettings.deep() s1 = ast.LiteralSet([ast.Number(1), ast.Number(2), ast.Number(3)]) s2 = ast.LiteralSet([ast.Number(1)]) s3 = ast.LiteralSet([ast.Number(1), ast.Number(2), ast.Number(3), ast.Number(4), ast.Number(5)]) l = ast.Literal('foo') c1 = ast.ContainsOperator(s1, l) c2 = ast.ContainsOperator(s2, l) c3 = ast.ContainsOperator(s3, l) name = merge.node_name(c1, True) select = contains.select_rewrite_expression(settings, name, [c1, c2, c3]) assert select is c1
def test_select_rewrite_low_density(self): "Test rewrite selection" settings = merge.RefactorSettings.deep() nums = [ast.Number(x) for x in range(100)] s1 = ast.LiteralSet(nums) nums = [ast.Number(x) for x in range(100, 200)] s2 = ast.LiteralSet(nums) l = ast.Literal('foo') c1 = ast.ContainsOperator(s1, l) c2 = ast.ContainsOperator(s2, l) name = merge.node_name(c1, True) select = contains.select_rewrite_expression(settings, name, [c1, c2]) # Density is too low assert select is None
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_bad_child(self): c = ast.CompareOperator("!", ast.Literal("foo"), ast.Empty()) a = ast.LogicalOperator("and", ast.Literal("foo"), c) valid, info = a.validate() assert not valid assert "Unknown compare" in info["errors"][0]
def test_bad_logic(self): a = ast.LogicalOperator("!", ast.Literal("foo"), ast.Empty()) valid, info = a.validate() assert not valid assert "Unknown logical" in info["errors"][0]
def test_bad_compare(self): a = ast.CompareOperator("!", ast.Literal("foo"), ast.Empty()) valid, info = a.validate() assert not valid assert "Unknown compare" in info["errors"][0]
def test_contains_valid_args(self): a = ast.ContainsOperator(ast.Literal("foo"), ast.Literal("bar")) valid, info = a.validate() assert valid