1#!/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 24 25 26# pylint: disable=missing-docstring 27 28 29class GeneratorTest(unittest.TestCase): 30 def test_omit_version(self): 31 # Thorough testing of the cases involved here is handled by 32 # OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest. 33 src_file = io.StringIO() 34 version_file = io.StringIO() 35 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9, 36 False, False) 37 38 version = symbolfile.Version('VERSION_PRIVATE', None, [], [ 39 symbolfile.Symbol('foo', []), 40 ]) 41 generator.write_version(version) 42 self.assertEqual('', src_file.getvalue()) 43 self.assertEqual('', version_file.getvalue()) 44 45 version = symbolfile.Version('VERSION', None, ['x86'], [ 46 symbolfile.Symbol('foo', []), 47 ]) 48 generator.write_version(version) 49 self.assertEqual('', src_file.getvalue()) 50 self.assertEqual('', version_file.getvalue()) 51 52 version = symbolfile.Version('VERSION', None, ['introduced=14'], [ 53 symbolfile.Symbol('foo', []), 54 ]) 55 generator.write_version(version) 56 self.assertEqual('', src_file.getvalue()) 57 self.assertEqual('', version_file.getvalue()) 58 59 def test_omit_symbol(self): 60 # Thorough testing of the cases involved here is handled by 61 # SymbolPresenceTest. 62 src_file = io.StringIO() 63 version_file = io.StringIO() 64 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9, 65 False, False) 66 67 version = symbolfile.Version('VERSION_1', None, [], [ 68 symbolfile.Symbol('foo', ['x86']), 69 ]) 70 generator.write_version(version) 71 self.assertEqual('', src_file.getvalue()) 72 self.assertEqual('', version_file.getvalue()) 73 74 version = symbolfile.Version('VERSION_1', None, [], [ 75 symbolfile.Symbol('foo', ['introduced=14']), 76 ]) 77 generator.write_version(version) 78 self.assertEqual('', src_file.getvalue()) 79 self.assertEqual('', version_file.getvalue()) 80 81 version = symbolfile.Version('VERSION_1', None, [], [ 82 symbolfile.Symbol('foo', ['llndk']), 83 ]) 84 generator.write_version(version) 85 self.assertEqual('', src_file.getvalue()) 86 self.assertEqual('', version_file.getvalue()) 87 88 version = symbolfile.Version('VERSION_1', None, [], [ 89 symbolfile.Symbol('foo', ['apex']), 90 ]) 91 generator.write_version(version) 92 self.assertEqual('', src_file.getvalue()) 93 self.assertEqual('', version_file.getvalue()) 94 95 def test_write(self): 96 src_file = io.StringIO() 97 version_file = io.StringIO() 98 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9, 99 False, False) 100 101 versions = [ 102 symbolfile.Version('VERSION_1', None, [], [ 103 symbolfile.Symbol('foo', []), 104 symbolfile.Symbol('bar', ['var']), 105 symbolfile.Symbol('woodly', ['weak']), 106 symbolfile.Symbol('doodly', ['weak', 'var']), 107 ]), 108 symbolfile.Version('VERSION_2', 'VERSION_1', [], [ 109 symbolfile.Symbol('baz', []), 110 ]), 111 symbolfile.Version('VERSION_3', 'VERSION_1', [], [ 112 symbolfile.Symbol('qux', ['versioned=14']), 113 ]), 114 ] 115 116 generator.write(versions) 117 expected_src = textwrap.dedent("""\ 118 void foo() {} 119 int bar = 0; 120 __attribute__((weak)) void woodly() {} 121 __attribute__((weak)) int doodly = 0; 122 void baz() {} 123 void qux() {} 124 """) 125 self.assertEqual(expected_src, src_file.getvalue()) 126 127 expected_version = textwrap.dedent("""\ 128 VERSION_1 { 129 global: 130 foo; 131 bar; 132 woodly; 133 doodly; 134 }; 135 VERSION_2 { 136 global: 137 baz; 138 } VERSION_1; 139 """) 140 self.assertEqual(expected_version, version_file.getvalue()) 141 142 143class IntegrationTest(unittest.TestCase): 144 def test_integration(self): 145 api_map = { 146 'O': 9000, 147 'P': 9001, 148 } 149 150 input_file = io.StringIO(textwrap.dedent("""\ 151 VERSION_1 { 152 global: 153 foo; # var 154 bar; # x86 155 fizz; # introduced=O 156 buzz; # introduced=P 157 local: 158 *; 159 }; 160 161 VERSION_2 { # arm 162 baz; # introduced=9 163 qux; # versioned=14 164 } VERSION_1; 165 166 VERSION_3 { # introduced=14 167 woodly; 168 doodly; # var 169 } VERSION_2; 170 171 VERSION_4 { # versioned=9 172 wibble; 173 wizzes; # llndk 174 waggle; # apex 175 } VERSION_2; 176 177 VERSION_5 { # versioned=14 178 wobble; 179 } VERSION_4; 180 """)) 181 parser = symbolfile.SymbolFileParser(input_file, api_map, 'arm', 9, 182 False, False) 183 versions = parser.parse() 184 185 src_file = io.StringIO() 186 version_file = io.StringIO() 187 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9, 188 False, False) 189 generator.write(versions) 190 191 expected_src = textwrap.dedent("""\ 192 int foo = 0; 193 void baz() {} 194 void qux() {} 195 void wibble() {} 196 void wobble() {} 197 """) 198 self.assertEqual(expected_src, src_file.getvalue()) 199 200 expected_version = textwrap.dedent("""\ 201 VERSION_1 { 202 global: 203 foo; 204 }; 205 VERSION_2 { 206 global: 207 baz; 208 } VERSION_1; 209 VERSION_4 { 210 global: 211 wibble; 212 } VERSION_2; 213 """) 214 self.assertEqual(expected_version, version_file.getvalue()) 215 216 def test_integration_future_api(self): 217 api_map = { 218 'O': 9000, 219 'P': 9001, 220 'Q': 9002, 221 } 222 223 input_file = io.StringIO(textwrap.dedent("""\ 224 VERSION_1 { 225 global: 226 foo; # introduced=O 227 bar; # introduced=P 228 baz; # introduced=Q 229 local: 230 *; 231 }; 232 """)) 233 parser = symbolfile.SymbolFileParser(input_file, api_map, 'arm', 9001, 234 False, False) 235 versions = parser.parse() 236 237 src_file = io.StringIO() 238 version_file = io.StringIO() 239 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9001, 240 False, False) 241 generator.write(versions) 242 243 expected_src = textwrap.dedent("""\ 244 void foo() {} 245 void bar() {} 246 """) 247 self.assertEqual(expected_src, src_file.getvalue()) 248 249 expected_version = textwrap.dedent("""\ 250 VERSION_1 { 251 global: 252 foo; 253 bar; 254 }; 255 """) 256 self.assertEqual(expected_version, version_file.getvalue()) 257 258 def test_multiple_definition(self): 259 input_file = io.StringIO(textwrap.dedent("""\ 260 VERSION_1 { 261 global: 262 foo; 263 foo; 264 bar; 265 baz; 266 qux; # arm 267 local: 268 *; 269 }; 270 271 VERSION_2 { 272 global: 273 bar; 274 qux; # arm64 275 } VERSION_1; 276 277 VERSION_PRIVATE { 278 global: 279 baz; 280 } VERSION_2; 281 282 """)) 283 parser = symbolfile.SymbolFileParser(input_file, {}, 'arm', 16, False, 284 False) 285 286 with self.assertRaises( 287 symbolfile.MultiplyDefinedSymbolError) as ex_context: 288 parser.parse() 289 self.assertEqual(['bar', 'foo'], 290 ex_context.exception.multiply_defined_symbols) 291 292 def test_integration_with_apex(self): 293 api_map = { 294 'O': 9000, 295 'P': 9001, 296 } 297 298 input_file = io.StringIO(textwrap.dedent("""\ 299 VERSION_1 { 300 global: 301 foo; # var 302 bar; # x86 303 fizz; # introduced=O 304 buzz; # introduced=P 305 local: 306 *; 307 }; 308 309 VERSION_2 { # arm 310 baz; # introduced=9 311 qux; # versioned=14 312 } VERSION_1; 313 314 VERSION_3 { # introduced=14 315 woodly; 316 doodly; # var 317 } VERSION_2; 318 319 VERSION_4 { # versioned=9 320 wibble; 321 wizzes; # llndk 322 waggle; # apex 323 bubble; # apex llndk 324 duddle; # llndk apex 325 } VERSION_2; 326 327 VERSION_5 { # versioned=14 328 wobble; 329 } VERSION_4; 330 """)) 331 parser = symbolfile.SymbolFileParser(input_file, api_map, 'arm', 9, 332 False, True) 333 versions = parser.parse() 334 335 src_file = io.StringIO() 336 version_file = io.StringIO() 337 generator = ndkstubgen.Generator(src_file, version_file, 'arm', 9, 338 False, True) 339 generator.write(versions) 340 341 expected_src = textwrap.dedent("""\ 342 int foo = 0; 343 void baz() {} 344 void qux() {} 345 void wibble() {} 346 void waggle() {} 347 void bubble() {} 348 void duddle() {} 349 void wobble() {} 350 """) 351 self.assertEqual(expected_src, src_file.getvalue()) 352 353 expected_version = textwrap.dedent("""\ 354 VERSION_1 { 355 global: 356 foo; 357 }; 358 VERSION_2 { 359 global: 360 baz; 361 } VERSION_1; 362 VERSION_4 { 363 global: 364 wibble; 365 waggle; 366 bubble; 367 duddle; 368 } VERSION_2; 369 """) 370 self.assertEqual(expected_version, version_file.getvalue()) 371 372def main(): 373 suite = unittest.TestLoader().loadTestsFromName(__name__) 374 unittest.TextTestRunner(verbosity=3).run(suite) 375 376 377if __name__ == '__main__': 378 main() 379