blob: c1e821904e06924dc119e272b8ac53ebc594adfd [file] [log] [blame]
Dan Albert06f58af2020-06-22 15:10:31 -07001#
2# Copyright (C) 2016 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16"""Tests for symbolfile."""
17import io
18import textwrap
19import unittest
20
21import symbolfile
Dan Albertead21552021-06-04 14:30:40 -070022from symbolfile import Arch, Tag, Tags, Version
Dan Albert06f58af2020-06-22 15:10:31 -070023
24# pylint: disable=missing-docstring
25
26
27class DecodeApiLevelTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -070028 def test_decode_api_level(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070029 self.assertEqual(9, symbolfile.decode_api_level('9', {}))
30 self.assertEqual(9000, symbolfile.decode_api_level('O', {'O': 9000}))
31
32 with self.assertRaises(KeyError):
33 symbolfile.decode_api_level('O', {})
34
35
36class TagsTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -070037 def test_get_tags_no_tags(self) -> None:
Dan Albertead21552021-06-04 14:30:40 -070038 self.assertEqual(Tags(), symbolfile.get_tags('', {}))
39 self.assertEqual(Tags(), symbolfile.get_tags('foo bar baz', {}))
Dan Albert06f58af2020-06-22 15:10:31 -070040
Dan Albertaf7b36d2020-06-23 11:21:21 -070041 def test_get_tags(self) -> None:
Dan Albertead21552021-06-04 14:30:40 -070042 self.assertEqual(Tags.from_strs(['foo', 'bar']),
43 symbolfile.get_tags('# foo bar', {}))
44 self.assertEqual(Tags.from_strs(['bar', 'baz']),
45 symbolfile.get_tags('foo # bar baz', {}))
Dan Albert06f58af2020-06-22 15:10:31 -070046
Dan Albertaf7b36d2020-06-23 11:21:21 -070047 def test_split_tag(self) -> None:
48 self.assertTupleEqual(('foo', 'bar'),
49 symbolfile.split_tag(Tag('foo=bar')))
50 self.assertTupleEqual(('foo', 'bar=baz'),
51 symbolfile.split_tag(Tag('foo=bar=baz')))
Dan Albert06f58af2020-06-22 15:10:31 -070052 with self.assertRaises(ValueError):
Dan Albertaf7b36d2020-06-23 11:21:21 -070053 symbolfile.split_tag(Tag('foo'))
Dan Albert06f58af2020-06-22 15:10:31 -070054
Dan Albertaf7b36d2020-06-23 11:21:21 -070055 def test_get_tag_value(self) -> None:
56 self.assertEqual('bar', symbolfile.get_tag_value(Tag('foo=bar')))
57 self.assertEqual('bar=baz',
58 symbolfile.get_tag_value(Tag('foo=bar=baz')))
Dan Albert06f58af2020-06-22 15:10:31 -070059 with self.assertRaises(ValueError):
Dan Albertaf7b36d2020-06-23 11:21:21 -070060 symbolfile.get_tag_value(Tag('foo'))
Dan Albert06f58af2020-06-22 15:10:31 -070061
Dan Albertaf7b36d2020-06-23 11:21:21 -070062 def test_is_api_level_tag(self) -> None:
63 self.assertTrue(symbolfile.is_api_level_tag(Tag('introduced=24')))
64 self.assertTrue(symbolfile.is_api_level_tag(Tag('introduced-arm=24')))
65 self.assertTrue(symbolfile.is_api_level_tag(Tag('versioned=24')))
Dan Albert06f58af2020-06-22 15:10:31 -070066
67 # Shouldn't try to process things that aren't a key/value tag.
Dan Albertaf7b36d2020-06-23 11:21:21 -070068 self.assertFalse(symbolfile.is_api_level_tag(Tag('arm')))
69 self.assertFalse(symbolfile.is_api_level_tag(Tag('introduced')))
70 self.assertFalse(symbolfile.is_api_level_tag(Tag('versioned')))
Dan Albert06f58af2020-06-22 15:10:31 -070071
72 # We don't support arch specific `versioned` tags.
Dan Albertaf7b36d2020-06-23 11:21:21 -070073 self.assertFalse(symbolfile.is_api_level_tag(Tag('versioned-arm=24')))
Dan Albert06f58af2020-06-22 15:10:31 -070074
Dan Albertaf7b36d2020-06-23 11:21:21 -070075 def test_decode_api_level_tags(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070076 api_map = {
77 'O': 9000,
78 'P': 9001,
79 }
80
81 tags = [
Dan Albertead21552021-06-04 14:30:40 -070082 symbolfile.decode_api_level_tag(t, api_map) for t in (
83 Tag('introduced=9'),
84 Tag('introduced-arm=14'),
85 Tag('versioned=16'),
86 Tag('arm'),
87 Tag('introduced=O'),
88 Tag('introduced=P'),
89 )
Dan Albert06f58af2020-06-22 15:10:31 -070090 ]
91 expected_tags = [
Dan Albertaf7b36d2020-06-23 11:21:21 -070092 Tag('introduced=9'),
93 Tag('introduced-arm=14'),
94 Tag('versioned=16'),
95 Tag('arm'),
96 Tag('introduced=9000'),
97 Tag('introduced=9001'),
Dan Albert06f58af2020-06-22 15:10:31 -070098 ]
Dan Albertead21552021-06-04 14:30:40 -070099 self.assertListEqual(expected_tags, tags)
Dan Albert06f58af2020-06-22 15:10:31 -0700100
101 with self.assertRaises(symbolfile.ParseError):
Dan Albertead21552021-06-04 14:30:40 -0700102 symbolfile.decode_api_level_tag(Tag('introduced=O'), {})
Dan Albert06f58af2020-06-22 15:10:31 -0700103
104
105class PrivateVersionTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700106 def test_version_is_private(self) -> None:
Dan Albertead21552021-06-04 14:30:40 -0700107 def mock_version(name: str) -> Version:
108 return Version(name, base=None, tags=Tags(), symbols=[])
Dan Albert06f58af2020-06-22 15:10:31 -0700109
Dan Albertead21552021-06-04 14:30:40 -0700110 self.assertFalse(mock_version('foo').is_private)
111 self.assertFalse(mock_version('PRIVATE').is_private)
112 self.assertFalse(mock_version('PLATFORM').is_private)
113 self.assertFalse(mock_version('foo_private').is_private)
114 self.assertFalse(mock_version('foo_platform').is_private)
115 self.assertFalse(mock_version('foo_PRIVATE_').is_private)
116 self.assertFalse(mock_version('foo_PLATFORM_').is_private)
117
118 self.assertTrue(mock_version('foo_PRIVATE').is_private)
119 self.assertTrue(mock_version('foo_PLATFORM').is_private)
Dan Albert06f58af2020-06-22 15:10:31 -0700120
121
122class SymbolPresenceTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700123 def test_symbol_in_arch(self) -> None:
Dan Albertead21552021-06-04 14:30:40 -0700124 self.assertTrue(symbolfile.symbol_in_arch(Tags(), Arch('arm')))
125 self.assertTrue(
126 symbolfile.symbol_in_arch(Tags.from_strs(['arm']), Arch('arm')))
Dan Albert06f58af2020-06-22 15:10:31 -0700127
Dan Albertead21552021-06-04 14:30:40 -0700128 self.assertFalse(
129 symbolfile.symbol_in_arch(Tags.from_strs(['x86']), Arch('arm')))
Dan Albert06f58af2020-06-22 15:10:31 -0700130
Dan Albertaf7b36d2020-06-23 11:21:21 -0700131 def test_symbol_in_api(self) -> None:
132 self.assertTrue(symbolfile.symbol_in_api([], Arch('arm'), 9))
133 self.assertTrue(
134 symbolfile.symbol_in_api([Tag('introduced=9')], Arch('arm'), 9))
135 self.assertTrue(
136 symbolfile.symbol_in_api([Tag('introduced=9')], Arch('arm'), 14))
137 self.assertTrue(
138 symbolfile.symbol_in_api([Tag('introduced-arm=9')], Arch('arm'),
139 14))
140 self.assertTrue(
141 symbolfile.symbol_in_api([Tag('introduced-arm=9')], Arch('arm'),
142 14))
143 self.assertTrue(
144 symbolfile.symbol_in_api([Tag('introduced-x86=14')], Arch('arm'),
145 9))
146 self.assertTrue(
147 symbolfile.symbol_in_api(
148 [Tag('introduced-arm=9'),
149 Tag('introduced-x86=21')], Arch('arm'), 14))
150 self.assertTrue(
151 symbolfile.symbol_in_api(
152 [Tag('introduced=9'),
153 Tag('introduced-x86=21')], Arch('arm'), 14))
154 self.assertTrue(
155 symbolfile.symbol_in_api(
156 [Tag('introduced=21'),
157 Tag('introduced-arm=9')], Arch('arm'), 14))
158 self.assertTrue(
159 symbolfile.symbol_in_api([Tag('future')], Arch('arm'),
160 symbolfile.FUTURE_API_LEVEL))
Dan Albert06f58af2020-06-22 15:10:31 -0700161
Dan Albertaf7b36d2020-06-23 11:21:21 -0700162 self.assertFalse(
163 symbolfile.symbol_in_api([Tag('introduced=14')], Arch('arm'), 9))
164 self.assertFalse(
165 symbolfile.symbol_in_api([Tag('introduced-arm=14')], Arch('arm'),
166 9))
167 self.assertFalse(
168 symbolfile.symbol_in_api([Tag('future')], Arch('arm'), 9))
169 self.assertFalse(
170 symbolfile.symbol_in_api(
171 [Tag('introduced=9'), Tag('future')], Arch('arm'), 14))
172 self.assertFalse(
173 symbolfile.symbol_in_api([Tag('introduced-arm=9'),
174 Tag('future')], Arch('arm'), 14))
175 self.assertFalse(
176 symbolfile.symbol_in_api(
177 [Tag('introduced-arm=21'),
178 Tag('introduced-x86=9')], Arch('arm'), 14))
179 self.assertFalse(
180 symbolfile.symbol_in_api(
181 [Tag('introduced=9'),
182 Tag('introduced-arm=21')], Arch('arm'), 14))
183 self.assertFalse(
184 symbolfile.symbol_in_api(
185 [Tag('introduced=21'),
186 Tag('introduced-x86=9')], Arch('arm'), 14))
Dan Albert06f58af2020-06-22 15:10:31 -0700187
188 # Interesting edge case: this symbol should be omitted from the
189 # library, but this call should still return true because none of the
190 # tags indiciate that it's not present in this API level.
Dan Albertaf7b36d2020-06-23 11:21:21 -0700191 self.assertTrue(symbolfile.symbol_in_api([Tag('x86')], Arch('arm'), 9))
Dan Albert06f58af2020-06-22 15:10:31 -0700192
Dan Albertaf7b36d2020-06-23 11:21:21 -0700193 def test_verioned_in_api(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700194 self.assertTrue(symbolfile.symbol_versioned_in_api([], 9))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700195 self.assertTrue(
196 symbolfile.symbol_versioned_in_api([Tag('versioned=9')], 9))
197 self.assertTrue(
198 symbolfile.symbol_versioned_in_api([Tag('versioned=9')], 14))
Dan Albert06f58af2020-06-22 15:10:31 -0700199
Dan Albertaf7b36d2020-06-23 11:21:21 -0700200 self.assertFalse(
201 symbolfile.symbol_versioned_in_api([Tag('versioned=14')], 9))
Dan Albert06f58af2020-06-22 15:10:31 -0700202
203
204class OmitVersionTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700205 def test_omit_private(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700206 self.assertFalse(
207 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700208 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
209 False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700210
211 self.assertTrue(
212 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700213 symbolfile.Version('foo_PRIVATE', None, Tags(), []),
214 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700215 self.assertTrue(
216 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700217 symbolfile.Version('foo_PLATFORM', None, Tags(), []),
218 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700219
Dan Albert06f58af2020-06-22 15:10:31 -0700220 self.assertTrue(
221 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700222 symbolfile.Version('foo', None,
223 Tags.from_strs(['platform-only']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700224 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700225
Dan Albertaf7b36d2020-06-23 11:21:21 -0700226 def test_omit_llndk(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700227 self.assertTrue(
228 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700229 symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700230 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700231
232 self.assertFalse(
233 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700234 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
235 True, False))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700236 self.assertFalse(
237 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700238 symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700239 Arch('arm'), 9, True, False))
240
241 def test_omit_apex(self) -> None:
242 self.assertTrue(
243 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700244 symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700245 Arch('arm'), 9, False, False))
246
247 self.assertFalse(
248 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700249 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
250 False, True))
Dan Albert06f58af2020-06-22 15:10:31 -0700251 self.assertFalse(
252 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700253 symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700254 Arch('arm'), 9, False, True))
Dan Albert06f58af2020-06-22 15:10:31 -0700255
Dan Albert56f52de2021-06-04 14:31:58 -0700256 def test_omit_systemapi(self) -> None:
257 self.assertTrue(
258 symbolfile.should_omit_version(
259 symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
260 []), Arch('arm'), 9, False, False))
261
262 self.assertFalse(
263 symbolfile.should_omit_version(
264 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
265 False, True))
266 self.assertFalse(
267 symbolfile.should_omit_version(
268 symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
269 []), Arch('arm'), 9, False, True))
270
Dan Albertaf7b36d2020-06-23 11:21:21 -0700271 def test_omit_arch(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700272 self.assertFalse(
273 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700274 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
275 False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700276 self.assertFalse(
277 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700278 symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700279 Arch('arm'), 9, False, False))
280
281 self.assertTrue(
282 symbolfile.should_omit_version(
Dan Albertead21552021-06-04 14:30:40 -0700283 symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
284 Arch('arm'), 9, False, False))
285
286 def test_omit_api(self) -> None:
287 self.assertFalse(
288 symbolfile.should_omit_version(
289 symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
290 False, False))
291 self.assertFalse(
292 symbolfile.should_omit_version(
293 symbolfile.Version('foo', None,
294 Tags.from_strs(['introduced=9']), []),
295 Arch('arm'), 9, False, False))
296
297 self.assertTrue(
298 symbolfile.should_omit_version(
299 symbolfile.Version('foo', None,
300 Tags.from_strs(['introduced=14']), []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700301 Arch('arm'), 9, False, False))
302
Dan Albert06f58af2020-06-22 15:10:31 -0700303
304class OmitSymbolTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700305 def test_omit_llndk(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700306 self.assertTrue(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700307 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700308 symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
309 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700310
311 self.assertFalse(
Dan Albertead21552021-06-04 14:30:40 -0700312 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700313 Arch('arm'), 9, True, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700314 self.assertFalse(
315 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700316 symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
317 Arch('arm'), 9, True, False))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700318
319 def test_omit_apex(self) -> None:
320 self.assertTrue(
321 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700322 symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
323 Arch('arm'), 9, False, False))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700324
325 self.assertFalse(
Dan Albertead21552021-06-04 14:30:40 -0700326 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700327 Arch('arm'), 9, False, True))
328 self.assertFalse(
329 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700330 symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
331 Arch('arm'), 9, False, True))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700332
Dan Albert56f52de2021-06-04 14:31:58 -0700333 def test_omit_systemapi(self) -> None:
334 self.assertTrue(
335 symbolfile.should_omit_symbol(
336 symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
337 Arch('arm'), 9, False, False))
338
339 self.assertFalse(
340 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
341 Arch('arm'), 9, False, True))
342 self.assertFalse(
343 symbolfile.should_omit_symbol(
344 symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
345 Arch('arm'), 9, False, True))
346
Dan Albertaf7b36d2020-06-23 11:21:21 -0700347 def test_omit_arch(self) -> None:
348 self.assertFalse(
Dan Albertead21552021-06-04 14:30:40 -0700349 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700350 Arch('arm'), 9, False, False))
351 self.assertFalse(
352 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700353 symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
354 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700355
356 self.assertTrue(
357 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700358 symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
359 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700360
Dan Albertaf7b36d2020-06-23 11:21:21 -0700361 def test_omit_api(self) -> None:
362 self.assertFalse(
Dan Albertead21552021-06-04 14:30:40 -0700363 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700364 Arch('arm'), 9, False, False))
365 self.assertFalse(
366 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700367 symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
368 Arch('arm'), 9, False, False))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700369
370 self.assertTrue(
371 symbolfile.should_omit_symbol(
Dan Albertead21552021-06-04 14:30:40 -0700372 symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
373 Arch('arm'), 9, False, False))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700374
Dan Albert06f58af2020-06-22 15:10:31 -0700375
376class SymbolFileParseTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700377 def test_next_line(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700378 input_file = io.StringIO(textwrap.dedent("""\
379 foo
380
381 bar
382 # baz
383 qux
384 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700385 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
386 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700387 self.assertIsNone(parser.current_line)
388
389 self.assertEqual('foo', parser.next_line().strip())
Dan Albertaf7b36d2020-06-23 11:21:21 -0700390 assert parser.current_line is not None
Dan Albert06f58af2020-06-22 15:10:31 -0700391 self.assertEqual('foo', parser.current_line.strip())
392
393 self.assertEqual('bar', parser.next_line().strip())
394 self.assertEqual('bar', parser.current_line.strip())
395
396 self.assertEqual('qux', parser.next_line().strip())
397 self.assertEqual('qux', parser.current_line.strip())
398
399 self.assertEqual('', parser.next_line())
400 self.assertEqual('', parser.current_line)
401
Dan Albertaf7b36d2020-06-23 11:21:21 -0700402 def test_parse_version(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700403 input_file = io.StringIO(textwrap.dedent("""\
404 VERSION_1 { # foo bar
405 baz;
406 qux; # woodly doodly
407 };
408
409 VERSION_2 {
410 } VERSION_1; # asdf
411 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700412 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
413 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700414
415 parser.next_line()
416 version = parser.parse_version()
417 self.assertEqual('VERSION_1', version.name)
418 self.assertIsNone(version.base)
Dan Albertead21552021-06-04 14:30:40 -0700419 self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
Dan Albert06f58af2020-06-22 15:10:31 -0700420
421 expected_symbols = [
Dan Albertead21552021-06-04 14:30:40 -0700422 symbolfile.Symbol('baz', Tags()),
423 symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
Dan Albert06f58af2020-06-22 15:10:31 -0700424 ]
425 self.assertEqual(expected_symbols, version.symbols)
426
427 parser.next_line()
428 version = parser.parse_version()
429 self.assertEqual('VERSION_2', version.name)
430 self.assertEqual('VERSION_1', version.base)
Dan Albertead21552021-06-04 14:30:40 -0700431 self.assertEqual(Tags(), version.tags)
Dan Albert06f58af2020-06-22 15:10:31 -0700432
Dan Albertaf7b36d2020-06-23 11:21:21 -0700433 def test_parse_version_eof(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700434 input_file = io.StringIO(textwrap.dedent("""\
435 VERSION_1 {
436 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700437 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
438 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700439 parser.next_line()
440 with self.assertRaises(symbolfile.ParseError):
441 parser.parse_version()
442
Dan Albertaf7b36d2020-06-23 11:21:21 -0700443 def test_unknown_scope_label(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700444 input_file = io.StringIO(textwrap.dedent("""\
445 VERSION_1 {
446 foo:
447 }
448 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700449 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
450 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700451 parser.next_line()
452 with self.assertRaises(symbolfile.ParseError):
453 parser.parse_version()
454
Dan Albertaf7b36d2020-06-23 11:21:21 -0700455 def test_parse_symbol(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700456 input_file = io.StringIO(textwrap.dedent("""\
457 foo;
458 bar; # baz qux
459 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700460 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
461 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700462
463 parser.next_line()
464 symbol = parser.parse_symbol()
465 self.assertEqual('foo', symbol.name)
Dan Albertead21552021-06-04 14:30:40 -0700466 self.assertEqual(Tags(), symbol.tags)
Dan Albert06f58af2020-06-22 15:10:31 -0700467
468 parser.next_line()
469 symbol = parser.parse_symbol()
470 self.assertEqual('bar', symbol.name)
Dan Albertead21552021-06-04 14:30:40 -0700471 self.assertEqual(Tags.from_strs(['baz', 'qux']), symbol.tags)
Dan Albert06f58af2020-06-22 15:10:31 -0700472
Dan Albertaf7b36d2020-06-23 11:21:21 -0700473 def test_wildcard_symbol_global(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700474 input_file = io.StringIO(textwrap.dedent("""\
475 VERSION_1 {
476 *;
477 };
478 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700479 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
480 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700481 parser.next_line()
482 with self.assertRaises(symbolfile.ParseError):
483 parser.parse_version()
484
Dan Albertaf7b36d2020-06-23 11:21:21 -0700485 def test_wildcard_symbol_local(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700486 input_file = io.StringIO(textwrap.dedent("""\
487 VERSION_1 {
488 local:
489 *;
490 };
491 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700492 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
493 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700494 parser.next_line()
495 version = parser.parse_version()
496 self.assertEqual([], version.symbols)
497
Dan Albertaf7b36d2020-06-23 11:21:21 -0700498 def test_missing_semicolon(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700499 input_file = io.StringIO(textwrap.dedent("""\
500 VERSION_1 {
501 foo
502 };
503 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700504 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
505 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700506 parser.next_line()
507 with self.assertRaises(symbolfile.ParseError):
508 parser.parse_version()
509
Dan Albertaf7b36d2020-06-23 11:21:21 -0700510 def test_parse_fails_invalid_input(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700511 with self.assertRaises(symbolfile.ParseError):
512 input_file = io.StringIO('foo')
Dan Albertaf7b36d2020-06-23 11:21:21 -0700513 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
514 16, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700515 parser.parse()
516
Dan Albertaf7b36d2020-06-23 11:21:21 -0700517 def test_parse(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700518 input_file = io.StringIO(textwrap.dedent("""\
519 VERSION_1 {
520 local:
521 hidden1;
522 global:
523 foo;
524 bar; # baz
525 };
526
527 VERSION_2 { # wasd
528 # Implicit global scope.
529 woodly;
530 doodly; # asdf
531 local:
532 qwerty;
533 } VERSION_1;
534 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700535 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
536 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700537 versions = parser.parse()
538
539 expected = [
Dan Albertead21552021-06-04 14:30:40 -0700540 symbolfile.Version('VERSION_1', None, Tags(), [
541 symbolfile.Symbol('foo', Tags()),
542 symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
Dan Albert06f58af2020-06-22 15:10:31 -0700543 ]),
Dan Albertead21552021-06-04 14:30:40 -0700544 symbolfile.Version(
545 'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
546 symbolfile.Symbol('woodly', Tags()),
547 symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
548 ]),
Dan Albert06f58af2020-06-22 15:10:31 -0700549 ]
550
551 self.assertEqual(expected, versions)
552
Dan Albertaf7b36d2020-06-23 11:21:21 -0700553 def test_parse_llndk_apex_symbol(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700554 input_file = io.StringIO(textwrap.dedent("""\
555 VERSION_1 {
556 foo;
557 bar; # llndk
558 baz; # llndk apex
559 qux; # apex
560 };
561 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700562 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
563 False, True)
Dan Albert06f58af2020-06-22 15:10:31 -0700564
565 parser.next_line()
566 version = parser.parse_version()
567 self.assertEqual('VERSION_1', version.name)
568 self.assertIsNone(version.base)
569
570 expected_symbols = [
Dan Albertead21552021-06-04 14:30:40 -0700571 symbolfile.Symbol('foo', Tags()),
572 symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
573 symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
574 symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
Dan Albert06f58af2020-06-22 15:10:31 -0700575 ]
576 self.assertEqual(expected_symbols, version.symbols)
577
578
Dan Albertaf7b36d2020-06-23 11:21:21 -0700579def main() -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700580 suite = unittest.TestLoader().loadTestsFromName(__name__)
581 unittest.TextTestRunner(verbosity=3).run(suite)
582
583
584if __name__ == '__main__':
585 main()