blob: 7f9c63b00a77793e3a3c03d60220f8ca78894030 [file] [log] [blame]
#!/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
}
}
_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()
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('native_module_info.NativeModuleInfo._is_include_need_build')
@mock.patch('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('native_module_info.NativeModuleInfo._is_include_need_build')
@mock.patch('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('native_module_info.NativeModuleInfo._is_include_need_build')
@mock.patch('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']))
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()