-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TESTSUITE: Extract cmake logs in testresults. (#8235)
## 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
Showing
1 changed file
with
165 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |