1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
import os
import subprocess
import time
from typing import List
from ..util.setting import (
JSON_FOLDER_BASE_DIR,
MERGED_FOLDER_BASE_DIR,
TestList,
TestPlatform,
TestType,
)
from ..util.utils import (
check_platform_type,
convert_to_relative_path,
create_folder,
get_raw_profiles_folder,
get_test_name_from_whole_path,
print_log,
print_time,
related_to_test_list,
replace_extension,
)
from .utils import get_tool_path_by_platform, run_cpp_test
def create_corresponding_folder(
cur_path: str, prefix_cur_path: str, dir_list: List[str], new_base_folder: str
) -> None:
for dir_name in dir_list:
relative_path = convert_to_relative_path(
cur_path, prefix_cur_path
) # get folder name like 'aten'
new_folder_path = os.path.join(new_base_folder, relative_path, dir_name)
create_folder(new_folder_path)
def run_target(
binary_file: str, raw_file: str, test_type: TestType, platform_type: TestPlatform
) -> None:
print_log("start run: ", binary_file)
# set environment variable -- raw profile output path of the binary run
os.environ["LLVM_PROFILE_FILE"] = raw_file
# run binary
if test_type == TestType.PY and platform_type == TestPlatform.OSS:
from ..oss.utils import run_oss_python_test
run_oss_python_test(binary_file)
else:
run_cpp_test(binary_file)
def merge_target(raw_file: str, merged_file: str, platform_type: TestPlatform) -> None:
print_log("start to merge target: ", raw_file)
# run command
llvm_tool_path = get_tool_path_by_platform(platform_type)
subprocess.check_call(
[
f"{llvm_tool_path}/llvm-profdata",
"merge",
"-sparse",
raw_file,
"-o",
merged_file,
]
)
def export_target(
merged_file: str,
json_file: str,
binary_file: str,
shared_library_list: List[str],
platform_type: TestPlatform,
) -> None:
if binary_file is None:
raise Exception(f"{merged_file} doesn't have corresponding binary!")
print_log("start to export: ", merged_file)
# run export
cmd_shared_library = (
""
if not shared_library_list
else f" -object {' -object '.join(shared_library_list)}"
)
# if binary_file = "", then no need to add it (python test)
cmd_binary = "" if not binary_file else f" -object {binary_file} "
llvm_tool_path = get_tool_path_by_platform(platform_type)
cmd = f"{llvm_tool_path}/llvm-cov export {cmd_binary} {cmd_shared_library} -instr-profile={merged_file} > {json_file}"
os.system(cmd)
def merge(test_list: TestList, platform_type: TestPlatform) -> None:
print("start merge")
start_time = time.time()
# find all raw profile under raw_folder and sub-folders
raw_folder_path = get_raw_profiles_folder()
g = os.walk(raw_folder_path)
for path, dir_list, file_list in g:
# if there is a folder raw/aten/, create corresponding merged folder profile/merged/aten/ if not exists yet
create_corresponding_folder(
path, raw_folder_path, dir_list, MERGED_FOLDER_BASE_DIR
)
# check if we can find raw profile under this path's folder
for file_name in file_list:
if file_name.endswith(".profraw"):
if not related_to_test_list(file_name, test_list):
continue
print(f"start merge {file_name}")
raw_file = os.path.join(path, file_name)
merged_file_name = replace_extension(file_name, ".merged")
merged_file = os.path.join(
MERGED_FOLDER_BASE_DIR,
convert_to_relative_path(path, raw_folder_path),
merged_file_name,
)
merge_target(raw_file, merged_file, platform_type)
print_time("merge take time: ", start_time, summary_time=True)
def export(test_list: TestList, platform_type: TestPlatform) -> None:
print("start export")
start_time = time.time()
# find all merged profile under merged_folder and sub-folders
g = os.walk(MERGED_FOLDER_BASE_DIR)
for path, dir_list, file_list in g:
# create corresponding merged folder in [json folder] if not exists yet
create_corresponding_folder(
path, MERGED_FOLDER_BASE_DIR, dir_list, JSON_FOLDER_BASE_DIR
)
# check if we can find merged profile under this path's folder
for file_name in file_list:
if file_name.endswith(".merged"):
if not related_to_test_list(file_name, test_list):
continue
print(f"start export {file_name}")
# merged file
merged_file = os.path.join(path, file_name)
# json file
json_file_name = replace_extension(file_name, ".json")
json_file = os.path.join(
JSON_FOLDER_BASE_DIR,
convert_to_relative_path(path, MERGED_FOLDER_BASE_DIR),
json_file_name,
)
check_platform_type(platform_type)
# binary file and shared library
binary_file = ""
shared_library_list = []
if platform_type == TestPlatform.FBCODE:
from caffe2.fb.code_coverage.tool.package.fbcode.utils import ( # type: ignore[import]
get_fbcode_binary_folder,
)
binary_file = os.path.join(
get_fbcode_binary_folder(path),
get_test_name_from_whole_path(merged_file),
)
elif platform_type == TestPlatform.OSS:
from ..oss.utils import get_oss_binary_file, get_oss_shared_library
test_name = get_test_name_from_whole_path(merged_file)
# if it is python test, no need to provide binary, shared library is enough
binary_file = (
""
if test_name.endswith(".py")
else get_oss_binary_file(test_name, TestType.CPP)
)
shared_library_list = get_oss_shared_library()
export_target(
merged_file,
json_file,
binary_file,
shared_library_list,
platform_type,
)
print_time("export take time: ", start_time, summary_time=True)
|