|
1 |
| -# pylint:disable=missing-class-docstring,multiple-statements |
| 1 | +# pylint:disable=missing-class-docstring |
| 2 | +import unittest |
| 3 | + |
2 | 4 | import claripy
|
3 | 5 |
|
4 | 6 |
|
@@ -55,149 +57,137 @@ def apply_annotation(self, o, a):
|
55 | 57 | return o + a.number
|
56 | 58 |
|
57 | 59 |
|
58 |
| -def test_backend(): |
59 |
| - x = claripy.BVV(10, 32).annotate(AnnotationA("a", 1)) |
60 |
| - assert BackendA().convert(x) == 11 |
61 |
| - |
62 |
| - |
63 |
| -def test_simplification(): |
64 |
| - x = claripy.BVS("x", 32).annotate(AnnotationA("a", 1)) |
65 |
| - y = x ^ x |
66 |
| - assert y.depth == 1 |
67 |
| - assert len(y.annotations) == 0 |
68 |
| - |
69 |
| - x = claripy.BVS("x", 32).annotate(AnnotationB("a", 1)) |
70 |
| - y = x ^ x |
71 |
| - assert y.depth == 2 |
72 |
| - |
73 |
| - x = claripy.BVS("x", 32).annotate(AnnotationC("a", 1)) |
74 |
| - y = x ^ x |
75 |
| - assert y.depth == 1 |
76 |
| - assert len(y.annotations) == 1 |
77 |
| - assert y.annotations[0].number == 2 |
78 |
| - |
79 |
| - |
80 |
| -def test_missing_annotations_from_simplification(): |
81 |
| - relocatable_anno = AnnotationC("a", 2) |
82 |
| - |
83 |
| - x0 = claripy.BVS("x", 32) |
84 |
| - x1 = claripy.BVV(24, 32) |
85 |
| - k = (x1 + x0).annotate(relocatable_anno) |
86 |
| - |
87 |
| - x3 = claripy.simplify(k) |
88 |
| - |
89 |
| - assert len(x3.annotations) == 1 |
90 |
| - |
91 |
| - |
92 |
| -def test_annotations(): |
93 |
| - x = claripy.BVS("x", 32) + 1 |
94 |
| - xx = x._apply_to_annotations(lambda a: a) |
95 |
| - assert x is xx |
96 |
| - |
97 |
| - a1 = AnnotationA("a", 1) |
98 |
| - a2 = AnnotationA("a", 1) |
99 |
| - |
100 |
| - x1 = x.annotate(a1) |
101 |
| - x2 = x1.annotate(a2) |
102 |
| - x2a = x.annotate(a1, a2) |
103 |
| - x3 = x2.remove_annotation(a1) |
104 |
| - x4 = x3.remove_annotation(a2) |
105 |
| - x5 = x2.remove_annotations({a1, a2}) |
106 |
| - |
107 |
| - assert x.variables == x1.variables |
108 |
| - assert x.variables == x2.variables |
109 |
| - assert x.variables == x2a.variables |
110 |
| - assert x.variables == x3.variables |
111 |
| - assert x.variables == x4.variables |
112 |
| - assert x.variables == x5.variables |
113 |
| - |
114 |
| - assert x is not x1 |
115 |
| - assert x is not x2 |
116 |
| - assert x is not x3 |
117 |
| - assert x1 is not x2 |
118 |
| - assert x1 is not x3 |
119 |
| - assert x2 is not x3 |
120 |
| - assert x2 is x2a |
121 |
| - assert x is x4 |
122 |
| - assert x is x5 |
123 |
| - |
124 |
| - assert x.op == x1.op |
125 |
| - assert x.annotations == () |
126 |
| - assert x1.annotations == (a1,) |
127 |
| - assert x2.annotations == (a1, a2) |
128 |
| - assert x3.annotations == (a2,) |
129 |
| - |
130 |
| - assert claripy.backends.z3.convert(x).eq(claripy.backends.z3.convert(x3)) |
131 |
| - |
132 |
| - const = claripy.BVV(1, 32) |
133 |
| - consta = const.annotate(AnnotationB("a", 0)) |
134 |
| - const1 = consta + 1 |
135 |
| - const1a = const1.annotate(AnnotationB("b", 1)) |
136 |
| - const2 = const1a + 1 |
137 |
| - # const2 should be (const1a + 1), instead of (1 + 1 + 1) |
138 |
| - # the flatten simplifier for __add__ should not be applied as AnnotationB is not relocatable (and not eliminatable) |
139 |
| - assert const2.depth == 3 |
140 |
| - |
141 |
| - |
142 |
| -def test_eagerness(): |
143 |
| - x = claripy.BVV(10, 32).annotate(AnnotationD()) |
144 |
| - y = x + 1 |
145 |
| - assert y.annotations == x.annotations |
146 |
| - |
147 |
| - |
148 |
| -def test_ast_hash_should_consider_relocatable_annotations(): |
149 |
| - relocatable_anno = AnnotationC("a", 2) |
150 |
| - const = claripy.BVV(1337, 32) |
151 |
| - x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
152 |
| - y0 = claripy.Concat(x0, const) |
153 |
| - |
154 |
| - # make the annotation not relocatable |
155 |
| - # this is of course a hack, but it can demonstrate the problem |
156 |
| - relocatable_anno._relocatable = False |
157 |
| - x0._relocatable_annotations = frozenset() |
158 |
| - |
159 |
| - y1 = claripy.Concat(x0, const) |
160 |
| - |
161 |
| - assert len(y0.annotations) == 1 |
162 |
| - assert len(y1.annotations) == 0 |
163 |
| - assert y0._hash != y1._hash |
164 |
| - |
165 |
| - |
166 |
| -def test_remove_relocatable_annotations(): |
167 |
| - relocatable_anno = AnnotationC("a", 2) |
168 |
| - const = claripy.BVV(1337, 32) |
169 |
| - |
170 |
| - x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
171 |
| - y0 = claripy.Concat(x0, const) |
172 |
| - assert len(y0.annotations) == 1 |
173 |
| - assert y0.annotations == (relocatable_anno,) |
174 |
| - |
175 |
| - y1 = y0.remove_annotation(relocatable_anno) |
176 |
| - |
177 |
| - assert len(y1.annotations) == 0 |
178 |
| - |
179 |
| - |
180 |
| -def test_duplicated_annotations_from_makelike(): |
181 |
| - relocatable_anno = AnnotationC("a", 2) |
182 |
| - |
183 |
| - x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
184 |
| - x1 = claripy.BVV(24, 32) |
185 |
| - |
186 |
| - # make_like() should not re-apply child annotations if the child is the make_like target |
187 |
| - x2 = x0 + x1 |
188 |
| - assert len(x2.annotations) == 1 |
189 |
| - |
190 |
| - # simplify() should not re-apply annotations since annotations are kept during the simplification process by |
191 |
| - # make_like(). |
192 |
| - x3 = claripy.simplify(x0 + x1) |
193 |
| - assert len(x3.annotations) == 1 |
| 60 | +class TestAnnotation(unittest.TestCase): |
| 61 | + def test_backend(self): |
| 62 | + x = claripy.BVV(10, 32).annotate(AnnotationA("a", 1)) |
| 63 | + assert BackendA().convert(x) == 11 |
| 64 | + |
| 65 | + def test_simplification(self): |
| 66 | + x = claripy.BVS("x", 32).annotate(AnnotationA("a", 1)) |
| 67 | + y = x ^ x |
| 68 | + assert y.depth == 1 |
| 69 | + assert len(y.annotations) == 0 |
| 70 | + |
| 71 | + x = claripy.BVS("x", 32).annotate(AnnotationB("a", 1)) |
| 72 | + y = x ^ x |
| 73 | + assert y.depth == 2 |
| 74 | + |
| 75 | + x = claripy.BVS("x", 32).annotate(AnnotationC("a", 1)) |
| 76 | + y = x ^ x |
| 77 | + assert y.depth == 1 |
| 78 | + assert len(y.annotations) == 1 |
| 79 | + assert y.annotations[0].number == 2 |
| 80 | + |
| 81 | + def test_missing_annotations_from_simplification(self): |
| 82 | + relocatable_anno = AnnotationC("a", 2) |
| 83 | + |
| 84 | + x0 = claripy.BVS("x", 32) |
| 85 | + x1 = claripy.BVV(24, 32) |
| 86 | + k = (x1 + x0).annotate(relocatable_anno) |
| 87 | + |
| 88 | + x3 = claripy.simplify(k) |
| 89 | + |
| 90 | + assert len(x3.annotations) == 1 |
| 91 | + |
| 92 | + def test_annotations(self): |
| 93 | + x = claripy.BVS("x", 32) + 1 |
| 94 | + xx = x._apply_to_annotations(lambda a: a) |
| 95 | + assert x is xx |
| 96 | + |
| 97 | + a1 = AnnotationA("a", 1) |
| 98 | + a2 = AnnotationA("a", 1) |
| 99 | + |
| 100 | + x1 = x.annotate(a1) |
| 101 | + x2 = x1.annotate(a2) |
| 102 | + x2a = x.annotate(a1, a2) |
| 103 | + x3 = x2.remove_annotation(a1) |
| 104 | + x4 = x3.remove_annotation(a2) |
| 105 | + x5 = x2.remove_annotations({a1, a2}) |
| 106 | + |
| 107 | + assert x.variables == x1.variables |
| 108 | + assert x.variables == x2.variables |
| 109 | + assert x.variables == x2a.variables |
| 110 | + assert x.variables == x3.variables |
| 111 | + assert x.variables == x4.variables |
| 112 | + assert x.variables == x5.variables |
| 113 | + |
| 114 | + assert x is not x1 |
| 115 | + assert x is not x2 |
| 116 | + assert x is not x3 |
| 117 | + assert x1 is not x2 |
| 118 | + assert x1 is not x3 |
| 119 | + assert x2 is not x3 |
| 120 | + assert x2 is x2a |
| 121 | + assert x is x4 |
| 122 | + assert x is x5 |
| 123 | + |
| 124 | + assert x.op == x1.op |
| 125 | + assert x.annotations == () |
| 126 | + assert x1.annotations == (a1,) |
| 127 | + assert x2.annotations == (a1, a2) |
| 128 | + assert x3.annotations == (a2,) |
| 129 | + |
| 130 | + assert claripy.backends.z3.convert(x).eq(claripy.backends.z3.convert(x3)) |
| 131 | + |
| 132 | + const = claripy.BVV(1, 32) |
| 133 | + consta = const.annotate(AnnotationB("a", 0)) |
| 134 | + const1 = consta + 1 |
| 135 | + const1a = const1.annotate(AnnotationB("b", 1)) |
| 136 | + const2 = const1a + 1 |
| 137 | + # const2 should be (const1a + 1), instead of (1 + 1 + 1) |
| 138 | + # the flatten simplifier for __add__ should not be applied as AnnotationB is not relocatable (and not eliminatable) |
| 139 | + assert const2.depth == 3 |
| 140 | + |
| 141 | + def test_eagerness(self): |
| 142 | + x = claripy.BVV(10, 32).annotate(AnnotationD()) |
| 143 | + y = x + 1 |
| 144 | + assert y.annotations == x.annotations |
| 145 | + |
| 146 | + def test_ast_hash_should_consider_relocatable_annotations(self): |
| 147 | + relocatable_anno = AnnotationC("a", 2) |
| 148 | + const = claripy.BVV(1337, 32) |
| 149 | + x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
| 150 | + y0 = claripy.Concat(x0, const) |
| 151 | + |
| 152 | + # make the annotation not relocatable |
| 153 | + # this is of course a hack, but it can demonstrate the problem |
| 154 | + relocatable_anno._relocatable = False |
| 155 | + x0._relocatable_annotations = frozenset() |
| 156 | + |
| 157 | + y1 = claripy.Concat(x0, const) |
| 158 | + |
| 159 | + assert len(y0.annotations) == 1 |
| 160 | + assert len(y1.annotations) == 0 |
| 161 | + assert y0._hash != y1._hash |
| 162 | + |
| 163 | + def test_remove_relocatable_annotations(self): |
| 164 | + relocatable_anno = AnnotationC("a", 2) |
| 165 | + const = claripy.BVV(1337, 32) |
| 166 | + |
| 167 | + x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
| 168 | + y0 = claripy.Concat(x0, const) |
| 169 | + assert len(y0.annotations) == 1 |
| 170 | + assert y0.annotations == (relocatable_anno,) |
| 171 | + |
| 172 | + y1 = y0.remove_annotation(relocatable_anno) |
| 173 | + |
| 174 | + assert len(y1.annotations) == 0 |
| 175 | + |
| 176 | + def test_duplicated_annotations_from_makelike(self): |
| 177 | + relocatable_anno = AnnotationC("a", 2) |
| 178 | + |
| 179 | + x0 = claripy.BVS("x", 32).annotate(relocatable_anno) |
| 180 | + x1 = claripy.BVV(24, 32) |
| 181 | + |
| 182 | + # make_like() should not re-apply child annotations if the child is the make_like target |
| 183 | + x2 = x0 + x1 |
| 184 | + assert len(x2.annotations) == 1 |
| 185 | + |
| 186 | + # simplify() should not re-apply annotations since annotations are kept during the simplification process by |
| 187 | + # make_like(). |
| 188 | + x3 = claripy.simplify(x0 + x1) |
| 189 | + assert len(x3.annotations) == 1 |
194 | 190 |
|
195 | 191 |
|
196 | 192 | if __name__ == "__main__":
|
197 |
| - test_annotations() |
198 |
| - test_backend() |
199 |
| - test_eagerness() |
200 |
| - test_ast_hash_should_consider_relocatable_annotations() |
201 |
| - test_remove_relocatable_annotations() |
202 |
| - test_duplicated_annotations_from_makelike() |
203 |
| - test_simplification() |
| 193 | + unittest.main() |
0 commit comments