blob: 2ee9886937bcd016d9d4f330c0fe3c05a535a8e5 [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
25# pylint: disable=missing-docstring
26
27
Dan Albert3f6fb2d2017-03-28 16:04:25 -070028class DecodeApiLevelTest(unittest.TestCase):
29 def test_decode_api_level(self):
30 self.assertEqual(9, gsl.decode_api_level('9', {}))
31 self.assertEqual(9000, gsl.decode_api_level('O', {'O': 9000}))
32
33 with self.assertRaises(KeyError):
34 gsl.decode_api_level('O', {})
35
36
Dan Albert8bdccb92016-07-29 13:06:22 -070037class TagsTest(unittest.TestCase):
38 def test_get_tags_no_tags(self):
39 self.assertEqual([], gsl.get_tags(''))
40 self.assertEqual([], gsl.get_tags('foo bar baz'))
41
42 def test_get_tags(self):
43 self.assertEqual(['foo', 'bar'], gsl.get_tags('# foo bar'))
44 self.assertEqual(['bar', 'baz'], gsl.get_tags('foo # bar baz'))
45
Dan Albert3f6fb2d2017-03-28 16:04:25 -070046 def test_split_tag(self):
47 self.assertTupleEqual(('foo', 'bar'), gsl.split_tag('foo=bar'))
48 self.assertTupleEqual(('foo', 'bar=baz'), gsl.split_tag('foo=bar=baz'))
49 with self.assertRaises(ValueError):
50 gsl.split_tag('foo')
51
Dan Albert8bdccb92016-07-29 13:06:22 -070052 def test_get_tag_value(self):
53 self.assertEqual('bar', gsl.get_tag_value('foo=bar'))
54 self.assertEqual('bar=baz', gsl.get_tag_value('foo=bar=baz'))
55 with self.assertRaises(ValueError):
56 gsl.get_tag_value('foo')
57
Dan Albert3f6fb2d2017-03-28 16:04:25 -070058 def test_is_api_level_tag(self):
59 self.assertTrue(gsl.is_api_level_tag('introduced=24'))
60 self.assertTrue(gsl.is_api_level_tag('introduced-arm=24'))
61 self.assertTrue(gsl.is_api_level_tag('versioned=24'))
62
63 # Shouldn't try to process things that aren't a key/value tag.
64 self.assertFalse(gsl.is_api_level_tag('arm'))
65 self.assertFalse(gsl.is_api_level_tag('introduced'))
66 self.assertFalse(gsl.is_api_level_tag('versioned'))
67
68 # We don't support arch specific `versioned` tags.
69 self.assertFalse(gsl.is_api_level_tag('versioned-arm=24'))
70
71 def test_decode_api_level_tags(self):
72 api_map = {
73 'O': 9000,
74 'P': 9001,
75 }
76
77 tags = [
78 'introduced=9',
79 'introduced-arm=14',
80 'versioned=16',
81 'arm',
82 'introduced=O',
83 'introduced=P',
84 ]
85 expected_tags = [
86 'introduced=9',
87 'introduced-arm=14',
88 'versioned=16',
89 'arm',
90 'introduced=9000',
91 'introduced=9001',
92 ]
93 self.assertListEqual(
94 expected_tags, gsl.decode_api_level_tags(tags, api_map))
95
96 with self.assertRaises(gsl.ParseError):
97 gsl.decode_api_level_tags(['introduced=O'], {})
98
Dan Albert8bdccb92016-07-29 13:06:22 -070099
100class PrivateVersionTest(unittest.TestCase):
101 def test_version_is_private(self):
102 self.assertFalse(gsl.version_is_private('foo'))
103 self.assertFalse(gsl.version_is_private('PRIVATE'))
104 self.assertFalse(gsl.version_is_private('PLATFORM'))
105 self.assertFalse(gsl.version_is_private('foo_private'))
106 self.assertFalse(gsl.version_is_private('foo_platform'))
107 self.assertFalse(gsl.version_is_private('foo_PRIVATE_'))
108 self.assertFalse(gsl.version_is_private('foo_PLATFORM_'))
109
110 self.assertTrue(gsl.version_is_private('foo_PRIVATE'))
111 self.assertTrue(gsl.version_is_private('foo_PLATFORM'))
112
113
114class SymbolPresenceTest(unittest.TestCase):
115 def test_symbol_in_arch(self):
116 self.assertTrue(gsl.symbol_in_arch([], 'arm'))
117 self.assertTrue(gsl.symbol_in_arch(['arm'], 'arm'))
118
119 self.assertFalse(gsl.symbol_in_arch(['x86'], 'arm'))
120
121 def test_symbol_in_api(self):
122 self.assertTrue(gsl.symbol_in_api([], 'arm', 9))
123 self.assertTrue(gsl.symbol_in_api(['introduced=9'], 'arm', 9))
124 self.assertTrue(gsl.symbol_in_api(['introduced=9'], 'arm', 14))
125 self.assertTrue(gsl.symbol_in_api(['introduced-arm=9'], 'arm', 14))
126 self.assertTrue(gsl.symbol_in_api(['introduced-arm=9'], 'arm', 14))
127 self.assertTrue(gsl.symbol_in_api(['introduced-x86=14'], 'arm', 9))
128 self.assertTrue(gsl.symbol_in_api(
129 ['introduced-arm=9', 'introduced-x86=21'], 'arm', 14))
130 self.assertTrue(gsl.symbol_in_api(
131 ['introduced=9', 'introduced-x86=21'], 'arm', 14))
132 self.assertTrue(gsl.symbol_in_api(
133 ['introduced=21', 'introduced-arm=9'], 'arm', 14))
Dan Albertfd86e9e2016-11-08 13:35:12 -0800134 self.assertTrue(gsl.symbol_in_api(
135 ['future'], 'arm', gsl.FUTURE_API_LEVEL))
Dan Albert8bdccb92016-07-29 13:06:22 -0700136
137 self.assertFalse(gsl.symbol_in_api(['introduced=14'], 'arm', 9))
138 self.assertFalse(gsl.symbol_in_api(['introduced-arm=14'], 'arm', 9))
139 self.assertFalse(gsl.symbol_in_api(['future'], 'arm', 9))
140 self.assertFalse(gsl.symbol_in_api(
141 ['introduced=9', 'future'], 'arm', 14))
142 self.assertFalse(gsl.symbol_in_api(
143 ['introduced-arm=9', 'future'], 'arm', 14))
144 self.assertFalse(gsl.symbol_in_api(
145 ['introduced-arm=21', 'introduced-x86=9'], 'arm', 14))
146 self.assertFalse(gsl.symbol_in_api(
147 ['introduced=9', 'introduced-arm=21'], 'arm', 14))
148 self.assertFalse(gsl.symbol_in_api(
149 ['introduced=21', 'introduced-x86=9'], 'arm', 14))
150
151 # Interesting edge case: this symbol should be omitted from the
152 # library, but this call should still return true because none of the
153 # tags indiciate that it's not present in this API level.
154 self.assertTrue(gsl.symbol_in_api(['x86'], 'arm', 9))
155
156 def test_verioned_in_api(self):
157 self.assertTrue(gsl.symbol_versioned_in_api([], 9))
158 self.assertTrue(gsl.symbol_versioned_in_api(['versioned=9'], 9))
159 self.assertTrue(gsl.symbol_versioned_in_api(['versioned=9'], 14))
160
161 self.assertFalse(gsl.symbol_versioned_in_api(['versioned=14'], 9))
162
163
164class OmitVersionTest(unittest.TestCase):
165 def test_omit_private(self):
Dan Albert8bdccb92016-07-29 13:06:22 -0700166 self.assertFalse(
Dan Albert756f2d02018-10-09 16:36:03 -0700167 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900168 gsl.Version('foo', None, [], []), 'arm', 9, False, False))
Dan Albert8bdccb92016-07-29 13:06:22 -0700169
170 self.assertTrue(
Dan Albert756f2d02018-10-09 16:36:03 -0700171 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900172 gsl.Version('foo_PRIVATE', None, [], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700173 self.assertTrue(
174 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900175 gsl.Version('foo_PLATFORM', None, [], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700176
177 self.assertTrue(
178 gsl.should_omit_version(
179 gsl.Version('foo', None, ['platform-only'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900180 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700181
182 def test_omit_vndk(self):
183 self.assertTrue(
184 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900185 gsl.Version('foo', None, ['vndk'], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700186
187 self.assertFalse(
188 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900189 gsl.Version('foo', None, [], []), 'arm', 9, True, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700190 self.assertFalse(
191 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900192 gsl.Version('foo', None, ['vndk'], []), 'arm', 9, True, False))
193
194 def test_omit_apex(self):
195 self.assertTrue(
196 gsl.should_omit_version(
197 gsl.Version('foo', None, ['apex'], []), 'arm', 9, False, False))
198
199 self.assertFalse(
200 gsl.should_omit_version(
201 gsl.Version('foo', None, [], []), 'arm', 9, False, True))
202 self.assertFalse(
203 gsl.should_omit_version(
204 gsl.Version('foo', None, ['apex'], []), 'arm', 9, False, True))
Dan Albert756f2d02018-10-09 16:36:03 -0700205
206 def test_omit_arch(self):
207 self.assertFalse(
208 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900209 gsl.Version('foo', None, [], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700210 self.assertFalse(
211 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900212 gsl.Version('foo', None, ['arm'], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700213
214 self.assertTrue(
215 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900216 gsl.Version('foo', None, ['x86'], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700217
218 def test_omit_api(self):
219 self.assertFalse(
220 gsl.should_omit_version(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900221 gsl.Version('foo', None, [], []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700222 self.assertFalse(
223 gsl.should_omit_version(
224 gsl.Version('foo', None, ['introduced=9'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900225 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700226
227 self.assertTrue(
228 gsl.should_omit_version(
229 gsl.Version('foo', None, ['introduced=14'], []), 'arm', 9,
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900230 False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700231
232
233class OmitSymbolTest(unittest.TestCase):
234 def test_omit_vndk(self):
235 self.assertTrue(
236 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900237 gsl.Symbol('foo', ['vndk']), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700238
239 self.assertFalse(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900240 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, True, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700241 self.assertFalse(
242 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900243 gsl.Symbol('foo', ['vndk']), 'arm', 9, True, False))
244
245 def test_omit_apex(self):
246 self.assertTrue(
247 gsl.should_omit_symbol(
248 gsl.Symbol('foo', ['apex']), 'arm', 9, False, False))
249
250 self.assertFalse(
251 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False, True))
252 self.assertFalse(
253 gsl.should_omit_symbol(
254 gsl.Symbol('foo', ['apex']), 'arm', 9, False, True))
Dan Albert756f2d02018-10-09 16:36:03 -0700255
256 def test_omit_arch(self):
257 self.assertFalse(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900258 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700259 self.assertFalse(
260 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900261 gsl.Symbol('foo', ['arm']), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700262
263 self.assertTrue(
264 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900265 gsl.Symbol('foo', ['x86']), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700266
267 def test_omit_api(self):
268 self.assertFalse(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900269 gsl.should_omit_symbol(gsl.Symbol('foo', []), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700270 self.assertFalse(
271 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900272 gsl.Symbol('foo', ['introduced=9']), 'arm', 9, False, False))
Dan Albert756f2d02018-10-09 16:36:03 -0700273
274 self.assertTrue(
275 gsl.should_omit_symbol(
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900276 gsl.Symbol('foo', ['introduced=14']), 'arm', 9, False, False))
Dan Albert8bdccb92016-07-29 13:06:22 -0700277
278
279class SymbolFileParseTest(unittest.TestCase):
280 def test_next_line(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700281 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700282 foo
283
284 bar
285 # baz
286 qux
287 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900288 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700289 self.assertIsNone(parser.current_line)
290
291 self.assertEqual('foo', parser.next_line().strip())
292 self.assertEqual('foo', parser.current_line.strip())
293
294 self.assertEqual('bar', parser.next_line().strip())
295 self.assertEqual('bar', parser.current_line.strip())
296
297 self.assertEqual('qux', parser.next_line().strip())
298 self.assertEqual('qux', parser.current_line.strip())
299
300 self.assertEqual('', parser.next_line())
301 self.assertEqual('', parser.current_line)
302
303 def test_parse_version(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700304 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700305 VERSION_1 { # foo bar
306 baz;
307 qux; # woodly doodly
308 };
309
310 VERSION_2 {
311 } VERSION_1; # asdf
312 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900313 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700314
315 parser.next_line()
316 version = parser.parse_version()
317 self.assertEqual('VERSION_1', version.name)
318 self.assertIsNone(version.base)
319 self.assertEqual(['foo', 'bar'], version.tags)
320
321 expected_symbols = [
322 gsl.Symbol('baz', []),
323 gsl.Symbol('qux', ['woodly', 'doodly']),
324 ]
325 self.assertEqual(expected_symbols, version.symbols)
326
327 parser.next_line()
328 version = parser.parse_version()
329 self.assertEqual('VERSION_2', version.name)
330 self.assertEqual('VERSION_1', version.base)
331 self.assertEqual([], version.tags)
332
333 def test_parse_version_eof(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700334 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700335 VERSION_1 {
336 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900337 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700338 parser.next_line()
339 with self.assertRaises(gsl.ParseError):
340 parser.parse_version()
341
342 def test_unknown_scope_label(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700343 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700344 VERSION_1 {
345 foo:
346 }
347 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900348 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700349 parser.next_line()
350 with self.assertRaises(gsl.ParseError):
351 parser.parse_version()
352
353 def test_parse_symbol(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700354 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700355 foo;
356 bar; # baz qux
357 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900358 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700359
360 parser.next_line()
361 symbol = parser.parse_symbol()
362 self.assertEqual('foo', symbol.name)
363 self.assertEqual([], symbol.tags)
364
365 parser.next_line()
366 symbol = parser.parse_symbol()
367 self.assertEqual('bar', symbol.name)
368 self.assertEqual(['baz', 'qux'], symbol.tags)
369
370 def test_wildcard_symbol_global(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700371 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700372 VERSION_1 {
373 *;
374 };
375 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900376 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700377 parser.next_line()
378 with self.assertRaises(gsl.ParseError):
379 parser.parse_version()
380
381 def test_wildcard_symbol_local(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700382 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700383 VERSION_1 {
384 local:
385 *;
386 };
387 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900388 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700389 parser.next_line()
390 version = parser.parse_version()
391 self.assertEqual([], version.symbols)
392
393 def test_missing_semicolon(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700394 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700395 VERSION_1 {
396 foo
397 };
398 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900399 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700400 parser.next_line()
401 with self.assertRaises(gsl.ParseError):
402 parser.parse_version()
403
404 def test_parse_fails_invalid_input(self):
405 with self.assertRaises(gsl.ParseError):
Dan Albertf5b81842018-10-09 15:22:15 -0700406 input_file = io.StringIO('foo')
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900407 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700408 parser.parse()
409
410 def test_parse(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700411 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700412 VERSION_1 {
413 local:
414 hidden1;
415 global:
416 foo;
417 bar; # baz
418 };
419
420 VERSION_2 { # wasd
421 # Implicit global scope.
422 woodly;
423 doodly; # asdf
424 local:
425 qwerty;
426 } VERSION_1;
427 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900428 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700429 versions = parser.parse()
430
431 expected = [
432 gsl.Version('VERSION_1', None, [], [
433 gsl.Symbol('foo', []),
434 gsl.Symbol('bar', ['baz']),
435 ]),
436 gsl.Version('VERSION_2', 'VERSION_1', ['wasd'], [
437 gsl.Symbol('woodly', []),
438 gsl.Symbol('doodly', ['asdf']),
439 ]),
440 ]
441
442 self.assertEqual(expected, versions)
443
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900444 def test_parse_vndk_apex_symbol(self):
445 input_file = io.StringIO(textwrap.dedent("""\
446 VERSION_1 {
447 foo;
448 bar; # vndk
449 baz; # vndk apex
450 qux; # apex
451 };
452 """))
453 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, True)
454
455 parser.next_line()
456 version = parser.parse_version()
457 self.assertEqual('VERSION_1', version.name)
458 self.assertIsNone(version.base)
459
460 expected_symbols = [
461 gsl.Symbol('foo', []),
462 gsl.Symbol('bar', ['vndk']),
463 gsl.Symbol('baz', ['vndk', 'apex']),
464 gsl.Symbol('qux', ['apex']),
465 ]
466 self.assertEqual(expected_symbols, version.symbols)
467
Dan Albert8bdccb92016-07-29 13:06:22 -0700468
469class GeneratorTest(unittest.TestCase):
470 def test_omit_version(self):
471 # Thorough testing of the cases involved here is handled by
472 # OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
Dan Albertf5b81842018-10-09 15:22:15 -0700473 src_file = io.StringIO()
474 version_file = io.StringIO()
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900475 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700476
477 version = gsl.Version('VERSION_PRIVATE', None, [], [
478 gsl.Symbol('foo', []),
479 ])
480 generator.write_version(version)
481 self.assertEqual('', src_file.getvalue())
482 self.assertEqual('', version_file.getvalue())
483
484 version = gsl.Version('VERSION', None, ['x86'], [
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, ['introduced=14'], [
492 gsl.Symbol('foo', []),
493 ])
494 generator.write_version(version)
495 self.assertEqual('', src_file.getvalue())
496 self.assertEqual('', version_file.getvalue())
497
498 def test_omit_symbol(self):
499 # Thorough testing of the cases involved here is handled by
500 # SymbolPresenceTest.
Dan Albertf5b81842018-10-09 15:22:15 -0700501 src_file = io.StringIO()
502 version_file = io.StringIO()
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900503 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700504
505 version = gsl.Version('VERSION_1', None, [], [
506 gsl.Symbol('foo', ['x86']),
507 ])
508 generator.write_version(version)
509 self.assertEqual('', src_file.getvalue())
510 self.assertEqual('', version_file.getvalue())
511
512 version = gsl.Version('VERSION_1', None, [], [
513 gsl.Symbol('foo', ['introduced=14']),
514 ])
515 generator.write_version(version)
516 self.assertEqual('', src_file.getvalue())
517 self.assertEqual('', version_file.getvalue())
518
Dan Willemsenb01e7f72017-04-03 14:28:36 -0700519 version = gsl.Version('VERSION_1', None, [], [
520 gsl.Symbol('foo', ['vndk']),
521 ])
522 generator.write_version(version)
523 self.assertEqual('', src_file.getvalue())
524 self.assertEqual('', version_file.getvalue())
525
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900526 version = gsl.Version('VERSION_1', None, [], [
527 gsl.Symbol('foo', ['apex']),
528 ])
529 generator.write_version(version)
530 self.assertEqual('', src_file.getvalue())
531 self.assertEqual('', version_file.getvalue())
532
Dan Albert8bdccb92016-07-29 13:06:22 -0700533 def test_write(self):
Dan Albertf5b81842018-10-09 15:22:15 -0700534 src_file = io.StringIO()
535 version_file = io.StringIO()
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900536 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700537
538 versions = [
539 gsl.Version('VERSION_1', None, [], [
540 gsl.Symbol('foo', []),
541 gsl.Symbol('bar', ['var']),
Dan Albertf55f0782017-07-28 11:00:22 -0700542 gsl.Symbol('woodly', ['weak']),
543 gsl.Symbol('doodly', ['weak', 'var']),
Dan Albert8bdccb92016-07-29 13:06:22 -0700544 ]),
545 gsl.Version('VERSION_2', 'VERSION_1', [], [
546 gsl.Symbol('baz', []),
547 ]),
548 gsl.Version('VERSION_3', 'VERSION_1', [], [
549 gsl.Symbol('qux', ['versioned=14']),
550 ]),
551 ]
552
553 generator.write(versions)
554 expected_src = textwrap.dedent("""\
555 void foo() {}
556 int bar = 0;
Dan Albertf55f0782017-07-28 11:00:22 -0700557 __attribute__((weak)) void woodly() {}
558 __attribute__((weak)) int doodly = 0;
Dan Albert8bdccb92016-07-29 13:06:22 -0700559 void baz() {}
560 void qux() {}
561 """)
562 self.assertEqual(expected_src, src_file.getvalue())
563
564 expected_version = textwrap.dedent("""\
565 VERSION_1 {
566 global:
567 foo;
568 bar;
Dan Albertf55f0782017-07-28 11:00:22 -0700569 woodly;
570 doodly;
Dan Albert8bdccb92016-07-29 13:06:22 -0700571 };
572 VERSION_2 {
573 global:
574 baz;
575 } VERSION_1;
576 """)
577 self.assertEqual(expected_version, version_file.getvalue())
578
579
580class IntegrationTest(unittest.TestCase):
581 def test_integration(self):
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700582 api_map = {
583 'O': 9000,
584 'P': 9001,
585 }
586
Dan Albertf5b81842018-10-09 15:22:15 -0700587 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert8bdccb92016-07-29 13:06:22 -0700588 VERSION_1 {
589 global:
590 foo; # var
591 bar; # x86
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700592 fizz; # introduced=O
593 buzz; # introduced=P
Dan Albert8bdccb92016-07-29 13:06:22 -0700594 local:
595 *;
596 };
597
598 VERSION_2 { # arm
599 baz; # introduced=9
600 qux; # versioned=14
601 } VERSION_1;
602
603 VERSION_3 { # introduced=14
604 woodly;
605 doodly; # var
606 } VERSION_2;
Dan Albertae452cc2017-01-03 14:27:41 -0800607
608 VERSION_4 { # versioned=9
609 wibble;
Dan Willemsenb01e7f72017-04-03 14:28:36 -0700610 wizzes; # vndk
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900611 waggle; # apex
Dan Albertae452cc2017-01-03 14:27:41 -0800612 } VERSION_2;
613
614 VERSION_5 { # versioned=14
615 wobble;
616 } VERSION_4;
Dan Albert8bdccb92016-07-29 13:06:22 -0700617 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900618 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700619 versions = parser.parse()
620
Dan Albertf5b81842018-10-09 15:22:15 -0700621 src_file = io.StringIO()
622 version_file = io.StringIO()
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900623 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, False)
Dan Albert8bdccb92016-07-29 13:06:22 -0700624 generator.write(versions)
625
626 expected_src = textwrap.dedent("""\
627 int foo = 0;
628 void baz() {}
629 void qux() {}
Dan Albertae452cc2017-01-03 14:27:41 -0800630 void wibble() {}
631 void wobble() {}
Dan Albert8bdccb92016-07-29 13:06:22 -0700632 """)
633 self.assertEqual(expected_src, src_file.getvalue())
634
635 expected_version = textwrap.dedent("""\
636 VERSION_1 {
637 global:
638 foo;
639 };
640 VERSION_2 {
641 global:
642 baz;
643 } VERSION_1;
Dan Albertae452cc2017-01-03 14:27:41 -0800644 VERSION_4 {
645 global:
646 wibble;
647 } VERSION_2;
Dan Albert8bdccb92016-07-29 13:06:22 -0700648 """)
649 self.assertEqual(expected_version, version_file.getvalue())
650
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700651 def test_integration_future_api(self):
652 api_map = {
653 'O': 9000,
654 'P': 9001,
655 'Q': 9002,
656 }
657
Dan Albertf5b81842018-10-09 15:22:15 -0700658 input_file = io.StringIO(textwrap.dedent("""\
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700659 VERSION_1 {
660 global:
661 foo; # introduced=O
662 bar; # introduced=P
663 baz; # introduced=Q
664 local:
665 *;
666 };
667 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900668 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9001, False, False)
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700669 versions = parser.parse()
670
Dan Albertf5b81842018-10-09 15:22:15 -0700671 src_file = io.StringIO()
672 version_file = io.StringIO()
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900673 generator = gsl.Generator(src_file, version_file, 'arm', 9001, False, False)
Dan Albert3f6fb2d2017-03-28 16:04:25 -0700674 generator.write(versions)
675
676 expected_src = textwrap.dedent("""\
677 void foo() {}
678 void bar() {}
679 """)
680 self.assertEqual(expected_src, src_file.getvalue())
681
682 expected_version = textwrap.dedent("""\
683 VERSION_1 {
684 global:
685 foo;
686 bar;
687 };
688 """)
689 self.assertEqual(expected_version, version_file.getvalue())
690
Dan Albert756f2d02018-10-09 16:36:03 -0700691 def test_multiple_definition(self):
692 input_file = io.StringIO(textwrap.dedent("""\
693 VERSION_1 {
694 global:
695 foo;
696 foo;
697 bar;
698 baz;
699 qux; # arm
700 local:
701 *;
702 };
703
704 VERSION_2 {
705 global:
706 bar;
707 qux; # arm64
708 } VERSION_1;
709
710 VERSION_PRIVATE {
711 global:
712 baz;
713 } VERSION_2;
714
715 """))
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900716 parser = gsl.SymbolFileParser(input_file, {}, 'arm', 16, False, False)
Dan Albert756f2d02018-10-09 16:36:03 -0700717
718 with self.assertRaises(gsl.MultiplyDefinedSymbolError) as cm:
719 parser.parse()
720 self.assertEquals(['bar', 'foo'],
721 cm.exception.multiply_defined_symbols)
722
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900723 def test_integration_with_apex(self):
724 api_map = {
725 'O': 9000,
726 'P': 9001,
727 }
728
729 input_file = io.StringIO(textwrap.dedent("""\
730 VERSION_1 {
731 global:
732 foo; # var
733 bar; # x86
734 fizz; # introduced=O
735 buzz; # introduced=P
736 local:
737 *;
738 };
739
740 VERSION_2 { # arm
741 baz; # introduced=9
742 qux; # versioned=14
743 } VERSION_1;
744
745 VERSION_3 { # introduced=14
746 woodly;
747 doodly; # var
748 } VERSION_2;
749
750 VERSION_4 { # versioned=9
751 wibble;
752 wizzes; # vndk
753 waggle; # apex
Jiyong Park14317652019-02-08 20:34:32 +0900754 bubble; # apex vndk
755 duddle; # vndk apex
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900756 } VERSION_2;
757
758 VERSION_5 { # versioned=14
759 wobble;
760 } VERSION_4;
761 """))
762 parser = gsl.SymbolFileParser(input_file, api_map, 'arm', 9, False, True)
763 versions = parser.parse()
764
765 src_file = io.StringIO()
766 version_file = io.StringIO()
767 generator = gsl.Generator(src_file, version_file, 'arm', 9, False, True)
768 generator.write(versions)
769
770 expected_src = textwrap.dedent("""\
771 int foo = 0;
772 void baz() {}
773 void qux() {}
774 void wibble() {}
775 void waggle() {}
Jiyong Park14317652019-02-08 20:34:32 +0900776 void bubble() {}
777 void duddle() {}
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900778 void wobble() {}
779 """)
780 self.assertEqual(expected_src, src_file.getvalue())
781
782 expected_version = textwrap.dedent("""\
783 VERSION_1 {
784 global:
785 foo;
786 };
787 VERSION_2 {
788 global:
789 baz;
790 } VERSION_1;
791 VERSION_4 {
792 global:
793 wibble;
794 waggle;
Jiyong Park14317652019-02-08 20:34:32 +0900795 bubble;
796 duddle;
Jiyong Parkbb4e1352018-12-07 15:54:52 +0900797 } VERSION_2;
798 """)
799 self.assertEqual(expected_version, version_file.getvalue())
Dan Albert8bdccb92016-07-29 13:06:22 -0700800
801def main():
802 suite = unittest.TestLoader().loadTestsFromName(__name__)
803 unittest.TextTestRunner(verbosity=3).run(suite)
804
805
806if __name__ == '__main__':
807 main()