Merge changes I0484ea34,I188e4824 am: b3f18a9f9f am: 03c590b4e1

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2153678

Change-Id: I385312a0ff3627c4370a4dfc4de9586718ac6078
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2022-07-19 07:03:10 +00:00
committed by Automerger Merge Worker
8 changed files with 294 additions and 271 deletions

View File

@@ -949,8 +949,10 @@ func TestApexWithStubs(t *testing.T) {
// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
// ensureNotContains(t, mylib2Cflags, "-include ")
// Ensure that genstub is invoked with --apex
ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
// Ensure that genstub for platform-provided lib is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
// Ensure that genstub for apex-provided lib is invoked with --apex
ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",
@@ -1134,8 +1136,8 @@ func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylib2Cflags, "-include ")
// Ensure that genstub is invoked with --apex
ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"])
// Ensure that genstub is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",

View File

@@ -1032,9 +1032,19 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
return Objects{}
}
// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
// systemapi, respectively. The former is for symbols defined in platform libraries
// and the latter is for symbols defined in APEXes.
var flag string
if ctx.Module().(android.ApexModule).NotInPlatform() {
flag = "--apex"
} else {
// TODO(b/239274367) drop --apex when #apex is replaced with #systemapi
// in the map.txt files of platform libraries
flag = "--systemapi --apex"
}
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion),
"--apex")
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
library.versionScriptPath = android.OptionalPathForPath(
nativeAbiResult.versionScript)

View File

@@ -23,6 +23,7 @@ import sys
from xml.etree.ElementTree import Element, SubElement, tostring
from symbolfile import (
ALL_ARCHITECTURES,
Filter,
FUTURE_API_LEVEL,
MultiplyDefinedSymbolError,
SymbolFileParser,
@@ -139,9 +140,8 @@ def main():
with open(args.symbol_file) as symbol_file:
try:
versions = SymbolFileParser(
symbol_file, api_map, "", FUTURE_API_LEVEL, True, True
).parse()
filt = Filter("", FUTURE_API_LEVEL, True, True, True)
versions = SymbolFileParser(symbol_file, api_map, filt).parse()
except MultiplyDefinedSymbolError as ex:
sys.exit('{}: error: {}'.format(args.symbol_file, ex))

View File

@@ -20,7 +20,7 @@ import textwrap
import unittest
from xml.etree.ElementTree import fromstring
from symbolfile import FUTURE_API_LEVEL, SymbolFileParser
from symbolfile import Filter, FUTURE_API_LEVEL, SymbolFileParser
import ndk_api_coverage_parser as nparser
@@ -78,9 +78,8 @@ class ApiCoverageSymbolFileParserTest(unittest.TestCase):
"""
)
)
parser = SymbolFileParser(
input_file, {}, "", FUTURE_API_LEVEL, True, True
)
filt = Filter("", FUTURE_API_LEVEL, True, True, True)
parser = SymbolFileParser(input_file, {}, filt)
generator = nparser.XmlGenerator(io.StringIO())
result = generator.convertToXml(parser.parse())
expected = fromstring(

View File

@@ -29,15 +29,12 @@ from symbolfile import Arch, Version
class Generator:
"""Output generator that writes stub source files and version scripts."""
def __init__(self, src_file: TextIO, version_script: TextIO,
symbol_list: TextIO, arch: Arch, api: int, llndk: bool,
apex: bool) -> None:
symbol_list: TextIO, filt: symbolfile.Filter) -> None:
self.src_file = src_file
self.version_script = version_script
self.symbol_list = symbol_list
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.filter = filt
self.api = filt.api
def write(self, versions: Iterable[Version]) -> None:
"""Writes all symbol data to the output files."""
@@ -47,8 +44,7 @@ class Generator:
def write_version(self, version: Version) -> None:
"""Writes a single version block's data to the output files."""
if symbolfile.should_omit_version(version, self.arch, self.api,
self.llndk, self.apex):
if self.filter.should_omit_version(version):
return
section_versioned = symbolfile.symbol_versioned_in_api(
@@ -56,8 +52,7 @@ class Generator:
version_empty = True
pruned_symbols = []
for symbol in version.symbols:
if symbolfile.should_omit_symbol(symbol, self.arch, self.api,
self.llndk, self.apex):
if self.filter.should_omit_symbol(symbol):
continue
if symbolfile.symbol_versioned_in_api(symbol.tags, self.api):
@@ -110,12 +105,12 @@ def parse_args() -> argparse.Namespace:
parser.add_argument(
'--apex',
action='store_true',
help='Use the APEX variant. Note: equivalent to --system-api.')
help='Use the APEX variant.')
parser.add_argument(
'--system-api',
'--systemapi',
action='store_true',
dest='apex',
help='Use the SystemAPI variant. Note: equivalent to --apex.')
dest='systemapi',
help='Use the SystemAPI variant.')
parser.add_argument('--api-map',
type=resolved_path,
@@ -152,11 +147,10 @@ def main() -> None:
verbosity = 2
logging.basicConfig(level=verbose_map[verbosity])
filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi)
with args.symbol_file.open() as symbol_file:
try:
versions = symbolfile.SymbolFileParser(symbol_file, api_map,
args.arch, api, args.llndk,
args.apex).parse()
versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
except symbolfile.MultiplyDefinedSymbolError as ex:
sys.exit(f'{args.symbol_file}: error: {ex}')
@@ -164,7 +158,7 @@ def main() -> None:
with args.version_script.open('w') as version_script:
with args.symbol_list.open('w') as symbol_list:
generator = Generator(src_file, version_script, symbol_list,
args.arch, api, args.llndk, args.apex)
filt)
generator.write(versions)

View File

@@ -18,6 +18,7 @@
import io
import textwrap
import unittest
from copy import copy
import symbolfile
from symbolfile import Arch, Tags
@@ -29,6 +30,9 @@ import ndkstubgen
class GeneratorTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
def test_omit_version(self) -> None:
# Thorough testing of the cases involved here is handled by
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
@@ -37,7 +41,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
symbolfile.Symbol('foo', Tags()),
@@ -70,7 +74,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
version = symbolfile.Version('VERSION_1', None, Tags(), [
symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
@@ -106,7 +110,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
versions = [
symbolfile.Version('VERSION_1', None, Tags(), [
@@ -162,6 +166,9 @@ class GeneratorTest(unittest.TestCase):
class IntegrationTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
def test_integration(self) -> None:
api_map = {
'O': 9000,
@@ -199,8 +206,7 @@ class IntegrationTest(unittest.TestCase):
wobble;
} VERSION_4;
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9, False, False)
parser = symbolfile.SymbolFileParser(input_file, api_map, self.filter)
versions = parser.parse()
src_file = io.StringIO()
@@ -208,7 +214,7 @@ class IntegrationTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -263,16 +269,18 @@ class IntegrationTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9001, False, False)
f = copy(self.filter)
f.api = 9001
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.api = 9001
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9001, False, False)
version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -322,8 +330,9 @@ class IntegrationTest(unittest.TestCase):
} VERSION_2;
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
f = copy(self.filter)
f.api = 16
parser = symbolfile.SymbolFileParser(input_file, {}, f)
with self.assertRaises(
symbolfile.MultiplyDefinedSymbolError) as ex_context:
@@ -370,16 +379,18 @@ class IntegrationTest(unittest.TestCase):
wobble;
} VERSION_4;
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9, False, True)
f = copy(self.filter)
f.apex = True
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.apex = True
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, True)
version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -428,20 +439,19 @@ class IntegrationTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
9, llndk=False, apex=True)
f = copy(self.filter)
f.apex = True
parser = symbolfile.SymbolFileParser(input_file, {}, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.apex = True
generator = ndkstubgen.Generator(src_file,
version_file,
symbol_list_file,
Arch('arm'),
9,
llndk=False,
apex=True)
symbol_list_file, f)
generator.write(versions)
self.assertEqual('', src_file.getvalue())

View File

@@ -78,12 +78,17 @@ class Tags:
@property
def has_mode_tags(self) -> bool:
"""Returns True if any mode tags (apex, llndk, etc) are set."""
return self.has_apex_tags or self.has_llndk_tags
return self.has_apex_tags or self.has_llndk_tags or self.has_systemapi_tags
@property
def has_apex_tags(self) -> bool:
"""Returns True if any APEX tags are set."""
return 'apex' in self.tags or 'systemapi' in self.tags
return 'apex' in self.tags
@property
def has_systemapi_tags(self) -> bool:
"""Returns True if any APEX tags are set."""
return 'systemapi' in self.tags
@property
def has_llndk_tags(self) -> bool:
@@ -198,50 +203,57 @@ def get_tag_value(tag: Tag) -> str:
"""
return split_tag(tag)[1]
class Filter:
"""A filter encapsulates a condition that tells whether a version or a
symbol should be omitted or not
"""
def _should_omit_tags(tags: Tags, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi: bool = False):
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.systemapi = systemapi
def _should_omit_tags(self, tags: Tags) -> bool:
"""Returns True if the tagged object should be omitted.
This defines the rules shared between version tagging and symbol tagging.
"""
# The apex and llndk tags will only exclude APIs from other modes. If in
# APEX or LLNDK mode and neither tag is provided, we fall back to the
# default behavior because all NDK symbols are implicitly available to APEX
# and LLNDK.
# default behavior because all NDK symbols are implicitly available to
# APEX and LLNDK.
if tags.has_mode_tags:
if not apex and not llndk:
if self.apex and tags.has_apex_tags:
return False
if self.llndk and tags.has_llndk_tags:
return False
if self.systemapi and tags.has_systemapi_tags:
return False
return True
if apex and not tags.has_apex_tags:
if not symbol_in_arch(tags, self.arch):
return True
if llndk and not tags.has_llndk_tags:
return True
if not symbol_in_arch(tags, arch):
return True
if not symbol_in_api(tags, arch, api):
if not symbol_in_api(tags, self.arch, self.api):
return True
return False
def should_omit_version(version: Version, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
def should_omit_version(self, version: Version) -> bool:
"""Returns True if the version section should be omitted.
We want to omit any sections that do not have any symbols we'll have in the
stub library. Sections that contain entirely future symbols or only symbols
for certain architectures.
We want to omit any sections that do not have any symbols we'll have in
the stub library. Sections that contain entirely future symbols or only
symbols for certain architectures.
"""
if version.is_private:
return True
if version.tags.has_platform_only_tags:
return True
return _should_omit_tags(version.tags, arch, api, llndk, apex)
return self._should_omit_tags(version.tags)
def should_omit_symbol(symbol: Symbol, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
def should_omit_symbol(self, symbol: Symbol) -> bool:
"""Returns True if the symbol should be omitted."""
return _should_omit_tags(symbol.tags, arch, api, llndk, apex)
return self._should_omit_tags(symbol.tags)
def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
@@ -316,14 +328,10 @@ class MultiplyDefinedSymbolError(RuntimeError):
class SymbolFileParser:
"""Parses NDK symbol files."""
def __init__(self, input_file: TextIO, api_map: ApiMap, arch: Arch,
api: int, llndk: bool, apex: bool) -> None:
def __init__(self, input_file: TextIO, api_map: ApiMap, filt: Filter) -> None:
self.input_file = input_file
self.api_map = api_map
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.filter = filt
self.current_line: Optional[str] = None
def parse(self) -> List[Version]:
@@ -352,13 +360,11 @@ class SymbolFileParser:
symbol_names = set()
multiply_defined_symbols = set()
for version in versions:
if should_omit_version(version, self.arch, self.api, self.llndk,
self.apex):
if self.filter.should_omit_version(version):
continue
for symbol in version.symbols:
if should_omit_symbol(symbol, self.arch, self.api, self.llndk,
self.apex):
if self.filter.should_omit_symbol(symbol):
continue
if symbol.name in symbol_names:

View File

@@ -19,7 +19,8 @@ import textwrap
import unittest
import symbolfile
from symbolfile import Arch, Tag, Tags, Version
from symbolfile import Arch, Tag, Tags, Version, Symbol, Filter
from copy import copy
# pylint: disable=missing-docstring
@@ -202,178 +203,188 @@ class SymbolPresenceTest(unittest.TestCase):
class OmitVersionTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 9)
self.version = Version('foo', None, Tags(), [])
def assertOmit(self, f: Filter, v: Version) -> None:
self.assertTrue(f.should_omit_version(v))
def assertInclude(self, f: Filter, v: Version) -> None:
self.assertFalse(f.should_omit_version(v))
def test_omit_private(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
f = self.filter
v = self.version
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo_PRIVATE', None, Tags(), []),
Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo_PLATFORM', None, Tags(), []),
Arch('arm'), 9, False, False))
self.assertInclude(f, v)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['platform-only']), []),
Arch('arm'), 9, False, False))
v.name = 'foo_PRIVATE'
self.assertOmit(f, v)
v.name = 'foo_PLATFORM'
self.assertOmit(f, v)
v.name = 'foo'
v.tags = Tags.from_strs(['platform-only'])
self.assertOmit(f, v)
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_llndk = copy(v)
v_llndk.tags = Tags.from_strs(['llndk'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
True, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, True, False))
self.assertOmit(f, v_llndk)
f.llndk = True
self.assertInclude(f, v)
self.assertInclude(f, v_llndk)
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_apex = copy(v)
v_apex.tags = Tags.from_strs(['apex'])
v_systemapi = copy(v)
v_systemapi.tags = Tags.from_strs(['systemapi'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, True))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, True))
self.assertOmit(f, v_apex)
f.apex = True
self.assertInclude(f, v)
self.assertInclude(f, v_apex)
self.assertOmit(f, v_systemapi)
def test_omit_systemapi(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
[]), Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_apex = copy(v)
v_apex.tags = Tags.from_strs(['apex'])
v_systemapi = copy(v)
v_systemapi.tags = Tags.from_strs(['systemapi'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, True))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
[]), Arch('arm'), 9, False, True))
self.assertOmit(f, v_systemapi)
f.systemapi = True
self.assertInclude(f, v)
self.assertInclude(f, v_systemapi)
self.assertOmit(f, v_apex)
def test_omit_arch(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
Arch('arm'), 9, False, False))
f_arm = self.filter
v_none = self.version
self.assertInclude(f_arm, v_none)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
Arch('arm'), 9, False, False))
v_arm = copy(v_none)
v_arm.tags = Tags.from_strs(['arm'])
self.assertInclude(f_arm, v_arm)
v_x86 = copy(v_none)
v_x86.tags = Tags.from_strs(['x86'])
self.assertOmit(f_arm, v_x86)
def test_omit_api(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['introduced=9']), []),
Arch('arm'), 9, False, False))
f_api9 = self.filter
v_none = self.version
self.assertInclude(f_api9, v_none)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['introduced=14']), []),
Arch('arm'), 9, False, False))
v_api9 = copy(v_none)
v_api9.tags = Tags.from_strs(['introduced=9'])
self.assertInclude(f_api9, v_api9)
v_api14 = copy(v_none)
v_api14.tags = Tags.from_strs(['introduced=14'])
self.assertOmit(f_api9, v_api14)
class OmitSymbolTest(unittest.TestCase):
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
Arch('arm'), 9, False, False))
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 9)
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, True, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
Arch('arm'), 9, True, False))
def assertOmit(self, f: Filter, s: Symbol) -> None:
self.assertTrue(f.should_omit_symbol(s))
def assertInclude(self, f: Filter, s: Symbol) -> None:
self.assertFalse(f.should_omit_symbol(s))
def test_omit_llndk(self) -> None:
f_none = self.filter
f_llndk = copy(f_none)
f_llndk.llndk = True
s_none = Symbol('foo', Tags())
s_llndk = Symbol('foo', Tags.from_strs(['llndk']))
self.assertOmit(f_none, s_llndk)
self.assertInclude(f_llndk, s_none)
self.assertInclude(f_llndk, s_llndk)
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
Arch('arm'), 9, False, False))
f_none = self.filter
f_apex = copy(f_none)
f_apex.apex = True
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, True))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
Arch('arm'), 9, False, True))
s_none = Symbol('foo', Tags())
s_apex = Symbol('foo', Tags.from_strs(['apex']))
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
self.assertOmit(f_none, s_apex)
self.assertInclude(f_apex, s_none)
self.assertInclude(f_apex, s_apex)
self.assertOmit(f_apex, s_systemapi)
def test_omit_systemapi(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
Arch('arm'), 9, False, False))
f_none = self.filter
f_systemapi = copy(f_none)
f_systemapi.systemapi = True
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, True))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
Arch('arm'), 9, False, True))
s_none = Symbol('foo', Tags())
s_apex = Symbol('foo', Tags.from_strs(['apex']))
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
self.assertOmit(f_none, s_systemapi)
self.assertInclude(f_systemapi, s_none)
self.assertInclude(f_systemapi, s_systemapi)
self.assertOmit(f_systemapi, s_apex)
def test_omit_apex_and_systemapi(self) -> None:
f = self.filter
f.systemapi = True
f.apex = True
s_none = Symbol('foo', Tags())
s_apex = Symbol('foo', Tags.from_strs(['apex']))
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
self.assertInclude(f, s_none)
self.assertInclude(f, s_apex)
self.assertInclude(f, s_systemapi)
def test_omit_arch(self) -> None:
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
9, False, False))
f_arm = self.filter
s_none = Symbol('foo', Tags())
s_arm = Symbol('foo', Tags.from_strs(['arm']))
s_x86 = Symbol('foo', Tags.from_strs(['x86']))
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
9, False, False))
self.assertInclude(f_arm, s_none)
self.assertInclude(f_arm, s_arm)
self.assertOmit(f_arm, s_x86)
def test_omit_api(self) -> None:
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
Arch('arm'), 9, False, False))
f_api9 = self.filter
s_none = Symbol('foo', Tags())
s_api9 = Symbol('foo', Tags.from_strs(['introduced=9']))
s_api14 = Symbol('foo', Tags.from_strs(['introduced=14']))
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
Arch('arm'), 9, False, False))
self.assertInclude(f_api9, s_none)
self.assertInclude(f_api9, s_api9)
self.assertOmit(f_api9, s_api14)
class SymbolFileParseTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 16)
def test_next_line(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
foo
@@ -382,8 +393,7 @@ class SymbolFileParseTest(unittest.TestCase):
# baz
qux
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
self.assertIsNone(parser.current_line)
self.assertEqual('foo', parser.next_line().strip())
@@ -409,8 +419,7 @@ class SymbolFileParseTest(unittest.TestCase):
VERSION_2 {
} VERSION_1; # asdf
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
@@ -419,8 +428,8 @@ class SymbolFileParseTest(unittest.TestCase):
self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
expected_symbols = [
symbolfile.Symbol('baz', Tags()),
symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
Symbol('baz', Tags()),
Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
]
self.assertEqual(expected_symbols, version.symbols)
@@ -434,8 +443,7 @@ class SymbolFileParseTest(unittest.TestCase):
input_file = io.StringIO(textwrap.dedent("""\
VERSION_1 {
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -446,8 +454,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo:
}
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -457,8 +464,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo;
bar; # baz qux
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
symbol = parser.parse_symbol()
@@ -476,8 +482,7 @@ class SymbolFileParseTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -489,8 +494,7 @@ class SymbolFileParseTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
self.assertEqual([], version.symbols)
@@ -501,8 +505,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -510,8 +513,7 @@ class SymbolFileParseTest(unittest.TestCase):
def test_parse_fails_invalid_input(self) -> None:
with self.assertRaises(symbolfile.ParseError):
input_file = io.StringIO('foo')
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
16, False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.parse()
def test_parse(self) -> None:
@@ -532,19 +534,18 @@ class SymbolFileParseTest(unittest.TestCase):
qwerty;
} VERSION_1;
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
versions = parser.parse()
expected = [
symbolfile.Version('VERSION_1', None, Tags(), [
symbolfile.Symbol('foo', Tags()),
symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
Symbol('foo', Tags()),
Symbol('bar', Tags.from_strs(['baz'])),
]),
symbolfile.Version(
'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
symbolfile.Symbol('woodly', Tags()),
symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
Symbol('woodly', Tags()),
Symbol('doodly', Tags.from_strs(['asdf'])),
]),
]
@@ -559,8 +560,9 @@ class SymbolFileParseTest(unittest.TestCase):
qux; # apex
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, True)
f = copy(self.filter)
f.llndk = True
parser = symbolfile.SymbolFileParser(input_file, {}, f)
parser.next_line()
version = parser.parse_version()
@@ -568,10 +570,10 @@ class SymbolFileParseTest(unittest.TestCase):
self.assertIsNone(version.base)
expected_symbols = [
symbolfile.Symbol('foo', Tags()),
symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
Symbol('foo', Tags()),
Symbol('bar', Tags.from_strs(['llndk'])),
Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
Symbol('qux', Tags.from_strs(['apex'])),
]
self.assertEqual(expected_symbols, version.symbols)