Merge changes from topics "fix-header-checker-tests ", "fix-header-checker-tests"

am: 9bad754624

Change-Id: Id687fad64a04cfb19dd4c94a12e6aa4051bcf62c
This commit is contained in:
Jayant Chowdhary
2017-12-08 00:15:26 +00:00
committed by android-build-merger
13 changed files with 354 additions and 74 deletions

View File

@@ -88,6 +88,25 @@ inline abi_dump::RecordKind RecordKindIRToProtobuf(
assert(false);
}
inline RecordTypeIR::RecordKind RecordKindProtobufToIR(
abi_dump::RecordKind kind) {
switch (kind) {
case abi_dump::RecordKind::struct_kind:
return RecordTypeIR::struct_kind;
case abi_dump::RecordKind::class_kind:
return RecordTypeIR::class_kind;
case abi_dump::RecordKind::union_kind:
return RecordTypeIR::union_kind;
default:
return RecordTypeIR::struct_kind;
}
// Should not be reached
assert(false);
}
inline abi_dump::VTableComponent::Kind VTableComponentKindIRToProtobuf(
VTableComponentIR::Kind kind) {
switch (kind) {

View File

@@ -154,6 +154,8 @@ RecordTypeIR ProtobufTextFormatToIRReader::RecordTypeProtobufToIR(
// Base Specifiers
record_type_ir.SetCXXBaseSpecifiers(RecordCXXBaseSpecifiersProtobufToIR(
record_type_protobuf.base_specifiers()));
record_type_ir.SetRecordKind(
RecordKindProtobufToIR(record_type_protobuf.record_kind()));
return record_type_ir;
}

View File

@@ -21,10 +21,12 @@ DEFAULT_CFLAGS = ['-x', 'c++', '-std=c++11']
FILE_EXTENSIONS = ['h', 'hpp', 'hxx', 'cpp', 'cc', 'c']
def make_and_copy_reference_dumps(module, default_cflags):
def make_and_copy_reference_dumps(module, default_cflags,
reference_dump_dir=REFERENCE_DUMP_DIR):
lsdump_content = module.make_lsdump(default_cflags)
copy_reference_dump_content(module.get_name(), lsdump_content,
REFERENCE_DUMP_DIR, '', module.get_arch())
return copy_reference_dump_content(module.get_name(), lsdump_content,
reference_dump_dir, '',
module.get_arch())
def main():
patt = re.compile(

View File

@@ -84,27 +84,35 @@ class Module(object):
self.version_script, self.api,
self.arch)
@staticmethod
def mutate_module_for_all_arches(module):
modules = []
def mutate_module_for_arch(module, target_arch):
name = module.get_name()
srcs = module.get_srcs()
version_script = module.get_version_script()
cflags = module.get_cflags()
export_include_dirs = module.get_export_include_dirs()
api = module.get_api()
return Module(name, target_arch, srcs, version_script, cflags,
export_include_dirs, api)
@staticmethod
def mutate_module_for_all_arches(module):
modules = []
for target_arch in TARGET_ARCHS:
modules.append(Module(name, target_arch, srcs, version_script,
cflags, export_include_dirs, api))
modules.append(Module.mutate_module_for_arch(module, target_arch))
return modules
@staticmethod
def get_test_modules():
modules = []
for module in TEST_MODULES:
for module in TEST_MODULES.values():
if module.get_arch() == '':
modules += Module.mutate_module_for_all_arches(module)
return modules
@staticmethod
def get_test_module_by_name(name):
return TEST_MODULES[name]
TEST_MODULES = [
Module(
name = 'libc_and_cpp',
@@ -308,4 +316,16 @@ TEST_MODULES = [
arch = '',
api = 'current',
),
Module(
name = 'libreproducability',
srcs = ['integration/c_and_cpp/reproducability.c',
],
version_script = 'integration/c_and_cpp/repro_map.txt',
export_include_dirs = ['integration/c_and_cpp/include'],
cflags = [],
arch = '',
api = 'current',
),
]
TEST_MODULES = { m.name: m for m in TEST_MODULES }

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -0,0 +1,34 @@
record_types {
type_info {
name: "ShouldRepro"
size: 4
alignment: 4
referenced_type: "ShouldRepro"
source_file: "/development/vndk/tools/header-checker/tests/integration/c_and_cpp/include/reproducability_c.h"
linker_set_key: "ShouldRepro"
}
fields {
referenced_type: "int"
field_offset: 0
field_name: "a"
access: public_access
}
access: public_access
is_anonymous: true
record_kind: struct_kind
}
builtin_types {
type_info {
name: "int"
size: 4
alignment: 4
referenced_type: "int"
source_file: ""
linker_set_key: "int"
}
is_unsigned: false
is_integral: true
}
elf_functions {
name: "repro"
}

View File

@@ -3,19 +3,23 @@
import os
import unittest
import sys
import tempfile
import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
import_path = os.path.abspath(os.path.join(import_path, 'utils'))
sys.path.insert(1, import_path)
from utils import read_output_content
from utils import run_header_abi_dumper
from utils import run_abi_diff
from utils import SOURCE_ABI_DUMP_EXT
from utils import TARGET_ARCHS
from utils import get_build_var
from utils import make_library
from utils import find_lib_lsdump
from utils import AOSP_DIR
from module import Module
from gen_all import make_and_copy_reference_dumps
from gen_all import DEFAULT_CFLAGS
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
INPUT_DIR = os.path.join(SCRIPT_DIR, 'input')
@@ -27,6 +31,12 @@ class MyTest(unittest.TestCase):
def setUpClass(cls):
cls.maxDiff = None
def get_reference_dump_path(self, name, target_arch):
ref_dump_dir = os.path.join(REF_DUMP_DIR, target_arch)
ref_dump_path = os.path.join(ref_dump_dir,
name + SOURCE_ABI_DUMP_EXT)
return ref_dump_path
def run_and_compare(self, input_path, expected_path, cflags=[]):
with open(expected_path, 'r') as f:
expected_output = f.read()
@@ -47,27 +57,54 @@ class MyTest(unittest.TestCase):
def run_and_compare_abi_diff(self, old_dump, new_dump, lib, arch,
expected_return_code, flags=[]) :
actual_output = run_abi_diff(old_dump, new_dump, arch, lib, flags)
self.assertEqual(actual_output, expected_return_code)
actual_output = run_abi_diff(old_dump, new_dump, arch, lib, flags)
self.assertEqual(actual_output, expected_return_code)
def prepare_and_run_abi_diff(self, old_lib, new_lib,
def prepare_and_run_abi_diff(self, old_ref_dump_path, new_ref_dump_path,
target_arch, expected_return_code, flags=[]):
ref_dump_dir = os.path.join(REF_DUMP_DIR, target_arch)
old_ref_dump_path = os.path.join(ref_dump_dir,
old_lib + SOURCE_ABI_DUMP_EXT)
new_ref_dump_path = os.path.join(ref_dump_dir,
new_lib + SOURCE_ABI_DUMP_EXT)
self.run_and_compare_abi_diff(old_ref_dump_path, new_ref_dump_path,
new_lib, target_arch,
expected_return_code, flags)
'test', target_arch, expected_return_code,
flags)
def create_ref_dump(self, name, dir_name, target_arch):
module_bare = Module.get_test_module_by_name(name)
module = Module.mutate_module_for_arch(module_bare, target_arch)
return make_and_copy_reference_dumps(module, DEFAULT_CFLAGS,
dir_name)
def get_or_create_ref_dump(self, name, target_arch, dir_name, create):
if create == True:
return self.create_ref_dump(name, dir_name, target_arch)
return self.get_reference_dump_path(name, target_arch)
def prepare_and_run_abi_diff_all_archs(self, old_lib, new_lib,
expected_return_code, flags=[]):
for target_arch in TARGET_ARCHS:
self.prepare_and_run_abi_diff(old_lib, new_lib, target_arch,
expected_return_code, flags)
expected_return_code, flags=[],
create=True):
with tempfile.TemporaryDirectory() as tmp:
for target_arch in TARGET_ARCHS:
old_ref_dump_path = self.get_or_create_ref_dump(old_lib,
target_arch,
tmp, False)
new_ref_dump_path = self.get_or_create_ref_dump(new_lib,
target_arch,
tmp, create)
self.prepare_and_run_abi_diff(old_ref_dump_path,
new_ref_dump_path, target_arch,
expected_return_code, flags)
def prepare_and_absolute_diff_all_archs(self, old_lib, new_lib,
flags=[], create=True):
with tempfile.TemporaryDirectory() as tmp:
for target_arch in TARGET_ARCHS:
old_ref_dump_path = self.get_or_create_ref_dump(old_lib,
target_arch,
tmp, False)
new_ref_dump_path = self.get_or_create_ref_dump(new_lib,
target_arch,
tmp, create)
self.assertEqual(
read_output_content(old_ref_dump_path, AOSP_DIR),
read_output_content(new_ref_dump_path, AOSP_DIR))
def test_func_decl_no_args(self):
self.run_and_compare_name_c_cpp('func_decl_no_args.h')
@@ -157,7 +194,8 @@ class MyTest(unittest.TestCase):
def test_libgolden_cpp_fabricated_function_ast_removed_diff(self):
self.prepare_and_run_abi_diff_all_archs(
"libgolden_cpp_fabricated_function_ast_removed", "libgolden_cpp", 0)
"libgolden_cpp_fabricated_function_ast_removed", "libgolden_cpp", 0,
[], False)
def test_libgolden_cpp_member_fake_diff(self):
self.prepare_and_run_abi_diff_all_archs(
@@ -176,6 +214,10 @@ class MyTest(unittest.TestCase):
"libgolden_cpp",
"libgolden_cpp_unreferenced_elf_symbol_removed", 16)
def test_libreproducability(self):
self.prepare_and_absolute_diff_all_archs("libreproducability",
"libreproducability")
if __name__ == '__main__':
unittest.main()

View File

@@ -5,12 +5,8 @@ import re
import sys
import argparse
from utils import make_library
from utils import find_lib_lsdump
from utils import get_build_var
from utils import AOSP_DIR
from utils import read_output_content
from utils import copy_reference_dump
from utils import (make_library, find_lib_lsdumps, get_build_var, AOSP_DIR,
read_output_content, copy_reference_dumps)
class Target(object):
def __init__(self, has_2nd):
@@ -20,27 +16,19 @@ class Target(object):
self.cpu_variant = \
get_build_var('TARGET{}_CPU_VARIANT'.format(extra))
def get_vndk_libs(vndk_list_path):
with open(vndk_list_path, 'r') as f:
return f.read().splitlines()
def create_source_abi_reference_dumps(soong_dir, vndk_libs, args):
def create_source_abi_reference_dumps(soong_dir, args):
ref_dump_dir_stem = os.path.join(args.ref_dump_dir, args.version)
ref_dump_dir_insertion = 'source-based'
num_libs_copied = 0
for vndk_lib in vndk_libs:
if args.make_libs:
make_library(vndk_lib)
for target in [Target(True), Target(False)]:
arch_lsdump_path = find_lib_lsdump(vndk_lib, target.arch,
target.arch_variant,
target.cpu_variant)
# Copy the contents of the lsdump into it's corresponding
# reference directory.
num_libs_copied += copy_reference_dump(arch_lsdump_path,
ref_dump_dir_stem,
ref_dump_dir_insertion,
target.arch)
for target in [Target(True), Target(False)]:
arch_lsdump_paths = find_lib_lsdumps(target.arch, target.arch_variant,
target.cpu_variant, soong_dir)
# Copy the contents of the lsdump into it's corresponding
# reference directory.
num_libs_copied += copy_reference_dumps(arch_lsdump_paths,
ref_dump_dir_stem,
ref_dump_dir_insertion,
target.arch)
return num_libs_copied
@@ -48,17 +36,12 @@ def main():
# Parse command line options.
parser = argparse.ArgumentParser()
parser.add_argument('--version', help='VNDK version')
parser.add_argument('--vndk-list', help='file containing list of vndk \
libraries')
parser.add_argument('-ref-dump-dir', help='directory to copy reference abi \
dumps into')
parser.add_argument('-make-libs', action ="store_true", default = False,
help='make libraries before copying dumps')
args = parser.parse_args()
num_processed = 0
soong_dir = os.path.join(AOSP_DIR, 'out', 'soong', '.intermediates')
num_processed += create_source_abi_reference_dumps(soong_dir,\
get_vndk_libs(args.vndk_list), args)
num_processed += create_source_abi_reference_dumps(soong_dir, args)
print()
print('msg: Processed', num_processed, 'libraries')
if __name__ == '__main__':

View File

@@ -18,24 +18,32 @@ EXPORTED_HEADERS_DIR = (
'tests'),
)
SOURCE_ABI_DUMP_EXT = ".so.lsdump"
SO_EXT = '.so'
SOURCE_ABI_DUMP_EXT_END = '.lsdump'
SOURCE_ABI_DUMP_EXT = SO_EXT + SOURCE_ABI_DUMP_EXT_END
TARGET_ARCHS = ['arm', 'arm64', 'x86', 'x86_64', 'mips', 'mips64']
def get_reference_dump_dir(reference_dump_dir_stem,
reference_dump_dir_insertion, lib_arch):
reference_dump_dir_insertion, lib_arch):
reference_dump_dir = os.path.join(reference_dump_dir_stem, lib_arch)
reference_dump_dir = os.path.join(reference_dump_dir,
reference_dump_dir_insertion)
return reference_dump_dir
def copy_reference_dump(lib_path, reference_dump_dir_stem,
reference_dump_dir_insertion, lib_arch):
if lib_path is None:
return 0
reference_dump_dir = get_reference_dump_dir(reference_dump_dir_stem,
def copy_reference_dumps(lib_paths, reference_dir_stem,
reference_dump_dir_insertion, lib_arch):
reference_dump_dir = get_reference_dump_dir(reference_dir_stem,
reference_dump_dir_insertion,
lib_arch)
num_created = 0
for lib_path in lib_paths:
copy_reference_dump(lib_path, reference_dump_dir)
num_created += 1
return num_created
def copy_reference_dump(lib_path, reference_dump_dir):
reference_dump_path = os.path.join(reference_dump_dir,
os.path.basename(lib_path))
os.makedirs(os.path.dirname(reference_dump_path), exist_ok=True)
@@ -43,7 +51,7 @@ def copy_reference_dump(lib_path, reference_dump_dir_stem,
with open(reference_dump_path, 'w') as f:
f.write(output_content)
print('Created abi dump at ', reference_dump_path)
return 1
return reference_dump_path
def copy_reference_dump_content(lib_name, output_content,
reference_dump_dir_stem,
@@ -57,7 +65,7 @@ def copy_reference_dump_content(lib_name, output_content,
with open(reference_dump_path, 'w') as f:
f.write(output_content)
print('Created abi dump at ', reference_dump_path)
return 1
return reference_dump_path
def read_output_content(output_path, replace_str):
with open(output_path, 'r') as f:
@@ -104,14 +112,14 @@ def make_library(lib_name):
make_cmd = ['make', '-j', lib_name]
subprocess.check_call(make_cmd, cwd=AOSP_DIR)
def find_lib_lsdump(lib_name, target_arch, target_arch_variant,
target_cpu_variant):
def find_lib_lsdumps(target_arch, target_arch_variant,
target_cpu_variant, soong_dir):
""" Find the lsdump corresponding to lib_name for the given arch parameters
if it exists"""
assert 'ANDROID_PRODUCT_OUT' in os.environ
cpu_variant = '_' + target_cpu_variant
arch_variant = '_' + target_arch_variant
lsdump_paths = []
if target_cpu_variant == 'generic' or target_cpu_variant is None or\
target_cpu_variant == '':
cpu_variant = ''
@@ -120,16 +128,16 @@ def find_lib_lsdump(lib_name, target_arch, target_arch_variant,
arch_variant = ''
target_dir = 'android_' + target_arch + arch_variant +\
cpu_variant + '_shared_core'
soong_dir = os.path.join(AOSP_DIR, 'out', 'soong', '.intermediates')
expected_lsdump_name = lib_name + SOURCE_ABI_DUMP_EXT
cpu_variant + '_vendor_shared'
for base, dirnames, filenames in os.walk(soong_dir):
for filename in filenames:
if filename == expected_lsdump_name:
name, ext = os.path.splitext(filename)
sofile, soext = os.path.splitext(name)
if ext == SOURCE_ABI_DUMP_EXT_END and soext == SO_EXT :
path = os.path.join(base, filename)
if target_dir in os.path.dirname(path):
return path
return None
lsdump_paths.append(path)
return lsdump_paths
def run_abi_diff(old_test_dump_path, new_test_dump_path, arch, lib_name,
flags=[]):