Add Docker information retrieval and reporting to testsuite report script

This commit is contained in:
Nicolas Saillant 2024-11-29 15:43:57 +01:00
parent 7b5d5e4b1c
commit 1105ed409d
2 changed files with 244 additions and 0 deletions

View File

@ -2,6 +2,8 @@ import json
from typing import Dict, List from typing import Dict, List
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from collections import defaultdict
import subprocess
import re import re
import requests import requests
@ -82,12 +84,15 @@ def fragment_name(platform: PlatformInfo) -> str:
def generate_markdown_report(platforms_info: List[PlatformInfo], version: str) -> str: def generate_markdown_report(platforms_info: List[PlatformInfo], version: str) -> str:
"""Generate a markdown report from the platforms information.""" """Generate a markdown report from the platforms information."""
machines_info = get_docker_info()
update_machines_platforms(machines_info, platforms_info)
report = [] report = []
report.append("# TestSuite Report") report.append("# TestSuite Report")
report.append(f"\nGenerated on: { report.append(f"\nGenerated on: {
datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
url = TESTSUITE_URL_TEMPLATE.format(version=version) url = TESTSUITE_URL_TEMPLATE.format(version=version)
report.append(f"\nCGAL Version: [{version}]({url})\n") report.append(f"\nCGAL Version: [{version}]({url})\n")
add_machines_summary(report, machines_info)
report.append("## Platforms Summary\n") report.append("## Platforms Summary\n")
report.append("| Platform | Debug | OS | Tester | Compiler |") report.append("| Platform | Debug | OS | Tester | Compiler |")
report.append("|----------|-------|----|--------|----------|") report.append("|----------|-------|----|--------|----------|")
@ -113,6 +118,46 @@ def generate_markdown_report(platforms_info: List[PlatformInfo], version: str) -
f"\n**Summary**: found {found_tpls} third-party libraries out of {total_tpls}") f"\n**Summary**: found {found_tpls} third-party libraries out of {total_tpls}")
return "\n".join(report) return "\n".join(report)
def get_docker_info() -> Dict[str, Dict[str, List[str]]]:
"""Get Docker container information from test machines."""
result = subprocess.run(['./list_test_runner_machines', '--table'],
capture_output=True, text=True, check=True)
machines_info = defaultdict(lambda: {'containers': [], 'platforms': set()})
current_machine = ""
for line in result.stdout.split('\n'):
if line.startswith('## '):
current_machine = line.lstrip('# ').strip()
elif line.startswith('| CGAL-') and current_machine:
container = line.split('|')[1].strip()
machines_info[current_machine]['containers'].append(container)
return dict(machines_info)
def update_machines_platforms(machines_info: Dict[str, Dict[str, List[str]]], platforms_info: List[PlatformInfo]):
"""Update machines info with platform names."""
machine_mapping = {
'Friedrich': 'cgaltest@friedrich',
'friedrich': 'cgaltest@friedrich',
'cgal': 'lrineau@cgal',
'cgal (GF)': 'lrineau@cgal',
'Rubens': 'lrineau@rubens',
'rubens': 'lrineau@rubens',
'bonnard': 'lrineau@bonnard'
}
for platform in platforms_info:
if platform.tester in machine_mapping:
machine = machine_mapping[platform.tester]
if machine in machines_info:
machines_info[machine]['platforms'].add(platform.name)
def add_machines_summary(report: List[str], machines_info: Dict[str, Dict[str, List[str]]]):
"""Add machines summary to the report."""
report.append("\n## Test Machines Summary\n")
report.append("| Machine | Containers Count | Platforms |")
report.append("|---------|-----------------|-----------|")
for machine, info in machines_info.items():
containers_count = len(info['containers'])
platforms = ', '.join(sorted(info['platforms'])) or '-'
report.append(f"| {machine} | {containers_count} | {platforms} |")
def main(): def main():
"""Main function to generate the testsuite report.""" """Main function to generate the testsuite report."""

View File

