mirror of https://github.com/CGAL/cgal
Add Docker information retrieval and reporting to testsuite report script
This commit is contained in:
parent
7b5d5e4b1c
commit
1105ed409d
|
|
@ -2,6 +2,8 @@ import json
|
|||
from typing import Dict, List
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from collections import defaultdict
|
||||
import subprocess
|
||||
import re
|
||||
import requests
|
||||
|
||||
|
|
@ -82,12 +84,15 @@ def fragment_name(platform: PlatformInfo) -> str:
|
|||
|
||||
def generate_markdown_report(platforms_info: List[PlatformInfo], version: str) -> str:
|
||||
"""Generate a markdown report from the platforms information."""
|
||||
machines_info = get_docker_info()
|
||||
update_machines_platforms(machines_info, platforms_info)
|
||||
report = []
|
||||
report.append("# TestSuite Report")
|
||||
report.append(f"\nGenerated on: {
|
||||
datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
url = TESTSUITE_URL_TEMPLATE.format(version=version)
|
||||
report.append(f"\nCGAL Version: [{version}]({url})\n")
|
||||
add_machines_summary(report, machines_info)
|
||||
report.append("## Platforms Summary\n")
|
||||
report.append("| Platform | Debug | OS | Tester | Compiler |")
|
||||
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}")
|
||||
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():
|
||||
"""Main function to generate the testsuite report."""
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue