You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
15 KiB
375 lines
15 KiB
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2019, The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Unittests for native_module_info."""
|
|
|
|
import logging
|
|
import os
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from aidegen import constant
|
|
from aidegen.lib import common_util
|
|
from aidegen.lib import module_info
|
|
from aidegen.lib import native_module_info
|
|
|
|
import atest
|
|
|
|
_PATH_TO_MULT_MODULES_WITH_MULTI_ARCH = 'shared/path/to/be/used2'
|
|
_TESTABLE_MODULES_WITH_SHARED_PATH = [
|
|
'multiarch', 'multiarch1', 'multiarch2', 'multiarch3', 'multiarch3_32'
|
|
]
|
|
_REBUILD_TARGET1 = 'android.frameworks.bufferhub@1.0'
|
|
_NATIVE_INCLUDES1 = [
|
|
'frameworks/native/include',
|
|
'frameworks/native/libs/ui',
|
|
'out/soong/.intermediates/' + _REBUILD_TARGET1 + '_genc++_headers/gen'
|
|
]
|
|
_CC_NAME_TO_MODULE_INFO = {
|
|
'multiarch': {
|
|
'path': [
|
|
'shared/path/to/be/used2'
|
|
],
|
|
'srcs': [
|
|
'shared/path/to/be/used2/multiarch.cpp',
|
|
'out/soong/.intermediates/shared/path/to/be/used2/gen/Iarch.cpp'
|
|
],
|
|
'local_common_flags': {
|
|
constant.KEY_HEADER: _NATIVE_INCLUDES1
|
|
},
|
|
'module_name': 'multiarch'
|
|
},
|
|
'multiarch1': {
|
|
'path': [
|
|
'shared/path/to/be/used2/arch1'
|
|
],
|
|
'module_name': 'multiarch1'
|
|
},
|
|
'multiarch2': {
|
|
'path': [
|
|
'shared/path/to/be/used2/arch2'
|
|
],
|
|
'module_name': 'multiarch2'
|
|
},
|
|
'multiarch3': {
|
|
'path': [
|
|
'shared/path/to/be/used2/arch3'
|
|
],
|
|
'module_name': 'multiarch3'
|
|
},
|
|
'multiarch3_32': {
|
|
'path': [
|
|
'shared/path/to/be/used2/arch3_32'
|
|
],
|
|
'module_name': 'multiarch3_32'
|
|
},
|
|
_REBUILD_TARGET1: {
|
|
'path': [
|
|
'/path/to/rebuild'
|
|
],
|
|
'module_name': _REBUILD_TARGET1
|
|
},
|
|
'multiarch-eng': {
|
|
'path': [
|
|
'shared/path/to/be/used2-eng'
|
|
],
|
|
'srcs': [
|
|
'shared/path/to/be/used2/multiarch-eng.cpp',
|
|
'out/soong/.intermediates/shared/path/to/be/used2/gen/Iarch-eng.cpp'
|
|
],
|
|
'module_name': 'multiarch-eng'
|
|
}
|
|
}
|
|
_CC_MODULE_INFO = {
|
|
'clang': '${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/bin/clang',
|
|
'clang++': '${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/bin/clang++',
|
|
'modules': _CC_NAME_TO_MODULE_INFO
|
|
}
|
|
|
|
|
|
# pylint: disable=protected-access
|
|
class NativeModuleInfoUnittests(unittest.TestCase):
|
|
"""Unit tests for module_info.py"""
|
|
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
@mock.patch.object(common_util, 'get_related_paths')
|
|
def test_get_module_names_in_targets_paths(self, mock_relpath, mock_load):
|
|
"""Test get_module_names_in_targets_paths handling."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mock_relpath.return_value = (_PATH_TO_MULT_MODULES_WITH_MULTI_ARCH, '')
|
|
result = mod_info.get_module_names_in_targets_paths(['multiarch'])
|
|
self.assertEqual(_TESTABLE_MODULES_WITH_SHARED_PATH, result)
|
|
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_get_module_includes_empty(self, mock_load):
|
|
"""Test get_module_includes without include paths."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
result = mod_info.get_module_includes('multiarch1')
|
|
self.assertEqual(set(), result)
|
|
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_get_module_includes_not_empty(self, mock_load):
|
|
"""Test get_module_includes with include paths."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mod_info.name_to_module_info = _CC_NAME_TO_MODULE_INFO
|
|
result = mod_info.get_module_includes('multiarch')
|
|
self.assertEqual(set(_NATIVE_INCLUDES1), result)
|
|
|
|
@mock.patch.object(logging, 'warning')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_module_need_build_without_mod_info(self, mock_load, mock_warn):
|
|
"""Test get_module_includes without module info."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
self.assertFalse(mod_info.is_module_need_build('test_multiarch'))
|
|
self.assertTrue(mock_warn.called)
|
|
|
|
@mock.patch.object(logging, 'warning')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_module_need_build_with_mod_info(self, mock_load, mock_warn):
|
|
"""Test get_module_includes with module info."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
self.assertFalse(mod_info.is_module_need_build('multiarch1'))
|
|
self.assertFalse(mock_warn.called)
|
|
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_include_need_build')
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_source_need_build')
|
|
@mock.patch.object(logging, 'warning')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_module_need_build_with_src_needs(
|
|
self, mock_load, mock_warn, mock_src_need, mock_inc_need):
|
|
"""Test get_module_includes with needed build source modules."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mock_src_need.return_value = True
|
|
mock_inc_need.return_value = False
|
|
self.assertTrue(mod_info.is_module_need_build('multiarch'))
|
|
self.assertFalse(mock_warn.called)
|
|
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_include_need_build')
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_source_need_build')
|
|
@mock.patch.object(logging, 'warning')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_module_need_build_with_inc_needs(
|
|
self, mock_load, mock_warn, mock_src_need, mock_inc_need):
|
|
"""Test get_module_includes with needed build include modules."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mock_src_need.return_value = False
|
|
mock_inc_need.return_value = True
|
|
self.assertTrue(mod_info.is_module_need_build('multiarch'))
|
|
self.assertFalse(mock_warn.called)
|
|
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_include_need_build')
|
|
@mock.patch.object(native_module_info.NativeModuleInfo,
|
|
'_is_source_need_build')
|
|
@mock.patch.object(logging, 'warning')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_module_need_build_without_needs(
|
|
self, mock_load, mock_warn, mock_src_need, mock_inc_need):
|
|
"""Test get_module_includes without needs."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mock_src_need.return_value = False
|
|
mock_inc_need.return_value = False
|
|
self.assertFalse(mod_info.is_module_need_build('multiarch1'))
|
|
self.assertFalse(mock_warn.called)
|
|
|
|
@mock.patch.object(os.path, 'isfile')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_source_need_build_return_true(self, mock_load, mock_isfile):
|
|
"""Test _is_source_need_build with source paths or not existing."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
mock_isfile.return_value = False
|
|
self.assertTrue(mod_info._is_source_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch']))
|
|
|
|
@mock.patch.object(os.path, 'isfile')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_source_need_build_return_false(self, mock_load, mock_isfile):
|
|
"""Test _is_source_need_build without source paths or paths exist."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
self.assertFalse(mod_info._is_source_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch1']))
|
|
mock_isfile.return_value = True
|
|
self.assertFalse(mod_info._is_source_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch']))
|
|
|
|
@mock.patch.object(os.path, 'isdir')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_include_need_build_return_true(self, mock_load, mock_isdir):
|
|
"""Test _is_include_need_build with include paths and not existing."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mock_isdir.return_value = False
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
self.assertTrue(mod_info._is_include_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch']))
|
|
|
|
@mock.patch.object(os.path, 'isdir')
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_is_include_need_build_return_false(self, mock_load, mock_isdir):
|
|
"""Test _is_include_need_build without include paths or paths exist."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
self.assertFalse(mod_info._is_include_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch1']))
|
|
mock_isdir.return_value = True
|
|
self.assertFalse(mod_info._is_include_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch']))
|
|
mock_isdir.return_value = True
|
|
self.assertFalse(mod_info._is_include_need_build(
|
|
_CC_NAME_TO_MODULE_INFO['multiarch']))
|
|
|
|
def test_not_implemented_methods(self):
|
|
"""Test not implemented methods."""
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
target = 'test'
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.get_testable_modules()
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.is_testable_module(mock.Mock())
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.has_test_config(mock.Mock())
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.get_robolectric_test_name(target)
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.is_robolectric_test(target)
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.is_auto_gen_test_config(target)
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.is_robolectric_module(mock.Mock())
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.is_native_test(target)
|
|
|
|
@mock.patch.object(
|
|
native_module_info.NativeModuleInfo, '_load_module_info_file')
|
|
def test_not_implement_methods_check(self, mock_load):
|
|
"""Test for all not implemented methods which should raise error."""
|
|
mock_load.return_value = None, _CC_NAME_TO_MODULE_INFO
|
|
mod_info = native_module_info.NativeModuleInfo()
|
|
with self.assertRaises(NotImplementedError):
|
|
suite_name = 'test'
|
|
test_data = {'a': 'test'}
|
|
mod_info.is_suite_in_compatibility_suites(suite_name, test_data)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
mod_info.get_testable_modules()
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_data = {'a': 'test'}
|
|
mod_info.is_testable_module(test_data)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_data = {'a': 'test'}
|
|
mod_info.has_test_config(test_data)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_mod = 'mod_a'
|
|
mod_info.get_robolectric_test_name(test_mod)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_mod = 'mod_a'
|
|
mod_info.is_robolectric_test(test_mod)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_mod = 'a'
|
|
mod_info.is_auto_gen_test_config(test_mod)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_data = {'a': 'test'}
|
|
mod_info.is_robolectric_module(test_data)
|
|
|
|
with self.assertRaises(NotImplementedError):
|
|
test_mod = 'a'
|
|
mod_info.is_native_test(test_mod)
|
|
|
|
@mock.patch.object(atest.module_info.ModuleInfo, '_load_module_info_file')
|
|
@mock.patch.object(os.path, 'isfile')
|
|
@mock.patch.object(common_util, 'get_json_dict')
|
|
@mock.patch.object(module_info.AidegenModuleInfo,
|
|
'_discover_mod_file_and_target')
|
|
@mock.patch.object(common_util, 'get_blueprint_json_path')
|
|
def test_load_module_info_file(self, mock_get_json, mock_load, mock_dict,
|
|
mock_isfile, mock_base_load):
|
|
"""Test _load_module_info_file."""
|
|
force_build = True
|
|
mod_file = '/test/path'
|
|
mock_get_json.return_value = mod_file
|
|
native_module_info.NativeModuleInfo(force_build)
|
|
self.assertTrue(mock_get_json.called_with(
|
|
constant.BLUEPRINT_CC_JSONFILE_NAME))
|
|
mock_load.return_value = mod_file, mod_file
|
|
self.assertTrue(mock_load.called_with(True))
|
|
mock_dict.return_value = _CC_MODULE_INFO
|
|
self.assertTrue(mock_dict.called_with(mod_file))
|
|
self.assertFalse(mock_base_load.called)
|
|
mock_base_load.reset_mock()
|
|
mock_get_json.reset_mock()
|
|
mock_load.reset_mock()
|
|
mock_dict.reset_mock()
|
|
|
|
native_module_info.NativeModuleInfo(force_build, mod_file)
|
|
self.assertFalse(mock_get_json.called)
|
|
mock_load.return_value = None, mod_file
|
|
self.assertTrue(mock_load.called_with(True))
|
|
self.assertTrue(mock_dict.called_with(mod_file))
|
|
self.assertFalse(mock_base_load.called)
|
|
mock_base_load.reset_mock()
|
|
mock_get_json.reset_mock()
|
|
mock_load.reset_mock()
|
|
mock_dict.reset_mock()
|
|
|
|
force_build = False
|
|
mock_get_json.return_value = mod_file
|
|
native_module_info.NativeModuleInfo(force_build, mod_file)
|
|
self.assertFalse(mock_get_json.called)
|
|
mock_isfile.return_value = True
|
|
self.assertFalse(mock_load.called)
|
|
mock_dict.return_value = _CC_MODULE_INFO
|
|
self.assertTrue(mock_dict.called_with(mod_file))
|
|
self.assertFalse(mock_base_load.called)
|
|
mock_base_load.reset_mock()
|
|
mock_get_json.reset_mock()
|
|
mock_load.reset_mock()
|
|
mock_dict.reset_mock()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|