@@ -4,14 +4,25 @@ set -euo pipefail
4
4
set -o noglob
5
5
6
6
usage () {
7
- echo " -b TARGET_BASELINE The target used to collect the baseline"
8
- echo " -t TARGET_TESTS The test target"
9
- echo " -c CACHE The path to the bazel cache"
7
+ echo " Usage:"
8
+ echo " -b TARGET_BASELINE The target used to collect the baseline (-b \" target_1 target_2\" )"
9
+ echo " -t TARGET_TESTS The test target (-t \" target_1 target_2\" )"
10
+ echo " -c GCNO_DIR The path to the gcno files"
11
+ echo " -d GCDA_DIR The path to the gcda files"
10
12
echo " -s SKIP_HTML_REPORT Skip generation of HTML coverage report (default: false)."
11
13
echo " -o OUTPUT_DIR Directory for output (default is temp directory)"
12
14
echo " -h Display this help message"
13
15
}
14
16
17
+ create_directory () {
18
+ local dir=" $1 "
19
+ if [ ! -d " $dir " ]; then
20
+ echo " INFO: Creating directory: $dir "
21
+ mkdir -p " $dir "
22
+ fi
23
+ }
24
+
25
+ # Parse options
15
26
while getopts " b:t:c:d:o:sh" option; do
16
27
case " ${option} " in
17
28
b) TARGET_BASELINE=${OPTARG} ;;
@@ -27,121 +38,143 @@ while getopts "b:t:c:d:o:sh" option; do
27
38
esac
28
39
done
29
40
30
- if [[ -z " ${TARGET_TESTS+x} " ]]; then
41
+ # Validate required arguments
42
+ if [[ -z " ${TARGET_TESTS+x} " || -z " ${GCNO_DIR+x} " || -z " ${GCDA_DIR+x} " ]]; then
31
43
echo " ERROR: Missing required arguments."
32
44
usage
33
45
exit 1
34
46
fi
35
47
36
- if [[ -z " ${GCNO_DIR+x} " || -z " ${GCDA_DIR+x} " ]]; then
37
- echo " ERROR: Missing required directories for .gcno or .gcda files."
38
- usage
39
- exit 1
40
- fi
41
-
48
+ # Set defaults
42
49
SKIP_HTML_REPORT=" ${SKIP_HTML_REPORT:- false} "
43
- EXCLUDE_PATTERN=" external/*|* gtest/* |/usr/* "
50
+ EXCLUDE_PATTERN=" external| gtest|/usr"
44
51
TARGET_BASELINE=" ${TARGET_BASELINE:- " ${TARGET_TESTS} " } "
45
52
OUTPUT_DIR=" ${OUTPUT_DIR:- " $( mktemp -d) /cov_report" } "
46
- TARGET_DIR= " ${OUTPUT_DIR} /gcno_gcda "
47
- mkdir -p " ${TARGET_DIR} "
53
+
54
+ create_directory " $OUTPUT_DIR "
48
55
49
56
echo " INFO: Baseline target: ${TARGET_BASELINE} "
50
- echo " INFO: Tests target: ${TARGET_TESTS} "
57
+ echo " INFO: Test target: ${TARGET_TESTS} "
51
58
echo " INFO: Output directory: ${OUTPUT_DIR} "
52
59
53
60
readonly WORKSPACE=$( cd " $( dirname " $( readlink -f " ${0} " ) " ) " && bazel info workspace)
54
61
55
- function run_baseline() {
56
- echo " \nINFO: Build baseline"
57
- echo " Baseline target: ${TARGET_BASELINE} "
62
+ run_baseline () {
63
+ echo -e " \nINFO: Building baseline target: ${TARGET_BASELINE} "
58
64
bazel build \
59
65
--collect_code_coverage \
60
66
--experimental_fetch_all_coverage_outputs \
67
+ --cxxopt=" -O0" \
61
68
-- ${TARGET_BASELINE}
62
69
}
63
70
64
- function run_coverage_tests() {
65
- echo " \nINFO: Run test"
66
- echo " Test target: ${TARGET_TESTS} "
71
+ run_coverage_tests () {
72
+ echo -e " \nINFO: Running test target: ${TARGET_TESTS} "
67
73
bazel coverage \
68
74
--nocache_test_results \
69
75
--experimental_fetch_all_coverage_outputs \
70
76
--cxxopt=" -O0" \
77
+ --instrumentation_filter=" [/:]" \
71
78
-- ${TARGET_TESTS}
72
79
}
73
80
74
- function generate_hashed_name() {
75
- local file_path=" $1 "
76
- local extension=" ${file_path##* .} " # Get the file extension (e.g., .gcno or .gcda)
77
- local path_no_extension=" ${file_path% " .$extension " } " # Remove extension
78
- path_in_root=$( echo " $path_no_extension " | sed ' s/.*\(bin\/.*\)/\1/' ) # Get file name from bin
79
- local hash=$( echo -n " $path_in_root " | sha256sum | awk ' {print $1}' ) # Apply hash
80
- echo " $hash .$extension " # Return the hashed name with the original extension
81
+ delete_coverage_files () {
82
+ echo -e " \nINFO: Cleaning old .gcno and .gcda files"
83
+ local directories=(" ${GCNO_DIR} " " ${GCDA_DIR} " )
84
+ for dir in " ${directories[@]} " ; do
85
+ find " $dir " -type f \( -name " *.gcno" -o -name " *.gcda" \) -exec chmod +w {} \; -exec rm -f {} \; || true
86
+ done
81
87
}
82
88
83
- function delete_coverage_files() {
84
- echo " \nINFO: Clean old .gcno and .gcda files"
85
- echo " Input directory: $TARGET_DIR "
86
- find " $TARGET_DIR " -name " *.gcno" -exec rm -f {} \;
87
- find " $TARGET_DIR " -name " *.gcda" -exec rm -f {} \;
89
+ generate_hashed_name () {
90
+ local file_path=" $1 "
91
+ local extension=" ${file_path##* .} "
92
+ local path_no_extension=" ${file_path% .$extension } "
93
+ local path_in_bin=$( echo " $path_no_extension " | awk -F" bin" " {print substr(\$ 0, length(\$ 1\" bin\" ) + 1)}" )
94
+ local hash=$( echo -n " $path_in_bin " | sha256sum | awk " {print \$ 1}" )
95
+ echo " $hash .$extension "
88
96
}
89
97
90
- function collect_coverage_data() {
91
- echo " \nINFO: Copy hashed .gcno and .gcda files"
92
- echo " Input gcno directory: $GCNO_DIR "
93
- echo " Input gcda directory: $GCDA_DIR "
94
- echo " Output dir: $TARGET_DIR "
98
+ copy_coverage_files () {
99
+ echo -e " \nINFO: Copy hashed .gcno and .gcda files"
100
+ echo " Input directory: $1 "
101
+ echo " Output dir: $2 "
95
102
echo " Exclude pattern: $EXCLUDE_PATTERN "
96
103
97
- find " $GCDA_DIR " -name " *.gcda" ! -path " $EXCLUDE_PATTERN " | while read -r file; do
98
- new_name=$( generate_hashed_name " $file " " $GCDA_DIR " )
99
- cp " $file " " $TARGET_DIR /$new_name "
100
- echo " Copied gcda: $file -> $TARGET_DIR /$new_name "
101
- done
104
+ mkdir -p " $2 "
102
105
103
- find " $GCNO_DIR " -name " *.gcno" ! -path " $EXCLUDE_PATTERN " | while read -r file; do
104
- new_name=$( generate_hashed_name " $file " " $GCNO_DIR " )
105
- cp " $file " " $TARGET_DIR /$new_name "
106
- echo " Copied gcno : $file -> $TARGET_DIR /$new_name "
106
+ find " $1 " -type f \( - name " *.gcda " -o -name " *. gcno" \) ! -path " */external/* " ! -path " *gtest* " ! -path " *test* " | while IFS= read -r file; do
107
+ new_name=$( generate_hashed_name " $file " " $1 " )
108
+ cp " $file " " $2 /$new_name "
109
+ echo " Copied: $file -> $2 /$new_name "
107
110
done
108
111
}
109
112
110
- function calculate_coverage() {
111
- echo " \nINFO: Generate coverage data"
112
- echo " Output directory: $OUTPUT_DIR "
113
- lcov --directory " $TARGET_DIR " \
113
+ main () {
114
+ pushd " ${WORKSPACE} " || return
115
+
116
+ bazel clean
117
+ delete_coverage_files
118
+ run_baseline
119
+ echo -e " \nINFO: Create baseline.info"
120
+ lcov \
121
+ --directory " ${GCNO_DIR} " \
122
+ --capture \
123
+ -i \
124
+ --output-file " ${OUTPUT_DIR} /baseline.info"
125
+
126
+ echo -e " \nINFO: Filter baseline.info"
127
+ lcov \
128
+ --directory " ${GCNO_DIR} " \
129
+ --remove " ${OUTPUT_DIR} /baseline.info" \
130
+ ' /usr/*' \
131
+ ' *external/*' \
132
+ ' *gtest*' \
133
+ --ignore-errors unused \
134
+ --ignore-errors empty \
135
+ --output-file " ${OUTPUT_DIR} /baseline_filtered.info"
136
+
137
+ run_coverage_tests
138
+
139
+ echo -e " \nINFO: Create tests.info"
140
+ lcov \
141
+ --directory " ${GCDA_DIR} " \
114
142
--capture \
115
143
--ignore-errors source \
116
- --output-file " ${OUTPUT_DIR} /coverage.info"
117
- lcov --remove " ${OUTPUT_DIR} /coverage.info" \
144
+ --output-file " ${OUTPUT_DIR} /tests.info"
145
+
146
+ echo -e " \nINFO: Filter tests.info"
147
+ lcov \
148
+ --directory " ${GCDA_DIR} " \
149
+ --remove " ${OUTPUT_DIR} /tests.info" \
118
150
' /usr/*' \
119
151
' external/*' \
120
152
' *gtest*' \
121
153
--ignore-errors unused \
122
154
--ignore-errors source \
123
- --output-file " ${OUTPUT_DIR} /coverage_filtered.info"
124
- sed -i ' s|/proc/self/cwd/||g' " ${OUTPUT_DIR} /coverage_filtered.info" # Remove file prefix
155
+ --output-file " ${OUTPUT_DIR} /tests_filtered.info"
156
+
157
+ sed -i ' s|/__w/Team04/Team04||g' " ${OUTPUT_DIR} /baseline_filtered.info"
158
+ sed -i ' s|/proc/self/cwd||g' " ${OUTPUT_DIR} /baseline_filtered.info"
159
+ sed -i ' s|/__w/Team04/Team04||g' " ${OUTPUT_DIR} /tests_filtered.info"
160
+ sed -i ' s|/proc/self/cwd/||g' " ${OUTPUT_DIR} /tests_filtered.info"
161
+
162
+ echo -e " \nINFO: Merge baseline and tests coverage report"
163
+ lcov \
164
+ -a " ${OUTPUT_DIR} /baseline_filtered.info" \
165
+ -a " ${OUTPUT_DIR} /tests_filtered.info" \
166
+ -o " ${OUTPUT_DIR} /coverage.info"
125
167
126
168
if [ " ${SKIP_HTML_REPORT} " = false ]; then
127
- echo " \nINFO: Generate HTML coverage report"
128
- genhtml " ${OUTPUT_DIR} /coverage_filtered.info" \
129
- --ignore-errors source \
130
- --output-directory " $OUTPUT_DIR "
169
+ echo -e " \nINFO: Generating HTML coverage report"
170
+ genhtml " ${OUTPUT_DIR} /coverage.info" \
171
+ --output-directory " ${OUTPUT_DIR} "
131
172
else
132
- echo " \nINFO: Generate coverage summary"
133
- lcov --summary " ${OUTPUT_DIR} /coverage_filtered .info"
173
+ echo -e " \nINFO: Generating coverage summary"
174
+ lcov --summary " ${OUTPUT_DIR} /coverage .info"
134
175
fi
135
- }
136
176
137
- function main() {
138
- pushd " ${WORKSPACE} " || return
139
- run_baseline
140
- run_coverage_tests
141
- delete_coverage_files
142
- collect_coverage_data
143
- calculate_coverage
144
- popd || return
177
+ popd & > /dev/null || true
145
178
}
146
179
147
180
main
0 commit comments