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 logging 21import os.path 22import unittest 23from unittest import mock 24 25from aidegen import aidegen_main 26from aidegen import unittest_constants 27from aidegen.lib import common_util 28from aidegen.lib import errors 29from aidegen.lib import module_info_util 30from aidegen.lib import project_config 31 32from atest import atest_utils 33 34_TEST_CLASS_DICT = {'class': ['JAVA_LIBRARIES']} 35_TEST_SRCS_BAR_DICT = {'srcs': ['Bar']} 36_TEST_SRCS_BAZ_DICT = {'srcs': ['Baz']} 37_TEST_DEP_FOO_DIST = {'dependencies': ['Foo']} 38_TEST_DEP_SRC_DICT = {'dependencies': ['Foo'], 'srcs': ['Bar']} 39_TEST_DEP_SRC_MORE_DICT = {'dependencies': ['Foo'], 'srcs': ['Baz', 'Bar']} 40_TEST_MODULE_A_DICT = { 41 'module_a': { 42 'class': ['JAVA_LIBRARIES'], 43 'path': ['path_a'], 44 'installed': ['out/path_a/a.jar'], 45 'dependencies': ['Foo'], 46 'srcs': ['Bar'], 47 'compatibility_suites': ['null-suite'], 48 'module_name': ['ltp_fstat03_64'] 49 } 50} 51_TEST_MODULE_A_DICT_HAS_NONEED_ITEMS = { 52 'module_a': { 53 'class': ['JAVA_LIBRARIES'], 54 'path': ['path_a'], 55 'installed': ['out/path_a/a.jar'], 56 'dependencies': ['Foo'], 57 'srcs': ['Bar'], 58 'compatibility_suites': ['null-suite'], 59 'module_name': ['ltp_fstat03_64'] 60 } 61} 62_TEST_MODULE_A_JOIN_PATH_DICT = { 63 'module_a': { 64 'class': ['JAVA_LIBRARIES'], 65 'path': ['path_a'], 66 'installed': ['out/path_a/a.jar'], 67 'dependencies': ['Foo'], 68 'srcs': ['path_a/Bar'] 69 } 70} 71 72 73# pylint: disable=invalid-name 74# pylint: disable=protected-access 75class AidegenModuleInfoUtilUnittests(unittest.TestCase): 76 """Unit tests for module_info_utils.py""" 77 78 @mock.patch.object(os.path, 'getmtime') 79 @mock.patch.object(logging, 'info') 80 @mock.patch.object(os.path, 'isfile') 81 @mock.patch.object(module_info_util, '_get_generated_json_files') 82 def test_of_build_bp_info_reuse_jsons(self, mock_json, mock_isfile, 83 mock_log, mock_time): 84 """Test of _build_bp_info to well reuse existing files.""" 85 gen_files = ['file1', 'file_a', 'file_b'] 86 mock_json.return_value = gen_files 87 # Test of the well reuse existing files. 88 mock_isfile.side_effect = (True, True, True) 89 mod_info = mock.MagicMock() 90 module_info_util._build_bp_info(mod_info, skip_build=True) 91 self.assertTrue(mock_json.called) 92 self.assertTrue(mock_log.called) 93 self.assertFalse(mock_time.called) 94 95 # pylint: disable=too-many-arguments 96 @mock.patch.object(module_info_util, '_generate_rust_project_link') 97 @mock.patch.object(module_info_util, '_show_build_failed_message') 98 @mock.patch.object(module_info_util, '_show_files_reuse_message') 99 @mock.patch.object(atest_utils, 'build') 100 @mock.patch.object(os.path, 'getmtime') 101 @mock.patch.object(logging, 'warning') 102 @mock.patch.object(os.path, 'isfile') 103 @mock.patch.object(module_info_util, '_get_generated_json_files') 104 def test_of_build_bp_info_rebuild_jsons(self, mock_json, mock_isfile, 105 mock_log, mock_time, mock_build, 106 mock_reuse, mock_fail, 107 mock_gen_rust): 108 """Test of _build_bp_info on rebuilding jsons.""" 109 gen_files = ['file2', 'file_a', 'file_b'] 110 mock_json.return_value = gen_files 111 mod_info = mock.MagicMock() 112 # Test of the existing files can't reuse. 113 mock_json.return_value = gen_files 114 mock_isfile.side_effect = (True, False, True) 115 mock_time.side_effect = (None, None, None) 116 mock_build.side_effect = (True, True) 117 module_info_util._build_bp_info(mod_info, skip_build=True) 118 self.assertTrue(mock_json.called) 119 self.assertTrue(mock_log.called) 120 self.assertTrue(mock_gen_rust.called) 121 122 # Test of the well rebuild case. 123 action_pass = '\nGenerate blueprint json successfully.' 124 self.assertTrue(mock_build.called) 125 self.assertTrue(mock_log.called_with(action_pass)) 126 self.assertFalse(mock_reuse.called) 127 self.assertFalse(mock_fail.called) 128 129 @mock.patch.object(module_info_util, '_generate_rust_project_link') 130 @mock.patch.object(module_info_util, '_show_build_failed_message') 131 @mock.patch.object(module_info_util, '_show_files_reuse_message') 132 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 133 @mock.patch.object(atest_utils, 'build') 134 @mock.patch.object(os.path, 'getmtime') 135 @mock.patch.object(logging, 'warning') 136 @mock.patch.object(os.path, 'isfile') 137 @mock.patch.object(module_info_util, '_get_generated_json_files') 138 def test_of_build_bp_info_show_build_fail(self, mock_json, mock_isfile, 139 mock_log, mock_time, mock_build, 140 mock_judge, mock_reuse, 141 mock_fail, mock_gen_rust): 142 """Test of _build_bp_info to show build failed message.""" 143 gen_files = ['file3', 'file_a', 'file_b'] 144 mock_json.return_value = gen_files 145 mod_info = mock.MagicMock() 146 # Test rebuild failed case - show build fail message. 147 mock_json.return_value = gen_files 148 test_prj = 'main' 149 mock_isfile.side_effect = (True, False, True) 150 mock_time.side_effect = (None, None, None) 151 mock_build.side_effect = (True, False) 152 mock_judge.side_effect = [True, False, False] 153 module_info_util._build_bp_info(mod_info, main_project=test_prj, 154 skip_build=False) 155 self.assertTrue(mock_json.called) 156 self.assertTrue(mock_log.called) 157 self.assertTrue(mock_build.called) 158 self.assertTrue(mock_gen_rust.called) 159 self.assertFalse(mock_reuse.called) 160 self.assertFalse(mock_fail.called) 161 162 @mock.patch.object(module_info_util, '_generate_rust_project_link') 163 @mock.patch.object(module_info_util, '_show_build_failed_message') 164 @mock.patch.object(module_info_util, '_show_files_reuse_message') 165 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 166 @mock.patch.object(atest_utils, 'build') 167 @mock.patch.object(os.path, 'getmtime') 168 @mock.patch.object(logging, 'warning') 169 @mock.patch.object(os.path, 'isfile') 170 @mock.patch.object(module_info_util, '_get_generated_json_files') 171 def test_of_build_bp_info_rebuild_and_reuse(self, mock_json, mock_isfile, 172 mock_log, mock_time, mock_build, 173 mock_judge, mock_reuse, 174 mock_fail, mock_gen_rust): 175 """Test of _build_bp_info to reuse existing jsons.""" 176 gen_files = ['file4', 'file_a', 'file_b'] 177 mock_json.return_value = gen_files 178 mod_info = mock.MagicMock() 179 mock_json.return_value = gen_files 180 test_prj = 'main' 181 # Test rebuild failed case - show reuse message. 182 mock_isfile.side_effect = (True, True, True) 183 mock_time.side_effect = (None, None, None) 184 mock_build.side_effect = (True, False) 185 mock_judge.side_effect = [True, False, True] 186 module_info_util._build_bp_info( 187 mod_info, main_project=test_prj, skip_build=False) 188 self.assertTrue(mock_log.called) 189 self.assertTrue(mock_gen_rust.called) 190 self.assertFalse(mock_reuse.called) 191 self.assertFalse(mock_fail.called) 192 193 @mock.patch.object(module_info_util, '_generate_rust_project_link') 194 @mock.patch.object(module_info_util, '_show_build_failed_message') 195 @mock.patch.object(module_info_util, '_show_files_reuse_message') 196 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 197 @mock.patch.object(atest_utils, 'build') 198 @mock.patch.object(os.path, 'getmtime') 199 @mock.patch.object(logging, 'warning') 200 @mock.patch.object(os.path, 'isfile') 201 @mock.patch.object(module_info_util, '_get_generated_json_files') 202 def test_of_build_bp_info_reuse_pass(self, mock_json, mock_isfile, mock_log, 203 mock_time, mock_build, mock_judge, 204 mock_reuse, mock_fail, mock_gen_rust): 205 """Test of _build_bp_info reuse pass.""" 206 gen_files = ['file5', 'file_a', 'file_b'] 207 mock_json.return_value = gen_files 208 test_prj = 'main' 209 mod_info = mock.MagicMock() 210 # Test rebuild failed case - show nothing. 211 mock_isfile.side_effect = (False, True, True) 212 mock_time.side_effect = (None, None, None) 213 mock_build.side_effect = (True, False) 214 mock_judge.side_effect = [True, True, True] 215 module_info_util._build_bp_info(mod_info, main_project=test_prj, 216 skip_build=False) 217 self.assertTrue(mock_log.called) 218 self.assertTrue(mock_gen_rust.called) 219 self.assertFalse(mock_reuse.called) 220 self.assertFalse(mock_fail.called) 221 222 # pylint: enable=too-many-arguments 223 def test_merge_module_keys_with_empty_dict(self): 224 """Test _merge_module_keys with an empty dictionary.""" 225 test_b_dict = {} 226 test_m_dict = copy.deepcopy(_TEST_DEP_SRC_DICT) 227 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 228 self.assertEqual(_TEST_DEP_SRC_DICT, test_m_dict) 229 230 def test_merge_module_keys_with_key_not_in_original_dict(self): 231 """Test _merge_module_keys with the key does not exist in the dictionary 232 to be merged into. 233 """ 234 test_b_dict = _TEST_SRCS_BAR_DICT 235 test_m_dict = copy.deepcopy(_TEST_DEP_FOO_DIST) 236 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 237 self.assertEqual(_TEST_DEP_SRC_DICT, test_m_dict) 238 239 def test_merge_module_keys_with_key_in_original_dict(self): 240 """Test _merge_module_keys with the key exists in the dictionary 241 to be merged into. 242 """ 243 test_b_dict = _TEST_SRCS_BAZ_DICT 244 test_m_dict = copy.deepcopy(_TEST_DEP_SRC_DICT) 245 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 246 self.assertEqual( 247 set(_TEST_DEP_SRC_MORE_DICT['srcs']), set(test_m_dict['srcs'])) 248 self.assertEqual( 249 set(_TEST_DEP_SRC_MORE_DICT['dependencies']), 250 set(test_m_dict['dependencies'])) 251 252 def test_merge_module_keys_with_duplicated_item_dict(self): 253 """Test _merge_module_keys with the key exists in the dictionary 254 to be merged into. 255 """ 256 test_b_dict = _TEST_CLASS_DICT 257 test_m_dict = copy.deepcopy(_TEST_CLASS_DICT) 258 module_info_util._merge_module_keys(test_m_dict, test_b_dict) 259 self.assertEqual(_TEST_CLASS_DICT, test_m_dict) 260 261 def test_copy_needed_items_from_empty_dict(self): 262 """Test _copy_needed_items_from an empty dictionary.""" 263 test_mk_dict = {} 264 want_dict = {} 265 self.assertEqual(want_dict, 266 module_info_util._copy_needed_items_from(test_mk_dict)) 267 268 def test_copy_needed_items_from_all_needed_items_dict(self): 269 """Test _copy_needed_items_from a dictionary with all needed items.""" 270 self.assertEqual( 271 _TEST_MODULE_A_DICT, 272 module_info_util._copy_needed_items_from(_TEST_MODULE_A_DICT)) 273 274 def test_copy_needed_items_from_some_needed_items_dict(self): 275 """Test _copy_needed_items_from a dictionary with some needed items.""" 276 self.assertEqual( 277 _TEST_MODULE_A_DICT, 278 module_info_util._copy_needed_items_from( 279 _TEST_MODULE_A_DICT_HAS_NONEED_ITEMS)) 280 281 @mock.patch.object(os.path, 'getmtime') 282 @mock.patch.object(atest_utils, 'build') 283 @mock.patch('os.path.isfile') 284 def test_build_bp_info_normal(self, mock_isfile, mock_build, mock_time): 285 """Test _build_target with verbose true and false.""" 286 amodule_info = mock.MagicMock() 287 skip = True 288 mock_isfile.return_value = True 289 mock_build.return_value = True 290 module_info_util._build_bp_info(amodule_info, unittest_constants. 291 TEST_MODULE, False, skip) 292 self.assertFalse(mock_build.called) 293 skip = False 294 mock_time.return_value = float() 295 module_info_util._build_bp_info(amodule_info, unittest_constants. 296 TEST_MODULE, False, skip) 297 self.assertTrue(mock_time.called) 298 self.assertEqual(mock_build.call_count, 1) 299 300 @mock.patch('os.path.getmtime') 301 @mock.patch('os.path.isfile') 302 def test_is_new_json_file_generated(self, mock_isfile, mock_getmtime): 303 """Test _is_new_json_file_generated with different situations.""" 304 jfile = 'path/test.json' 305 mock_isfile.return_value = False 306 self.assertFalse( 307 module_info_util._is_new_json_file_generated(jfile, None)) 308 mock_isfile.return_value = True 309 self.assertTrue( 310 module_info_util._is_new_json_file_generated(jfile, None)) 311 original_file_mtime = 1000 312 mock_getmtime.return_value = original_file_mtime 313 self.assertFalse( 314 module_info_util._is_new_json_file_generated( 315 jfile, original_file_mtime)) 316 mock_getmtime.return_value = 1001 317 self.assertTrue( 318 module_info_util._is_new_json_file_generated( 319 jfile, original_file_mtime)) 320 321 @mock.patch('builtins.input') 322 @mock.patch('glob.glob') 323 def test_build_failed_handle(self, mock_glob, mock_input): 324 """Test _build_failed_handle with different situations.""" 325 mock_glob.return_value = ['project/file.iml'] 326 mock_input.return_value = 'N' 327 with self.assertRaises(SystemExit) as cm: 328 module_info_util._build_failed_handle( 329 unittest_constants.TEST_MODULE) 330 self.assertEqual(cm.exception.code, 1) 331 mock_glob.return_value = [] 332 with self.assertRaises(errors.BuildFailureError): 333 module_info_util._build_failed_handle( 334 unittest_constants.TEST_MODULE) 335 336 @mock.patch.object(project_config.ProjectConfig, 'get_instance') 337 @mock.patch.object(module_info_util, '_merge_dict') 338 @mock.patch.object(common_util, 'get_json_dict') 339 @mock.patch.object(module_info_util, '_build_bp_info') 340 def test_generate_merged_module_info( 341 self, mock_build, mock_get_soong, mock_merge_dict, mock_get_inst): 342 """Test generate_merged_module_info function.""" 343 config = mock.MagicMock() 344 config.atest_module_info = mock.MagicMock() 345 main_project = 'tradefed' 346 args = aidegen_main._parse_args([main_project, '-n', '-v']) 347 config.targets = args.targets 348 config.verbose = args.verbose 349 config.is_skip_build = args.skip_build 350 module_info_util.generate_merged_module_info() 351 self.assertTrue(mock_get_inst.called) 352 self.assertTrue(mock_build.called) 353 self.assertTrue(mock_get_soong.called) 354 self.assertTrue(mock_merge_dict.called) 355 356 @mock.patch.object(common_util, 'get_blueprint_json_files_relative_dict') 357 def test_get_generated_json_files(self, mock_get_bp_dict): 358 """Test _get_generated_json_files function with conditions.""" 359 a_env = 'GEN_A' 360 b_env = 'GEN_B' 361 a_file_path = 'a/b/path/to/a_file' 362 b_file_path = 'a/b/path/to/b_file' 363 file_paths = [a_file_path, b_file_path] 364 env_on = {a_env: 'true', b_env: 'true'} 365 mock_get_bp_dict.return_value = {a_env: a_file_path, b_env: b_file_path} 366 result_paths = file_paths 367 self.assertEqual( 368 result_paths, module_info_util._get_generated_json_files(env_on)) 369 result_paths = [] 370 env_on = {a_env: 'false', b_env: 'false'} 371 self.assertEqual( 372 result_paths, module_info_util._get_generated_json_files(env_on)) 373 c_env = 'GEN_C' 374 d_env = 'GEN_D' 375 c_file_path = 'a/b/path/to/d_file' 376 d_file_path = 'a/b/path/to/d_file' 377 env_on = {a_env: 'true', b_env: 'true'} 378 mock_get_bp_dict.return_value = {c_env: c_file_path, d_env: d_file_path} 379 result_paths = [] 380 self.assertEqual( 381 result_paths, module_info_util._get_generated_json_files(env_on)) 382 383 @mock.patch.object(common_util, 'get_related_paths') 384 @mock.patch.object(module_info_util, '_build_failed_handle') 385 def test_show_build_failed_message( 386 self, mock_handle, mock_relpath): 387 """Test _show_build_failed_message with different conditions.""" 388 main_project = '' 389 mock_relpath.return_value = 'c/d', 'a/b/c/d' 390 module_info_util._show_build_failed_message({}, main_project) 391 self.assertFalse(mock_handle.called) 392 main_project = 'tradefed' 393 module_info_util._show_build_failed_message({}, main_project) 394 self.assertTrue(mock_handle.called) 395 396 # pylint: disable=too-many-arguments 397 @mock.patch.object(module_info_util, '_show_build_failed_message') 398 @mock.patch.object(module_info_util, '_show_files_reuse_message') 399 @mock.patch.object(logging, 'warning') 400 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 401 @mock.patch.object(atest_utils, 'build') 402 @mock.patch.object(os.path, 'getmtime') 403 @mock.patch.object(logging, 'info') 404 @mock.patch.object(os.path, 'isfile') 405 @mock.patch.object(module_info_util, '_get_generated_json_files') 406 def test_build_bp_info_skip(self, mock_gen_jsons, mock_isfile, 407 mock_log_info, mock_get_mtimes, mock_build, 408 mock_news, mock_warn, mock_show_reuse, 409 mock_build_fail): 410 """Test _build_bp_info function with skip build.""" 411 mock_gen_jsons.return_value = [ 412 'a/b/out/soong/module_bp_java_deps.json', 413 'a/b/out/soong/module_bp_cc_deps.json' 414 ] 415 mock_isfile.return_value = True 416 module_info_util._build_bp_info( 417 module_info=mock.Mock(), skip_build=True) 418 self.assertTrue(mock_log_info.called) 419 self.assertFalse(mock_get_mtimes.called) 420 self.assertFalse(mock_build.called) 421 self.assertFalse(mock_news.called) 422 self.assertFalse(mock_warn.called) 423 self.assertFalse(mock_show_reuse.called) 424 self.assertFalse(mock_build_fail.called) 425 426 @mock.patch.object(module_info_util, '_show_build_failed_message') 427 @mock.patch.object(module_info_util, '_show_files_reuse_message') 428 @mock.patch.object(logging, 'warning') 429 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 430 @mock.patch.object(atest_utils, 'build') 431 @mock.patch.object(os.path, 'getmtime') 432 @mock.patch.object(logging, 'info') 433 @mock.patch.object(os.path, 'isfile') 434 @mock.patch.object(module_info_util, '_get_generated_json_files') 435 def test_build_bp_info_no_skip(self, mock_gen_jsons, mock_isfile, 436 mock_log_info, mock_get_mtimes, mock_build, 437 mock_news, mock_warn, mock_show_reuse, 438 mock_build_fail): 439 """Test _build_bp_info function without skip build.""" 440 mock_gen_jsons.return_value = [ 441 'a/b/out/soong/module_bp_java_deps.json', 442 'a/b/out/soong/module_bp_cc_deps.json' 443 ] 444 mock_isfile.return_value = True 445 mock_build.return_value = True 446 module_info_util._build_bp_info( 447 module_info=mock.Mock(), skip_build=False) 448 self.assertTrue(mock_log_info.called) 449 self.assertTrue(mock_get_mtimes.called) 450 self.assertTrue(mock_build.called) 451 self.assertFalse(mock_news.called) 452 self.assertTrue(mock_warn.called) 453 self.assertFalse(mock_show_reuse.called) 454 self.assertFalse(mock_build_fail.called) 455 456 @mock.patch.object(module_info_util, '_show_build_failed_message') 457 @mock.patch.object(module_info_util, '_show_files_reuse_message') 458 @mock.patch.object(logging, 'warning') 459 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 460 @mock.patch.object(atest_utils, 'build') 461 @mock.patch.object(os.path, 'getmtime') 462 @mock.patch.object(logging, 'info') 463 @mock.patch.object(os.path, 'isfile') 464 @mock.patch.object(module_info_util, '_get_generated_json_files') 465 def test_build_bp_info_failed(self, mock_gen_jsons, mock_isfile, 466 mock_log_info, mock_get_mtimes, mock_build, 467 mock_news, mock_warn, mock_show_reuse, 468 mock_build_fail): 469 """Test _build_bp_info function with build failed.""" 470 mock_gen_jsons.return_value = [ 471 'a/b/out/soong/module_bp_java_deps.json', 472 'a/b/out/soong/module_bp_cc_deps.json' 473 ] 474 mock_isfile.return_value = True 475 mock_build.return_value = False 476 mock_news.return_value = False 477 module_info_util._build_bp_info( 478 module_info=mock.Mock(), skip_build=False) 479 self.assertFalse(mock_log_info.called) 480 self.assertTrue(mock_get_mtimes.called) 481 self.assertTrue(mock_build.called) 482 self.assertTrue(mock_news.called) 483 self.assertTrue(mock_warn.called) 484 self.assertTrue(mock_show_reuse.called) 485 self.assertFalse(mock_build_fail.called) 486 487 @mock.patch.object(module_info_util, '_show_build_failed_message') 488 @mock.patch.object(module_info_util, '_show_files_reuse_message') 489 @mock.patch.object(logging, 'warning') 490 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 491 @mock.patch.object(atest_utils, 'build') 492 @mock.patch.object(os.path, 'getmtime') 493 @mock.patch.object(logging, 'info') 494 @mock.patch.object(os.path, 'isfile') 495 @mock.patch.object(module_info_util, '_get_generated_json_files') 496 def test_build_bp_info_failed_not_exist( 497 self, mock_gen_jsons, mock_isfile, mock_log_info, 498 mock_get_mtimes, mock_build, mock_news, mock_warn, mock_show_reuse, 499 mock_build_fail): 500 """Test _build_bp_info function with build failed files not exist.""" 501 mock_gen_jsons.return_value = [ 502 'a/b/out/soong/module_bp_java_deps.json', 503 'a/b/out/soong/module_bp_cc_deps.json' 504 ] 505 mock_isfile.return_value = False 506 mock_build.return_value = False 507 mock_news.return_value = False 508 module_info_util._build_bp_info( 509 module_info=mock.Mock(), skip_build=False) 510 self.assertFalse(mock_log_info.called) 511 self.assertFalse(mock_get_mtimes.called) 512 self.assertTrue(mock_build.called) 513 self.assertTrue(mock_news.called) 514 self.assertTrue(mock_warn.called) 515 self.assertFalse(mock_show_reuse.called) 516 self.assertTrue(mock_build_fail.called) 517 518 @mock.patch.object(module_info_util, '_show_build_failed_message') 519 @mock.patch.object(module_info_util, '_show_files_reuse_message') 520 @mock.patch.object(logging, 'warning') 521 @mock.patch.object(module_info_util, '_is_new_json_file_generated') 522 @mock.patch.object(atest_utils, 'build') 523 @mock.patch.object(os.path, 'getmtime') 524 @mock.patch.object(logging, 'info') 525 @mock.patch.object(os.path, 'isfile') 526 @mock.patch.object(module_info_util, '_get_generated_json_files') 527 def test_build_bp_info_failed_files_exist( 528 self, mock_gen_jsons, mock_isfile, mock_log_info, 529 mock_get_mtimes, mock_build, mock_news, mock_warn, mock_show_reuse, 530 mock_build_fail): 531 """Test _build_bp_info function with build failed files not exist.""" 532 mock_gen_jsons.return_value = [ 533 'a/b/out/soong/module_bp_java_deps.json', 534 'a/b/out/soong/module_bp_cc_deps.json' 535 ] 536 mock_isfile.return_value = False 537 mock_build.return_value = False 538 mock_news.return_value = True 539 module_info_util._build_bp_info( 540 module_info=mock.Mock(), skip_build=False) 541 self.assertFalse(mock_log_info.called) 542 self.assertFalse(mock_get_mtimes.called) 543 self.assertTrue(mock_build.called) 544 self.assertTrue(mock_news.called) 545 self.assertTrue(mock_warn.called) 546 self.assertFalse(mock_show_reuse.called) 547 self.assertFalse(mock_build_fail.called) 548 549 @mock.patch('builtins.print') 550 @mock.patch('os.symlink') 551 @mock.patch('os.remove') 552 @mock.patch('os.path.islink') 553 @mock.patch('os.path.isfile') 554 def test_generate_rust_project_link(self, mock_isfile, mock_islink, 555 mock_remove, mock_symlink, mock_print): 556 """Test _generate_rust_project_link function.""" 557 mock_isfile.return_value = True 558 mock_islink.return_value = False 559 module_info_util._generate_rust_project_link() 560 self.assertFalse(mock_print.called) 561 self.assertFalse(mock_remove.called) 562 self.assertTrue(mock_symlink.called) 563 564 mock_symlink.mock_reset() 565 mock_remove.mock_reset() 566 mock_print.mock_reset() 567 mock_islink.return_value = True 568 module_info_util._generate_rust_project_link() 569 self.assertTrue(mock_remove.called) 570 self.assertFalse(mock_print.called) 571 self.assertTrue(mock_symlink.called) 572 573 mock_symlink.mock_reset() 574 mock_remove.mock_reset() 575 mock_print.mock_reset() 576 mock_isfile.return_value = False 577 module_info_util._generate_rust_project_link() 578 self.assertTrue(mock_print.called) 579 580 mock_symlink.mock_reset() 581 mock_remove.mock_reset() 582 mock_print.mock_reset() 583 mock_islink.return_value = True 584 module_info_util._generate_rust_project_link() 585 self.assertTrue(mock_print.called) 586 587 588if __name__ == '__main__': 589 unittest.main() 590