1from __future__ import annotations 2 3import os 4import shutil 5import sys 6import time 7from typing import Any, NoReturn 8 9from .setting import ( 10 CompilerType, 11 LOG_DIR, 12 PROFILE_DIR, 13 TestList, 14 TestPlatform, 15 TestType, 16) 17 18 19def convert_time(seconds: float) -> str: 20 seconds = int(round(seconds)) 21 seconds = seconds % (24 * 3600) 22 hour = seconds // 3600 23 seconds %= 3600 24 minutes = seconds // 60 25 seconds %= 60 26 27 return "%d:%02d:%02d" % (hour, minutes, seconds) 28 29 30def print_time(message: str, start_time: float, summary_time: bool = False) -> None: 31 with open(os.path.join(LOG_DIR, "log.txt"), "a+") as log_file: 32 end_time = time.time() 33 print(message, convert_time(end_time - start_time), file=log_file) 34 if summary_time: 35 print("\n", file=log_file) 36 37 38def print_log(*args: Any) -> None: 39 with open(os.path.join(LOG_DIR, "log.txt"), "a+") as log_file: 40 print(f"[LOG] {' '.join(args)}", file=log_file) 41 42 43def print_error(*args: Any) -> None: 44 with open(os.path.join(LOG_DIR, "log.txt"), "a+") as log_file: 45 print(f"[ERROR] {' '.join(args)}", file=log_file) 46 47 48def remove_file(path: str) -> None: 49 if os.path.exists(path): 50 os.remove(path) 51 52 53def remove_folder(path: str) -> None: 54 shutil.rmtree(path) 55 56 57def create_folder(*paths: Any) -> None: 58 for path in paths: 59 os.makedirs(path, exist_ok=True) 60 61 62# clean up all the files generated by coverage tool 63def clean_up() -> None: 64 # remove profile folder 65 remove_folder(PROFILE_DIR) 66 sys.exit("Clean Up Successfully!") 67 68 69def convert_to_relative_path(whole_path: str, base_path: str) -> str: 70 # ("profile/raw", "profile") -> "raw" 71 if base_path not in whole_path: 72 raise RuntimeError(base_path + " is not in " + whole_path) 73 return whole_path[len(base_path) + 1 :] 74 75 76def replace_extension(filename: str, ext: str) -> str: 77 return filename[: filename.rfind(".")] + ext 78 79 80# a file is related if it's in one of the test_list folder 81def related_to_test_list(file_name: str, test_list: TestList) -> bool: 82 for test in test_list: 83 if test.name in file_name: 84 return True 85 return False 86 87 88def get_raw_profiles_folder() -> str: 89 return os.environ.get("RAW_PROFILES_FOLDER", os.path.join(PROFILE_DIR, "raw")) 90 91 92def detect_compiler_type(platform: TestPlatform) -> CompilerType: 93 if platform == TestPlatform.OSS: 94 from package.oss.utils import ( # type: ignore[assignment, import, misc] 95 detect_compiler_type, 96 ) 97 98 cov_type = detect_compiler_type() # type: ignore[call-arg] 99 else: 100 from caffe2.fb.code_coverage.tool.package.fbcode.utils import ( # type: ignore[import] 101 detect_compiler_type, 102 ) 103 104 cov_type = detect_compiler_type() 105 106 check_compiler_type(cov_type) 107 return cov_type # type: ignore[no-any-return] 108 109 110def get_test_name_from_whole_path(path: str) -> str: 111 # code_coverage_tool/profile/merged/haha.merged -> haha 112 start = path.rfind("/") 113 end = path.rfind(".") 114 assert start >= 0 and end >= 0 115 return path[start + 1 : end] 116 117 118def check_compiler_type(cov_type: CompilerType | None) -> None: 119 if cov_type is not None and cov_type in [CompilerType.GCC, CompilerType.CLANG]: 120 return 121 raise Exception( # noqa: TRY002 122 f"Can't parse compiler type: {cov_type}.", 123 " Please set environment variable COMPILER_TYPE as CLANG or GCC", 124 ) 125 126 127def check_platform_type(platform_type: TestPlatform) -> None: 128 if platform_type in [TestPlatform.OSS, TestPlatform.FBCODE]: 129 return 130 raise Exception( # noqa: TRY002 131 f"Can't parse platform type: {platform_type}.", 132 " Please set environment variable COMPILER_TYPE as OSS or FBCODE", 133 ) 134 135 136def check_test_type(test_type: str, target: str) -> None: 137 if test_type in [TestType.CPP.value, TestType.PY.value]: 138 return 139 raise Exception( # noqa: TRY002 140 f"Can't parse test type: {test_type}.", 141 f" Please check the type of buck target: {target}", 142 ) 143 144 145def raise_no_test_found_exception( 146 cpp_binary_folder: str, python_binary_folder: str 147) -> NoReturn: 148 raise RuntimeError( 149 f"No cpp and python tests found in folder **{cpp_binary_folder} and **{python_binary_folder}**" 150 ) 151