xref: /aosp_15_r20/build/soong/scripts/hiddenapi/signature_patterns_test.py (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker#!/usr/bin/env python
2*333d2b36SAndroid Build Coastguard Worker#
3*333d2b36SAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project
4*333d2b36SAndroid Build Coastguard Worker#
5*333d2b36SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the 'License');
6*333d2b36SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*333d2b36SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*333d2b36SAndroid Build Coastguard Worker#
9*333d2b36SAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
10*333d2b36SAndroid Build Coastguard Worker#
11*333d2b36SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*333d2b36SAndroid Build Coastguard Worker# distributed under the License is distributed on an 'AS IS' BASIS,
13*333d2b36SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*333d2b36SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*333d2b36SAndroid Build Coastguard Worker# limitations under the License.
16*333d2b36SAndroid Build Coastguard Worker"""Unit tests for signature_patterns.py."""
17*333d2b36SAndroid Build Coastguard Workerimport io
18*333d2b36SAndroid Build Coastguard Workerimport unittest
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Workerimport signature_patterns
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Workerclass TestGeneratedPatterns(unittest.TestCase):
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker    csv_flags = """
26*333d2b36SAndroid Build Coastguard WorkerLjava/lang/ProcessBuilder$Redirect$1;-><init>()V,blocked
27*333d2b36SAndroid Build Coastguard WorkerLjava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;,public-api
28*333d2b36SAndroid Build Coastguard WorkerLjava/lang/Object;->hashCode()I,public-api,system-api,test-api
29*333d2b36SAndroid Build Coastguard WorkerLjava/lang/Object;->toString()Ljava/lang/String;,blocked
30*333d2b36SAndroid Build Coastguard Worker"""
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Worker    @staticmethod
33*333d2b36SAndroid Build Coastguard Worker    def produce_patterns_from_string(csv_text,
34*333d2b36SAndroid Build Coastguard Worker                                     split_packages=None,
35*333d2b36SAndroid Build Coastguard Worker                                     single_packages=None,
36*333d2b36SAndroid Build Coastguard Worker                                     package_prefixes=None):
37*333d2b36SAndroid Build Coastguard Worker        with io.StringIO(csv_text) as f:
38*333d2b36SAndroid Build Coastguard Worker            return signature_patterns.produce_patterns_from_stream(
39*333d2b36SAndroid Build Coastguard Worker                f, split_packages, single_packages, package_prefixes)
40*333d2b36SAndroid Build Coastguard Worker
41*333d2b36SAndroid Build Coastguard Worker    def test_generate_unmatched(self):
42*333d2b36SAndroid Build Coastguard Worker        _, errors = self.produce_patterns_from_string(
43*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags)
44*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([
45*333d2b36SAndroid Build Coastguard Worker            'The following packages were unexpected, please add them to one of '
46*333d2b36SAndroid Build Coastguard Worker            'the hidden_api properties, split_packages, single_packages or '
47*333d2b36SAndroid Build Coastguard Worker            'package_prefixes:\n'
48*333d2b36SAndroid Build Coastguard Worker            '    java.lang'
49*333d2b36SAndroid Build Coastguard Worker        ], errors)
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker    def test_generate_default(self):
52*333d2b36SAndroid Build Coastguard Worker        patterns, errors = self.produce_patterns_from_string(
53*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags, single_packages=['java/lang'])
54*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([], errors)
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker        expected = [
57*333d2b36SAndroid Build Coastguard Worker            'java/lang/*',
58*333d2b36SAndroid Build Coastguard Worker        ]
59*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, patterns)
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker    def test_generate_split_package(self):
62*333d2b36SAndroid Build Coastguard Worker        patterns, errors = self.produce_patterns_from_string(
63*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags, split_packages={'java/lang'})
64*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([], errors)
65*333d2b36SAndroid Build Coastguard Worker
66*333d2b36SAndroid Build Coastguard Worker        expected = [
67*333d2b36SAndroid Build Coastguard Worker            'java/lang/Character',
68*333d2b36SAndroid Build Coastguard Worker            'java/lang/Object',
69*333d2b36SAndroid Build Coastguard Worker            'java/lang/ProcessBuilder',
70*333d2b36SAndroid Build Coastguard Worker        ]
71*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, patterns)
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker    def test_generate_split_package_wildcard(self):
74*333d2b36SAndroid Build Coastguard Worker        patterns, errors = self.produce_patterns_from_string(
75*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags, split_packages={'*'})
76*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([], errors)
77*333d2b36SAndroid Build Coastguard Worker
78*333d2b36SAndroid Build Coastguard Worker        expected = [
79*333d2b36SAndroid Build Coastguard Worker            'java/lang/Character',
80*333d2b36SAndroid Build Coastguard Worker            'java/lang/Object',
81*333d2b36SAndroid Build Coastguard Worker            'java/lang/ProcessBuilder',
82*333d2b36SAndroid Build Coastguard Worker        ]
83*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, patterns)
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker    def test_generate_package_prefix(self):
86*333d2b36SAndroid Build Coastguard Worker        patterns, errors = self.produce_patterns_from_string(
87*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags, package_prefixes={'java/lang'})
88*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([], errors)
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker        expected = [
91*333d2b36SAndroid Build Coastguard Worker            'java/lang/**',
92*333d2b36SAndroid Build Coastguard Worker        ]
93*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, patterns)
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Worker    def test_generate_package_prefix_top_package(self):
96*333d2b36SAndroid Build Coastguard Worker        patterns, errors = self.produce_patterns_from_string(
97*333d2b36SAndroid Build Coastguard Worker            TestGeneratedPatterns.csv_flags, package_prefixes={'java'})
98*333d2b36SAndroid Build Coastguard Worker        self.assertEqual([], errors)
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard Worker        expected = [
101*333d2b36SAndroid Build Coastguard Worker            'java/**',
102*333d2b36SAndroid Build Coastguard Worker        ]
103*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, patterns)
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker    def test_split_package_wildcard_conflicts_with_other_split_packages(self):
106*333d2b36SAndroid Build Coastguard Worker        errors = signature_patterns.validate_split_packages({'*', 'java'})
107*333d2b36SAndroid Build Coastguard Worker        expected = [
108*333d2b36SAndroid Build Coastguard Worker            'split packages are invalid as they contain both the wildcard (*)'
109*333d2b36SAndroid Build Coastguard Worker            ' and specific packages, use the wildcard or specific packages,'
110*333d2b36SAndroid Build Coastguard Worker            ' not a mixture'
111*333d2b36SAndroid Build Coastguard Worker        ]
112*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, errors)
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker    def test_split_package_wildcard_conflicts_with_package_prefixes(self):
115*333d2b36SAndroid Build Coastguard Worker        errors = signature_patterns.validate_package_prefixes(
116*333d2b36SAndroid Build Coastguard Worker            {'*'}, [], package_prefixes={'java'})
117*333d2b36SAndroid Build Coastguard Worker        expected = [
118*333d2b36SAndroid Build Coastguard Worker            "split package '*' conflicts with all package prefixes java\n"
119*333d2b36SAndroid Build Coastguard Worker            '    add split_packages:[] to fix',
120*333d2b36SAndroid Build Coastguard Worker        ]
121*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, errors)
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Worker    def test_split_package_conflicts_with_package_prefixes(self):
124*333d2b36SAndroid Build Coastguard Worker        errors = signature_patterns.validate_package_prefixes(
125*333d2b36SAndroid Build Coastguard Worker            {'java/split'}, [], package_prefixes={'java'})
126*333d2b36SAndroid Build Coastguard Worker        expected = [
127*333d2b36SAndroid Build Coastguard Worker            'split package java.split is matched by package prefix java',
128*333d2b36SAndroid Build Coastguard Worker        ]
129*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, errors)
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Worker    def test_single_package_conflicts_with_package_prefixes(self):
132*333d2b36SAndroid Build Coastguard Worker        errors = signature_patterns.validate_package_prefixes(
133*333d2b36SAndroid Build Coastguard Worker            {}, ['java/single'], package_prefixes={'java'})
134*333d2b36SAndroid Build Coastguard Worker        expected = [
135*333d2b36SAndroid Build Coastguard Worker            'single package java.single is matched by package prefix java',
136*333d2b36SAndroid Build Coastguard Worker        ]
137*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, errors)
138*333d2b36SAndroid Build Coastguard Worker
139*333d2b36SAndroid Build Coastguard Worker    def test_single_package_conflicts_with_split_packages(self):
140*333d2b36SAndroid Build Coastguard Worker        errors = signature_patterns.validate_single_packages({'java/pkg'},
141*333d2b36SAndroid Build Coastguard Worker                                                             ['java/pkg'])
142*333d2b36SAndroid Build Coastguard Worker        expected = [
143*333d2b36SAndroid Build Coastguard Worker            'single_packages and split_packages overlap, please ensure the '
144*333d2b36SAndroid Build Coastguard Worker            'following packages are only present in one:\n    java/pkg'
145*333d2b36SAndroid Build Coastguard Worker        ]
146*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, errors)
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Workerif __name__ == '__main__':
150*333d2b36SAndroid Build Coastguard Worker    unittest.main(verbosity=2)
151