xref: /aosp_15_r20/build/soong/scripts/hiddenapi/analyze_bcpf_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) 2022 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 analyzing bootclasspath_fragment modules."""
17*333d2b36SAndroid Build Coastguard Workerimport os.path
18*333d2b36SAndroid Build Coastguard Workerimport shutil
19*333d2b36SAndroid Build Coastguard Workerimport tempfile
20*333d2b36SAndroid Build Coastguard Workerimport unittest
21*333d2b36SAndroid Build Coastguard Workerimport unittest.mock
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Workerimport sys
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Workerimport analyze_bcpf as ab
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker_FRAMEWORK_HIDDENAPI = "frameworks/base/boot/hiddenapi"
28*333d2b36SAndroid Build Coastguard Worker_MAX_TARGET_O = f"{_FRAMEWORK_HIDDENAPI}/hiddenapi-max-target-o.txt"
29*333d2b36SAndroid Build Coastguard Worker_MAX_TARGET_P = f"{_FRAMEWORK_HIDDENAPI}/hiddenapi-max-target-p.txt"
30*333d2b36SAndroid Build Coastguard Worker_MAX_TARGET_Q = f"{_FRAMEWORK_HIDDENAPI}/hiddenapi-max-target-q.txt"
31*333d2b36SAndroid Build Coastguard Worker_MAX_TARGET_R = f"{_FRAMEWORK_HIDDENAPI}/hiddenapi-max-target-r-loprio.txt"
32*333d2b36SAndroid Build Coastguard Worker
33*333d2b36SAndroid Build Coastguard Worker_MULTI_LINE_COMMENT = """
34*333d2b36SAndroid Build Coastguard WorkerLorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu justo,
35*333d2b36SAndroid Build Coastguard Workerbibendum eu malesuada vel, fringilla in odio. Etiam gravida ultricies sem
36*333d2b36SAndroid Build Coastguard Workertincidunt luctus.""".replace("\n", " ").strip()
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Workerclass FakeBuildOperation(ab.BuildOperation):
40*333d2b36SAndroid Build Coastguard Worker
41*333d2b36SAndroid Build Coastguard Worker    def __init__(self, lines, return_code):
42*333d2b36SAndroid Build Coastguard Worker        ab.BuildOperation.__init__(self, None)
43*333d2b36SAndroid Build Coastguard Worker        self._lines = lines
44*333d2b36SAndroid Build Coastguard Worker        self.returncode = return_code
45*333d2b36SAndroid Build Coastguard Worker
46*333d2b36SAndroid Build Coastguard Worker    def lines(self):
47*333d2b36SAndroid Build Coastguard Worker        return iter(self._lines)
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Worker    def wait(self, *args, **kwargs):
50*333d2b36SAndroid Build Coastguard Worker        return
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Workerclass TestAnalyzeBcpf(unittest.TestCase):
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Worker    def setUp(self):
56*333d2b36SAndroid Build Coastguard Worker        # Create a temporary directory
57*333d2b36SAndroid Build Coastguard Worker        self.test_dir = tempfile.mkdtemp()
58*333d2b36SAndroid Build Coastguard Worker
59*333d2b36SAndroid Build Coastguard Worker    def tearDown(self):
60*333d2b36SAndroid Build Coastguard Worker        # Remove the directory after the test
61*333d2b36SAndroid Build Coastguard Worker        shutil.rmtree(self.test_dir)
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker    @staticmethod
64*333d2b36SAndroid Build Coastguard Worker    def write_abs_file(abs_path, contents):
65*333d2b36SAndroid Build Coastguard Worker        os.makedirs(os.path.dirname(abs_path), exist_ok=True)
66*333d2b36SAndroid Build Coastguard Worker        with open(abs_path, "w", encoding="utf8") as f:
67*333d2b36SAndroid Build Coastguard Worker            print(contents.removeprefix("\n"), file=f, end="")
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker    def populate_fs(self, fs):
70*333d2b36SAndroid Build Coastguard Worker        for path, contents in fs.items():
71*333d2b36SAndroid Build Coastguard Worker            abs_path = os.path.join(self.test_dir, path)
72*333d2b36SAndroid Build Coastguard Worker            self.write_abs_file(abs_path, contents)
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker    def create_analyzer_for_test(self,
75*333d2b36SAndroid Build Coastguard Worker                                 fs=None,
76*333d2b36SAndroid Build Coastguard Worker                                 bcpf="bcpf",
77*333d2b36SAndroid Build Coastguard Worker                                 apex="apex",
78*333d2b36SAndroid Build Coastguard Worker                                 sdk="sdk",
79*333d2b36SAndroid Build Coastguard Worker                                 fix=False):
80*333d2b36SAndroid Build Coastguard Worker        if fs:
81*333d2b36SAndroid Build Coastguard Worker            self.populate_fs(fs)
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard Worker        top_dir = self.test_dir
84*333d2b36SAndroid Build Coastguard Worker        out_dir = os.path.join(self.test_dir, "out")
85*333d2b36SAndroid Build Coastguard Worker        product_out_dir = "out/product"
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard Worker        bcpf_dir = f"{bcpf}-dir"
88*333d2b36SAndroid Build Coastguard Worker        modules = {bcpf: {"path": [bcpf_dir]}}
89*333d2b36SAndroid Build Coastguard Worker        module_info = ab.ModuleInfo(modules)
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Worker        analyzer = ab.BcpfAnalyzer(
92*333d2b36SAndroid Build Coastguard Worker            tool_path=os.path.join(out_dir, "bin"),
93*333d2b36SAndroid Build Coastguard Worker            top_dir=top_dir,
94*333d2b36SAndroid Build Coastguard Worker            out_dir=out_dir,
95*333d2b36SAndroid Build Coastguard Worker            product_out_dir=product_out_dir,
96*333d2b36SAndroid Build Coastguard Worker            bcpf=bcpf,
97*333d2b36SAndroid Build Coastguard Worker            apex=apex,
98*333d2b36SAndroid Build Coastguard Worker            sdk=sdk,
99*333d2b36SAndroid Build Coastguard Worker            fix=fix,
100*333d2b36SAndroid Build Coastguard Worker            module_info=module_info,
101*333d2b36SAndroid Build Coastguard Worker        )
102*333d2b36SAndroid Build Coastguard Worker        analyzer.load_all_flags()
103*333d2b36SAndroid Build Coastguard Worker        return analyzer
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker    def test_reformat_report_text(self):
106*333d2b36SAndroid Build Coastguard Worker        lines = """
107*333d2b36SAndroid Build Coastguard Worker99. An item in a numbered list
108*333d2b36SAndroid Build Coastguard Workerthat traverses multiple lines.
109*333d2b36SAndroid Build Coastguard Worker
110*333d2b36SAndroid Build Coastguard Worker   An indented example
111*333d2b36SAndroid Build Coastguard Worker   that should not be reformatted.
112*333d2b36SAndroid Build Coastguard Worker"""
113*333d2b36SAndroid Build Coastguard Worker        reformatted = ab.BcpfAnalyzer.reformat_report_test(lines)
114*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(
115*333d2b36SAndroid Build Coastguard Worker            """
116*333d2b36SAndroid Build Coastguard Worker99. An item in a numbered list that traverses multiple lines.
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker   An indented example
119*333d2b36SAndroid Build Coastguard Worker   that should not be reformatted.
120*333d2b36SAndroid Build Coastguard Worker""", reformatted)
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Worker    def do_test_build_flags(self, fix):
123*333d2b36SAndroid Build Coastguard Worker        lines = """
124*333d2b36SAndroid Build Coastguard WorkerERROR: Hidden API flags are inconsistent:
125*333d2b36SAndroid Build Coastguard Worker< out/soong/.intermediates/bcpf-dir/bcpf-dir/filtered-flags.csv
126*333d2b36SAndroid Build Coastguard Worker> out/soong/hiddenapi/hiddenapi-flags.csv
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Worker< Lacme/test/Class;-><init>()V,blocked
129*333d2b36SAndroid Build Coastguard Worker> Lacme/test/Class;-><init>()V,max-target-o
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Worker< Lacme/test/Other;->getThing()Z,blocked
132*333d2b36SAndroid Build Coastguard Worker> Lacme/test/Other;->getThing()Z,max-target-p
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker< Lacme/test/Widget;-><init()V,blocked
135*333d2b36SAndroid Build Coastguard Worker> Lacme/test/Widget;-><init()V,max-target-q
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker< Lacme/test/Gadget;->NAME:Ljava/lang/String;,blocked
138*333d2b36SAndroid Build Coastguard Worker> Lacme/test/Gadget;->NAME:Ljava/lang/String;,lo-prio,max-target-r
139*333d2b36SAndroid Build Coastguard Worker16:37:32 ninja failed with: exit status 1
140*333d2b36SAndroid Build Coastguard Worker""".strip().splitlines()
141*333d2b36SAndroid Build Coastguard Worker        operation = FakeBuildOperation(lines=lines, return_code=1)
142*333d2b36SAndroid Build Coastguard Worker
143*333d2b36SAndroid Build Coastguard Worker        fs = {
144*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_O:
145*333d2b36SAndroid Build Coastguard Worker                """
146*333d2b36SAndroid Build Coastguard WorkerLacme/items/Magnet;->size:I
147*333d2b36SAndroid Build Coastguard WorkerLacme/test/Class;-><init>()V
148*333d2b36SAndroid Build Coastguard Worker""",
149*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_P:
150*333d2b36SAndroid Build Coastguard Worker                """
151*333d2b36SAndroid Build Coastguard WorkerLacme/items/Rocket;->size:I
152*333d2b36SAndroid Build Coastguard WorkerLacme/test/Other;->getThing()Z
153*333d2b36SAndroid Build Coastguard Worker""",
154*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_Q:
155*333d2b36SAndroid Build Coastguard Worker                """
156*333d2b36SAndroid Build Coastguard WorkerLacme/items/Rock;->size:I
157*333d2b36SAndroid Build Coastguard WorkerLacme/test/Widget;-><init()V
158*333d2b36SAndroid Build Coastguard Worker""",
159*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_R:
160*333d2b36SAndroid Build Coastguard Worker                """
161*333d2b36SAndroid Build Coastguard WorkerLacme/items/Lever;->size:I
162*333d2b36SAndroid Build Coastguard WorkerLacme/test/Gadget;->NAME:Ljava/lang/String;
163*333d2b36SAndroid Build Coastguard Worker""",
164*333d2b36SAndroid Build Coastguard Worker            "bcpf-dir/hiddenapi/hiddenapi-max-target-p.txt":
165*333d2b36SAndroid Build Coastguard Worker                """
166*333d2b36SAndroid Build Coastguard WorkerLacme/old/Class;->getWidget()Lacme/test/Widget;
167*333d2b36SAndroid Build Coastguard Worker""",
168*333d2b36SAndroid Build Coastguard Worker            "out/soong/.intermediates/bcpf-dir/bcpf/all-flags.csv":
169*333d2b36SAndroid Build Coastguard Worker                """
170*333d2b36SAndroid Build Coastguard WorkerLacme/test/Gadget;->NAME:Ljava/lang/String;,blocked
171*333d2b36SAndroid Build Coastguard WorkerLacme/test/Widget;-><init()V,blocked
172*333d2b36SAndroid Build Coastguard WorkerLacme/test/Class;-><init>()V,blocked
173*333d2b36SAndroid Build Coastguard WorkerLacme/test/Other;->getThing()Z,blocked
174*333d2b36SAndroid Build Coastguard Worker""",
175*333d2b36SAndroid Build Coastguard Worker        }
176*333d2b36SAndroid Build Coastguard Worker
177*333d2b36SAndroid Build Coastguard Worker        analyzer = self.create_analyzer_for_test(fs, fix=fix)
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker        # Override the build_file_read_output() method to just return a fake
180*333d2b36SAndroid Build Coastguard Worker        # build operation.
181*333d2b36SAndroid Build Coastguard Worker        analyzer.build_file_read_output = unittest.mock.Mock(
182*333d2b36SAndroid Build Coastguard Worker            return_value=operation)
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Worker        # Override the run_command() method to do nothing.
185*333d2b36SAndroid Build Coastguard Worker        analyzer.run_command = unittest.mock.Mock()
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker        result = ab.Result()
188*333d2b36SAndroid Build Coastguard Worker
189*333d2b36SAndroid Build Coastguard Worker        analyzer.build_monolithic_flags(result)
190*333d2b36SAndroid Build Coastguard Worker        expected_diffs = {
191*333d2b36SAndroid Build Coastguard Worker            "Lacme/test/Gadget;->NAME:Ljava/lang/String;":
192*333d2b36SAndroid Build Coastguard Worker                (["blocked"], ["lo-prio", "max-target-r"]),
193*333d2b36SAndroid Build Coastguard Worker            "Lacme/test/Widget;-><init()V": (["blocked"], ["max-target-q"]),
194*333d2b36SAndroid Build Coastguard Worker            "Lacme/test/Class;-><init>()V": (["blocked"], ["max-target-o"]),
195*333d2b36SAndroid Build Coastguard Worker            "Lacme/test/Other;->getThing()Z": (["blocked"], ["max-target-p"])
196*333d2b36SAndroid Build Coastguard Worker        }
197*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected_diffs, result.diffs, msg="flag differences")
198*333d2b36SAndroid Build Coastguard Worker
199*333d2b36SAndroid Build Coastguard Worker        expected_property_changes = [
200*333d2b36SAndroid Build Coastguard Worker            ab.HiddenApiPropertyChange(
201*333d2b36SAndroid Build Coastguard Worker                property_name="max_target_o_low_priority",
202*333d2b36SAndroid Build Coastguard Worker                values=["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
203*333d2b36SAndroid Build Coastguard Worker                property_comment=""),
204*333d2b36SAndroid Build Coastguard Worker            ab.HiddenApiPropertyChange(
205*333d2b36SAndroid Build Coastguard Worker                property_name="max_target_p",
206*333d2b36SAndroid Build Coastguard Worker                values=["hiddenapi/hiddenapi-max-target-p.txt"],
207*333d2b36SAndroid Build Coastguard Worker                property_comment=""),
208*333d2b36SAndroid Build Coastguard Worker            ab.HiddenApiPropertyChange(
209*333d2b36SAndroid Build Coastguard Worker                property_name="max_target_q",
210*333d2b36SAndroid Build Coastguard Worker                values=["hiddenapi/hiddenapi-max-target-q.txt"],
211*333d2b36SAndroid Build Coastguard Worker                property_comment=""),
212*333d2b36SAndroid Build Coastguard Worker            ab.HiddenApiPropertyChange(
213*333d2b36SAndroid Build Coastguard Worker                property_name="max_target_r_low_priority",
214*333d2b36SAndroid Build Coastguard Worker                values=["hiddenapi/hiddenapi-max-target-r-low-priority.txt"],
215*333d2b36SAndroid Build Coastguard Worker                property_comment=""),
216*333d2b36SAndroid Build Coastguard Worker        ]
217*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(
218*333d2b36SAndroid Build Coastguard Worker            expected_property_changes,
219*333d2b36SAndroid Build Coastguard Worker            result.property_changes,
220*333d2b36SAndroid Build Coastguard Worker            msg="property changes")
221*333d2b36SAndroid Build Coastguard Worker
222*333d2b36SAndroid Build Coastguard Worker        return result
223*333d2b36SAndroid Build Coastguard Worker
224*333d2b36SAndroid Build Coastguard Worker    def test_build_flags_report(self):
225*333d2b36SAndroid Build Coastguard Worker        result = self.do_test_build_flags(fix=False)
226*333d2b36SAndroid Build Coastguard Worker
227*333d2b36SAndroid Build Coastguard Worker        expected_file_changes = [
228*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
229*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/"
230*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-o-low-priority.txt",
231*333d2b36SAndroid Build Coastguard Worker                description="""Add the following entries:
232*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Class;-><init>()V
233*333d2b36SAndroid Build Coastguard Worker""",
234*333d2b36SAndroid Build Coastguard Worker            ),
235*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
236*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/hiddenapi-max-target-p.txt",
237*333d2b36SAndroid Build Coastguard Worker                description="""Add the following entries:
238*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Other;->getThing()Z
239*333d2b36SAndroid Build Coastguard Worker""",
240*333d2b36SAndroid Build Coastguard Worker            ),
241*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
242*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/hiddenapi-max-target-q.txt",
243*333d2b36SAndroid Build Coastguard Worker                description="""Add the following entries:
244*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Widget;-><init()V
245*333d2b36SAndroid Build Coastguard Worker"""),
246*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
247*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/"
248*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-r-low-priority.txt",
249*333d2b36SAndroid Build Coastguard Worker                description="""Add the following entries:
250*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Gadget;->NAME:Ljava/lang/String;
251*333d2b36SAndroid Build Coastguard Worker"""),
252*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
253*333d2b36SAndroid Build Coastguard Worker                path="frameworks/base/boot/hiddenapi/"
254*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-o.txt",
255*333d2b36SAndroid Build Coastguard Worker                description="""Remove the following entries:
256*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Class;-><init>()V
257*333d2b36SAndroid Build Coastguard Worker"""),
258*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
259*333d2b36SAndroid Build Coastguard Worker                path="frameworks/base/boot/hiddenapi/"
260*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-p.txt",
261*333d2b36SAndroid Build Coastguard Worker                description="""Remove the following entries:
262*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Other;->getThing()Z
263*333d2b36SAndroid Build Coastguard Worker"""),
264*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
265*333d2b36SAndroid Build Coastguard Worker                path="frameworks/base/boot/hiddenapi/"
266*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-q.txt",
267*333d2b36SAndroid Build Coastguard Worker                description="""Remove the following entries:
268*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Widget;-><init()V
269*333d2b36SAndroid Build Coastguard Worker"""),
270*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
271*333d2b36SAndroid Build Coastguard Worker                path="frameworks/base/boot/hiddenapi/"
272*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-r-loprio.txt",
273*333d2b36SAndroid Build Coastguard Worker                description="""Remove the following entries:
274*333d2b36SAndroid Build Coastguard Worker            Lacme/test/Gadget;->NAME:Ljava/lang/String;
275*333d2b36SAndroid Build Coastguard Worker""")
276*333d2b36SAndroid Build Coastguard Worker        ]
277*333d2b36SAndroid Build Coastguard Worker        result.file_changes.sort()
278*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(
279*333d2b36SAndroid Build Coastguard Worker            expected_file_changes, result.file_changes, msg="file_changes")
280*333d2b36SAndroid Build Coastguard Worker
281*333d2b36SAndroid Build Coastguard Worker    def test_build_flags_fix(self):
282*333d2b36SAndroid Build Coastguard Worker        result = self.do_test_build_flags(fix=True)
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Worker        expected_file_changes = [
285*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
286*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/"
287*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-o-low-priority.txt",
288*333d2b36SAndroid Build Coastguard Worker                description="Created with 'bcpf' specific entries"),
289*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
290*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/hiddenapi-max-target-p.txt",
291*333d2b36SAndroid Build Coastguard Worker                description="Added 'bcpf' specific entries"),
292*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
293*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/hiddenapi-max-target-q.txt",
294*333d2b36SAndroid Build Coastguard Worker                description="Created with 'bcpf' specific entries"),
295*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
296*333d2b36SAndroid Build Coastguard Worker                path="bcpf-dir/hiddenapi/"
297*333d2b36SAndroid Build Coastguard Worker                "hiddenapi-max-target-r-low-priority.txt",
298*333d2b36SAndroid Build Coastguard Worker                description="Created with 'bcpf' specific entries"),
299*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
300*333d2b36SAndroid Build Coastguard Worker                path=_MAX_TARGET_O,
301*333d2b36SAndroid Build Coastguard Worker                description="Removed 'bcpf' specific entries"),
302*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
303*333d2b36SAndroid Build Coastguard Worker                path=_MAX_TARGET_P,
304*333d2b36SAndroid Build Coastguard Worker                description="Removed 'bcpf' specific entries"),
305*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
306*333d2b36SAndroid Build Coastguard Worker                path=_MAX_TARGET_Q,
307*333d2b36SAndroid Build Coastguard Worker                description="Removed 'bcpf' specific entries"),
308*333d2b36SAndroid Build Coastguard Worker            ab.FileChange(
309*333d2b36SAndroid Build Coastguard Worker                path=_MAX_TARGET_R,
310*333d2b36SAndroid Build Coastguard Worker                description="Removed 'bcpf' specific entries")
311*333d2b36SAndroid Build Coastguard Worker        ]
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Worker        result.file_changes.sort()
314*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(
315*333d2b36SAndroid Build Coastguard Worker            expected_file_changes, result.file_changes, msg="file_changes")
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Worker        expected_file_contents = {
318*333d2b36SAndroid Build Coastguard Worker            "bcpf-dir/hiddenapi/hiddenapi-max-target-o-low-priority.txt":
319*333d2b36SAndroid Build Coastguard Worker                """
320*333d2b36SAndroid Build Coastguard WorkerLacme/test/Class;-><init>()V
321*333d2b36SAndroid Build Coastguard Worker""",
322*333d2b36SAndroid Build Coastguard Worker            "bcpf-dir/hiddenapi/hiddenapi-max-target-p.txt":
323*333d2b36SAndroid Build Coastguard Worker                """
324*333d2b36SAndroid Build Coastguard WorkerLacme/old/Class;->getWidget()Lacme/test/Widget;
325*333d2b36SAndroid Build Coastguard WorkerLacme/test/Other;->getThing()Z
326*333d2b36SAndroid Build Coastguard Worker""",
327*333d2b36SAndroid Build Coastguard Worker            "bcpf-dir/hiddenapi/hiddenapi-max-target-q.txt":
328*333d2b36SAndroid Build Coastguard Worker                """
329*333d2b36SAndroid Build Coastguard WorkerLacme/test/Widget;-><init()V
330*333d2b36SAndroid Build Coastguard Worker""",
331*333d2b36SAndroid Build Coastguard Worker            "bcpf-dir/hiddenapi/hiddenapi-max-target-r-low-priority.txt":
332*333d2b36SAndroid Build Coastguard Worker                """
333*333d2b36SAndroid Build Coastguard WorkerLacme/test/Gadget;->NAME:Ljava/lang/String;
334*333d2b36SAndroid Build Coastguard Worker""",
335*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_O:
336*333d2b36SAndroid Build Coastguard Worker                """
337*333d2b36SAndroid Build Coastguard WorkerLacme/items/Magnet;->size:I
338*333d2b36SAndroid Build Coastguard Worker""",
339*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_P:
340*333d2b36SAndroid Build Coastguard Worker                """
341*333d2b36SAndroid Build Coastguard WorkerLacme/items/Rocket;->size:I
342*333d2b36SAndroid Build Coastguard Worker""",
343*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_Q:
344*333d2b36SAndroid Build Coastguard Worker                """
345*333d2b36SAndroid Build Coastguard WorkerLacme/items/Rock;->size:I
346*333d2b36SAndroid Build Coastguard Worker""",
347*333d2b36SAndroid Build Coastguard Worker            _MAX_TARGET_R:
348*333d2b36SAndroid Build Coastguard Worker                """
349*333d2b36SAndroid Build Coastguard WorkerLacme/items/Lever;->size:I
350*333d2b36SAndroid Build Coastguard Worker""",
351*333d2b36SAndroid Build Coastguard Worker        }
352*333d2b36SAndroid Build Coastguard Worker        for file_change in result.file_changes:
353*333d2b36SAndroid Build Coastguard Worker            path = file_change.path
354*333d2b36SAndroid Build Coastguard Worker            expected_contents = expected_file_contents[path].lstrip()
355*333d2b36SAndroid Build Coastguard Worker            abs_path = os.path.join(self.test_dir, path)
356*333d2b36SAndroid Build Coastguard Worker            with open(abs_path, "r", encoding="utf8") as tio:
357*333d2b36SAndroid Build Coastguard Worker                contents = tio.read()
358*333d2b36SAndroid Build Coastguard Worker                self.assertEqual(
359*333d2b36SAndroid Build Coastguard Worker                    expected_contents, contents, msg=f"{path} contents")
360*333d2b36SAndroid Build Coastguard Worker
361*333d2b36SAndroid Build Coastguard Worker    def test_compute_hiddenapi_package_properties(self):
362*333d2b36SAndroid Build Coastguard Worker        fs = {
363*333d2b36SAndroid Build Coastguard Worker            "out/soong/.intermediates/bcpf-dir/bcpf/all-flags.csv":
364*333d2b36SAndroid Build Coastguard Worker                """
365*333d2b36SAndroid Build Coastguard WorkerLa/b/C;->m()V
366*333d2b36SAndroid Build Coastguard WorkerLa/b/c/D;->m()V
367*333d2b36SAndroid Build Coastguard WorkerLa/b/c/E;->m()V
368*333d2b36SAndroid Build Coastguard WorkerLb/c/D;->m()V
369*333d2b36SAndroid Build Coastguard WorkerLb/c/E;->m()V
370*333d2b36SAndroid Build Coastguard WorkerLb/c/d/E;->m()V
371*333d2b36SAndroid Build Coastguard Worker""",
372*333d2b36SAndroid Build Coastguard Worker            "out/soong/hiddenapi/hiddenapi-flags.csv":
373*333d2b36SAndroid Build Coastguard Worker                """
374*333d2b36SAndroid Build Coastguard WorkerLa/b/C;->m()V
375*333d2b36SAndroid Build Coastguard WorkerLa/b/D;->m()V
376*333d2b36SAndroid Build Coastguard WorkerLa/b/E;->m()V
377*333d2b36SAndroid Build Coastguard WorkerLa/b/c/D;->m()V
378*333d2b36SAndroid Build Coastguard WorkerLa/b/c/E;->m()V
379*333d2b36SAndroid Build Coastguard WorkerLa/b/c/d/E;->m()V
380*333d2b36SAndroid Build Coastguard WorkerLa/b/c/d/e/F;->m()V
381*333d2b36SAndroid Build Coastguard WorkerLb/c/D;->m()V
382*333d2b36SAndroid Build Coastguard WorkerLb/c/E;->m()V
383*333d2b36SAndroid Build Coastguard WorkerLb/c/d/E;->m()V
384*333d2b36SAndroid Build Coastguard Worker"""
385*333d2b36SAndroid Build Coastguard Worker        }
386*333d2b36SAndroid Build Coastguard Worker        analyzer = self.create_analyzer_for_test(fs)
387*333d2b36SAndroid Build Coastguard Worker        analyzer.load_all_flags()
388*333d2b36SAndroid Build Coastguard Worker
389*333d2b36SAndroid Build Coastguard Worker        result = ab.Result()
390*333d2b36SAndroid Build Coastguard Worker        analyzer.compute_hiddenapi_package_properties(result)
391*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b"], list(result.split_packages.keys()))
392*333d2b36SAndroid Build Coastguard Worker
393*333d2b36SAndroid Build Coastguard Worker        reason = result.split_packages["a.b"]
394*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b.C"], reason.bcpf)
395*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b.D", "a.b.E"], reason.other)
396*333d2b36SAndroid Build Coastguard Worker
397*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b.c"], list(result.single_packages.keys()))
398*333d2b36SAndroid Build Coastguard Worker
399*333d2b36SAndroid Build Coastguard Worker        reason = result.single_packages["a.b.c"]
400*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b.c"], reason.bcpf)
401*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["a.b.c.d", "a.b.c.d.e"], reason.other)
402*333d2b36SAndroid Build Coastguard Worker
403*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(["b"], result.package_prefixes)
404*333d2b36SAndroid Build Coastguard Worker
405*333d2b36SAndroid Build Coastguard Worker
406*333d2b36SAndroid Build Coastguard Workerclass TestHiddenApiPropertyChange(unittest.TestCase):
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker    def setUp(self):
409*333d2b36SAndroid Build Coastguard Worker        # Create a temporary directory
410*333d2b36SAndroid Build Coastguard Worker        self.test_dir = tempfile.mkdtemp()
411*333d2b36SAndroid Build Coastguard Worker
412*333d2b36SAndroid Build Coastguard Worker    def tearDown(self):
413*333d2b36SAndroid Build Coastguard Worker        # Remove the directory after the test
414*333d2b36SAndroid Build Coastguard Worker        shutil.rmtree(self.test_dir)
415*333d2b36SAndroid Build Coastguard Worker
416*333d2b36SAndroid Build Coastguard Worker    def check_change_fix(self, change, bpmodify_output, expected):
417*333d2b36SAndroid Build Coastguard Worker        file = os.path.join(self.test_dir, "Android.bp")
418*333d2b36SAndroid Build Coastguard Worker
419*333d2b36SAndroid Build Coastguard Worker        with open(file, "w", encoding="utf8") as tio:
420*333d2b36SAndroid Build Coastguard Worker            tio.write(bpmodify_output.strip("\n"))
421*333d2b36SAndroid Build Coastguard Worker
422*333d2b36SAndroid Build Coastguard Worker        bpmodify_runner = ab.BpModifyRunner(
423*333d2b36SAndroid Build Coastguard Worker            os.path.join(os.path.dirname(sys.argv[0]), "bpmodify"))
424*333d2b36SAndroid Build Coastguard Worker        change.fix_bp_file(file, "bcpf", bpmodify_runner)
425*333d2b36SAndroid Build Coastguard Worker
426*333d2b36SAndroid Build Coastguard Worker        with open(file, "r", encoding="utf8") as tio:
427*333d2b36SAndroid Build Coastguard Worker            contents = tio.read()
428*333d2b36SAndroid Build Coastguard Worker            self.assertEqual(expected.lstrip("\n"), contents)
429*333d2b36SAndroid Build Coastguard Worker
430*333d2b36SAndroid Build Coastguard Worker    def check_change_snippet(self, change, expected):
431*333d2b36SAndroid Build Coastguard Worker        snippet = change.snippet("        ")
432*333d2b36SAndroid Build Coastguard Worker        self.assertEqual(expected, snippet)
433*333d2b36SAndroid Build Coastguard Worker
434*333d2b36SAndroid Build Coastguard Worker    def test_change_property_with_value_no_comment(self):
435*333d2b36SAndroid Build Coastguard Worker        change = ab.HiddenApiPropertyChange(
436*333d2b36SAndroid Build Coastguard Worker            property_name="split_packages",
437*333d2b36SAndroid Build Coastguard Worker            values=["android.provider"],
438*333d2b36SAndroid Build Coastguard Worker        )
439*333d2b36SAndroid Build Coastguard Worker
440*333d2b36SAndroid Build Coastguard Worker        self.check_change_snippet(
441*333d2b36SAndroid Build Coastguard Worker            change, """
442*333d2b36SAndroid Build Coastguard Worker        split_packages: [
443*333d2b36SAndroid Build Coastguard Worker            "android.provider",
444*333d2b36SAndroid Build Coastguard Worker        ],
445*333d2b36SAndroid Build Coastguard Worker""")
446*333d2b36SAndroid Build Coastguard Worker
447*333d2b36SAndroid Build Coastguard Worker        self.check_change_fix(
448*333d2b36SAndroid Build Coastguard Worker            change, """
449*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
450*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
451*333d2b36SAndroid Build Coastguard Worker
452*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
453*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
454*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
455*333d2b36SAndroid Build Coastguard Worker        split_packages: [
456*333d2b36SAndroid Build Coastguard Worker            "android.provider",
457*333d2b36SAndroid Build Coastguard Worker        ],
458*333d2b36SAndroid Build Coastguard Worker    },
459*333d2b36SAndroid Build Coastguard Worker}
460*333d2b36SAndroid Build Coastguard Worker""", """
461*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
462*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
465*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
466*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
467*333d2b36SAndroid Build Coastguard Worker        split_packages: [
468*333d2b36SAndroid Build Coastguard Worker            "android.provider",
469*333d2b36SAndroid Build Coastguard Worker        ],
470*333d2b36SAndroid Build Coastguard Worker    },
471*333d2b36SAndroid Build Coastguard Worker}
472*333d2b36SAndroid Build Coastguard Worker""")
473*333d2b36SAndroid Build Coastguard Worker
474*333d2b36SAndroid Build Coastguard Worker    def test_change_property_with_value_and_comment(self):
475*333d2b36SAndroid Build Coastguard Worker        change = ab.HiddenApiPropertyChange(
476*333d2b36SAndroid Build Coastguard Worker            property_name="split_packages",
477*333d2b36SAndroid Build Coastguard Worker            values=["android.provider"],
478*333d2b36SAndroid Build Coastguard Worker            property_comment=_MULTI_LINE_COMMENT,
479*333d2b36SAndroid Build Coastguard Worker        )
480*333d2b36SAndroid Build Coastguard Worker
481*333d2b36SAndroid Build Coastguard Worker        self.check_change_snippet(
482*333d2b36SAndroid Build Coastguard Worker            change, """
483*333d2b36SAndroid Build Coastguard Worker        // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu
484*333d2b36SAndroid Build Coastguard Worker        // justo, bibendum eu malesuada vel, fringilla in odio. Etiam gravida
485*333d2b36SAndroid Build Coastguard Worker        // ultricies sem tincidunt luctus.
486*333d2b36SAndroid Build Coastguard Worker        split_packages: [
487*333d2b36SAndroid Build Coastguard Worker            "android.provider",
488*333d2b36SAndroid Build Coastguard Worker        ],
489*333d2b36SAndroid Build Coastguard Worker""")
490*333d2b36SAndroid Build Coastguard Worker
491*333d2b36SAndroid Build Coastguard Worker        self.check_change_fix(
492*333d2b36SAndroid Build Coastguard Worker            change, """
493*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
494*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
495*333d2b36SAndroid Build Coastguard Worker
496*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
497*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
498*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
499*333d2b36SAndroid Build Coastguard Worker        split_packages: [
500*333d2b36SAndroid Build Coastguard Worker            "android.provider",
501*333d2b36SAndroid Build Coastguard Worker        ],
502*333d2b36SAndroid Build Coastguard Worker
503*333d2b36SAndroid Build Coastguard Worker        single_packages: [
504*333d2b36SAndroid Build Coastguard Worker            "android.system",
505*333d2b36SAndroid Build Coastguard Worker        ],
506*333d2b36SAndroid Build Coastguard Worker
507*333d2b36SAndroid Build Coastguard Worker    },
508*333d2b36SAndroid Build Coastguard Worker}
509*333d2b36SAndroid Build Coastguard Worker""", """
510*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
511*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
512*333d2b36SAndroid Build Coastguard Worker
513*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
514*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
515*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
516*333d2b36SAndroid Build Coastguard Worker
517*333d2b36SAndroid Build Coastguard Worker        // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu
518*333d2b36SAndroid Build Coastguard Worker        // justo, bibendum eu malesuada vel, fringilla in odio. Etiam gravida
519*333d2b36SAndroid Build Coastguard Worker        // ultricies sem tincidunt luctus.
520*333d2b36SAndroid Build Coastguard Worker        split_packages: [
521*333d2b36SAndroid Build Coastguard Worker            "android.provider",
522*333d2b36SAndroid Build Coastguard Worker        ],
523*333d2b36SAndroid Build Coastguard Worker
524*333d2b36SAndroid Build Coastguard Worker        single_packages: [
525*333d2b36SAndroid Build Coastguard Worker            "android.system",
526*333d2b36SAndroid Build Coastguard Worker        ],
527*333d2b36SAndroid Build Coastguard Worker
528*333d2b36SAndroid Build Coastguard Worker    },
529*333d2b36SAndroid Build Coastguard Worker}
530*333d2b36SAndroid Build Coastguard Worker""")
531*333d2b36SAndroid Build Coastguard Worker
532*333d2b36SAndroid Build Coastguard Worker    def test_set_property_with_value_and_comment(self):
533*333d2b36SAndroid Build Coastguard Worker        change = ab.HiddenApiPropertyChange(
534*333d2b36SAndroid Build Coastguard Worker            property_name="split_packages",
535*333d2b36SAndroid Build Coastguard Worker            values=["another.provider", "other.system"],
536*333d2b36SAndroid Build Coastguard Worker            property_comment=_MULTI_LINE_COMMENT,
537*333d2b36SAndroid Build Coastguard Worker            action=ab.PropertyChangeAction.REPLACE,
538*333d2b36SAndroid Build Coastguard Worker        )
539*333d2b36SAndroid Build Coastguard Worker
540*333d2b36SAndroid Build Coastguard Worker        self.check_change_snippet(
541*333d2b36SAndroid Build Coastguard Worker            change, """
542*333d2b36SAndroid Build Coastguard Worker        // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu
543*333d2b36SAndroid Build Coastguard Worker        // justo, bibendum eu malesuada vel, fringilla in odio. Etiam gravida
544*333d2b36SAndroid Build Coastguard Worker        // ultricies sem tincidunt luctus.
545*333d2b36SAndroid Build Coastguard Worker        split_packages: [
546*333d2b36SAndroid Build Coastguard Worker            "another.provider",
547*333d2b36SAndroid Build Coastguard Worker            "other.system",
548*333d2b36SAndroid Build Coastguard Worker        ],
549*333d2b36SAndroid Build Coastguard Worker""")
550*333d2b36SAndroid Build Coastguard Worker
551*333d2b36SAndroid Build Coastguard Worker        self.check_change_fix(
552*333d2b36SAndroid Build Coastguard Worker            change, """
553*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
554*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
555*333d2b36SAndroid Build Coastguard Worker
556*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
557*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
558*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
559*333d2b36SAndroid Build Coastguard Worker        split_packages: [
560*333d2b36SAndroid Build Coastguard Worker            "another.provider",
561*333d2b36SAndroid Build Coastguard Worker            "other.system",
562*333d2b36SAndroid Build Coastguard Worker        ],
563*333d2b36SAndroid Build Coastguard Worker    },
564*333d2b36SAndroid Build Coastguard Worker}
565*333d2b36SAndroid Build Coastguard Worker""", """
566*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
567*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
568*333d2b36SAndroid Build Coastguard Worker
569*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
570*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
571*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
572*333d2b36SAndroid Build Coastguard Worker
573*333d2b36SAndroid Build Coastguard Worker        // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu
574*333d2b36SAndroid Build Coastguard Worker        // justo, bibendum eu malesuada vel, fringilla in odio. Etiam gravida
575*333d2b36SAndroid Build Coastguard Worker        // ultricies sem tincidunt luctus.
576*333d2b36SAndroid Build Coastguard Worker        split_packages: [
577*333d2b36SAndroid Build Coastguard Worker            "another.provider",
578*333d2b36SAndroid Build Coastguard Worker            "other.system",
579*333d2b36SAndroid Build Coastguard Worker        ],
580*333d2b36SAndroid Build Coastguard Worker    },
581*333d2b36SAndroid Build Coastguard Worker}
582*333d2b36SAndroid Build Coastguard Worker""")
583*333d2b36SAndroid Build Coastguard Worker
584*333d2b36SAndroid Build Coastguard Worker    def test_set_property_with_no_value_or_comment(self):
585*333d2b36SAndroid Build Coastguard Worker        change = ab.HiddenApiPropertyChange(
586*333d2b36SAndroid Build Coastguard Worker            property_name="split_packages",
587*333d2b36SAndroid Build Coastguard Worker            values=[],
588*333d2b36SAndroid Build Coastguard Worker            action=ab.PropertyChangeAction.REPLACE,
589*333d2b36SAndroid Build Coastguard Worker        )
590*333d2b36SAndroid Build Coastguard Worker
591*333d2b36SAndroid Build Coastguard Worker        self.check_change_snippet(change, """
592*333d2b36SAndroid Build Coastguard Worker        split_packages: [],
593*333d2b36SAndroid Build Coastguard Worker""")
594*333d2b36SAndroid Build Coastguard Worker
595*333d2b36SAndroid Build Coastguard Worker        self.check_change_fix(
596*333d2b36SAndroid Build Coastguard Worker            change, """
597*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
598*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
599*333d2b36SAndroid Build Coastguard Worker
600*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
601*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
602*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
603*333d2b36SAndroid Build Coastguard Worker        split_packages: [
604*333d2b36SAndroid Build Coastguard Worker            "another.provider",
605*333d2b36SAndroid Build Coastguard Worker            "other.system",
606*333d2b36SAndroid Build Coastguard Worker        ],
607*333d2b36SAndroid Build Coastguard Worker        package_prefixes: ["android.provider"],
608*333d2b36SAndroid Build Coastguard Worker    },
609*333d2b36SAndroid Build Coastguard Worker}
610*333d2b36SAndroid Build Coastguard Worker""", """
611*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
612*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
613*333d2b36SAndroid Build Coastguard Worker
614*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
615*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
616*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
617*333d2b36SAndroid Build Coastguard Worker        split_packages: [],
618*333d2b36SAndroid Build Coastguard Worker        package_prefixes: ["android.provider"],
619*333d2b36SAndroid Build Coastguard Worker    },
620*333d2b36SAndroid Build Coastguard Worker}
621*333d2b36SAndroid Build Coastguard Worker""")
622*333d2b36SAndroid Build Coastguard Worker
623*333d2b36SAndroid Build Coastguard Worker    def test_set_empty_property_with_no_value_or_comment(self):
624*333d2b36SAndroid Build Coastguard Worker        change = ab.HiddenApiPropertyChange(
625*333d2b36SAndroid Build Coastguard Worker            property_name="split_packages",
626*333d2b36SAndroid Build Coastguard Worker            values=[],
627*333d2b36SAndroid Build Coastguard Worker            action=ab.PropertyChangeAction.REPLACE,
628*333d2b36SAndroid Build Coastguard Worker        )
629*333d2b36SAndroid Build Coastguard Worker
630*333d2b36SAndroid Build Coastguard Worker        self.check_change_snippet(change, """
631*333d2b36SAndroid Build Coastguard Worker        split_packages: [],
632*333d2b36SAndroid Build Coastguard Worker""")
633*333d2b36SAndroid Build Coastguard Worker
634*333d2b36SAndroid Build Coastguard Worker        self.check_change_fix(
635*333d2b36SAndroid Build Coastguard Worker            change, """
636*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
637*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
638*333d2b36SAndroid Build Coastguard Worker
639*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
640*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
641*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
642*333d2b36SAndroid Build Coastguard Worker        split_packages: [],
643*333d2b36SAndroid Build Coastguard Worker        package_prefixes: ["android.provider"],
644*333d2b36SAndroid Build Coastguard Worker    },
645*333d2b36SAndroid Build Coastguard Worker}
646*333d2b36SAndroid Build Coastguard Worker""", """
647*333d2b36SAndroid Build Coastguard Workerbootclasspath_fragment {
648*333d2b36SAndroid Build Coastguard Worker    name: "bcpf",
649*333d2b36SAndroid Build Coastguard Worker
650*333d2b36SAndroid Build Coastguard Worker    // modified by the Soong or platform compat team.
651*333d2b36SAndroid Build Coastguard Worker    hidden_api: {
652*333d2b36SAndroid Build Coastguard Worker        max_target_o_low_priority: ["hiddenapi/hiddenapi-max-target-o-low-priority.txt"],
653*333d2b36SAndroid Build Coastguard Worker        split_packages: [],
654*333d2b36SAndroid Build Coastguard Worker        package_prefixes: ["android.provider"],
655*333d2b36SAndroid Build Coastguard Worker    },
656*333d2b36SAndroid Build Coastguard Worker}
657*333d2b36SAndroid Build Coastguard Worker""")
658*333d2b36SAndroid Build Coastguard Worker
659*333d2b36SAndroid Build Coastguard Worker
660*333d2b36SAndroid Build Coastguard Workerif __name__ == "__main__":
661*333d2b36SAndroid Build Coastguard Worker    unittest.main(verbosity=3)
662