blob: 6d2c9d673210c91d7c6d2476c3a9e2c61883e77d [file] [log] [blame]
Dan Albert06f58af2020-06-22 15:10:31 -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 ndkstubgen.py."""
18import io
19import textwrap
20import unittest
21
22import ndkstubgen
23import symbolfile
Dan Albertaf7b36d2020-06-23 11:21:21 -070024from symbolfile import Arch, Tag
Dan Albert06f58af2020-06-22 15:10:31 -070025
26
27# pylint: disable=missing-docstring
28
29
30class GeneratorTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -070031 def test_omit_version(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070032 # Thorough testing of the cases involved here is handled by
33 # OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
34 src_file = io.StringIO()
35 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -070036 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
37 9, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -070038
39 version = symbolfile.Version('VERSION_PRIVATE', None, [], [
40 symbolfile.Symbol('foo', []),
41 ])
42 generator.write_version(version)
43 self.assertEqual('', src_file.getvalue())
44 self.assertEqual('', version_file.getvalue())
45
Dan Albertaf7b36d2020-06-23 11:21:21 -070046 version = symbolfile.Version('VERSION', None, [Tag('x86')], [
Dan Albert06f58af2020-06-22 15:10:31 -070047 symbolfile.Symbol('foo', []),
48 ])
49 generator.write_version(version)
50 self.assertEqual('', src_file.getvalue())
51 self.assertEqual('', version_file.getvalue())
52
Dan Albertaf7b36d2020-06-23 11:21:21 -070053 version = symbolfile.Version('VERSION', None, [Tag('introduced=14')], [
Dan Albert06f58af2020-06-22 15:10:31 -070054 symbolfile.Symbol('foo', []),
55 ])
56 generator.write_version(version)
57 self.assertEqual('', src_file.getvalue())
58 self.assertEqual('', version_file.getvalue())
59
Dan Albertaf7b36d2020-06-23 11:21:21 -070060 def test_omit_symbol(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070061 # Thorough testing of the cases involved here is handled by
62 # SymbolPresenceTest.
63 src_file = io.StringIO()
64 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -070065 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
66 9, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -070067
68 version = symbolfile.Version('VERSION_1', None, [], [
Dan Albertaf7b36d2020-06-23 11:21:21 -070069 symbolfile.Symbol('foo', [Tag('x86')]),
Dan Albert06f58af2020-06-22 15:10:31 -070070 ])
71 generator.write_version(version)
72 self.assertEqual('', src_file.getvalue())
73 self.assertEqual('', version_file.getvalue())
74
75 version = symbolfile.Version('VERSION_1', None, [], [
Dan Albertaf7b36d2020-06-23 11:21:21 -070076 symbolfile.Symbol('foo', [Tag('introduced=14')]),
Dan Albert06f58af2020-06-22 15:10:31 -070077 ])
78 generator.write_version(version)
79 self.assertEqual('', src_file.getvalue())
80 self.assertEqual('', version_file.getvalue())
81
82 version = symbolfile.Version('VERSION_1', None, [], [
Dan Albertaf7b36d2020-06-23 11:21:21 -070083 symbolfile.Symbol('foo', [Tag('llndk')]),
Dan Albert06f58af2020-06-22 15:10:31 -070084 ])
85 generator.write_version(version)
86 self.assertEqual('', src_file.getvalue())
87 self.assertEqual('', version_file.getvalue())
88
89 version = symbolfile.Version('VERSION_1', None, [], [
Dan Albertaf7b36d2020-06-23 11:21:21 -070090 symbolfile.Symbol('foo', [Tag('apex')]),
Dan Albert06f58af2020-06-22 15:10:31 -070091 ])
92 generator.write_version(version)
93 self.assertEqual('', src_file.getvalue())
94 self.assertEqual('', version_file.getvalue())
95
Dan Albertaf7b36d2020-06-23 11:21:21 -070096 def test_write(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -070097 src_file = io.StringIO()
98 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -070099 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
100 9, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700101
102 versions = [
103 symbolfile.Version('VERSION_1', None, [], [
104 symbolfile.Symbol('foo', []),
Dan Albertaf7b36d2020-06-23 11:21:21 -0700105 symbolfile.Symbol('bar', [Tag('var')]),
106 symbolfile.Symbol('woodly', [Tag('weak')]),
107 symbolfile.Symbol('doodly',
108 [Tag('weak'), Tag('var')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700109 ]),
110 symbolfile.Version('VERSION_2', 'VERSION_1', [], [
111 symbolfile.Symbol('baz', []),
112 ]),
113 symbolfile.Version('VERSION_3', 'VERSION_1', [], [
Dan Albertaf7b36d2020-06-23 11:21:21 -0700114 symbolfile.Symbol('qux', [Tag('versioned=14')]),
Dan Albert06f58af2020-06-22 15:10:31 -0700115 ]),
116 ]
117
118 generator.write(versions)
119 expected_src = textwrap.dedent("""\
120 void foo() {}
121 int bar = 0;
122 __attribute__((weak)) void woodly() {}
123 __attribute__((weak)) int doodly = 0;
124 void baz() {}
125 void qux() {}
126 """)
127 self.assertEqual(expected_src, src_file.getvalue())
128
129 expected_version = textwrap.dedent("""\
130 VERSION_1 {
131 global:
132 foo;
133 bar;
134 woodly;
135 doodly;
136 };
137 VERSION_2 {
138 global:
139 baz;
140 } VERSION_1;
141 """)
142 self.assertEqual(expected_version, version_file.getvalue())
143
144
145class IntegrationTest(unittest.TestCase):
Dan Albertaf7b36d2020-06-23 11:21:21 -0700146 def test_integration(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700147 api_map = {
148 'O': 9000,
149 'P': 9001,
150 }
151
152 input_file = io.StringIO(textwrap.dedent("""\
153 VERSION_1 {
154 global:
155 foo; # var
156 bar; # x86
157 fizz; # introduced=O
158 buzz; # introduced=P
159 local:
160 *;
161 };
162
163 VERSION_2 { # arm
164 baz; # introduced=9
165 qux; # versioned=14
166 } VERSION_1;
167
168 VERSION_3 { # introduced=14
169 woodly;
170 doodly; # var
171 } VERSION_2;
172
173 VERSION_4 { # versioned=9
174 wibble;
175 wizzes; # llndk
176 waggle; # apex
177 } VERSION_2;
178
179 VERSION_5 { # versioned=14
180 wobble;
181 } VERSION_4;
182 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700183 parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
184 9, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700185 versions = parser.parse()
186
187 src_file = io.StringIO()
188 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -0700189 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
190 9, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700191 generator.write(versions)
192
193 expected_src = textwrap.dedent("""\
194 int foo = 0;
195 void baz() {}
196 void qux() {}
197 void wibble() {}
198 void wobble() {}
199 """)
200 self.assertEqual(expected_src, src_file.getvalue())
201
202 expected_version = textwrap.dedent("""\
203 VERSION_1 {
204 global:
205 foo;
206 };
207 VERSION_2 {
208 global:
209 baz;
210 } VERSION_1;
211 VERSION_4 {
212 global:
213 wibble;
214 } VERSION_2;
215 """)
216 self.assertEqual(expected_version, version_file.getvalue())
217
Dan Albertaf7b36d2020-06-23 11:21:21 -0700218 def test_integration_future_api(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700219 api_map = {
220 'O': 9000,
221 'P': 9001,
222 'Q': 9002,
223 }
224
225 input_file = io.StringIO(textwrap.dedent("""\
226 VERSION_1 {
227 global:
228 foo; # introduced=O
229 bar; # introduced=P
230 baz; # introduced=Q
231 local:
232 *;
233 };
234 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700235 parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
236 9001, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700237 versions = parser.parse()
238
239 src_file = io.StringIO()
240 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -0700241 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
242 9001, False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700243 generator.write(versions)
244
245 expected_src = textwrap.dedent("""\
246 void foo() {}
247 void bar() {}
248 """)
249 self.assertEqual(expected_src, src_file.getvalue())
250
251 expected_version = textwrap.dedent("""\
252 VERSION_1 {
253 global:
254 foo;
255 bar;
256 };
257 """)
258 self.assertEqual(expected_version, version_file.getvalue())
259
Dan Albertaf7b36d2020-06-23 11:21:21 -0700260 def test_multiple_definition(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700261 input_file = io.StringIO(textwrap.dedent("""\
262 VERSION_1 {
263 global:
264 foo;
265 foo;
266 bar;
267 baz;
268 qux; # arm
269 local:
270 *;
271 };
272
273 VERSION_2 {
274 global:
275 bar;
276 qux; # arm64
277 } VERSION_1;
278
279 VERSION_PRIVATE {
280 global:
281 baz;
282 } VERSION_2;
283
284 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700285 parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
286 False, False)
Dan Albert06f58af2020-06-22 15:10:31 -0700287
288 with self.assertRaises(
289 symbolfile.MultiplyDefinedSymbolError) as ex_context:
290 parser.parse()
291 self.assertEqual(['bar', 'foo'],
292 ex_context.exception.multiply_defined_symbols)
293
Dan Albertaf7b36d2020-06-23 11:21:21 -0700294 def test_integration_with_apex(self) -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700295 api_map = {
296 'O': 9000,
297 'P': 9001,
298 }
299
300 input_file = io.StringIO(textwrap.dedent("""\
301 VERSION_1 {
302 global:
303 foo; # var
304 bar; # x86
305 fizz; # introduced=O
306 buzz; # introduced=P
307 local:
308 *;
309 };
310
311 VERSION_2 { # arm
312 baz; # introduced=9
313 qux; # versioned=14
314 } VERSION_1;
315
316 VERSION_3 { # introduced=14
317 woodly;
318 doodly; # var
319 } VERSION_2;
320
321 VERSION_4 { # versioned=9
322 wibble;
323 wizzes; # llndk
324 waggle; # apex
325 bubble; # apex llndk
326 duddle; # llndk apex
327 } VERSION_2;
328
329 VERSION_5 { # versioned=14
330 wobble;
331 } VERSION_4;
332 """))
Dan Albertaf7b36d2020-06-23 11:21:21 -0700333 parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
334 9, False, True)
Dan Albert06f58af2020-06-22 15:10:31 -0700335 versions = parser.parse()
336
337 src_file = io.StringIO()
338 version_file = io.StringIO()
Dan Albertaf7b36d2020-06-23 11:21:21 -0700339 generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
340 9, False, True)
Dan Albert06f58af2020-06-22 15:10:31 -0700341 generator.write(versions)
342
343 expected_src = textwrap.dedent("""\
344 int foo = 0;
345 void baz() {}
346 void qux() {}
347 void wibble() {}
348 void waggle() {}
349 void bubble() {}
350 void duddle() {}
351 void wobble() {}
352 """)
353 self.assertEqual(expected_src, src_file.getvalue())
354
355 expected_version = textwrap.dedent("""\
356 VERSION_1 {
357 global:
358 foo;
359 };
360 VERSION_2 {
361 global:
362 baz;
363 } VERSION_1;
364 VERSION_4 {
365 global:
366 wibble;
367 waggle;
368 bubble;
369 duddle;
370 } VERSION_2;
371 """)
372 self.assertEqual(expected_version, version_file.getvalue())
373
Dan Albertaf7b36d2020-06-23 11:21:21 -0700374
375def main() -> None:
Dan Albert06f58af2020-06-22 15:10:31 -0700376 suite = unittest.TestLoader().loadTestsFromName(__name__)
377 unittest.TextTestRunner(verbosity=3).run(suite)
378
379
380if __name__ == '__main__':
381 main()