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