Skip to content

Commit 316db45

Browse files
authored
Merge pull request #970 from arielswalker/part-cfs/workflows#122-add-internal-workflows
Part cFS/workflows#122, Add Internal Workflows
2 parents be9937a + dad5474 commit 316db45

17 files changed

Lines changed: 1300 additions & 947 deletions

.clang-format

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,4 @@ SpacesInParentheses: false
108108
SpacesInSquareBrackets: false
109109
Standard: Cpp11
110110
TabWidth: '4'
111-
UseTab: Never
111+
UseTab: Never

.github/scripts/mcdc-analyze.sh

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/bin/bash
2+
3+
# Redirect all echo outputs to mcdc_results.txt and capture gcov output
4+
exec > >(tee -a mcdc_results.txt) 2>&1
5+
6+
# Pass the test modules after running unit tests
7+
# Ex. echo "MODULES=$(grep -oP 'Test #\d+: \K[\w\-\_]+' test_results.txt | tr '\n' ' ' | sed 's/ $//')" >> $GITHUB_ENV
8+
if [ -n "$MODULES" ]; then
9+
modules="$MODULES"
10+
echo "Test modules provided: "
11+
for module in $modules; do
12+
echo "$module"
13+
done
14+
else
15+
echo "No test modules provided."
16+
exit 1
17+
fi
18+
19+
# Initialize overall counters
20+
overall_total_functions=0
21+
overall_total_covered_functions=0
22+
overall_file_count=0
23+
overall_no_conditions_count=0
24+
module_count=0
25+
26+
27+
# Show coverage for each file in a module and summary coverage for each module
28+
for module in $modules; do
29+
module_name=$(basename "$module")
30+
31+
# Skip specific files and directories
32+
if [[ "$module_name" == "core-cpu1" || \
33+
"$module_name" == "Makefile" || \
34+
"$module_name" == "CTestTestfile" || \
35+
"$module_name" == "cmake_install" || \
36+
"$module_name" == "gmon" || \
37+
"$module_name" == *"stubs"* ]]; then
38+
continue
39+
fi
40+
41+
module_name_no_testrunner=$(echo "$module_name" | sed 's/-testrunner$//')
42+
43+
echo " "
44+
echo "Processing $module_name_no_testrunner module..."
45+
46+
# Initialize module-level counters
47+
total_functions=0
48+
total_covered_functions=0
49+
file_count=0
50+
no_conditions_count=0
51+
52+
module_dirs=""
53+
54+
if [ -n "$BASE_DIR" ]; then
55+
# If BASE_DIR is provided, search within the BASE_DIR for the module directories.
56+
# FIX, module dirs doesn't always show
57+
module_dirs=$(find "$BASE_DIR" -type d -name "*${module_name}*")
58+
echo "Base directory specified: $BASE_DIR"
59+
echo "Searching for .gcda directory..."
60+
else
61+
# Otherwise, look for the default module directories.
62+
module_dirs=$(find "build/native/default_cpu1" -type d -name "*${module_name}*.dir")
63+
echo "No base directory provided: Searching for .gcda directory..."
64+
fi
65+
66+
if [ -n "$module_dirs" ]; then
67+
for module_dir in $module_dirs; do
68+
echo "Found module directory: $module_dir"
69+
70+
parent_dir=$(dirname "$module_dir")
71+
echo "Searching for .gcda files under parent directory: $parent_dir..."
72+
gcda_files=$(find "$parent_dir" -type d -name "*${module_name_no_testrunner}*.dir" -exec find {} -type f -name "*.gcda" \;)
73+
74+
if [ -n "$gcda_files" ]; then
75+
for gcda_file in $gcda_files; do
76+
c_file=$(echo "$gcda_file" | sed 's/\.gcda$/.c/')
77+
78+
echo "Processing corresponding .c file: $c_file"
79+
echo "Running gcov on $c_file..."
80+
81+
# Capture gcov output and remove header files
82+
gcov_output=$(gcov -abcgi "$c_file" | sed "/\.h/,/^$/d")
83+
84+
# Output the gcov result of each file and save to mcdc_results.txt
85+
echo "$gcov_output" | tee -a mcdc_results.txt
86+
87+
# Process gcov results for coverage summary
88+
while IFS= read -r line; do
89+
if [[ $line == *"Condition outcomes covered:"* ]]; then
90+
condition_covered=$(echo "$line" | grep -oP 'Condition outcomes covered:\K[0-9.]+')
91+
total_conditions_in_file=$(echo "$line" | grep -oP 'of \K[0-9]+')
92+
93+
covered_functions_in_file=$(awk -v pct="$condition_covered" -v total="$total_conditions_in_file" 'BEGIN {printf "%.2f", (pct / 100) * total}')
94+
95+
total_functions=$((total_functions + total_conditions_in_file))
96+
total_covered_functions=$(awk -v covered="$total_covered_functions" -v new_covered="$covered_functions_in_file" 'BEGIN {printf "%.2f", covered + new_covered}')
97+
98+
file_count=$((file_count + 1))
99+
elif [[ $line == *"No conditions"* ]]; then
100+
no_conditions_count=$((no_conditions_count + 1))
101+
fi
102+
done <<< "$gcov_output"
103+
done
104+
else
105+
echo "No .gcda files found for $module_name under parent directory $parent_dir."
106+
fi
107+
done
108+
else
109+
echo "Directory for module $module_name \(e.g., ${module_name}.dir\) not found."
110+
fi
111+
112+
if [ "$total_functions" -ne 0 ]; then
113+
average_condition_coverage=$(awk -v covered="$total_covered_functions" -v total="$total_functions" 'BEGIN {printf "%.2f", (covered / total) * 100}')
114+
else
115+
average_condition_coverage=0
116+
fi
117+
118+
overall_total_functions=$((overall_total_functions + total_functions))
119+
overall_total_covered_functions=$(awk -v covered="$overall_total_covered_functions" -v new_covered="$total_covered_functions" 'BEGIN {printf "%.2f", covered + new_covered}')
120+
overall_file_count=$((overall_file_count + file_count))
121+
overall_no_conditions_count=$((overall_no_conditions_count + no_conditions_count))
122+
123+
module_count=$((module_count + 1))
124+
125+
echo "Summary for $module_name_no_testrunner module:"
126+
echo " Total files processed: $file_count"
127+
echo " Number of files with no condition data: $no_conditions_count"
128+
echo " Condition outcomes covered: ${average_condition_coverage}% of $total_functions"
129+
echo " "
130+
done
131+
132+
if [ "$overall_total_functions" -ne 0 ]; then
133+
overall_condition_coverage=$(awk -v covered="$overall_total_covered_functions" -v total="$overall_total_functions" 'BEGIN {printf "%.2f", (covered / total) * 100}')
134+
else
135+
overall_condition_coverage=0
136+
fi
137+
138+
echo " "
139+
echo "Overall summary:"
140+
echo " Total files processed: $overall_file_count"
141+
echo " Number of files with no condition data: $overall_no_conditions_count"
142+
echo " Overall condition outcomes covered: ${overall_condition_coverage}% of $overall_total_functions"

