blob: 92b13999e7a989db3f28e2822a4ad602a17a7419 [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 Albertaf7b36d2020-06-23 11:21:21 -070022from symbolfile import Arch, Tag
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 Albert06f58af2020-06-22 15:10:31 -070038 self.assertEqual([], symbolfile.get_tags(''))
39 self.assertEqual([], symbolfile.get_tags('foo bar baz'))
40
Dan Albertaf7b36d2020-06-23 11:21:21 -070041 def test_get_tags(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070042 self.assertEqual(['foo', 'bar'], symbolfile.get_tags('# foo bar'))
43 self.assertEqual(['bar', 'baz'], symbolfile.get_tags('foo # bar baz'))
44
Dan Albertaf7b36d2020-06-23 11:21:21 -070045 def test_split_tag(self) -> None:
46 self.assertTupleEqual(('foo', 'bar'),
47 symbolfile.split_tag(Tag('foo=bar')))
48 self.assertTupleEqual(('foo', 'bar=baz'),
49 symbolfile.split_tag(Tag('foo=bar=baz')))
Dan Albert06f58af2020-06-22 15:10:31 -070050 with self.assertRaises(ValueError):
Dan Albertaf7b36d2020-06-23 11:21:21 -070051 symbolfile.split_tag(Tag('foo'))
Dan Albert06f58af2020-06-22 15:10:31 -070052
Dan Albertaf7b36d2020-06-23 11:21:21 -070053 def test_get_tag_value(self) -> None:
54 self.assertEqual('bar', symbolfile.get_tag_value(Tag('foo=bar')))
55 self.assertEqual('bar=baz',
56 symbolfile.get_tag_value(Tag('foo=bar=baz')))
Dan Albert06f58af2020-06-22 15:10:31 -070057 with self.assertRaises(ValueError):
Dan Albertaf7b36d2020-06-23 11:21:21 -070058 symbolfile.get_tag_value(Tag('foo'))
Dan Albert06f58af2020-06-22 15:10:31 -070059
Dan Albertaf7b36d2020-06-23 11:21:21 -070060 def test_is_api_level_tag(self) -> None:
61 self.assertTrue(symbolfile.is_api_level_tag(Tag('introduced=24')))
62 self.assertTrue(symbolfile.is_api_level_tag(Tag('introduced-arm=24')))
63 self.assertTrue(symbolfile.is_api_level_tag(Tag('versioned=24')))
Dan Albert06f58af2020-06-22 15:10:31 -070064
65 # Shouldn't try to process things that aren't a key/value tag.
Dan Albertaf7b36d2020-06-23 11:21:21 -070066 self.assertFalse(symbolfile.is_api_level_tag(Tag('arm')))
67 self.assertFalse(symbolfile.is_api_level_tag(Tag('introduced')))
68 self.assertFalse(symbolfile.is_api_level_tag(Tag('versioned')))
Dan Albert06f58af2020-06-22 15:10:31 -070069
70 # We don't support arch specific `versioned` tags.
Dan Albertaf7b36d2020-06-23 11:21:21 -070071 self.assertFalse(symbolfile.is_api_level_tag(Tag('versioned-arm=24')))
Dan Albert06f58af2020-06-22 15:10:31 -070072
Dan Albertaf7b36d2020-06-23 11:21:21 -070073 def test_decode_api_level_tags(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070074 api_map = {
75 'O': 9000,
76 'P': 9001,
77 }
78
79 tags = [
Dan Albertaf7b36d2020-06-23 11:21:21 -070080 Tag('introduced=9'),
81 Tag('introduced-arm=14'),
82 Tag('versioned=16'),
83 Tag('arm'),
84 Tag('introduced=O'),
85 Tag('introduced=P'),
Dan Albert06f58af2020-06-22 15:10:31 -070086 ]
87 expected_tags = [
Dan Albertaf7b36d2020-06-23 11:21:21 -070088 Tag('introduced=9'),
89 Tag('introduced-arm=14'),
90 Tag('versioned=16'),
91 Tag('arm'),
92 Tag('introduced=9000'),
93 Tag('introduced=9001'),
Dan Albert06f58af2020-06-22 15:10:31 -070094 ]
95 self.assertListEqual(
96 expected_tags, symbolfile.decode_api_level_tags(tags, api_map))
97
98 with self.assertRaises(symbolfile.ParseError):
Dan Albertaf7b36d2020-06-23 11:21:21 -070099 symbolfile.decode_api_level_tags([Tag('introduced=O')], {})
Dan Albert06f58af2020-06-22 15:10:31 -0700100
101
102class PrivateVersionTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700103 def test_version_is_private(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700104 self.assertFalse(symbolfile.version_is_private('foo'))
105 self.assertFalse(symbolfile.version_is_private('PRIVATE'))
106 self.assertFalse(symbolfile.version_is_private('PLATFORM'))
107 self.assertFalse(symbolfile.version_is_private('foo_private'))
108 self.assertFalse(symbolfile.version_is_private('foo_platform'))
109 self.assertFalse(symbolfile.version_is_private('foo_PRIVATE_'))
110 self.assertFalse(symbolfile.version_is_private('foo_PLATFORM_'))
111
112 self.assertTrue(symbolfile.version_is_private('foo_PRIVATE'))
113 self.assertTrue(symbolfile.version_is_private('foo_PLATFORM'))
114
115
116class SymbolPresenceTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700117 def test_symbol_in_arch(self) -> None:
118 self.assertTrue(symbolfile.symbol_in_arch([], Arch('arm')))
119 self.assertTrue(symbolfile.symbol_in_arch([Tag('arm')], Arch('arm')))
Dan Albert06f58af2020-06-22 15:10:31 -0700120
Dan Albertaf7b36d2020-06-23 11:21:21 -0700121 self.assertFalse(symbolfile.symbol_in_arch([Tag('x86')], Arch('arm')))
Dan Albert06f58af2020-06-22 15:10:31 -0700122
Dan Albertaf7b36d2020-06-23 11:21:21 -0700123 def test_symbol_in_api(self) -> None:
124 self.assertTrue(symbolfile.symbol_in_api([], Arch('arm'), 9))
125 self.assertTrue(
126 symbolfile.symbol_in_api([Tag('introduced=9')], Arch('arm'), 9))
127 self.assertTrue(
128 symbolfile.symbol_in_api([Tag('introduced=9')], Arch('arm'), 14))
129 self.assertTrue(
130 symbolfile.symbol_in_api([Tag('introduced-arm=9')], Arch('arm'),
131 14))
132 self.assertTrue(
133 symbolfile.symbol_in_api([Tag('introduced-arm=9')], Arch('arm'),
134 14))
135 self.assertTrue(
136 symbolfile.symbol_in_api([Tag('introduced-x86=14')], Arch('arm'),
137 9))
138 self.assertTrue(
139 symbolfile.symbol_in_api(
140 [Tag('introduced-arm=9'),
141 Tag('introduced-x86=21')], Arch('arm'), 14))
142 self.assertTrue(
143 symbolfile.symbol_in_api(
144 [Tag('introduced=9'),
145 Tag('introduced-x86=21')], Arch('arm'), 14))
146 self.assertTrue(
147 symbolfile.symbol_in_api(
148 [Tag('introduced=21'),
149 Tag('introduced-arm=9')], Arch('arm'), 14))
150 self.assertTrue(
151 symbolfile.symbol_in_api([Tag('future')], Arch('arm'),
152 symbolfile.FUTURE_API_LEVEL))
Dan Albert06f58af2020-06-22 15:10:31 -0700153
Dan Albertaf7b36d2020-06-23 11:21:21 -0700154 self.assertFalse(
155 symbolfile.symbol_in_api([Tag('introduced=14')], Arch('arm'), 9))
156 self.assertFalse(
157 symbolfile.symbol_in_api([Tag('introduced-arm=14')], Arch('arm'),
158 9))
159 self.assertFalse(
160 symbolfile.symbol_in_api([Tag('future')], Arch('arm'), 9))
161 self.assertFalse(
162 symbolfile.symbol_in_api(
163 [Tag('introduced=9'), Tag('future')], Arch('arm'), 14))
164 self.assertFalse(
165 symbolfile.symbol_in_api([Tag('introduced-arm=9'),
166 Tag('future')], Arch('arm'), 14))
167 self.assertFalse(
168 symbolfile.symbol_in_api(
169 [Tag('introduced-arm=21'),
170 Tag('introduced-x86=9')], Arch('arm'), 14))
171 self.assertFalse(
172 symbolfile.symbol_in_api(
173 [Tag('introduced=9'),
174 Tag('introduced-arm=21')], Arch('arm'), 14))
175 self.assertFalse(
176 symbolfile.symbol_in_api(
177 [Tag('introduced=21'),
178 Tag('introduced-x86=9')], Arch('arm'), 14))
Dan Albert06f58af2020-06-22 15:10:31 -0700179
180 # Interesting edge case: this symbol should be omitted from the
181 # library, but this call should still return true because none of the
182 # tags indiciate that it's not present in this API level.
Dan Albertaf7b36d2020-06-23 11:21:21 -0700183 self.assertTrue(symbolfile.symbol_in_api([Tag('x86')], Arch('arm'), 9))
Dan Albert06f58af2020-06-22 15:10:31 -0700184
Dan Albertaf7b36d2020-06-23 11:21:21 -0700185 def test_verioned_in_api(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700186 self.assertTrue(symbolfile.symbol_versioned_in_api([], 9))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700187 self.assertTrue(
188 symbolfile.symbol_versioned_in_api([Tag('versioned=9')], 9))
189 self.assertTrue(
190 symbolfile.symbol_versioned_in_api([Tag('versioned=9')], 14))
Dan Albert06f58af2020-06-22 15:10:31 -0700191
Dan Albertaf7b36d2020-06-23 11:21:21 -0700192 self.assertFalse(
193 symbolfile.symbol_versioned_in_api([Tag('versioned=14')], 9))
Dan Albert06f58af2020-06-22 15:10:31 -0700194
195
196class OmitVersionTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700197 def test_omit_private(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700198 self.assertFalse(
199 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700200 symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
Dan Albert06f58af2020-06-22 15:10:31 -0700201 False))
202
203 self.assertTrue(
204 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700205 symbolfile.Version('foo_PRIVATE', None, [], []), Arch('arm'),
206 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700207 self.assertTrue(
208 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700209 symbolfile.Version('foo_PLATFORM', None, [], []), Arch('arm'),
Dan Albert06f58af2020-06-22 15:10:31 -0700210 9, False, False))
211
Dan Albert06f58af2020-06-22 15:10:31 -0700212 self.assertTrue(
213 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700214 symbolfile.Version('foo', None, [Tag('platform-only')], []),
215 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700216
Dan Albertaf7b36d2020-06-23 11:21:21 -0700217 def test_omit_llndk(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700218 self.assertTrue(
219 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700220 symbolfile.Version('foo', None, [Tag('llndk')], []),
221 Arch('arm'), 9, False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700222
223 self.assertFalse(
224 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700225 symbolfile.Version('foo', None, [], []), Arch('arm'), 9, True,
226 False))
227 self.assertFalse(
228 symbolfile.should_omit_version(
229 symbolfile.Version('foo', None, [Tag('llndk')], []),
230 Arch('arm'), 9, True, False))
231
232 def test_omit_apex(self) -> None:
233 self.assertTrue(
234 symbolfile.should_omit_version(
235 symbolfile.Version('foo', None, [Tag('apex')], []),
236 Arch('arm'), 9, False, False))
237
238 self.assertFalse(
239 symbolfile.should_omit_version(
240 symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
Dan Albert06f58af2020-06-22 15:10:31 -0700241 True))
242 self.assertFalse(
243 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700244 symbolfile.Version('foo', None, [Tag('apex')], []),
245 Arch('arm'), 9, False, True))
Dan Albert06f58af2020-06-22 15:10:31 -0700246
Dan Albertaf7b36d2020-06-23 11:21:21 -0700247 def test_omit_arch(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700248 self.assertFalse(
249 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700250 symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
Dan Albert06f58af2020-06-22 15:10:31 -0700251 False))
252 self.assertFalse(
253 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700254 symbolfile.Version('foo', None, [Tag('arm')], []), Arch('arm'),
Dan Albert06f58af2020-06-22 15:10:31 -0700255 9, False, False))
256
257 self.assertTrue(
258 symbolfile.should_omit_version(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700259 symbolfile.Version('foo', None, [Tag('x86')], []), Arch('arm'),
Dan Albert06f58af2020-06-22 15:10:31 -0700260 9, False, False))
261
Dan Albertaf7b36d2020-06-23 11:21:21 -0700262 def test_omit_api(self) -> None:
263 self.assertFalse(
264 symbolfile.should_omit_version(
265 symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
266 False))
267 self.assertFalse(
268 symbolfile.should_omit_version(
269 symbolfile.Version('foo', None, [Tag('introduced=9')], []),
270 Arch('arm'), 9, False, False))
271
272 self.assertTrue(
273 symbolfile.should_omit_version(
274 symbolfile.Version('foo', None, [Tag('introduced=14')], []),
275 Arch('arm'), 9, False, False))
276
Dan Albert06f58af2020-06-22 15:10:31 -0700277
278class OmitSymbolTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700279 def test_omit_llndk(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700280 self.assertTrue(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700281 symbolfile.should_omit_symbol(
282 symbolfile.Symbol('foo', [Tag('llndk')]), Arch('arm'), 9,
283 False, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700284
285 self.assertFalse(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700286 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
287 Arch('arm'), 9, True, False))
Dan Albert06f58af2020-06-22 15:10:31 -0700288 self.assertFalse(
289 symbolfile.should_omit_symbol(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700290 symbolfile.Symbol('foo', [Tag('llndk')]), Arch('arm'), 9, True,
291 False))
292
293 def test_omit_apex(self) -> None:
294 self.assertTrue(
295 symbolfile.should_omit_symbol(
296 symbolfile.Symbol('foo', [Tag('apex')]), Arch('arm'), 9, False,
297 False))
298
299 self.assertFalse(
300 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
301 Arch('arm'), 9, False, True))
302 self.assertFalse(
303 symbolfile.should_omit_symbol(
304 symbolfile.Symbol('foo', [Tag('apex')]), Arch('arm'), 9, False,
305 True))
306
307 def test_omit_arch(self) -> None:
308 self.assertFalse(
309 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
310 Arch('arm'), 9, False, False))
311 self.assertFalse(
312 symbolfile.should_omit_symbol(
313 symbolfile.Symbol('foo', [Tag('arm')]), Arch('arm'), 9, False,
Dan Albert06f58af2020-06-22 15:10:31 -0700314 False))
315
316 self.assertTrue(
317 symbolfile.should_omit_symbol(
Dan Albertaf7b36d2020-06-23 11:21:21 -0700318 symbolfile.Symbol('foo', [Tag('x86')]), Arch('arm'), 9, False,
Dan Albert06f58af2020-06-22 15:10:31 -0700319 False))
320
Dan Albertaf7b36d2020-06-23 11:21:21 -0700321 def test_omit_api(self) -> None:
322 self.assertFalse(
323 symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
324 Arch('arm'), 9, False, False))
325 self.assertFalse(
326 symbolfile.should_omit_symbol(
327 symbolfile.Symbol('foo', [Tag('introduced=9')]), Arch('arm'),
328 9, False, False))
329
330 self.assertTrue(
331 symbolfile.should_omit_symbol(
332 symbolfile.Symbol('foo', [Tag('introduced=14')]), Arch('arm'),
333 9, False, False))
334
Dan Albert06f58af2020-06-22 15:10:31 -0700335
336class SymbolFileParseTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700337 def test_next_line(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700338 input_file = io.StringIO(textwrap.dedent("""\
339 foo
340
341 bar
342 # baz
343 qux
344 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700345 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
346 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700347 self.assertIsNone(parser.current_line)
348
349 self.assertEqual('foo', parser.next_line().strip())
Dan Albertaf7b36d2020-06-23 11:21:21 -0700350 assert parser.current_line is not None
Dan Albert06f58af2020-06-22 15:10:31 -0700351 self.assertEqual('foo', parser.current_line.strip())
352
353 self.assertEqual('bar', parser.next_line().strip())
354 self.assertEqual('bar', parser.current_line.strip())
355
356 self.assertEqual('qux', parser.next_line().strip())
357 self.assertEqual('qux', parser.current_line.strip())
358
359 self.assertEqual('', parser.next_line())
360 self.assertEqual('', parser.current_line)
361
Dan Albertaf7b36d2020-06-23 11:21:21 -0700362 def test_parse_version(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700363 input_file = io.StringIO(textwrap.dedent("""\
364 VERSION_1 { # foo bar
365 baz;
366 qux; # woodly doodly
367 };
368
369 VERSION_2 {
370 } VERSION_1; # asdf
371 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700372 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
373 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700374
375 parser.next_line()
376 version = parser.parse_version()
377 self.assertEqual('VERSION_1', version.name)
378 self.assertIsNone(version.base)
379 self.assertEqual(['foo', 'bar'], version.tags)
380
381 expected_symbols = [
382 symbolfile.Symbol('baz', []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700383 symbolfile.Symbol('qux', [Tag('woodly'), Tag('doodly')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700384 ]
385 self.assertEqual(expected_symbols, version.symbols)
386
387 parser.next_line()
388 version = parser.parse_version()
389 self.assertEqual('VERSION_2', version.name)
390 self.assertEqual('VERSION_1', version.base)
391 self.assertEqual([], version.tags)
392
Dan Albertaf7b36d2020-06-23 11:21:21 -0700393 def test_parse_version_eof(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700394 input_file = io.StringIO(textwrap.dedent("""\
395 VERSION_1 {
396 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700397 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
398 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700399 parser.next_line()
400 with self.assertRaises(symbolfile.ParseError):
401 parser.parse_version()
402
Dan Albertaf7b36d2020-06-23 11:21:21 -0700403 def test_unknown_scope_label(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700404 input_file = io.StringIO(textwrap.dedent("""\
405 VERSION_1 {
406 foo:
407 }
408 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700409 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
410 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700411 parser.next_line()
412 with self.assertRaises(symbolfile.ParseError):
413 parser.parse_version()
414
Dan Albertaf7b36d2020-06-23 11:21:21 -0700415 def test_parse_symbol(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700416 input_file = io.StringIO(textwrap.dedent("""\
417 foo;
418 bar; # baz qux
419 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700420 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
421 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700422
423 parser.next_line()
424 symbol = parser.parse_symbol()
425 self.assertEqual('foo', symbol.name)
426 self.assertEqual([], symbol.tags)
427
428 parser.next_line()
429 symbol = parser.parse_symbol()
430 self.assertEqual('bar', symbol.name)
431 self.assertEqual(['baz', 'qux'], symbol.tags)
432
Dan Albertaf7b36d2020-06-23 11:21:21 -0700433 def test_wildcard_symbol_global(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700434 input_file = io.StringIO(textwrap.dedent("""\
435 VERSION_1 {
436 *;
437 };
438 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700439 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
440 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700441 parser.next_line()
442 with self.assertRaises(symbolfile.ParseError):
443 parser.parse_version()
444
Dan Albertaf7b36d2020-06-23 11:21:21 -0700445 def test_wildcard_symbol_local(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700446 input_file = io.StringIO(textwrap.dedent("""\
447 VERSION_1 {
448 local:
449 *;
450 };
451 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700452 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
453 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700454 parser.next_line()
455 version = parser.parse_version()
456 self.assertEqual([], version.symbols)
457
Dan Albertaf7b36d2020-06-23 11:21:21 -0700458 def test_missing_semicolon(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700459 input_file = io.StringIO(textwrap.dedent("""\
460 VERSION_1 {
461 foo
462 };
463 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700464 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
465 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700466 parser.next_line()
467 with self.assertRaises(symbolfile.ParseError):
468 parser.parse_version()
469
Dan Albertaf7b36d2020-06-23 11:21:21 -0700470 def test_parse_fails_invalid_input(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700471 with self.assertRaises(symbolfile.ParseError):
472 input_file = io.StringIO('foo')
Dan Albertaf7b36d2020-06-23 11:21:21 -0700473 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
474 16, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700475 parser.parse()
476
Dan Albertaf7b36d2020-06-23 11:21:21 -0700477 def test_parse(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700478 input_file = io.StringIO(textwrap.dedent("""\
479 VERSION_1 {
480 local:
481 hidden1;
482 global:
483 foo;
484 bar; # baz
485 };
486
487 VERSION_2 { # wasd
488 # Implicit global scope.
489 woodly;
490 doodly; # asdf
491 local:
492 qwerty;
493 } VERSION_1;
494 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700495 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
496 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700497 versions = parser.parse()
498
499 expected = [
500 symbolfile.Version('VERSION_1', None, [], [
501 symbolfile.Symbol('foo', []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700502 symbolfile.Symbol('bar', [Tag('baz')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700503 ]),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700504 symbolfile.Version('VERSION_2', 'VERSION_1', [Tag('wasd')], [
Dan Albert06f58af2020-06-22 15:10:31 -0700505 symbolfile.Symbol('woodly', []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700506 symbolfile.Symbol('doodly', [Tag('asdf')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700507 ]),
508 ]
509
510 self.assertEqual(expected, versions)
511
Dan Albertaf7b36d2020-06-23 11:21:21 -0700512 def test_parse_llndk_apex_symbol(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700513 input_file = io.StringIO(textwrap.dedent("""\
514 VERSION_1 {
515 foo;
516 bar; # llndk
517 baz; # llndk apex
518 qux; # apex
519 };
520 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700521 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
522 False, True)
Dan Albert06f58af2020-06-22 15:10:31 -0700523
524 parser.next_line()
525 version = parser.parse_version()
526 self.assertEqual('VERSION_1', version.name)
527 self.assertIsNone(version.base)
528
529 expected_symbols = [
530 symbolfile.Symbol('foo', []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700531 symbolfile.Symbol('bar', [Tag('llndk')]),
532 symbolfile.Symbol('baz', [Tag('llndk'), Tag('apex')]),
533 symbolfile.Symbol('qux', [Tag('apex')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700534 ]
535 self.assertEqual(expected_symbols, version.symbols)
536
537
Dan Albertaf7b36d2020-06-23 11:21:21 -0700538def main() -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700539 suite = unittest.TestLoader().loadTestsFromName(__name__)
540 unittest.TextTestRunner(verbosity=3).run(suite)
541
542
543if __name__ == '__main__':
544 main()