blob: de861996696bfd9be1a399fc921973234e75f1da [file] [log] [blame]
Dan Albert8bdccb92016-07-29 13:06:22 -07001#!/usr/bin/env python
2#
3# Copyright (C) 2016 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""Tests for gen_stub_libs.py."""
Dan Albertf5b81842018-10-09 15:22:15 -070018import io
Dan Albert8bdccb92016-07-29 13:06:22 -070019import textwrap
20import unittest
21
22import gen_stub_libs as gsl
23
24
Dan Albert802cc822020-06-22 15:59:12 -070025
Dan Albert8bdccb92016-07-29 13:06:22 -070026# pylint: disable=missing-docstring
27
28
Dan Albert3f6fb2d2017-03-28 16:04:25 -070029class DecodeApiLevelTest(unittest.TestCase):
30 def test_decode_api_level(self):
31 self.assertEqual(9, gsl.decode_api_level('9', {}))
32 self.assertEqual(9000, gsl.decode_api_level('O', {'O': 9000}))
33
34 with self.assertRaises(KeyError):
35 gsl.decode_api_level('O', {})
36
37
Dan Albert8bdccb92016-07-29 13:06:22 -070038class TagsTest(unittest.TestCase):
39 def test_get_tags_no_tags(self):
40 self.assertEqual([], gsl.get_tags(''))
41 self.assertEqual([], gsl.get_tags('foo bar baz'))
42
43 def test_get_tags(self):
44 self.assertEqual(['foo', 'bar'], gsl.get_tags('# foo bar'))
45 self.assertEqual(['bar', 'baz'], gsl.get_tags('foo # bar baz'))
46
Dan Albert3f6fb2d2017-03-28 16:04:25 -070047 def test_split_tag(self):
48 self.assertTupleEqual(('foo', 'bar'), gsl.split_tag('foo=bar'))
49 self.assertTupleEqual(('foo', 'bar=baz'), gsl.split_tag('foo=bar=baz'))
50 with self.assertRaises(ValueError):
51 gsl.split_tag('foo')
52
Dan Albert8bdccb92016-07-29 13:06:22 -070053 def test_get_tag_value(self):
54 self.assertEqual('bar', gsl.get_tag_value('foo=bar'))
55 self.assertEqual('bar=baz', gsl.get_tag_value('foo=bar=baz'))
56 with self.assertRaises(ValueError):
57 gsl.get_tag_value('foo')
58
Dan Albert3f6fb2d2017-03-28 16:04:25 -070059 def test_is_api_level_tag(self):
60 self.assertTrue(gsl.is_api_level_tag('introduced=24'))
61 self.assertTrue(gsl.is_api_level_tag('introduced-arm=24'))
62 self.assertTrue(gsl.is_api_level_tag('versioned=24'))
63
64 # Shouldn't try to process things that aren't a key/value tag.
65 self.assertFalse(gsl.is_api_level_tag('arm'))
66 self.assertFalse(gsl.is_api_level_tag('introduced'))
67 self.assertFalse(gsl.is_api_level_tag('versioned'))
68
69 # We don't support arch specific `versioned` tags.
70 self.assertFalse(gsl.is_api_level_tag('versioned-arm=24'))
71
72 def test_decode_api_level_tags(self):
73 api_map = {
74 'O': 9000,
75 'P': 9001,
76 }
77
78 tags = [
79 'introduced=9',
80 'introduced-arm=14',
81 'versioned=16',
82 'arm',
83 'introduced=O',
84 'introduced=P',
85 ]
86 expected_tags = [
87 'introduced=9',
88 'introduced-arm=14',
89 'versioned=16',
90 'arm',
91 'introduced=9000',
92 'introduced=9001',
93 ]
94 self.assertListEqual(
95 expected_tags, gsl.decode_api_level_tags(tags, api_map))
96
97 with self.assertRaises(gsl.ParseError):
98 gsl.decode_api_level_tags(['introduced=O'], {})
99
Dan Albert8bdccb92016-07-29 13:06:22 -0700100
101class PrivateVersionTest(unittest.TestCase):
102 def test_version_is_private(self):
103 self.assertFalse(gsl.version_is_private('foo'))
104 self.assertFalse(gsl.version_is_private('PRIVATE'))
105 self.assertFalse(gsl.version_is_private('PLATFORM'))
106 self.assertFalse(gsl.version_is_private('foo_private'))
107 self.assertFalse(gsl.version_is_private('foo_platform'))
108 self.assertFalse(gsl.version_is_private('foo_PRIVATE_'))
109 self.assertFalse(gsl.version_is_private('foo_PLATFORM_'))
110
111 self.assertTrue(gsl.version_is_private('foo_PRIVATE'))
112 self.assertTrue(gsl.version_is_private('foo_PLATFORM'))
113
114
115class SymbolPresenceTest(unittest.TestCase):
116 def test_symbol_in_arch(self):
117 self.assertTrue(gsl.symbol_in_arch([], 'arm'))
118 self.assertTrue(gsl.symbol_in_arch(['arm'], 'arm'))
119
120 self.assertFalse(gsl.symbol_in_arch(['x86'], 'arm'))
121
122 def test_symbol_in_api(self):
123 self.assertTrue(gsl.symbol_in_api([], 'arm', 9))
124 self.assertTrue(gsl.symbol_in_api(['introduced=9'], 'arm', 9))
125 self.assertTrue(gsl.symbol_in_api(['introduced=9'], 'arm', 14))
126 self.assertTrue(gsl.symbol_in_api(['introduced-arm=9'], 'arm', 14))
127 self.assertTrue(gsl.symbol_in_api(['introduced-arm=9'], 'arm', 14))
128 self.assertTrue(gsl.symbol_in_api(['introduced-x86=14'], 'arm', 9))
129 self.assertTrue(gsl.symbol_in_api(
130 ['introduced-arm=9', 'introduced-x86=21'], 'arm', 14))
131 self.assertTrue(gsl.symbol_in_api(
132 ['introduced=9', 'introduced-x86=21'], 'arm', 14))
133 self.assertTrue(gsl.symbol_in_api(
134 ['introduced=21', 'introduced-arm=9'], 'arm', 14))
Dan Albertfd86e9e2016-11-08 13:35:12 -0800135 self.assertTrue(gsl.symbol_in_api(
136 ['future'], 'arm', gsl.FUTURE_API_LEVEL))
Dan Albert8bdccb92016-07-29 13:06:22 -0700137
138 self.assertFalse(gsl.symbol_in_api(['introduced=14'], 'arm', 9))
139 self.assertFalse(gsl.symbol_in_api(['introduced-arm=14'], 'arm', 9))
140 self.assertFalse(gsl.symbol_in_api(['future'], 'arm', 9))
141 self.assertFalse(gsl.symbol_in_api(
142 ['introduced=9', 'future'], 'arm', 14))
143 self.assertFalse(gsl.symbol_in_api(
144 ['introduced-arm=9', 'future'], 'arm', 14))
145 self.assertFalse(gsl.symbol_in_api(
146 ['introduced-arm=21', 'introduced-x86=9'], 'arm', 14))
147 self.assertFalse(gsl.symbol_in_api(
148 ['introduced=9', 'introduced-arm=21'], 'arm', 14))
149 self.assertFalse(gsl.symbol_in_api(
150 ['introduced=21', 'introduced-x86=9'], 'arm', 14))
151
152 # Interesting edge case: this symbol should be omitted from the
153 # library, but this call should still return true because none of the
154 # tags indiciate that it's not present in this API level.
155 self.assertTrue(gsl.symbol_in_api(['x86'], 'arm', 9))
156
157 def test_verioned_in_api(self):
158 self.assertTrue(gsl.symbol_versioned_in_api([], 9))
159 self.assertTrue(gsl.symbol_versioned_in_api(['versioned=9'], 9))
160 self.assertTrue(gsl.symbol_versioned_in_api(['versioned=9'], 14))
161
162 self.assertFalse(gsl.symbol_versioned_in_api(['versioned=14'], 9))
163
164
165class OmitVersionTest(unittest.TestCase):
166 def test_omit_private(self):
Dan Albert8bdccb92016-07-29 13:06:22 -0700167 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700168 gsl.should_omit_version(gsl.Version('foo', None, [], []), 'arm', 9,
169 False, False))
Dan Albert8bdccb92016-07-29 13:06:22 -0700170
171 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700172 gsl.should_omit_version(gsl.Version('foo_PRIVATE', None, [], []),
173 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700174 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700175 gsl.should_omit_version(gsl.Version('foo_PLATFORM', None, [], []),
176 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700177
178 self.assertTrue(
179 gsl.should_omit_version(
180 gsl.Version('foo', None, ['platform-only'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900181 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700182
Jiyong Park92d6bc12019-11-06 12:37:43 +0900183 def test_omit_llndk(self):
Dan Albert756f2d02018-10-09 16:36:03 -0700184 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700185 gsl.should_omit_version(gsl.Version('foo', None, ['llndk'], []),
186 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700187
188 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700189 gsl.should_omit_version(gsl.Version('foo', None, [], []), 'arm', 9,
190 True, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700191 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700192 gsl.should_omit_version(gsl.Version('foo', None, ['llndk'], []),
193 'arm', 9, True, False))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900194
195 def test_omit_apex(self):
196 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700197 gsl.should_omit_version(gsl.Version('foo', None, ['apex'], []),
198 'arm', 9, False, False))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900199
200 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700201 gsl.should_omit_version(gsl.Version('foo', None, [], []), 'arm', 9,
202 False, True))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900203 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700204 gsl.should_omit_version(gsl.Version('foo', None, ['apex'], []),
205 'arm', 9, False, True))
Dan Albert756f2d02018-10-09 16:36:03 -0700206
207 def test_omit_arch(self):
208 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700209 gsl.should_omit_version(gsl.Version('foo', None, [], []), 'arm', 9,
210 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700211 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700212 gsl.should_omit_version(gsl.Version('foo', None, ['arm'], []),
213 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700214
215 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700216 gsl.should_omit_version(gsl.Version('foo', None, ['x86'], []),
217 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700218
219 def test_omit_api(self):
220 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700221 gsl.should_omit_version(gsl.Version('foo', None, [], []), 'arm', 9,
222 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700223 self.assertFalse(
224 gsl.should_omit_version(
225 gsl.Version('foo', None, ['introduced=9'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900226 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700227
228 self.assertTrue(
229 gsl.should_omit_version(
230 gsl.Version('foo', None, ['introduced=14'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900231 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700232
233
234class OmitSymbolTest(unittest.TestCase):
Jiyong Park92d6bc12019-11-06 12:37:43 +0900235 def test_omit_llndk(self):
Dan Albert756f2d02018-10-09 16:36:03 -0700236 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700237 gsl.should_omit_symbol(gsl.Symbol('foo', ['llndk']), 'arm', 9,
238 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700239
240 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700241 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, True,
242 False))
Dan Albert756f2d02018-10-09 16:36:03 -0700243 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700244 gsl.should_omit_symbol(gsl.Symbol('foo', ['llndk']), 'arm', 9,
245 True, False))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900246
247 def test_omit_apex(self):
248 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700249 gsl.should_omit_symbol(gsl.Symbol('foo', ['apex']), 'arm', 9,
250 False, False))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900251
252 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700253 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False,
254 True))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900255 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700256 gsl.should_omit_symbol(gsl.Symbol('foo', ['apex']), 'arm', 9,
257 False, True))
Dan Albert756f2d02018-10-09 16:36:03 -0700258
259 def test_omit_arch(self):
260 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700261 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False,
262 False))
Dan Albert756f2d02018-10-09 16:36:03 -0700263 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700264 gsl.should_omit_symbol(gsl.Symbol('foo', ['arm']), 'arm', 9, False,
265 False))
Dan Albert756f2d02018-10-09 16:36:03 -0700266
267 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700268 gsl.should_omit_symbol(gsl.Symbol('foo', ['x86']), 'arm', 9, False,
269 False))
Dan Albert756f2d02018-10-09 16:36:03 -0700270
271 def test_omit_api(self):
272 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700273 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False,
274 False))
Dan Albert756f2d02018-10-09 16:36:03 -0700275 self.assertFalse(
Dan Albert802cc822020-06-22 15:59:12 -0700276 gsl.should_omit_symbol(gsl.Symbol('foo', ['introduced=9']), 'arm',
277 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700278
279 self.assertTrue(
Dan Albert802cc822020-06-22 15:59:12 -0700280 gsl.should_omit_symbol(gsl.Symbol('foo', ['introduced=14']), 'arm',
281 9, False, False))
Dan Albert8bdccb92016-07-29 13:06:22 -0700282
283
284class SymbolFileParseTest(unittest.TestCase):
285 def test_next_line(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700286 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700287 foo
288
289 bar
290 # baz
291 qux
292 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900293 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700294 self.assertIsNone(parser.current_line)
295
296 self.assertEqual('foo', parser.next_line().strip())
297 self.assertEqual('foo', parser.current_line.strip())
298
299 self.assertEqual('bar', parser.next_line().strip())
300 self.assertEqual('bar', parser.current_line.strip())
301
302 self.assertEqual('qux', parser.next_line().strip())
303 self.assertEqual('qux', parser.current_line.strip())
304
305 self.assertEqual('', parser.next_line())
306 self.assertEqual('', parser.current_line)
307
308 def test_parse_version(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700309 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700310 VERSION_1 { # foo bar
311 baz;
312 qux; # woodly doodly
313 };
314
315 VERSION_2 {
316 } VERSION_1; # asdf
317 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900318 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700319
320 parser.next_line()
321 version = parser.parse_version()
322 self.assertEqual('VERSION_1', version.name)
323 self.assertIsNone(version.base)
324 self.assertEqual(['foo', 'bar'], version.tags)
325
326 expected_symbols = [
327 gsl.Symbol('baz', []),
328 gsl.Symbol('qux', ['woodly', 'doodly']),
329 ]
330 self.assertEqual(expected_symbols, version.symbols)
331
332 parser.next_line()
333 version = parser.parse_version()
334 self.assertEqual('VERSION_2', version.name)
335 self.assertEqual('VERSION_1', version.base)
336 self.assertEqual([], version.tags)
337
338 def test_parse_version_eof(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700339 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700340 VERSION_1 {
341 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900342 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700343 parser.next_line()
344 with self.assertRaises(gsl.ParseError):
345 parser.parse_version()
346
347 def test_unknown_scope_label(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700348 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700349 VERSION_1 {
350 foo:
351 }
352 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900353 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700354 parser.next_line()
355 with self.assertRaises(gsl.ParseError):
356 parser.parse_version()
357
358 def test_parse_symbol(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700359 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700360 foo;
361 bar; # baz qux
362 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900363 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700364
365 parser.next_line()
366 symbol = parser.parse_symbol()
367 self.assertEqual('foo', symbol.name)
368 self.assertEqual([], symbol.tags)
369
370 parser.next_line()
371 symbol = parser.parse_symbol()
372 self.assertEqual('bar', symbol.name)
373 self.assertEqual(['baz', 'qux'], symbol.tags)
374
375 def test_wildcard_symbol_global(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700376 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700377 VERSION_1 {
378 *;
379 };
380 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900381 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700382 parser.next_line()
383 with self.assertRaises(gsl.ParseError):
384 parser.parse_version()
385
386 def test_wildcard_symbol_local(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700387 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700388 VERSION_1 {
389 local:
390 *;
391 };
392 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900393 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700394 parser.next_line()
395 version = parser.parse_version()
396 self.assertEqual([], version.symbols)
397
398 def test_missing_semicolon(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700399 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700400 VERSION_1 {
401 foo
402 };
403 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900404 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700405 parser.next_line()
406 with self.assertRaises(gsl.ParseError):
407 parser.parse_version()
408
409 def test_parse_fails_invalid_input(self):
410 with self.assertRaises(gsl.ParseError):
Dan Albertf5b81842018-10-09 15:22:15 -0700411 input_file = io.StringIO('foo')
Dan Albert802cc822020-06-22 15:59:12 -0700412 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False,
413 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700414 parser.parse()
415
416 def test_parse(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700417 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700418 VERSION_1 {
419 local:
420 hidden1;
421 global:
422 foo;
423 bar; # baz
424 };
425
426 VERSION_2 { # wasd
427 # Implicit global scope.
428 woodly;
429 doodly; # asdf
430 local:
431 qwerty;
432 } VERSION_1;
433 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900434 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700435 versions = parser.parse()
436
437 expected = [
438 gsl.Version('VERSION_1', None, [], [
439 gsl.Symbol('foo', []),
440 gsl.Symbol('bar', ['baz']),
441 ]),
442 gsl.Version('VERSION_2', 'VERSION_1', ['wasd'], [
443 gsl.Symbol('woodly', []),
444 gsl.Symbol('doodly', ['asdf']),
445 ]),
446 ]
447
448 self.assertEqual(expected, versions)
449
Jiyong Park92d6bc12019-11-06 12:37:43 +0900450 def test_parse_llndk_apex_symbol(self):
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900451 input_file = io.StringIO(textwrap.dedent("""\
452 VERSION_1 {
453 foo;
Jiyong Park92d6bc12019-11-06 12:37:43 +0900454 bar; # llndk
455 baz; # llndk apex
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900456 qux; # apex
457 };
458 """))
459 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, True)
460
461 parser.next_line()
462 version = parser.parse_version()
463 self.assertEqual('VERSION_1', version.name)
464 self.assertIsNone(version.base)
465
466 expected_symbols = [
467 gsl.Symbol('foo', []),
Jiyong Park92d6bc12019-11-06 12:37:43 +0900468 gsl.Symbol('bar', ['llndk']),
469 gsl.Symbol('baz', ['llndk', 'apex']),
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900470 gsl.Symbol('qux', ['apex']),
471 ]
472 self.assertEqual(expected_symbols, version.symbols)
473
Dan Albert8bdccb92016-07-29 13:06:22 -0700474
475class GeneratorTest(unittest.TestCase):
476 def test_omit_version(self):
477 # Thorough testing of the cases involved here is handled by
478 # OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
Dan Albertf5b81842018-10-09 15:22:15 -0700479 src_file = io.StringIO()
480 version_file = io.StringIO()
Dan Albert802cc822020-06-22 15:59:12 -0700481 generator = gsl.Generator(src_file, version_file, 'arm', 9, False,
482 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700483
484 version = gsl.Version('VERSION_PRIVATE', None, [], [
485 gsl.Symbol('foo', []),
486 ])
487 generator.write_version(version)
488 self.assertEqual('', src_file.getvalue())
489 self.assertEqual('', version_file.getvalue())
490
491 version = gsl.Version('VERSION', None, ['x86'], [
492 gsl.Symbol('foo', []),
493 ])
494 generator.write_version(version)
495 self.assertEqual('', src_file.getvalue())
496 self.assertEqual('', version_file.getvalue())
497
498 version = gsl.Version('VERSION', None, ['introduced=14'], [
499 gsl.Symbol('foo', []),
500 ])
501 generator.write_version(version)
502 self.assertEqual('', src_file.getvalue())
503 self.assertEqual('', version_file.getvalue())
504
505 def test_omit_symbol(self):
506 # Thorough testing of the cases involved here is handled by
507 # SymbolPresenceTest.
Dan Albertf5b81842018-10-09 15:22:15 -0700508 src_file = io.StringIO()
509 version_file = io.StringIO()
Dan Albert802cc822020-06-22 15:59:12 -0700510 generator = gsl.Generator(src_file, version_file, 'arm', 9, False,
511 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700512
513 version = gsl.Version('VERSION_1', None, [], [
514 gsl.Symbol('foo', ['x86']),
515 ])
516 generator.write_version(version)
517 self.assertEqual('', src_file.getvalue())
518 self.assertEqual('', version_file.getvalue())
519
520 version = gsl.Version('VERSION_1', None, [], [
521 gsl.Symbol('foo', ['introduced=14']),
522 ])
523 generator.write_version(version)
524 self.assertEqual('', src_file.getvalue())
525 self.assertEqual('', version_file.getvalue())
526
Dan Willemsenb01e7f72017-04-03 14:28:36 -0700527 version = gsl.Version('VERSION_1', None, [], [
Jiyong Park92d6bc12019-11-06 12:37:43 +0900528 gsl.Symbol('foo', ['llndk']),
Dan Willemsenb01e7f72017-04-03 14:28:36 -0700529 ])
530 generator.write_version(version)
531 self.assertEqual('', src_file.getvalue())
532 self.assertEqual('', version_file.getvalue())
533
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900534 version = gsl.Version('VERSION_1', None, [], [
535 gsl.Symbol('foo', ['apex']),
536 ])
537 generator.write_version(version)
538 self.assertEqual('', src_file.getvalue())
539 self.assertEqual('', version_file.getvalue())
540
Dan Albert8bdccb92016-07-29 13:06:22 -0700541 def test_write(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700542 src_file = io.StringIO()
543 version_file = io.StringIO()
Dan Albert802cc822020-06-22 15:59:12 -0700544 generator = gsl.Generator(src_file, version_file, 'arm', 9, False,
545 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700546
547 versions = [
548 gsl.Version('VERSION_1', None, [], [
549 gsl.Symbol('foo', []),
550 gsl.Symbol('bar', ['var']),
Dan Albertf55f0782017-07-28 11:00:22 -0700551 gsl.Symbol('woodly', ['weak']),
552 gsl.Symbol('doodly', ['weak', 'var']),
Dan Albert8bdccb92016-07-29 13:06:22 -0700553 ]),
554 gsl.Version('VERSION_2', 'VERSION_1', [], [
555 gsl.Symbol('baz', []),
556 ]),
557 gsl.Version('VERSION_3', 'VERSION_1', [], [
558 gsl.Symbol('qux', ['versioned=14']),
559 ]),
560 ]
561
562 generator.write(versions)
563 expected_src = textwrap.dedent("""\
564 void foo() {}
565 int bar = 0;
Dan Albertf55f0782017-07-28 11:00:22 -0700566 __attribute__((weak)) void woodly() {}
567 __attribute__((weak)) int doodly = 0;
Dan Albert8bdccb92016-07-29 13:06:22 -0700568 void baz() {}
569 void qux() {}
570 """)
571 self.assertEqual(expected_src, src_file.getvalue())
572
573 expected_version = textwrap.dedent("""\
574 VERSION_1 {
575 global:
576 foo;
577 bar;
Dan Albertf55f0782017-07-28 11:00:22 -0700578 woodly;
579 doodly;
Dan Albert8bdccb92016-07-29 13:06:22 -0700580 };
581 VERSION_2 {
582 global:
583 baz;
584 } VERSION_1;
585 """)
586 self.assertEqual(expected_version, version_file.getvalue())
587
588
589class IntegrationTest(unittest.TestCase):
590 def test_integration(self):
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700591 api_map = {
592 'O': 9000,
593 'P': 9001,
594 }
595
Dan Albertf5b81842018-10-09 15:22:15 -0700596 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700597 VERSION_1 {
598 global:
599 foo; # var
600 bar; # x86
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700601 fizz; # introduced=O
602 buzz; # introduced=P
Dan Albert8bdccb92016-07-29 13:06:22 -0700603 local:
604 *;
605 };
606
607 VERSION_2 { # arm
608 baz; # introduced=9
609 qux; # versioned=14
610 } VERSION_1;
611
612 VERSION_3 { # introduced=14
613 woodly;
614 doodly; # var
615 } VERSION_2;
Dan Albertae452cc2017-01-03 14:27:41 -0800616
617 VERSION_4 { # versioned=9
618 wibble;
Jiyong Park92d6bc12019-11-06 12:37:43 +0900619 wizzes; # llndk
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900620 waggle; # apex
Dan Albertae452cc2017-01-03 14:27:41 -0800621 } VERSION_2;
622
623 VERSION_5 { # versioned=14
624 wobble;
625 } VERSION_4;
Dan Albert8bdccb92016-07-29 13:06:22 -0700626 """))
Dan Albert802cc822020-06-22 15:59:12 -0700627 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9, False,
628 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700629 versions = parser.parse()
630
Dan Albertf5b81842018-10-09 15:22:15 -0700631 src_file = io.StringIO()
632 version_file = io.StringIO()
Dan Albert802cc822020-06-22 15:59:12 -0700633 generator = gsl.Generator(src_file, version_file, 'arm', 9, False,
634 False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700635 generator.write(versions)
636
637 expected_src = textwrap.dedent("""\
638 int foo = 0;
639 void baz() {}
640 void qux() {}
Dan Albertae452cc2017-01-03 14:27:41 -0800641 void wibble() {}
642 void wobble() {}
Dan Albert8bdccb92016-07-29 13:06:22 -0700643 """)
644 self.assertEqual(expected_src, src_file.getvalue())
645
646 expected_version = textwrap.dedent("""\
647 VERSION_1 {
648 global:
649 foo;
650 };
651 VERSION_2 {
652 global:
653 baz;
654 } VERSION_1;
Dan Albertae452cc2017-01-03 14:27:41 -0800655 VERSION_4 {
656 global:
657 wibble;
658 } VERSION_2;
Dan Albert8bdccb92016-07-29 13:06:22 -0700659 """)
660 self.assertEqual(expected_version, version_file.getvalue())
661
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700662 def test_integration_future_api(self):
663 api_map = {
664 'O': 9000,
665 'P': 9001,
666 'Q': 9002,
667 }
668
Dan Albertf5b81842018-10-09 15:22:15 -0700669 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700670 VERSION_1 {
671 global:
672 foo; # introduced=O
673 bar; # introduced=P
674 baz; # introduced=Q
675 local:
676 *;
677 };
678 """))
Dan Albert802cc822020-06-22 15:59:12 -0700679 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9001, False,
680 False)
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700681 versions = parser.parse()
682
Dan Albertf5b81842018-10-09 15:22:15 -0700683 src_file = io.StringIO()
684 version_file = io.StringIO()
Dan Albert802cc822020-06-22 15:59:12 -0700685 generator = gsl.Generator(src_file, version_file, 'arm', 9001, False,
686 False)
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700687 generator.write(versions)
688
689 expected_src = textwrap.dedent("""\
690 void foo() {}
691 void bar() {}
692 """)
693 self.assertEqual(expected_src, src_file.getvalue())
694
695 expected_version = textwrap.dedent("""\
696 VERSION_1 {
697 global:
698 foo;
699 bar;
700 };
701 """)
702 self.assertEqual(expected_version, version_file.getvalue())
703
Dan Albert756f2d02018-10-09 16:36:03 -0700704 def test_multiple_definition(self):
705 input_file = io.StringIO(textwrap.dedent("""\
706 VERSION_1 {
707 global:
708 foo;
709 foo;
710 bar;
711 baz;
712 qux; # arm
713 local:
714 *;
715 };
716
717 VERSION_2 {
718 global:
719 bar;
720 qux; # arm64
721 } VERSION_1;
722
723 VERSION_PRIVATE {
724 global:
725 baz;
726 } VERSION_2;
727
728 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900729 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert756f2d02018-10-09 16:36:03 -0700730
Dan Albert802cc822020-06-22 15:59:12 -0700731 with self.assertRaises(gsl.MultiplyDefinedSymbolError) as ex_context:
Dan Albert756f2d02018-10-09 16:36:03 -0700732 parser.parse()
Dan Albert802cc822020-06-22 15:59:12 -0700733 self.assertEqual(['bar', 'foo'],
734 ex_context.exception.multiply_defined_symbols)
Dan Albert756f2d02018-10-09 16:36:03 -0700735
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900736 def test_integration_with_apex(self):
737 api_map = {
738 'O': 9000,
739 'P': 9001,
740 }
741
742 input_file = io.StringIO(textwrap.dedent("""\
743 VERSION_1 {
744 global:
745 foo; # var
746 bar; # x86
747 fizz; # introduced=O
748 buzz; # introduced=P
749 local:
750 *;
751 };
752
753 VERSION_2 { # arm
754 baz; # introduced=9
755 qux; # versioned=14
756 } VERSION_1;
757
758 VERSION_3 { # introduced=14
759 woodly;
760 doodly; # var
761 } VERSION_2;
762
763 VERSION_4 { # versioned=9
764 wibble;
Jiyong Park92d6bc12019-11-06 12:37:43 +0900765 wizzes; # llndk
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900766 waggle; # apex
Jiyong Park92d6bc12019-11-06 12:37:43 +0900767 bubble; # apex llndk
768 duddle; # llndk apex
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900769 } VERSION_2;
770
771 VERSION_5 { # versioned=14
772 wobble;
773 } VERSION_4;
774 """))
Dan Albert802cc822020-06-22 15:59:12 -0700775 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9, False,
776 True)
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900777 versions = parser.parse()
778
779 src_file = io.StringIO()
780 version_file = io.StringIO()
781 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, True)
782 generator.write(versions)
783
784 expected_src = textwrap.dedent("""\
785 int foo = 0;
786 void baz() {}
787 void qux() {}
788 void wibble() {}
789 void waggle() {}
Jiyong Park14317652019-02-08 20:34:32 +0900790 void bubble() {}
791 void duddle() {}
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900792 void wobble() {}
793 """)
794 self.assertEqual(expected_src, src_file.getvalue())
795
796 expected_version = textwrap.dedent("""\
797 VERSION_1 {
798 global:
799 foo;
800 };
801 VERSION_2 {
802 global:
803 baz;
804 } VERSION_1;
805 VERSION_4 {
806 global:
807 wibble;
808 waggle;
Jiyong Park14317652019-02-08 20:34:32 +0900809 bubble;
810 duddle;
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900811 } VERSION_2;
812 """)
813 self.assertEqual(expected_version, version_file.getvalue())
Dan Albert8bdccb92016-07-29 13:06:22 -0700814
815def main():
816 suite = unittest.TestLoader().loadTestsFromName(__name__)
817 unittest.TextTestRunner(verbosity=3).run(suite)
818
819
820if __name__ == '__main__':
821 main()