.github/scripts/mcdc-compare.sh

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/bin/bash
2+
3+
exec > >(tee -a mcdc_compare.txt) 2>&1
4+
5+
# Function to check if a file exists and return an error message for missing files
6+
check_file_exists() {
7+
file=$1
8+
if [ ! -f "$file" ]; then
9+
echo "Error: File '$file' does not exist."
10+
missing_files=true
11+
fi
12+
}
13+
14+
# Function to extract the relevant numbers from a module's "Summary for module" section
15+
extract_module_numbers() {
16+
file=$1
17+
module=$2
18+
19+
total_files_processed=$(sed -n "/^Summary for ${module} module:/,/^$/p" "$file" | head -n 4 | grep -Po 'Total files processed:\s*\K\d*')
20+
no_condition_data=$(sed -n "/^Summary for ${module} module:/,/^$/p" "$file" | head -n 4 | grep -Po 'Number of files with no condition data:\s*\K\d+')
21+
condition_outcomes_covered_percent=$(sed -n "/^Summary for ${module} module:/,/^$/p" "$file" | head -n 4 | grep -Po 'Condition outcomes covered:\s*\K[0-9]+(\.[0-9]+)?')
22+
condition_outcomes_out_of=$(sed -n "/^Summary for ${module} module:/,/^$/p" "$file" | head -n 4 | grep -Po 'Condition outcomes covered:.*of\s*\K\d*')
23+
24+
echo "$total_files_processed $no_condition_data $condition_outcomes_covered_percent $condition_outcomes_out_of"
25+
}
26+
27+
# Compare results for each module between two files
28+
compare_mcdc_results() {
29+
main_results_file=$1
30+
pr_results_file=$2
31+
modules_file=$3
32+
33+
# Initialize a flag to track if any files are missing
34+
missing_files=false
35+
36+
# Check if the files exist before proceeding
37+
check_file_exists "$main_results_file"
38+
check_file_exists "$pr_results_file"
39+
check_file_exists "$modules_file"
40+
41+
# If any files are missing, exit early
42+
if [ "$missing_files" = true ]; then
43+
echo "Error: One or more input files are missing. Exiting."
44+
exit 1
45+
fi
46+
47+
# Read modules from modules.txt (passed as argument)
48+
modules=$(cat "$modules_file")
49+
50+
# Check if modules are empty or not
51+
if [ -z "$modules" ]; then
52+
echo "Error: No modules found in $modules_file"
53+
exit 1
54+
fi
55+
56+
# Initialize variables to store the output for modules with and without changes
57+
modules_with_changes=""
58+
modules_without_changes=""
59+
60+
# Loop through all modules to compare each one
61+
for module in $modules; do
62+
63+
# Extract numbers for the main results file and PR results file for the current module
64+
read main_total_files main_no_condition main_condition_covered_percent main_condition_out_of <<< $(extract_module_numbers "$main_results_file" "$module")
65+
read pr_total_files pr_no_condition pr_condition_covered_percent pr_condition_out_of <<< $(extract_module_numbers "$pr_results_file" "$module")
66+
67+
# Echo numbers extracted from each file for each module
68+
echo -e "\nResults for module: $module"
69+
echo "PR Branch - Total files processed: $pr_total_files, No condition data: $pr_no_condition, Covered condition %: $pr_condition_covered_percent%, Out of value: $pr_condition_out_of"
70+
echo "Main Branch - Total files processed: $main_total_files, No condition data: $main_no_condition, Covered condition %: $main_condition_covered_percent%, Out of value: $main_condition_out_of"
71+
72+
# Initialize variables to store differences
73+
total_files_diff=""
74+
no_condition_data_diff=""
75+
condition_outcomes_covered_diff_percent=""
76+
condition_outcomes_out_of_diff=""
77+
78+
# Calculate difference between files
79+
total_files_diff=$((pr_total_files - main_total_files))
80+
no_condition_data_diff=$((pr_no_condition - main_no_condition))
81+
condition_outcomes_covered_diff_percent=$(echo "$pr_condition_covered_percent - $main_condition_covered_percent" | bc)
82+
condition_outcomes_out_of_diff=$((pr_condition_out_of - main_condition_out_of))
83+
84+
echo "Differences:"
85+
echo " Total files processed difference: $total_files_diff"
86+
echo " No condition data difference: $no_condition_data_diff"
87+
echo " Covered condition % difference: $condition_outcomes_covered_diff_percent"
88+
echo " Out of value difference: $condition_outcomes_out_of_diff"
89+
echo " "
90+
91+
changes=""
92+
93+
if [ "$total_files_diff" -gt 0 ]; then
94+
changes="${changes} Number of files processed: +$total_files_diff\n"
95+
elif [ "$total_files_diff" -lt 0 ]; then
96+
changes="${changes} Number of files processed: $total_files_diff\n"
97+
fi
98+
99+
if [ "$no_condition_data_diff" -gt 0 ]; then
100+
changes="${changes} Number of files with no condition data: +$no_condition_data_diff\n"
101+
elif [ "$no_condition_data_diff" -lt 0 ]; then
102+
changes="${changes} Number of files with no condition data: $no_condition_data_diff\n"
103+
fi
104+
105+
if [ $(echo "$condition_outcomes_covered_diff_percent > 0" | bc) -eq 1 ]; then
106+
changes="${changes} Percentage of covered conditions: +$condition_outcomes_covered_diff_percent%\n"
107+
elif [ $(echo "$condition_outcomes_covered_diff_percent < 0" | bc) -eq 1 ]; then
108+
changes="${changes} Percentage of covered conditions: $condition_outcomes_covered_diff_percent%\n"
109+
fi
110+
111+
if [ "$condition_outcomes_out_of_diff" -gt 0 ]; then
112+
changes="${changes} Number of conditions: +$condition_outcomes_out_of_diff\n"
113+
elif [ "$condition_outcomes_out_of_diff" -lt 0 ]; then
114+
changes="${changes} Number of conditions: $condition_outcomes_out_of_diff\n"
115+
fi
116+
117+
if [ -n "$changes" ]; then
118+
modules_with_changes="${modules_with_changes} $module\n$changes\n"
119+
else
120+
modules_without_changes="${modules_without_changes} $module\n"
121+
fi
122+
done
123+
124+
echo " "
125+
echo "MC/DC results compared to latest dev branch:"
126+
echo " "
127+
echo "Modules with changes:"
128+
echo -e "$modules_with_changes"
129+
echo "Modules without changes:"
130+
echo -e "$modules_without_changes"
131+
132+
# Write results to mcdc_comment.txt / pull request
133+
if [ -n "$modules_with_changes" ]; then
134+
echo "MC/DC results compared to latest dev branch:" > mcdc_comment.txt
135+
echo "" >> mcdc_comment.txt
136+
echo "Modules with changes:" >> mcdc_comment.txt
137+
echo -e "$modules_with_changes" >> mcdc_comment.txt
138+
echo "" >> mcdc_comment.txt
139+
echo "See file uncovered.json for more details"
140+
else
141+
echo "No MC/DC changes were made." > mcdc_comment.txt
142+
fi
143+
144+
}
145+
146+
# creates single json file that contains info on all uncovered branches
147+
generate_json_report() {
148+
jq_script=$(find $GITHUB_WORKSPACE -name "uncovered_filter.jq" | tail -n 1)
149+
if [ -z "$jq_script" ]; then
150+
echo "Error: Could not find uncovered_filter.jq"
151+
return 1
152+
fi
153+
154+
for zipped_file in *.gcov.json.gz; do
155+
if [ -f "$zipped_file" ]; then
156+
base_name="${zipped_file%.gcov.json.gz}"
157+
gunzip -c "$zipped_file" > "${base_name}.json"
158+
if [ -f "${base_name}.json" ]; then
159+
jq -f "$jq_script" "${base_name}.json" > "${base_name}_filtered.json"
160+
else
161+
echo "Error: Failed to decompress $zipped_file"
162+
return 1
163+
fi
164+
else
165+
echo "Warning: No .gcov.json.gz files found"
166+
return 0
167+
fi
168+
done
169+
170+
if ls *_filtered.json 1> /dev/null 2>&1; then
171+
jq -s '.' *_filtered.json > uncovered.json
172+
echo "Successfully created uncovered.json"
173+
else
174+
echo "No filtered JSON files found to merge"
175+
return 1
176+
fi
177+
178+
if jq 'flatten' uncovered.json > temp.json; then
179+
mv temp.json uncovered.json
180+
else
181+
rm -f temp.json
182+
echo "Error processing JSON file"
183+
exit 1
184+
fi
185+
186+
if jq '.' uncovered.json > temp.json; then
187+
mv temp.json uncovered.json
188+
else
189+
rm -f temp.json
190+
echo "Error processing JSON file"
191+
exit 1
192+
fi
193+
}
194+
195+
# Check the script arguments
196+
if [ $# -ne 3 ]; then
197+
echo "Usage: $0 <main_results_file> <pr_results_file> <modules_file>"
198+
exit 1
199+
fi
200+
201+
# Run the comparison function with the provided arguments
202+
generate_json_report
203+
compare_mcdc_results "$1" "$2" "$3"

0 commit comments

Comments
 (0)