1*333d2b36SAndroid Build Coastguard Worker#!/usr/bin/env python 2*333d2b36SAndroid Build Coastguard Worker# 3*333d2b36SAndroid Build Coastguard Worker# Copyright (C) 2016 The Android Open Source Project 4*333d2b36SAndroid Build Coastguard Worker# 5*333d2b36SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*333d2b36SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*333d2b36SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*333d2b36SAndroid Build Coastguard Worker# 9*333d2b36SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*333d2b36SAndroid Build Coastguard Worker# 11*333d2b36SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*333d2b36SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*333d2b36SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*333d2b36SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*333d2b36SAndroid Build Coastguard Worker# limitations under the License. 16*333d2b36SAndroid Build Coastguard Worker# 17*333d2b36SAndroid Build Coastguard Worker"""Tests for ndkstubgen.py.""" 18*333d2b36SAndroid Build Coastguard Workerimport io 19*333d2b36SAndroid Build Coastguard Workerimport textwrap 20*333d2b36SAndroid Build Coastguard Workerimport unittest 21*333d2b36SAndroid Build Coastguard Workerfrom copy import copy 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Workerimport symbolfile 24*333d2b36SAndroid Build Coastguard Workerfrom symbolfile import Arch, Tags 25*333d2b36SAndroid Build Coastguard Worker 26*333d2b36SAndroid Build Coastguard Workerimport ndkstubgen 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker# pylint: disable=missing-docstring 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Worker 32*333d2b36SAndroid Build Coastguard Workerclass GeneratorTest(unittest.TestCase): 33*333d2b36SAndroid Build Coastguard Worker def setUp(self) -> None: 34*333d2b36SAndroid Build Coastguard Worker self.filter = symbolfile.Filter(Arch('arm'), 9, False, False) 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker def test_omit_version(self) -> None: 37*333d2b36SAndroid Build Coastguard Worker # Thorough testing of the cases involved here is handled by 38*333d2b36SAndroid Build Coastguard Worker # OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest. 39*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 40*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 41*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 42*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 43*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, 44*333d2b36SAndroid Build Coastguard Worker self.filter) 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [ 47*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags()), 48*333d2b36SAndroid Build Coastguard Worker ]) 49*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 50*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 51*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION', None, Tags.from_strs(['x86']), 54*333d2b36SAndroid Build Coastguard Worker [ 55*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags()), 56*333d2b36SAndroid Build Coastguard Worker ]) 57*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 58*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 59*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 60*333d2b36SAndroid Build Coastguard Worker 61*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION', None, 62*333d2b36SAndroid Build Coastguard Worker Tags.from_strs(['introduced=14']), [ 63*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags()), 64*333d2b36SAndroid Build Coastguard Worker ]) 65*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 66*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 67*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker def test_omit_symbol(self) -> None: 70*333d2b36SAndroid Build Coastguard Worker # Thorough testing of the cases involved here is handled by 71*333d2b36SAndroid Build Coastguard Worker # SymbolPresenceTest. 72*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 73*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 74*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 75*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 76*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, 77*333d2b36SAndroid Build Coastguard Worker self.filter) 78*333d2b36SAndroid Build Coastguard Worker 79*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION_1', None, Tags(), [ 80*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags.from_strs(['x86'])), 81*333d2b36SAndroid Build Coastguard Worker ]) 82*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 83*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 84*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 85*333d2b36SAndroid Build Coastguard Worker 86*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION_1', None, Tags(), [ 87*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])), 88*333d2b36SAndroid Build Coastguard Worker ]) 89*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 90*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 91*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION_1', None, Tags(), [ 94*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags.from_strs(['llndk'])), 95*333d2b36SAndroid Build Coastguard Worker ]) 96*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 97*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 98*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Worker version = symbolfile.Version('VERSION_1', None, Tags(), [ 101*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags.from_strs(['apex'])), 102*333d2b36SAndroid Build Coastguard Worker ]) 103*333d2b36SAndroid Build Coastguard Worker generator.write_version(version) 104*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 105*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Worker def test_write(self) -> None: 108*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 109*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 110*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 111*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 112*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, 113*333d2b36SAndroid Build Coastguard Worker self.filter) 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Worker versions = [ 116*333d2b36SAndroid Build Coastguard Worker symbolfile.Version('VERSION_1', None, Tags(), [ 117*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('foo', Tags()), 118*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('bar', Tags.from_strs(['var'])), 119*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('woodly', Tags.from_strs(['weak'])), 120*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('doodly', Tags.from_strs(['weak', 'var'])), 121*333d2b36SAndroid Build Coastguard Worker ]), 122*333d2b36SAndroid Build Coastguard Worker symbolfile.Version('VERSION_2', 'VERSION_1', Tags(), [ 123*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('baz', Tags()), 124*333d2b36SAndroid Build Coastguard Worker ]), 125*333d2b36SAndroid Build Coastguard Worker symbolfile.Version('VERSION_3', 'VERSION_1', Tags(), [ 126*333d2b36SAndroid Build Coastguard Worker symbolfile.Symbol('qux', Tags.from_strs(['versioned=14'])), 127*333d2b36SAndroid Build Coastguard Worker ]), 128*333d2b36SAndroid Build Coastguard Worker ] 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 131*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 132*333d2b36SAndroid Build Coastguard Worker void foo() {} 133*333d2b36SAndroid Build Coastguard Worker int bar = 0; 134*333d2b36SAndroid Build Coastguard Worker __attribute__((weak)) void woodly() {} 135*333d2b36SAndroid Build Coastguard Worker __attribute__((weak)) int doodly = 0; 136*333d2b36SAndroid Build Coastguard Worker void baz() {} 137*333d2b36SAndroid Build Coastguard Worker void qux() {} 138*333d2b36SAndroid Build Coastguard Worker """) 139*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 140*333d2b36SAndroid Build Coastguard Worker 141*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 142*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 143*333d2b36SAndroid Build Coastguard Worker global: 144*333d2b36SAndroid Build Coastguard Worker foo; 145*333d2b36SAndroid Build Coastguard Worker bar; 146*333d2b36SAndroid Build Coastguard Worker woodly; 147*333d2b36SAndroid Build Coastguard Worker doodly; 148*333d2b36SAndroid Build Coastguard Worker }; 149*333d2b36SAndroid Build Coastguard Worker VERSION_2 { 150*333d2b36SAndroid Build Coastguard Worker global: 151*333d2b36SAndroid Build Coastguard Worker baz; 152*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 153*333d2b36SAndroid Build Coastguard Worker """) 154*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 155*333d2b36SAndroid Build Coastguard Worker 156*333d2b36SAndroid Build Coastguard Worker expected_allowlist = textwrap.dedent("""\ 157*333d2b36SAndroid Build Coastguard Worker [abi_symbol_list] 158*333d2b36SAndroid Build Coastguard Worker foo 159*333d2b36SAndroid Build Coastguard Worker bar 160*333d2b36SAndroid Build Coastguard Worker woodly 161*333d2b36SAndroid Build Coastguard Worker doodly 162*333d2b36SAndroid Build Coastguard Worker baz 163*333d2b36SAndroid Build Coastguard Worker qux 164*333d2b36SAndroid Build Coastguard Worker """) 165*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_allowlist, symbol_list_file.getvalue()) 166*333d2b36SAndroid Build Coastguard Worker 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Workerclass IntegrationTest(unittest.TestCase): 169*333d2b36SAndroid Build Coastguard Worker def setUp(self) -> None: 170*333d2b36SAndroid Build Coastguard Worker self.filter = symbolfile.Filter(Arch('arm'), 9, False, False) 171*333d2b36SAndroid Build Coastguard Worker 172*333d2b36SAndroid Build Coastguard Worker def test_integration(self) -> None: 173*333d2b36SAndroid Build Coastguard Worker api_map = { 174*333d2b36SAndroid Build Coastguard Worker 'O': 9000, 175*333d2b36SAndroid Build Coastguard Worker 'P': 9001, 176*333d2b36SAndroid Build Coastguard Worker } 177*333d2b36SAndroid Build Coastguard Worker 178*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 179*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 180*333d2b36SAndroid Build Coastguard Worker global: 181*333d2b36SAndroid Build Coastguard Worker foo; # var 182*333d2b36SAndroid Build Coastguard Worker bar; # x86 183*333d2b36SAndroid Build Coastguard Worker fizz; # introduced=O 184*333d2b36SAndroid Build Coastguard Worker buzz; # introduced=P 185*333d2b36SAndroid Build Coastguard Worker local: 186*333d2b36SAndroid Build Coastguard Worker *; 187*333d2b36SAndroid Build Coastguard Worker }; 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Worker VERSION_2 { # arm 190*333d2b36SAndroid Build Coastguard Worker baz; # introduced=9 191*333d2b36SAndroid Build Coastguard Worker qux; # versioned=14 192*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 193*333d2b36SAndroid Build Coastguard Worker 194*333d2b36SAndroid Build Coastguard Worker VERSION_3 { # introduced=14 195*333d2b36SAndroid Build Coastguard Worker woodly; 196*333d2b36SAndroid Build Coastguard Worker doodly; # var 197*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 198*333d2b36SAndroid Build Coastguard Worker 199*333d2b36SAndroid Build Coastguard Worker VERSION_4 { # versioned=9 200*333d2b36SAndroid Build Coastguard Worker wibble; 201*333d2b36SAndroid Build Coastguard Worker wizzes; # llndk 202*333d2b36SAndroid Build Coastguard Worker waggle; # apex 203*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker VERSION_5 { # versioned=14 206*333d2b36SAndroid Build Coastguard Worker wobble; 207*333d2b36SAndroid Build Coastguard Worker } VERSION_4; 208*333d2b36SAndroid Build Coastguard Worker """)) 209*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, api_map, self.filter) 210*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 211*333d2b36SAndroid Build Coastguard Worker 212*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 213*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 214*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 215*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 216*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, 217*333d2b36SAndroid Build Coastguard Worker self.filter) 218*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 221*333d2b36SAndroid Build Coastguard Worker int foo = 0; 222*333d2b36SAndroid Build Coastguard Worker void baz() {} 223*333d2b36SAndroid Build Coastguard Worker void qux() {} 224*333d2b36SAndroid Build Coastguard Worker void wibble() {} 225*333d2b36SAndroid Build Coastguard Worker void wobble() {} 226*333d2b36SAndroid Build Coastguard Worker """) 227*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 228*333d2b36SAndroid Build Coastguard Worker 229*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 230*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 231*333d2b36SAndroid Build Coastguard Worker global: 232*333d2b36SAndroid Build Coastguard Worker foo; 233*333d2b36SAndroid Build Coastguard Worker }; 234*333d2b36SAndroid Build Coastguard Worker VERSION_2 { 235*333d2b36SAndroid Build Coastguard Worker global: 236*333d2b36SAndroid Build Coastguard Worker baz; 237*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 238*333d2b36SAndroid Build Coastguard Worker VERSION_4 { 239*333d2b36SAndroid Build Coastguard Worker global: 240*333d2b36SAndroid Build Coastguard Worker wibble; 241*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 242*333d2b36SAndroid Build Coastguard Worker """) 243*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 244*333d2b36SAndroid Build Coastguard Worker 245*333d2b36SAndroid Build Coastguard Worker expected_allowlist = textwrap.dedent("""\ 246*333d2b36SAndroid Build Coastguard Worker [abi_symbol_list] 247*333d2b36SAndroid Build Coastguard Worker foo 248*333d2b36SAndroid Build Coastguard Worker baz 249*333d2b36SAndroid Build Coastguard Worker qux 250*333d2b36SAndroid Build Coastguard Worker wibble 251*333d2b36SAndroid Build Coastguard Worker wobble 252*333d2b36SAndroid Build Coastguard Worker """) 253*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_allowlist, symbol_list_file.getvalue()) 254*333d2b36SAndroid Build Coastguard Worker 255*333d2b36SAndroid Build Coastguard Worker def test_integration_future_api(self) -> None: 256*333d2b36SAndroid Build Coastguard Worker api_map = { 257*333d2b36SAndroid Build Coastguard Worker 'O': 9000, 258*333d2b36SAndroid Build Coastguard Worker 'P': 9001, 259*333d2b36SAndroid Build Coastguard Worker 'Q': 9002, 260*333d2b36SAndroid Build Coastguard Worker } 261*333d2b36SAndroid Build Coastguard Worker 262*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 263*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 264*333d2b36SAndroid Build Coastguard Worker global: 265*333d2b36SAndroid Build Coastguard Worker foo; # introduced=O 266*333d2b36SAndroid Build Coastguard Worker bar; # introduced=P 267*333d2b36SAndroid Build Coastguard Worker baz; # introduced=Q 268*333d2b36SAndroid Build Coastguard Worker local: 269*333d2b36SAndroid Build Coastguard Worker *; 270*333d2b36SAndroid Build Coastguard Worker }; 271*333d2b36SAndroid Build Coastguard Worker """)) 272*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 273*333d2b36SAndroid Build Coastguard Worker f.api = 9001 274*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, api_map, f) 275*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 276*333d2b36SAndroid Build Coastguard Worker 277*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 278*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 279*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 280*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 281*333d2b36SAndroid Build Coastguard Worker f.api = 9001 282*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 283*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, f) 284*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 285*333d2b36SAndroid Build Coastguard Worker 286*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 287*333d2b36SAndroid Build Coastguard Worker void foo() {} 288*333d2b36SAndroid Build Coastguard Worker void bar() {} 289*333d2b36SAndroid Build Coastguard Worker """) 290*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 291*333d2b36SAndroid Build Coastguard Worker 292*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 293*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 294*333d2b36SAndroid Build Coastguard Worker global: 295*333d2b36SAndroid Build Coastguard Worker foo; 296*333d2b36SAndroid Build Coastguard Worker bar; 297*333d2b36SAndroid Build Coastguard Worker }; 298*333d2b36SAndroid Build Coastguard Worker """) 299*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 300*333d2b36SAndroid Build Coastguard Worker 301*333d2b36SAndroid Build Coastguard Worker expected_allowlist = textwrap.dedent("""\ 302*333d2b36SAndroid Build Coastguard Worker [abi_symbol_list] 303*333d2b36SAndroid Build Coastguard Worker foo 304*333d2b36SAndroid Build Coastguard Worker bar 305*333d2b36SAndroid Build Coastguard Worker """) 306*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_allowlist, symbol_list_file.getvalue()) 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Worker def test_multiple_definition(self) -> None: 309*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 310*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 311*333d2b36SAndroid Build Coastguard Worker global: 312*333d2b36SAndroid Build Coastguard Worker foo; 313*333d2b36SAndroid Build Coastguard Worker foo; 314*333d2b36SAndroid Build Coastguard Worker bar; 315*333d2b36SAndroid Build Coastguard Worker baz; 316*333d2b36SAndroid Build Coastguard Worker qux; # arm 317*333d2b36SAndroid Build Coastguard Worker local: 318*333d2b36SAndroid Build Coastguard Worker *; 319*333d2b36SAndroid Build Coastguard Worker }; 320*333d2b36SAndroid Build Coastguard Worker 321*333d2b36SAndroid Build Coastguard Worker VERSION_2 { 322*333d2b36SAndroid Build Coastguard Worker global: 323*333d2b36SAndroid Build Coastguard Worker bar; 324*333d2b36SAndroid Build Coastguard Worker qux; # arm64 325*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 326*333d2b36SAndroid Build Coastguard Worker 327*333d2b36SAndroid Build Coastguard Worker VERSION_PRIVATE { 328*333d2b36SAndroid Build Coastguard Worker global: 329*333d2b36SAndroid Build Coastguard Worker baz; 330*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 331*333d2b36SAndroid Build Coastguard Worker 332*333d2b36SAndroid Build Coastguard Worker """)) 333*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 334*333d2b36SAndroid Build Coastguard Worker f.api = 16 335*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, {}, f) 336*333d2b36SAndroid Build Coastguard Worker 337*333d2b36SAndroid Build Coastguard Worker with self.assertRaises( 338*333d2b36SAndroid Build Coastguard Worker symbolfile.MultiplyDefinedSymbolError) as ex_context: 339*333d2b36SAndroid Build Coastguard Worker parser.parse() 340*333d2b36SAndroid Build Coastguard Worker self.assertEqual(['bar', 'foo'], 341*333d2b36SAndroid Build Coastguard Worker ex_context.exception.multiply_defined_symbols) 342*333d2b36SAndroid Build Coastguard Worker 343*333d2b36SAndroid Build Coastguard Worker def test_integration_with_apex(self) -> None: 344*333d2b36SAndroid Build Coastguard Worker api_map = { 345*333d2b36SAndroid Build Coastguard Worker 'O': 9000, 346*333d2b36SAndroid Build Coastguard Worker 'P': 9001, 347*333d2b36SAndroid Build Coastguard Worker } 348*333d2b36SAndroid Build Coastguard Worker 349*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 350*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 351*333d2b36SAndroid Build Coastguard Worker global: 352*333d2b36SAndroid Build Coastguard Worker foo; # var 353*333d2b36SAndroid Build Coastguard Worker bar; # x86 354*333d2b36SAndroid Build Coastguard Worker fizz; # introduced=O 355*333d2b36SAndroid Build Coastguard Worker buzz; # introduced=P 356*333d2b36SAndroid Build Coastguard Worker local: 357*333d2b36SAndroid Build Coastguard Worker *; 358*333d2b36SAndroid Build Coastguard Worker }; 359*333d2b36SAndroid Build Coastguard Worker 360*333d2b36SAndroid Build Coastguard Worker VERSION_2 { # arm 361*333d2b36SAndroid Build Coastguard Worker baz; # introduced=9 362*333d2b36SAndroid Build Coastguard Worker qux; # versioned=14 363*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 364*333d2b36SAndroid Build Coastguard Worker 365*333d2b36SAndroid Build Coastguard Worker VERSION_3 { # introduced=14 366*333d2b36SAndroid Build Coastguard Worker woodly; 367*333d2b36SAndroid Build Coastguard Worker doodly; # var 368*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 369*333d2b36SAndroid Build Coastguard Worker 370*333d2b36SAndroid Build Coastguard Worker VERSION_4 { # versioned=9 371*333d2b36SAndroid Build Coastguard Worker wibble; 372*333d2b36SAndroid Build Coastguard Worker wizzes; # llndk 373*333d2b36SAndroid Build Coastguard Worker waggle; # apex 374*333d2b36SAndroid Build Coastguard Worker bubble; # apex llndk 375*333d2b36SAndroid Build Coastguard Worker duddle; # llndk apex 376*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 377*333d2b36SAndroid Build Coastguard Worker 378*333d2b36SAndroid Build Coastguard Worker VERSION_5 { # versioned=14 379*333d2b36SAndroid Build Coastguard Worker wobble; 380*333d2b36SAndroid Build Coastguard Worker } VERSION_4; 381*333d2b36SAndroid Build Coastguard Worker """)) 382*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 383*333d2b36SAndroid Build Coastguard Worker f.apex = True 384*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, api_map, f) 385*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 386*333d2b36SAndroid Build Coastguard Worker 387*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 388*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 389*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 390*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 391*333d2b36SAndroid Build Coastguard Worker f.apex = True 392*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 393*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, f) 394*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 395*333d2b36SAndroid Build Coastguard Worker 396*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 397*333d2b36SAndroid Build Coastguard Worker int foo = 0; 398*333d2b36SAndroid Build Coastguard Worker void baz() {} 399*333d2b36SAndroid Build Coastguard Worker void qux() {} 400*333d2b36SAndroid Build Coastguard Worker void wibble() {} 401*333d2b36SAndroid Build Coastguard Worker void waggle() {} 402*333d2b36SAndroid Build Coastguard Worker void bubble() {} 403*333d2b36SAndroid Build Coastguard Worker void duddle() {} 404*333d2b36SAndroid Build Coastguard Worker void wobble() {} 405*333d2b36SAndroid Build Coastguard Worker """) 406*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 407*333d2b36SAndroid Build Coastguard Worker 408*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 409*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 410*333d2b36SAndroid Build Coastguard Worker global: 411*333d2b36SAndroid Build Coastguard Worker foo; 412*333d2b36SAndroid Build Coastguard Worker }; 413*333d2b36SAndroid Build Coastguard Worker VERSION_2 { 414*333d2b36SAndroid Build Coastguard Worker global: 415*333d2b36SAndroid Build Coastguard Worker baz; 416*333d2b36SAndroid Build Coastguard Worker } VERSION_1; 417*333d2b36SAndroid Build Coastguard Worker VERSION_4 { 418*333d2b36SAndroid Build Coastguard Worker global: 419*333d2b36SAndroid Build Coastguard Worker wibble; 420*333d2b36SAndroid Build Coastguard Worker waggle; 421*333d2b36SAndroid Build Coastguard Worker bubble; 422*333d2b36SAndroid Build Coastguard Worker duddle; 423*333d2b36SAndroid Build Coastguard Worker } VERSION_2; 424*333d2b36SAndroid Build Coastguard Worker """) 425*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 426*333d2b36SAndroid Build Coastguard Worker 427*333d2b36SAndroid Build Coastguard Worker def test_integration_with_nondk(self) -> None: 428*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 429*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 430*333d2b36SAndroid Build Coastguard Worker global: 431*333d2b36SAndroid Build Coastguard Worker foo; 432*333d2b36SAndroid Build Coastguard Worker bar; # apex 433*333d2b36SAndroid Build Coastguard Worker local: 434*333d2b36SAndroid Build Coastguard Worker *; 435*333d2b36SAndroid Build Coastguard Worker }; 436*333d2b36SAndroid Build Coastguard Worker """)) 437*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 438*333d2b36SAndroid Build Coastguard Worker f.apex = True 439*333d2b36SAndroid Build Coastguard Worker f.ndk = False # ndk symbols should be excluded 440*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, {}, f) 441*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 442*333d2b36SAndroid Build Coastguard Worker 443*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 444*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 445*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 446*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 447*333d2b36SAndroid Build Coastguard Worker f.apex = True 448*333d2b36SAndroid Build Coastguard Worker f.ndk = False # ndk symbols should be excluded 449*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 450*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, f) 451*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 452*333d2b36SAndroid Build Coastguard Worker 453*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 454*333d2b36SAndroid Build Coastguard Worker void bar() {} 455*333d2b36SAndroid Build Coastguard Worker """) 456*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 457*333d2b36SAndroid Build Coastguard Worker 458*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 459*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 460*333d2b36SAndroid Build Coastguard Worker global: 461*333d2b36SAndroid Build Coastguard Worker bar; 462*333d2b36SAndroid Build Coastguard Worker }; 463*333d2b36SAndroid Build Coastguard Worker """) 464*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 465*333d2b36SAndroid Build Coastguard Worker 466*333d2b36SAndroid Build Coastguard Worker def test_integration_with_llndk(self) -> None: 467*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 468*333d2b36SAndroid Build Coastguard Worker VERSION_34 { # introduced=34 469*333d2b36SAndroid Build Coastguard Worker global: 470*333d2b36SAndroid Build Coastguard Worker foo; 471*333d2b36SAndroid Build Coastguard Worker bar; # llndk 472*333d2b36SAndroid Build Coastguard Worker }; 473*333d2b36SAndroid Build Coastguard Worker VERSION_35 { # introduced=35 474*333d2b36SAndroid Build Coastguard Worker global: 475*333d2b36SAndroid Build Coastguard Worker wiggle; 476*333d2b36SAndroid Build Coastguard Worker waggle; # llndk 477*333d2b36SAndroid Build Coastguard Worker } VERSION_34; 478*333d2b36SAndroid Build Coastguard Worker VERSION_36 { # introduced=36 479*333d2b36SAndroid Build Coastguard Worker global: 480*333d2b36SAndroid Build Coastguard Worker abc; 481*333d2b36SAndroid Build Coastguard Worker xyz; # llndk 482*333d2b36SAndroid Build Coastguard Worker } VERSION_35; 483*333d2b36SAndroid Build Coastguard Worker """)) 484*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 485*333d2b36SAndroid Build Coastguard Worker f.llndk = True 486*333d2b36SAndroid Build Coastguard Worker f.api = 35 487*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, {}, f) 488*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 489*333d2b36SAndroid Build Coastguard Worker 490*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 491*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 492*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 493*333d2b36SAndroid Build Coastguard Worker 494*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 495*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, f) 496*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 497*333d2b36SAndroid Build Coastguard Worker 498*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 499*333d2b36SAndroid Build Coastguard Worker void foo() {} 500*333d2b36SAndroid Build Coastguard Worker void bar() {} 501*333d2b36SAndroid Build Coastguard Worker void wiggle() {} 502*333d2b36SAndroid Build Coastguard Worker void waggle() {} 503*333d2b36SAndroid Build Coastguard Worker """) 504*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 505*333d2b36SAndroid Build Coastguard Worker 506*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 507*333d2b36SAndroid Build Coastguard Worker VERSION_34 { 508*333d2b36SAndroid Build Coastguard Worker global: 509*333d2b36SAndroid Build Coastguard Worker foo; 510*333d2b36SAndroid Build Coastguard Worker bar; 511*333d2b36SAndroid Build Coastguard Worker }; 512*333d2b36SAndroid Build Coastguard Worker VERSION_35 { 513*333d2b36SAndroid Build Coastguard Worker global: 514*333d2b36SAndroid Build Coastguard Worker wiggle; 515*333d2b36SAndroid Build Coastguard Worker waggle; 516*333d2b36SAndroid Build Coastguard Worker } VERSION_34; 517*333d2b36SAndroid Build Coastguard Worker """) 518*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 519*333d2b36SAndroid Build Coastguard Worker 520*333d2b36SAndroid Build Coastguard Worker def test_integration_with_llndk_with_single_version_block(self) -> None: 521*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 522*333d2b36SAndroid Build Coastguard Worker LIBANDROID { 523*333d2b36SAndroid Build Coastguard Worker global: 524*333d2b36SAndroid Build Coastguard Worker foo; # introduced=34 525*333d2b36SAndroid Build Coastguard Worker bar; # introduced=35 llndk 526*333d2b36SAndroid Build Coastguard Worker baz; # introduced=V 527*333d2b36SAndroid Build Coastguard Worker qux; # introduced=36 528*333d2b36SAndroid Build Coastguard Worker }; 529*333d2b36SAndroid Build Coastguard Worker """)) 530*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 531*333d2b36SAndroid Build Coastguard Worker f.llndk = True 532*333d2b36SAndroid Build Coastguard Worker f.api = 35 533*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, {'V': 35}, f) 534*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 535*333d2b36SAndroid Build Coastguard Worker 536*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 537*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 538*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 539*333d2b36SAndroid Build Coastguard Worker 540*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 541*333d2b36SAndroid Build Coastguard Worker version_file, symbol_list_file, f) 542*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 543*333d2b36SAndroid Build Coastguard Worker 544*333d2b36SAndroid Build Coastguard Worker expected_src = textwrap.dedent("""\ 545*333d2b36SAndroid Build Coastguard Worker void foo() {} 546*333d2b36SAndroid Build Coastguard Worker void bar() {} 547*333d2b36SAndroid Build Coastguard Worker void baz() {} 548*333d2b36SAndroid Build Coastguard Worker """) 549*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_src, src_file.getvalue()) 550*333d2b36SAndroid Build Coastguard Worker 551*333d2b36SAndroid Build Coastguard Worker expected_version = textwrap.dedent("""\ 552*333d2b36SAndroid Build Coastguard Worker LIBANDROID { 553*333d2b36SAndroid Build Coastguard Worker global: 554*333d2b36SAndroid Build Coastguard Worker foo; 555*333d2b36SAndroid Build Coastguard Worker bar; 556*333d2b36SAndroid Build Coastguard Worker baz; 557*333d2b36SAndroid Build Coastguard Worker }; 558*333d2b36SAndroid Build Coastguard Worker """) 559*333d2b36SAndroid Build Coastguard Worker self.assertEqual(expected_version, version_file.getvalue()) 560*333d2b36SAndroid Build Coastguard Worker 561*333d2b36SAndroid Build Coastguard Worker def test_empty_stub(self) -> None: 562*333d2b36SAndroid Build Coastguard Worker """Tests that empty stubs can be generated. 563*333d2b36SAndroid Build Coastguard Worker 564*333d2b36SAndroid Build Coastguard Worker This is not a common case, but libraries whose only behavior is to 565*333d2b36SAndroid Build Coastguard Worker interpose symbols to alter existing behavior do not need to expose 566*333d2b36SAndroid Build Coastguard Worker their interposing symbols as API, so it's possible for the stub to be 567*333d2b36SAndroid Build Coastguard Worker empty while still needing a stub to link against. libsigchain is an 568*333d2b36SAndroid Build Coastguard Worker example of this. 569*333d2b36SAndroid Build Coastguard Worker """ 570*333d2b36SAndroid Build Coastguard Worker input_file = io.StringIO(textwrap.dedent("""\ 571*333d2b36SAndroid Build Coastguard Worker VERSION_1 { 572*333d2b36SAndroid Build Coastguard Worker local: 573*333d2b36SAndroid Build Coastguard Worker *; 574*333d2b36SAndroid Build Coastguard Worker }; 575*333d2b36SAndroid Build Coastguard Worker """)) 576*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 577*333d2b36SAndroid Build Coastguard Worker f.apex = True 578*333d2b36SAndroid Build Coastguard Worker parser = symbolfile.SymbolFileParser(input_file, {}, f) 579*333d2b36SAndroid Build Coastguard Worker versions = parser.parse() 580*333d2b36SAndroid Build Coastguard Worker 581*333d2b36SAndroid Build Coastguard Worker src_file = io.StringIO() 582*333d2b36SAndroid Build Coastguard Worker version_file = io.StringIO() 583*333d2b36SAndroid Build Coastguard Worker symbol_list_file = io.StringIO() 584*333d2b36SAndroid Build Coastguard Worker f = copy(self.filter) 585*333d2b36SAndroid Build Coastguard Worker f.apex = True 586*333d2b36SAndroid Build Coastguard Worker generator = ndkstubgen.Generator(src_file, 587*333d2b36SAndroid Build Coastguard Worker version_file, 588*333d2b36SAndroid Build Coastguard Worker symbol_list_file, f) 589*333d2b36SAndroid Build Coastguard Worker generator.write(versions) 590*333d2b36SAndroid Build Coastguard Worker 591*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', src_file.getvalue()) 592*333d2b36SAndroid Build Coastguard Worker self.assertEqual('', version_file.getvalue()) 593*333d2b36SAndroid Build Coastguard Worker 594*333d2b36SAndroid Build Coastguard Worker 595*333d2b36SAndroid Build Coastguard Workerdef main() -> None: 596*333d2b36SAndroid Build Coastguard Worker suite = unittest.TestLoader().loadTestsFromName(__name__) 597*333d2b36SAndroid Build Coastguard Worker unittest.TextTestRunner(verbosity=3).run(suite) 598*333d2b36SAndroid Build Coastguard Worker 599*333d2b36SAndroid Build Coastguard Worker 600*333d2b36SAndroid Build Coastguard Workerif __name__ == '__main__': 601*333d2b36SAndroid Build Coastguard Worker main() 602