Skip to content

Commit

Permalink
TESTSUITE: Extract cmake logs in testresults. (#8235)
Browse files Browse the repository at this point in the history
## Summary of Changes

This PR moves and adds some CMake logs to the test results.
The changes of this Pull Request can be viewed
[here](https://cgal.geometryfactory.com/~nsaillant/CmakeLogsTestsuite/TestReport_cgal_tester_Fedora)

## Release Management

* Issue(s) solved (if any): #8165
  • Loading branch information
lrineau authored Sep 25, 2024
2 parents 2be2e30 + 7c8d5a0 commit 50219fc
Showing 1 changed file with 165 additions and 71 deletions.
236 changes: 165 additions & 71 deletions Testsuite/test/post_process_ctest_results.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,169 @@
import sys
import io
import re
import os
import collections
import logging
from itertools import islice

report_file=sys.argv[1]
report_name=sys.argv[2]
global_report_name=sys.argv[3]
rx=re.compile('(.*Configuring (examples|demo|test)*( in )*(test\/|examples\/|demo\/)*)((?!done)\w+)')
rx_demo=re.compile('.*in demo\/')
rx_examples=re.compile('.*in examples\/')


#open the Installation report
#For each NAME, check if NAME is a directory. If not, create one, create a
#text report, and write everything that is in the report until the next NAME
#in it. Then, add 'NAME r' in the global report. This should allow to get all
#the NOTICE and other info explaining why the configuration is skipped.

name=""
is_writing=False
is_ignored=False
global_report=open(global_report_name, "a+")
with open(report_file, "rt") as test_report:
for myline in test_report:
m=rx.match(myline)

if is_writing:
if m:
is_writing=False
test_report.close()
if is_ignored:
print("{label} {result}".format(label=name, result='r'), file=global_report)
is_ignored=False
else:
test_report.write(myline)
if not is_writing:
if m:
name=m.group(0).replace(m.group(1), "")
if rx_demo.match(myline):
name="{str}_Demo".format(str=name)
elif rx_examples.match(myline):
name="{str}_Examples".format(str=name)
elif name == "libCGAL":
name="libCGAL_shared"
elif name == "libCGAL_Core":
name="libCGALCore_shared"
elif name == "libCGAL_ImageIO":
name="libCGALimageIO_shared"
elif name == "libCGAL_Qt6":
name="libCGALQt6_shared"
if name=="incomplete":
is_writing=False
is_ignored=False
continue
else:
if not os.path.isdir(name):
is_ignored=True
os.mkdir(name)
test_report=open("{dir}/{file}".format(dir=name, file=report_name), "w+")
print("""
{scm_branch}
""" .format(scm_branch=open("{}/../../../../../.scm-branch".format(os.getcwd()), 'r').read()),file=test_report)
else:
is_ignored=False
test_report=open("{dir}/{file}".format(dir=name, file=report_name), "a+")
test_report.write(" --- CMake Results: --- \n\n")
is_writing=True
if is_writing:
is_writing=False
test_report.close()
if is_ignored:
print("{label} {result}".format(label=name, result='r'), file=global_report)
is_ignored=False
global_report.close()
CONFIG_REGEX = re.compile(
r"(.*Configuring (examples|demo|test) *in *(test/|examples/|demo/))((?!done)\w+)"
)
DEMO_REGEX = re.compile(r".*in demo/")
EXAMPLES_REGEX = re.compile(r'.*in examples/')
SEPARATOR = "------------------------------------------------------------------"

def find_third_separator(contents):
"""Find the position of the third separator line in the contents.
If there are less than 3 separators, then return the position where the third separator
should be inserted.
"""
separator_positions = (
i for i, line in enumerate(contents) if line.strip() == SEPARATOR
)
return next(islice(separator_positions, 2, None), len(contents) + 2)

def last(iterator):
"""Return the last item of an iterator or None if empty."""
return collections.deque(iterator, maxlen=1).pop()

def find_last(contents, query_string):
"""Find the number of the last line matching the query string."""
position, _ = last(filter(lambda x: x[1].strip() == query_string, enumerate(contents)))
return position

def read_file_lines(file_path):
"""Read the lines of a file and return them as a list."""
try:
with open(file_path, "r", encoding="utf-8") as file:
return file.readlines()
except IOError as e:
print(f"Error opening file {file_path}: {e}")
return []

def write_file_lines(file_path, contents):
"""Write the contents to a file. The contents should be a list of strings."""
try:
with open(file_path, "w", encoding="utf-8") as file:
file.write("".join(contents))
except IOError as e:
print(f"Error writing to file {file_path}: {e}")

def mark_package_as_missing_requirements(global_report_file_name, name):
"""Mark a package as missing requirements in the global report file."""
try:
with open(global_report_file_name, "a+", encoding="utf-8") as global_report:
print(f"{name} r", file=global_report)
except IOError as e:
print(f"Error opening global report file {global_report_file_name}: {e}")

def handle_end_of_package(package_name, report_file_name, lines_to_write):
"""Handle the end of a package by inserting the lines to write into the report file."""
if not lines_to_write:
return

file_path = f"{package_name}/{report_file_name}"
contents = read_file_lines(file_path)
position = find_third_separator(contents)

if not any(re.search("- CMake Results .*", content) for content in contents):
lines_to_write.insert(0, f"""
{SEPARATOR}
- CMake Results for {package_name}
{SEPARATOR}
""")
contents[position:position] = lines_to_write

write_file_lines(file_path, contents)


SCM_BRANCH_FILE_CONTENT = read_file_lines(f"{os.getcwd()}/../../../../../.scm-branch")

def handle_new_package__is_ignored(name, report_file_name, cmake_logs):
"""Handle new package creation or update logs if package already exists."""
if not os.path.isdir(name):
os.mkdir(name)
write_file_lines(f"{name}/{report_file_name}", SCM_BRANCH_FILE_CONTENT)
return True
else:
file_path = f"{name}/{report_file_name}"
contents = read_file_lines(file_path)
position = find_third_separator(contents)

if not any(re.search("- CMake Logs .*", content) for content in contents):
contents.insert(
position - 1,
SEPARATOR + "\n- CMake Logs from Installation \n" + SEPARATOR + "\n\n",
)
for log in cmake_logs:
contents.insert(position, log)
position += 1

write_file_lines(file_path, contents)
return False

def retrieve_cmake_logs(file_path):
"""Retrieve the CMake logs from a file and return them as a list."""
logging.debug("Opening file %s", file_path)
contents = read_file_lines(file_path)

position_begin = 1 + find_last(contents, SEPARATOR)
position_end = 1 + find_last(contents, "== Generating build files for tests ==")

cmake_logs = contents[position_begin:position_end]

logging.debug("CMake log beginning is at line %d", position_begin)
logging.debug("CMake log end is at line %d", position_end)
logging.debug("Length of contents is %d", len(contents))
logging.debug("Length of installation CMake logs is %d", len(cmake_logs))
logging.debug("Installation CMake logs are %s", "".join(cmake_logs))
return cmake_logs

def main():
"""Main function that processes the input report file and performs necessary operations."""
input_report_file_name = sys.argv[1]
report_file_name = sys.argv[2]
global_report_file_name = sys.argv[3]

cmake_logs = retrieve_cmake_logs(f"Installation/{report_file_name}")

package_name = ""
lines_to_write = []

for line in read_file_lines(input_report_file_name):

line_matches_new_package = CONFIG_REGEX.match(line)
if package_name and line_matches_new_package:
handle_end_of_package(package_name, report_file_name, lines_to_write)
lines_to_write = []
package_name = ""

if line_matches_new_package:
logging.debug("Found new package %s", line_matches_new_package.group(0))
logging.debug(" group 1 %s", line_matches_new_package.group(1))
new_package_name = line_matches_new_package.group(0).replace(
line_matches_new_package.group(1), ""
)
logging.debug("Setting package name to %s", new_package_name)
package_name = new_package_name
if DEMO_REGEX.match(line):
package_name = f"{package_name}_Demo"
elif EXAMPLES_REGEX.match(line):
package_name = f"{package_name}_Examples"

if package_name == "incomplete":
package_name = ""
continue
else:
is_ignored = handle_new_package__is_ignored(
package_name, report_file_name, cmake_logs
)
logging.debug("Is package %s ignored? %s", package_name, is_ignored)
if is_ignored:
mark_package_as_missing_requirements(global_report_file_name, package_name)

if package_name and not line_matches_new_package and line.strip() != "":
lines_to_write.append(line)

if __name__ == "__main__":
main()

0 comments on commit 50219fc

Please sign in to comment.