blob: 22a1cdf6df0f1b0999e24f1ae8839b905ae657ec [file] [log] [blame]
Paul Duffin428c6512021-07-21 15:33:22 +01001#!/usr/bin/env python
2#
3# Copyright (C) 2021 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the 'License');
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an 'AS IS' BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Paul Duffin428c6512021-07-21 15:33:22 +010016"""Unit tests for verify_overlaps_test.py."""
17import io
18import unittest
19
Spandan Das559132f2021-08-25 18:17:33 +000020from verify_overlaps import * #pylint: disable=unused-wildcard-import,wildcard-import
21
Paul Duffin428c6512021-07-21 15:33:22 +010022
Paul Duffinc11f6672021-07-20 00:04:21 +010023class TestSignatureToElements(unittest.TestCase):
24
25 def signatureToElements(self, signature):
26 return InteriorNode().signatureToElements(signature)
27
28 def test_signatureToElements_1(self):
29 expected = [
30 'package:java',
31 'package:lang',
32 'class:ProcessBuilder',
33 'class:Redirect',
34 'class:1',
35 'member:<init>()V',
36 ]
Spandan Das559132f2021-08-25 18:17:33 +000037 self.assertEqual(
38 expected,
39 self.signatureToElements(
40 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V'))
Paul Duffinc11f6672021-07-20 00:04:21 +010041
42 def test_signatureToElements_2(self):
43 expected = [
44 'package:java',
45 'package:lang',
46 'class:Object',
47 'member:hashCode()I',
48 ]
Spandan Das559132f2021-08-25 18:17:33 +000049 self.assertEqual(
50 expected,
51 self.signatureToElements('Ljava/lang/Object;->hashCode()I'))
Paul Duffinc11f6672021-07-20 00:04:21 +010052
53 def test_signatureToElements_3(self):
54 expected = [
55 'package:java',
56 'package:lang',
57 'class:CharSequence',
58 'class:',
59 'class:ExternalSyntheticLambda0',
60 'member:<init>(Ljava/lang/CharSequence;)V',
61 ]
Spandan Das559132f2021-08-25 18:17:33 +000062 self.assertEqual(
63 expected,
64 self.signatureToElements(
65 'Ljava/lang/CharSequence$$ExternalSyntheticLambda0;'
66 '-><init>(Ljava/lang/CharSequence;)V'))
Paul Duffinc11f6672021-07-20 00:04:21 +010067
Spandan Das559132f2021-08-25 18:17:33 +000068#pylint: disable=line-too-long
Paul Duffin428c6512021-07-21 15:33:22 +010069class TestDetectOverlaps(unittest.TestCase):
70
Spandan Das559132f2021-08-25 18:17:33 +000071 def read_flag_trie_from_string(self, csvdata):
72 with io.StringIO(csvdata) as f:
Paul Duffinc11f6672021-07-20 00:04:21 +010073 return read_flag_trie_from_stream(f)
74
Spandan Das559132f2021-08-25 18:17:33 +000075 def read_signature_csv_from_string_as_dict(self, csvdata):
76 with io.StringIO(csvdata) as f:
Paul Duffin428c6512021-07-21 15:33:22 +010077 return read_signature_csv_from_stream_as_dict(f)
78
Spandan Das559132f2021-08-25 18:17:33 +000079 def extract_subset_from_monolithic_flags_as_dict_from_string(
80 self, monolithic, patterns):
Paul Duffin67b9d612021-07-21 17:38:47 +010081 with io.StringIO(patterns) as f:
Spandan Das559132f2021-08-25 18:17:33 +000082 return extract_subset_from_monolithic_flags_as_dict_from_stream(
83 monolithic, f)
Paul Duffin67b9d612021-07-21 17:38:47 +010084
Spandan Das559132f2021-08-25 18:17:33 +000085 extractInput = """
Paul Duffin53a76072021-07-21 17:27:09 +010086Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
87Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
Paul Duffinc11f6672021-07-20 00:04:21 +010088Ljava/util/zip/ZipFile;-><clinit>()V,blocked
89Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;,blocked
90Ljava/lang/Character;->serialVersionUID:J,sdk
91Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V,blocked
Spandan Das559132f2021-08-25 18:17:33 +000092"""
Paul Duffin53a76072021-07-21 17:27:09 +010093
Paul Duffinc11f6672021-07-20 00:04:21 +010094 def test_extract_subset_signature(self):
Spandan Das559132f2021-08-25 18:17:33 +000095 monolithic = self.read_flag_trie_from_string(
96 TestDetectOverlaps.extractInput)
Paul Duffin67b9d612021-07-21 17:38:47 +010097
98 patterns = 'Ljava/lang/Object;->hashCode()I'
99
Spandan Das559132f2021-08-25 18:17:33 +0000100 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
101 monolithic, patterns)
Paul Duffin53a76072021-07-21 17:27:09 +0100102 expected = {
103 'Ljava/lang/Object;->hashCode()I': {
104 None: ['public-api', 'system-api', 'test-api'],
105 'signature': 'Ljava/lang/Object;->hashCode()I',
106 },
107 }
108 self.assertEqual(expected, subset)
109
Paul Duffinc11f6672021-07-20 00:04:21 +0100110 def test_extract_subset_class(self):
Spandan Das559132f2021-08-25 18:17:33 +0000111 monolithic = self.read_flag_trie_from_string(
112 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100113
114 patterns = 'java/lang/Object'
115
Spandan Das559132f2021-08-25 18:17:33 +0000116 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
117 monolithic, patterns)
Paul Duffinc11f6672021-07-20 00:04:21 +0100118 expected = {
119 'Ljava/lang/Object;->hashCode()I': {
120 None: ['public-api', 'system-api', 'test-api'],
121 'signature': 'Ljava/lang/Object;->hashCode()I',
122 },
123 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
124 None: ['blocked'],
125 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
126 },
127 }
128 self.assertEqual(expected, subset)
129
130 def test_extract_subset_outer_class(self):
Spandan Das559132f2021-08-25 18:17:33 +0000131 monolithic = self.read_flag_trie_from_string(
132 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100133
134 patterns = 'java/lang/Character'
135
Spandan Das559132f2021-08-25 18:17:33 +0000136 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
137 monolithic, patterns)
Paul Duffinc11f6672021-07-20 00:04:21 +0100138 expected = {
Spandan Das559132f2021-08-25 18:17:33 +0000139 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
140 {
141 None: ['blocked'],
142 'signature':
143 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
144 },
Paul Duffinc11f6672021-07-20 00:04:21 +0100145 'Ljava/lang/Character;->serialVersionUID:J': {
146 None: ['sdk'],
147 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
148 },
149 }
150 self.assertEqual(expected, subset)
151
152 def test_extract_subset_nested_class(self):
Spandan Das559132f2021-08-25 18:17:33 +0000153 monolithic = self.read_flag_trie_from_string(
154 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100155
156 patterns = 'java/lang/Character$UnicodeScript'
157
Spandan Das559132f2021-08-25 18:17:33 +0000158 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
159 monolithic, patterns)
Paul Duffinc11f6672021-07-20 00:04:21 +0100160 expected = {
Spandan Das559132f2021-08-25 18:17:33 +0000161 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
162 {
163 None: ['blocked'],
164 'signature':
165 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
166 },
Paul Duffinc11f6672021-07-20 00:04:21 +0100167 }
168 self.assertEqual(expected, subset)
169
170 def test_extract_subset_package(self):
Spandan Das559132f2021-08-25 18:17:33 +0000171 monolithic = self.read_flag_trie_from_string(
172 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100173
174 patterns = 'java/lang/*'
175
Spandan Das559132f2021-08-25 18:17:33 +0000176 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
177 monolithic, patterns)
Paul Duffinc11f6672021-07-20 00:04:21 +0100178 expected = {
Spandan Das559132f2021-08-25 18:17:33 +0000179 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
180 {
181 None: ['blocked'],
182 'signature':
183 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
184 },
Paul Duffinc11f6672021-07-20 00:04:21 +0100185 'Ljava/lang/Character;->serialVersionUID:J': {
186 None: ['sdk'],
187 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
188 },
189 'Ljava/lang/Object;->hashCode()I': {
190 None: ['public-api', 'system-api', 'test-api'],
191 'signature': 'Ljava/lang/Object;->hashCode()I',
192 },
193 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
194 None: ['blocked'],
195 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
196 },
197 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V': {
198 None: ['blocked'],
199 'signature': 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V',
200 },
201 }
202 self.assertEqual(expected, subset)
203
204 def test_extract_subset_recursive_package(self):
Spandan Das559132f2021-08-25 18:17:33 +0000205 monolithic = self.read_flag_trie_from_string(
206 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100207
208 patterns = 'java/**'
209
Spandan Das559132f2021-08-25 18:17:33 +0000210 subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
211 monolithic, patterns)
Paul Duffinc11f6672021-07-20 00:04:21 +0100212 expected = {
Spandan Das559132f2021-08-25 18:17:33 +0000213 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
214 {
215 None: ['blocked'],
216 'signature':
217 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
218 },
Paul Duffinc11f6672021-07-20 00:04:21 +0100219 'Ljava/lang/Character;->serialVersionUID:J': {
220 None: ['sdk'],
221 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
222 },
223 'Ljava/lang/Object;->hashCode()I': {
224 None: ['public-api', 'system-api', 'test-api'],
225 'signature': 'Ljava/lang/Object;->hashCode()I',
226 },
227 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
228 None: ['blocked'],
229 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
230 },
231 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V': {
232 None: ['blocked'],
233 'signature': 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V',
234 },
235 'Ljava/util/zip/ZipFile;-><clinit>()V': {
236 None: ['blocked'],
237 'signature': 'Ljava/util/zip/ZipFile;-><clinit>()V',
238 },
239 }
240 self.assertEqual(expected, subset)
241
242 def test_extract_subset_invalid_pattern_wildcard_and_member(self):
Spandan Das559132f2021-08-25 18:17:33 +0000243 monolithic = self.read_flag_trie_from_string(
244 TestDetectOverlaps.extractInput)
Paul Duffinc11f6672021-07-20 00:04:21 +0100245
246 patterns = 'Ljava/lang/*;->hashCode()I'
247
248 with self.assertRaises(Exception) as context:
Spandan Das559132f2021-08-25 18:17:33 +0000249 self.extract_subset_from_monolithic_flags_as_dict_from_string(
250 monolithic, patterns)
251 self.assertTrue('contains wildcard * and member signature hashCode()I'
252 in str(context.exception))
Paul Duffinc11f6672021-07-20 00:04:21 +0100253
254 def test_read_trie_duplicate(self):
255 with self.assertRaises(Exception) as context:
Spandan Das559132f2021-08-25 18:17:33 +0000256 self.read_flag_trie_from_string("""
Paul Duffinc11f6672021-07-20 00:04:21 +0100257Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
258Ljava/lang/Object;->hashCode()I,blocked
Spandan Das559132f2021-08-25 18:17:33 +0000259""")
260 self.assertTrue('Duplicate signature: Ljava/lang/Object;->hashCode()I'
261 in str(context.exception))
Paul Duffinc11f6672021-07-20 00:04:21 +0100262
263 def test_read_trie_missing_member(self):
264 with self.assertRaises(Exception) as context:
Spandan Das559132f2021-08-25 18:17:33 +0000265 self.read_flag_trie_from_string("""
Paul Duffinc11f6672021-07-20 00:04:21 +0100266Ljava/lang/Object,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000267""")
268 self.assertTrue(
269 'Invalid signature: Ljava/lang/Object, does not identify a specific member'
270 in str(context.exception))
Paul Duffinc11f6672021-07-20 00:04:21 +0100271
Paul Duffin428c6512021-07-21 15:33:22 +0100272 def test_match(self):
Spandan Das559132f2021-08-25 18:17:33 +0000273 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100274Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000275""")
276 modular = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100277Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000278""")
Paul Duffin428c6512021-07-21 15:33:22 +0100279 mismatches = compare_signature_flags(monolithic, modular)
280 expected = []
281 self.assertEqual(expected, mismatches)
282
283 def test_mismatch_overlapping_flags(self):
Spandan Das559132f2021-08-25 18:17:33 +0000284 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100285Ljava/lang/Object;->toString()Ljava/lang/String;,public-api
Spandan Das559132f2021-08-25 18:17:33 +0000286""")
287 modular = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100288Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000289""")
Paul Duffin428c6512021-07-21 15:33:22 +0100290 mismatches = compare_signature_flags(monolithic, modular)
291 expected = [
292 (
293 'Ljava/lang/Object;->toString()Ljava/lang/String;',
294 ['public-api', 'system-api', 'test-api'],
295 ['public-api'],
296 ),
297 ]
298 self.assertEqual(expected, mismatches)
299
Paul Duffin428c6512021-07-21 15:33:22 +0100300 def test_mismatch_monolithic_blocked(self):
Spandan Das559132f2021-08-25 18:17:33 +0000301 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100302Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
Spandan Das559132f2021-08-25 18:17:33 +0000303""")
304 modular = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100305Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000306""")
Paul Duffin428c6512021-07-21 15:33:22 +0100307 mismatches = compare_signature_flags(monolithic, modular)
308 expected = [
309 (
310 'Ljava/lang/Object;->toString()Ljava/lang/String;',
311 ['public-api', 'system-api', 'test-api'],
312 ['blocked'],
313 ),
314 ]
315 self.assertEqual(expected, mismatches)
316
317 def test_mismatch_modular_blocked(self):
Spandan Das559132f2021-08-25 18:17:33 +0000318 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100319Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000320""")
321 modular = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100322Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
Spandan Das559132f2021-08-25 18:17:33 +0000323""")
Paul Duffin428c6512021-07-21 15:33:22 +0100324 mismatches = compare_signature_flags(monolithic, modular)
325 expected = [
326 (
327 'Ljava/lang/Object;->toString()Ljava/lang/String;',
328 ['blocked'],
329 ['public-api', 'system-api', 'test-api'],
330 ),
331 ]
332 self.assertEqual(expected, mismatches)
333
Paul Duffin280bae62021-07-20 18:03:53 +0100334 def test_match_treat_missing_from_modular_as_blocked(self):
Paul Duffin53a76072021-07-21 17:27:09 +0100335 monolithic = self.read_signature_csv_from_string_as_dict('')
Spandan Das559132f2021-08-25 18:17:33 +0000336 modular = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100337Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000338""")
Paul Duffin428c6512021-07-21 15:33:22 +0100339 mismatches = compare_signature_flags(monolithic, modular)
340 expected = [
341 (
342 'Ljava/lang/Object;->toString()Ljava/lang/String;',
343 ['public-api', 'system-api', 'test-api'],
344 [],
345 ),
346 ]
347 self.assertEqual(expected, mismatches)
348
Paul Duffin280bae62021-07-20 18:03:53 +0100349 def test_mismatch_treat_missing_from_modular_as_blocked(self):
Spandan Das559132f2021-08-25 18:17:33 +0000350 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100351Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
Spandan Das559132f2021-08-25 18:17:33 +0000352""")
Paul Duffin428c6512021-07-21 15:33:22 +0100353 modular = {}
354 mismatches = compare_signature_flags(monolithic, modular)
Paul Duffin53a76072021-07-21 17:27:09 +0100355 expected = [
356 (
357 'Ljava/lang/Object;->hashCode()I',
Paul Duffin280bae62021-07-20 18:03:53 +0100358 ['blocked'],
Paul Duffin53a76072021-07-21 17:27:09 +0100359 ['public-api', 'system-api', 'test-api'],
360 ),
361 ]
Paul Duffin428c6512021-07-21 15:33:22 +0100362 self.assertEqual(expected, mismatches)
363
364 def test_blocked_missing_from_modular(self):
Spandan Das559132f2021-08-25 18:17:33 +0000365 monolithic = self.read_signature_csv_from_string_as_dict("""
Paul Duffin428c6512021-07-21 15:33:22 +0100366Ljava/lang/Object;->hashCode()I,blocked
Spandan Das559132f2021-08-25 18:17:33 +0000367""")
Paul Duffin428c6512021-07-21 15:33:22 +0100368 modular = {}
369 mismatches = compare_signature_flags(monolithic, modular)
Paul Duffin280bae62021-07-20 18:03:53 +0100370 expected = []
Paul Duffin428c6512021-07-21 15:33:22 +0100371 self.assertEqual(expected, mismatches)
Spandan Das559132f2021-08-25 18:17:33 +0000372#pylint: enable=line-too-long
Paul Duffin428c6512021-07-21 15:33:22 +0100373
374if __name__ == '__main__':
375 unittest.main(verbosity=2)