xref: /aosp_15_r20/external/pigweed/pw_bloat/py/label_test.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*61c4878aSAndroid Build Coastguard Worker# Copyright 2022 The Pigweed Authors
3*61c4878aSAndroid Build Coastguard Worker#
4*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
6*61c4878aSAndroid Build Coastguard Worker# the License at
7*61c4878aSAndroid Build Coastguard Worker#
8*61c4878aSAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
9*61c4878aSAndroid Build Coastguard Worker#
10*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
14*61c4878aSAndroid Build Coastguard Worker# the License.
15*61c4878aSAndroid Build Coastguard Worker"""Tests for bloaty configuration tooling."""
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Workerimport unittest
18*61c4878aSAndroid Build Coastguard Workerimport os
19*61c4878aSAndroid Build Coastguard Workerimport logging
20*61c4878aSAndroid Build Coastguard Workerimport sys
21*61c4878aSAndroid Build Coastguard Workerfrom pw_bloat.label import DataSourceMap, Label
22*61c4878aSAndroid Build Coastguard Worker
23*61c4878aSAndroid Build Coastguard WorkerLIST_LABELS = [
24*61c4878aSAndroid Build Coastguard Worker    Label(name='main()', size=30, parents=tuple(['FLASH', '.code'])),
25*61c4878aSAndroid Build Coastguard Worker    Label(name='foo()', size=100, parents=tuple(['RAM', '.heap'])),
26*61c4878aSAndroid Build Coastguard Worker    Label(name='bar()', size=220, parents=tuple(['RAM', '.heap'])),
27*61c4878aSAndroid Build Coastguard Worker]
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Workerlogger = logging.getLogger()
30*61c4878aSAndroid Build Coastguard Workerlogger.level = logging.DEBUG
31*61c4878aSAndroid Build Coastguard Workerlogger.addHandler(logging.StreamHandler(sys.stdout))
32*61c4878aSAndroid Build Coastguard Worker
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard Workerdef get_test_map():
35*61c4878aSAndroid Build Coastguard Worker    pw_root = os.environ.get("PW ROOT")
36*61c4878aSAndroid Build Coastguard Worker    filename = f"{pw_root}/pigweed/pw_bloat/test_label.csv"
37*61c4878aSAndroid Build Coastguard Worker    with open(filename, 'r') as csvfile:
38*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap.from_bloaty_tsv(csvfile)
39*61c4878aSAndroid Build Coastguard Worker        capacity_patterns = [("^__TEXT$", 459), ("^_", 920834)]
40*61c4878aSAndroid Build Coastguard Worker        for cap_pattern, cap_size in capacity_patterns:
41*61c4878aSAndroid Build Coastguard Worker            ds_map.add_capacity(cap_pattern, cap_size)
42*61c4878aSAndroid Build Coastguard Worker    return ds_map
43*61c4878aSAndroid Build Coastguard Worker
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard Workerclass LabelStructTest(unittest.TestCase):
46*61c4878aSAndroid Build Coastguard Worker    """Testing class for the label structs."""
47*61c4878aSAndroid Build Coastguard Worker
48*61c4878aSAndroid Build Coastguard Worker    def test_data_source_total_size(self):
49*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
50*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 0)
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker    def test_data_source_single_insert_total_size(self):
53*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
54*61c4878aSAndroid Build Coastguard Worker        ds_map.insert_label_hierarchy(['FLASH', '.code', 'main()'], 30)
55*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 30)
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker    def test_data_source_multiple_insert_total_size(self):
58*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
59*61c4878aSAndroid Build Coastguard Worker        ds_map.insert_label_hierarchy(['FLASH', '.code', 'main()'], 30)
60*61c4878aSAndroid Build Coastguard Worker        ds_map.insert_label_hierarchy(['RAM', '.code', 'foo()'], 100)
61*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 130)
62*61c4878aSAndroid Build Coastguard Worker
63*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_three_datasource_names(self):
64*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
65*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
66*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
67*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
68*61c4878aSAndroid Build Coastguard Worker            )
69*61c4878aSAndroid Build Coastguard Worker        list_labels_three = [*LIST_LABELS, Label(name='total', size=350)]
70*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels():
71*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_three)
72*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
73*61c4878aSAndroid Build Coastguard Worker
74*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_two_datasource_names(self):
75*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b'])
76*61c4878aSAndroid Build Coastguard Worker        ds_label_list = [
77*61c4878aSAndroid Build Coastguard Worker            Label(name='main()', size=30, parents=tuple(['FLASH'])),
78*61c4878aSAndroid Build Coastguard Worker            Label(name='foo()', size=100, parents=tuple(['RAM'])),
79*61c4878aSAndroid Build Coastguard Worker            Label(name='bar()', size=220, parents=tuple(['RAM'])),
80*61c4878aSAndroid Build Coastguard Worker        ]
81*61c4878aSAndroid Build Coastguard Worker        for label in ds_label_list:
82*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
83*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.name], label.size
84*61c4878aSAndroid Build Coastguard Worker            )
85*61c4878aSAndroid Build Coastguard Worker        list_labels_two = [*ds_label_list, Label(name='total', size=350)]
86*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels():
87*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_two)
88*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_specified_datasource_1(self):
91*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
92*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
93*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
94*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
95*61c4878aSAndroid Build Coastguard Worker            )
96*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b = [
97*61c4878aSAndroid Build Coastguard Worker            Label(name='.code', size=30, parents=tuple(['FLASH'])),
98*61c4878aSAndroid Build Coastguard Worker            Label(name='.heap', size=320, parents=tuple(['RAM'])),
99*61c4878aSAndroid Build Coastguard Worker        ]
100*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b += [Label(name='total', size=350)]
101*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels(1):
102*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_b)
103*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
104*61c4878aSAndroid Build Coastguard Worker
105*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_specified_datasource_str_2(self):
106*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
107*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
108*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
109*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
110*61c4878aSAndroid Build Coastguard Worker            )
111*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_a = [
112*61c4878aSAndroid Build Coastguard Worker            Label(name='FLASH', size=30, parents=tuple([])),
113*61c4878aSAndroid Build Coastguard Worker            Label(name='RAM', size=320, parents=tuple([])),
114*61c4878aSAndroid Build Coastguard Worker        ]
115*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_a += [Label(name='total', size=350)]
116*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels(0):
117*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_a)
118*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
119*61c4878aSAndroid Build Coastguard Worker
120*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_specified_datasource_int(self):
121*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
122*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
123*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
124*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
125*61c4878aSAndroid Build Coastguard Worker            )
126*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_a = [
127*61c4878aSAndroid Build Coastguard Worker            Label(name='FLASH', size=30, parents=tuple([])),
128*61c4878aSAndroid Build Coastguard Worker            Label(name='RAM', size=320, parents=tuple([])),
129*61c4878aSAndroid Build Coastguard Worker        ]
130*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_a += [Label(name='total', size=350)]
131*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels(0):
132*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_a)
133*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
134*61c4878aSAndroid Build Coastguard Worker
135*61c4878aSAndroid Build Coastguard Worker    def test_parsing_generator_specified_datasource_int_2(self):
136*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
137*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
138*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
139*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
140*61c4878aSAndroid Build Coastguard Worker            )
141*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b = [
142*61c4878aSAndroid Build Coastguard Worker            Label(name='.code', size=30, parents=tuple(['FLASH'])),
143*61c4878aSAndroid Build Coastguard Worker            Label(name='.heap', size=320, parents=tuple(['RAM'])),
144*61c4878aSAndroid Build Coastguard Worker        ]
145*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b += [Label(name='total', size=350)]
146*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map.labels(1):
147*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_b)
148*61c4878aSAndroid Build Coastguard Worker        self.assertEqual(ds_map.get_total_size(), 350)
149*61c4878aSAndroid Build Coastguard Worker
150*61c4878aSAndroid Build Coastguard Worker    def test_diff_same_ds_labels_diff_sizes(self):
151*61c4878aSAndroid Build Coastguard Worker        """Same map with different sizes."""
152*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
153*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
154*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
155*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
156*61c4878aSAndroid Build Coastguard Worker            )
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard Worker        ds_map2 = DataSourceMap(['a', 'b', 'c'])
159*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
160*61c4878aSAndroid Build Coastguard Worker            ds_map2.insert_label_hierarchy(
161*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name],
162*61c4878aSAndroid Build Coastguard Worker                label.size + 10,
163*61c4878aSAndroid Build Coastguard Worker            )
164*61c4878aSAndroid Build Coastguard Worker
165*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b = [
166*61c4878aSAndroid Build Coastguard Worker            Label(
167*61c4878aSAndroid Build Coastguard Worker                name='main()',
168*61c4878aSAndroid Build Coastguard Worker                size=-10,
169*61c4878aSAndroid Build Coastguard Worker                exists_both=True,
170*61c4878aSAndroid Build Coastguard Worker                parents=tuple(['FLASH', '.code']),
171*61c4878aSAndroid Build Coastguard Worker            ),
172*61c4878aSAndroid Build Coastguard Worker            Label(
173*61c4878aSAndroid Build Coastguard Worker                name='foo()',
174*61c4878aSAndroid Build Coastguard Worker                size=-10,
175*61c4878aSAndroid Build Coastguard Worker                exists_both=True,
176*61c4878aSAndroid Build Coastguard Worker                parents=tuple(['RAM', '.heap']),
177*61c4878aSAndroid Build Coastguard Worker            ),
178*61c4878aSAndroid Build Coastguard Worker            Label(
179*61c4878aSAndroid Build Coastguard Worker                name='bar()',
180*61c4878aSAndroid Build Coastguard Worker                size=-10,
181*61c4878aSAndroid Build Coastguard Worker                exists_both=True,
182*61c4878aSAndroid Build Coastguard Worker                parents=tuple(['RAM', '.heap']),
183*61c4878aSAndroid Build Coastguard Worker            ),
184*61c4878aSAndroid Build Coastguard Worker        ]
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Worker        ds_map_diff = ds_map.diff(ds_map2)
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map_diff.labels():
189*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_b)
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard Worker    def test_diff_missing_ds_labels_diff_sizes(self):
192*61c4878aSAndroid Build Coastguard Worker        """Different map with different sizes."""
193*61c4878aSAndroid Build Coastguard Worker        ds_map = DataSourceMap(['a', 'b', 'c'])
194*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS:
195*61c4878aSAndroid Build Coastguard Worker            ds_map.insert_label_hierarchy(
196*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name], label.size
197*61c4878aSAndroid Build Coastguard Worker            )
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker        ds_map2 = DataSourceMap(['a', 'b', 'c'])
200*61c4878aSAndroid Build Coastguard Worker        for label in LIST_LABELS[:-1]:
201*61c4878aSAndroid Build Coastguard Worker            ds_map2.insert_label_hierarchy(
202*61c4878aSAndroid Build Coastguard Worker                [label.parents[0], label.parents[1], label.name],
203*61c4878aSAndroid Build Coastguard Worker                label.size + 20,
204*61c4878aSAndroid Build Coastguard Worker            )
205*61c4878aSAndroid Build Coastguard Worker        ds_map2.insert_label_hierarchy(
206*61c4878aSAndroid Build Coastguard Worker            [label.parents[0], label.parents[1], 'foobar()'], label.size + 20
207*61c4878aSAndroid Build Coastguard Worker        )
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard Worker        ds_map2.insert_label_hierarchy(
210*61c4878aSAndroid Build Coastguard Worker            ["LOAD #5", 'random_load', 'func()'], 250
211*61c4878aSAndroid Build Coastguard Worker        )
212*61c4878aSAndroid Build Coastguard Worker
213*61c4878aSAndroid Build Coastguard Worker        list_labels_ds_b = [
214*61c4878aSAndroid Build Coastguard Worker            Label(
215*61c4878aSAndroid Build Coastguard Worker                name='FLASH',
216*61c4878aSAndroid Build Coastguard Worker                size=20,
217*61c4878aSAndroid Build Coastguard Worker                capacity=None,
218*61c4878aSAndroid Build Coastguard Worker                exists_both=True,
219*61c4878aSAndroid Build Coastguard Worker                parents=(),
220*61c4878aSAndroid Build Coastguard Worker            ),
221*61c4878aSAndroid Build Coastguard Worker            Label(
222*61c4878aSAndroid Build Coastguard Worker                name='RAM',
223*61c4878aSAndroid Build Coastguard Worker                size=-80,
224*61c4878aSAndroid Build Coastguard Worker                capacity=None,
225*61c4878aSAndroid Build Coastguard Worker                exists_both=True,
226*61c4878aSAndroid Build Coastguard Worker                parents=(),
227*61c4878aSAndroid Build Coastguard Worker            ),
228*61c4878aSAndroid Build Coastguard Worker            Label(
229*61c4878aSAndroid Build Coastguard Worker                name='LOAD #5',
230*61c4878aSAndroid Build Coastguard Worker                size=250,
231*61c4878aSAndroid Build Coastguard Worker                capacity=None,
232*61c4878aSAndroid Build Coastguard Worker                exists_both=False,
233*61c4878aSAndroid Build Coastguard Worker                parents=(),
234*61c4878aSAndroid Build Coastguard Worker            ),
235*61c4878aSAndroid Build Coastguard Worker        ]
236*61c4878aSAndroid Build Coastguard Worker
237*61c4878aSAndroid Build Coastguard Worker        ds_map_diff = ds_map2.diff(ds_map)
238*61c4878aSAndroid Build Coastguard Worker
239*61c4878aSAndroid Build Coastguard Worker        for label_hierarchy in ds_map_diff.labels(0):
240*61c4878aSAndroid Build Coastguard Worker            self.assertIn(label_hierarchy, list_labels_ds_b)
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard Worker
243*61c4878aSAndroid Build Coastguard Workerif __name__ == '__main__':
244*61c4878aSAndroid Build Coastguard Worker    unittest.main()
245