@ -0,0 +1,199 @@
#!/bin/bash
TEST_MACHINES=$(
cat <<'HEREDOC'
lrineau@bonnard
lrineau@cgal
cgaltest@friedrich
lrineau@rubens
HEREDOC
)
cat <<HEREDOC
# Test runner machines #
The following machines are used to run the tests:
HEREDOC
machine_title() {
printf '\n## %s ##\n' $1
}
machine_tested_images() {
echo
echo '```plain'
ssh $1 cat /home/$2/.config/CGAL/test_cgal_docker_images
echo '```'
}
docker_is_active_cmd() {
systemctl is-active -q docker
return $?
}
declare -xf docker_is_active_cmd
docker_cmd() {
if docker_is_active_cmd; then
docker $@
else
podman --url unix:/var/run/podman/podman.sock $@
fi
}
declare -xf docker_cmd
list_of_containers_cmd() {
docker_cmd ps -a --format '{{.Names}}' --filter name="CGAL-"
}
declare -xf list_of_containers_cmd
container_status_cmd() {
docker_cmd inspect --format '{{.State.Status}}' $1
}
declare -xf container_status_cmd
container_human_readable_status_cmd() {
docker_cmd ps --all --filter name=$1 --format '{{.Status}}'
}
declare -xf container_human_readable_status_cmd
simplify_date_cmd() {
date=$1
pattern=' \+[0-9]{4} [A-Z]{3,}$'
if [[ $date =~ $pattern ]]; then
date=${date% *}
fi
echo "$date"
}
declare -xf simplify_date_cmd
container_start_time_cmd() {
simplify_date_cmd "$(docker_cmd inspect --format '{{.State.StartedAt}}' $1)"
}
declare -xf container_start_time_cmd
container_end_time_cmd() {
simplify_date_cmd "$(docker_cmd inspect --format '{{.State.FinishedAt}}' $1)"
}
declare -xf container_end_time_cmd
container_running_time_cmd() {
start_time=$(container_start_time_cmd $1)
end_time=$(container_end_time_cmd $1)
status=$(container_status_cmd $1)
if [ "$status" = "running" ]; then
end_time=$(date -u '+%Y-%m-%dT%H:%M:%S.%NZ')
fi
secs=$(($(date -d "$end_time" +%s) - $(date -d "$start_time" +%s)))
printf '%02dh:%02dm:%02ds\n' $((secs / 3600)) $((secs % 3600 / 60)) $((secs % 60))
}
declare -xf container_running_time_cmd
display_one_container_line_cmd() {
printf '%s\t%s\t%s\t%s\t%s\n' "$1" "$2" "$3" "$4" "$5"
}
declare -xf display_one_container_line_cmd
list_cgal_test_container_cmd() {
# docker_cmd ps -a --filter name=CGAL-
display_one_container_line_cmd "CONTAINER" "START TIME" "END TIME" "RUNNING TIME" "STATUS"
for container in $(list_of_containers_cmd); do
start_time="$(container_start_time_cmd $container)"
end_time="$(container_end_time_cmd $container)"
dur=$(container_running_time_cmd $container)
status="$(container_status_cmd $container) - $(container_human_readable_status_cmd $container)"
display_one_container_line_cmd "$container" "$start_time" "$end_time" "$dur" "$status"
done
}
declare -xf list_cgal_test_container_cmd
display_all_exported_cmd_functions() {
funcs=$(declare -F | awk '/ -fx .*_cmd$/ {print $3}')
for func in $funcs; do
declare -f $func
done
}
machine_list_cgal_test_container() {
printf '\n```tsv\n'
remote_script=$(
display_all_exported_cmd_functions
echo list_cgal_test_container_cmd
)
ssh $1 bash -s <<<"$remote_script"
printf '```\n'
}
command -v sed >/dev/null || {
echo 'sed is required'
exit 1
}
if [[ $1 == --table ]] && ! command -v pandoc >/dev/null; then
echo 'pandoc is required for the option --table'
exit 1
fi
if [[ $1 == --column ]] && ! command -v column >/dev/null; then
echo 'column is required for the option --column'
exit 1
fi
if [[ $1 == --bat ]] && ! command -v bat >/dev/null; then
echo 'bat is required for the option --bat'
exit 1
fi
set_pretty_csv_to_md_table() {
pretty_csv() (
echo
sed '/```/ d; /^$/ d' | pandoc -f tsv -t gfm
)
}
set_pretty_csv_to_column() {
pretty_csv() {
echo
column -t -s $'\t' -o $'\t' | sed 's/^\(```[^ ]*\) *\t.*/\1/'
}
}
set_pretty_csv_to_bat() {
pretty_csv() {
bat --tabs=50 --paging=never --plain -l csv
}
}
set_pretty_csv_to_cat() {
pretty_csv() {
cat
}
}
case "$1" in
--table) set_pretty_csv_to_md_table ;;
--column) set_pretty_csv_to_column ;;
--bat) set_pretty_csv_to_bat ;;
--plain) set_pretty_csv_to_cat ;;
'')
if command -v bat >/dev/null; then
set_pretty_csv_to_bat
elif command -v column >/dev/null; then
set_pretty_csv_to_column
else
set_pretty_csv_to_cat
fi
;;
*)
echo "Unknown option $1"
exit 1
;;
esac
for machine in $TEST_MACHINES; do
USER=${machine%@*}
HOST=${machine#*@}
machine_title $machine
printf '\nusing `%s`\n' "$(ssh $HOST docker --version)"
printf '\nTested images:\n'
machine_tested_images $HOST $USER
printf '\nCGAL test containers:\n'
machine_list_cgal_test_container $HOST $USER | pretty_csv
done