1#!/usr/bin/env python3 2# 3# Copyright 2018, The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17"""Unittests for module_info_utils.""" 18 19import copy 20import os 21import subprocess 22import unittest 23from unittest import mock 24 25import aidegen.unittest_constants as uc 26from aidegen.lib import errors 27from aidegen.lib import module_info_util 28from atest import module_info 29 30 31_TEST_CLASS_DICT = {'class': ['JAVA_LIBRARIES']} 32_TEST_SRCS_BAR_DICT = {'srcs': ['Bar']} 33_TEST_SRCS_BAZ_DICT = {'srcs': ['Baz']} 34_TEST_DEP_FOO_DIST = {'dependencies': ['Foo']} 35_TEST_DEP_SRC_DICT = {'dependencies': ['Foo'], 'srcs': ['Bar']} 36_TEST_DEP_SRC_MORE_DICT = {'dependencies': ['Foo'], 'srcs': ['Baz', 'Bar']} 37_TEST_MODULE_A_DICT = { 38 'module_a': { 39 'class': ['JAVA_LIBRARIES'], 40 'path': ['path_a'], 41 'installed': ['out/path_a/a.jar'], 42 'dependencies': ['Foo'], 43 'srcs': ['Bar'] 44 } 45} 46_TEST_MODULE_A_DICT_HAS_NONEED_ITEMS = { 47 'module_a': { 48 'class': ['JAVA_LIBRARIES'], 49 'path': ['path_a'], 50 'installed': ['out/path_a/a.jar'], 51 'dependencies': ['Foo'], 52 'srcs': ['Bar'], 53 'compatibility_suites': ['null-suite'], 54 'module_name': ['ltp_fstat03_64'] 55 } 56} 57_TEST_MODULE_A_JOIN_PATH_DICT = { 58 'module_a': { 59 'class': ['JAVA_LIBRARIES'], 60 'path': ['path_a'], 61 'installed': ['out/path_a/a.jar'], 62 'dependencies': ['Foo'], 63 'srcs': ['path_a/Bar'] 64 } 65} 66 67 68# pylint: disable=protected-access 69# pylint: disable=invalid-name 70class AidegenModuleInfoUtilUnittests(unittest.TestCase): 71 """Unit tests for moduole_info_utils.py""" 72 73 def test_merge_module_keys_with_empty_dict(self): 74 """Test _merge_module_keys with an empty dictionary.""" 75 test_b_dict = {} 76 test_m_dict = copy.deepcopy(_TEST_DEP_SRC_DICT) 77 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 78 self.assertEqual(_TEST_DEP_SRC_DICT, test_m_dict) 79 80 def test_merge_module_keys_with_key_not_in_orginial_dict(self): 81 """Test _merge_module_keys with the key does not exist in the dictionary 82 to be merged into. 83 """ 84 test_b_dict = _TEST_SRCS_BAR_DICT 85 test_m_dict = copy.deepcopy(_TEST_DEP_FOO_DIST) 86 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 87 self.assertEqual(_TEST_DEP_SRC_DICT, test_m_dict) 88 89 def test_merge_module_keys_with_key_in_orginial_dict(self): 90 """Test _merge_module_keys with with the key exists in the dictionary 91 to be merged into. 92 """ 93 test_b_dict = _TEST_SRCS_BAZ_DICT 94 test_m_dict = copy.deepcopy(_TEST_DEP_SRC_DICT) 95 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 96 self.assertEqual( 97 set(_TEST_DEP_SRC_MORE_DICT['srcs']), set(test_m_dict['srcs'])) 98 self.assertEqual( 99 set(_TEST_DEP_SRC_MORE_DICT['dependencies']), 100 set(test_m_dict['dependencies'])) 101 102 def test_merge_module_keys_with_duplicated_item_dict(self): 103 """Test _merge_module_keys with with the key exists in the dictionary 104 to be merged into. 105 """ 106 test_b_dict = _TEST_CLASS_DICT 107 test_m_dict = copy.deepcopy(_TEST_CLASS_DICT) 108 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 109 self.assertEqual(_TEST_CLASS_DICT, test_m_dict) 110 111 def test_copy_needed_items_from_empty_dict(self): 112 """Test _copy_needed_items_from an empty dictionary.""" 113 test_mk_dict = {} 114 want_dict = {} 115 self.assertEqual(want_dict, 116 module_info_util._copy_needed_items_from(test_mk_dict)) 117 118 def test_copy_needed_items_from_all_needed_items_dict(self): 119 """Test _copy_needed_items_from a dictionary with all needed items.""" 120 self.assertEqual( 121 _TEST_MODULE_A_DICT, 122 module_info_util._copy_needed_items_from(_TEST_MODULE_A_DICT)) 123 124 def test_copy_needed_items_from_some_needed_items_dict(self): 125 """Test _copy_needed_items_from a dictionary with some needed items.""" 126 self.assertEqual( 127 _TEST_MODULE_A_DICT, 128 module_info_util._copy_needed_items_from( 129 _TEST_MODULE_A_DICT_HAS_NONEED_ITEMS)) 130 131 @mock.patch('subprocess.check_call') 132 @mock.patch('os.environ.copy') 133 def test_build_target_normal(self, mock_copy, mock_check_call): 134 """Test _build_target with verbose true and false.""" 135 mock_copy.return_value = '' 136 amodule_info = module_info.ModuleInfo() 137 cmd = [module_info_util._GENERATE_JSON_COMMAND] 138 module_info_util._build_target(cmd, uc.TEST_MODULE, amodule_info, True) 139 self.assertTrue(mock_copy.called) 140 self.assertTrue(mock_check_call.called) 141 mock_check_call.assert_called_with( 142 cmd, 143 stderr=subprocess.STDOUT, 144 env=mock_copy.return_value, 145 shell=True) 146 module_info_util._build_target(cmd, uc.TEST_MODULE, amodule_info, False) 147 self.assertTrue(mock_check_call.called) 148 mock_check_call.assert_called_with(cmd, shell=True) 149 150 @mock.patch('os.path.getmtime') 151 @mock.patch('os.path.isfile') 152 def test_is_new_json_file_generated(self, mock_isfile, mock_getmtime): 153 """Test _is_new_json_file_generated with different situations.""" 154 jfile = 'path/test.json' 155 mock_isfile.return_value = True 156 self.assertEqual( 157 mock_isfile.return_value, 158 module_info_util._is_new_json_file_generated(jfile, None)) 159 mock_isfile.return_value = False 160 self.assertEqual( 161 mock_isfile.return_value, 162 module_info_util._is_new_json_file_generated(jfile, None)) 163 original_file_mtime = 1000 164 mock_getmtime.return_value = original_file_mtime 165 self.assertEqual( 166 False, 167 module_info_util._is_new_json_file_generated( 168 jfile, original_file_mtime)) 169 mock_getmtime.return_value = 1001 170 self.assertEqual( 171 True, 172 module_info_util._is_new_json_file_generated( 173 jfile, original_file_mtime)) 174 175 @mock.patch('builtins.input') 176 @mock.patch('glob.glob') 177 def test_build_failed_handle(self, mock_glob, mock_input): 178 """Test _build_failed_handle with different situations.""" 179 mock_glob.return_value = ['project/file.iml'] 180 mock_input.return_value = 'N' 181 with self.assertRaises(SystemExit) as cm: 182 module_info_util._build_failed_handle(uc.TEST_MODULE) 183 self.assertEqual(cm.exception.code, 1) 184 mock_glob.return_value = [] 185 with self.assertRaises(errors.BuildFailureError): 186 module_info_util._build_failed_handle(uc.TEST_MODULE) 187 188 @mock.patch('builtins.open') 189 def test_get_soong_build_json_dict_failed(self, mock_open): 190 """Test _get_soong_build_json_dict failure and raise error.""" 191 mock_open.side_effect = IOError 192 with self.assertRaises(errors.JsonFileNotExistError): 193 module_info_util._get_soong_build_json_dict() 194 195 @mock.patch('aidegen.lib.module_info_util._build_failed_handle') 196 @mock.patch('aidegen.lib.module_info_util._is_new_json_file_generated') 197 @mock.patch('subprocess.check_call') 198 def test_build_target(self, mock_call, mock_new, mock_handle): 199 """Test _build_target with different arguments.""" 200 cmd = [module_info_util._GENERATE_JSON_COMMAND] 201 main_project = '' 202 amodule_info = {} 203 verbose = False 204 module_info_util._build_target(cmd, main_project, amodule_info, verbose) 205 mock_call.assert_called_with(cmd, shell=True) 206 verbose = True 207 full_env_vars = os.environ.copy() 208 module_info_util._build_target(cmd, main_project, amodule_info, verbose) 209 mock_call.assert_called_with(cmd, stderr=subprocess.STDOUT, 210 env=full_env_vars, shell=True) 211 mock_call.side_effect = subprocess.CalledProcessError(1, '') 212 mock_new.return_value = False 213 module_info_util._build_target(cmd, main_project, amodule_info, verbose) 214 self.assertTrue(mock_new.called) 215 self.assertFalse(mock_handle.called) 216 mock_new.return_value = True 217 module_info_util._build_target(cmd, main_project, amodule_info, verbose) 218 self.assertTrue(mock_new.called) 219 self.assertTrue(mock_handle.called) 220 221 222if __name__ == '__main__': 223 unittest.main() 224