Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add open fds valgrind check #4851

Merged
merged 21 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ if (BUILD_TESTING)
--error-limit=no \
--num-callers=40 \
--undef-value-errors=no \
--track-fds=yes \
--log-fd=2 \
--suppressions=valgrind.suppressions")

Expand Down
81 changes: 81 additions & 0 deletions codebuild/bin/s2n_open_fds_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import os
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
import re
import sys

# Allow stdin, stdout, stderr, and the file descriptor for dynamic analysis log to remain open at exit
ACCEPTABLE_OPEN_FDS = 4
ERROR_EXIT_CODE = 123
boquan-fang marked this conversation as resolved.
Show resolved Hide resolved

analysis_file_location = "../../build/Testing/Temporary"
boquan-fang marked this conversation as resolved.
Show resolved Hide resolved
analysis_file_pattern = re.compile(r"^LastDynamicAnalysis*")
# This regular expression captures valgrind 3.13 and valgrind 3.18+ log
boquan-fang marked this conversation as resolved.
Show resolved Hide resolved
fd_pattern = re.compile(r"FILE DESCRIPTORS: \d+ open(?: \(\d+ std\))? at exit.$")
error_message_start_pattern = re.compile(r"^Running /codebuild/output/src\d+/src/.*")
boquan-fang marked this conversation as resolved.
Show resolved Hide resolved
error_message_end_pattern = re.compile(r"^<end of output>$")


def open_analysis_file(path):
for file_name in os.listdir(path):
if analysis_file_pattern.match(file_name):
file = open(os.path.join(path, file_name), 'r')
return file


def print_error_message(file_name, error_message):
# Take the path to the failing test file
print(f"{file_name.split(' ')[1]} leaks file descriptor(s):\n")
dougch marked this conversation as resolved.
Show resolved Hide resolved
print(''.join(error_message))
return 0


def read_analysis_file(file):
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
exit_code = 0
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
error_message = []
to_store = False
to_print = False
file_name = ""
for line in file:
start_match = error_message_start_pattern.search(line)
if start_match:
file_name = start_match.group()
"""
The FILE DESCRIPTORS string sometimes come on the same line
as the Running s2n_test.c. Hence, we need multiple check to handle
that corner case.
"""
open_fd_match = fd_pattern.search(line)
if open_fd_match:
# Take the number of open file descriptors and check against the acceptable amount
if int(re.findall(r"\d+", open_fd_match.group())[0]) > ACCEPTABLE_OPEN_FDS:
exit_code = ERROR_EXIT_CODE
to_print = True
# Only store information about leaking file descriptors
to_store = True
else:
to_store = False

if error_message_end_pattern.match(line):
if to_print:
print_error_message(file_name, error_message)
to_store = False
error_message.clear()
file_name = ""
to_print = False

if to_store:
if open_fd_match:
error_message.append(open_fd_match.group() + '\n')
else:
error_message.append(line)

file.close()
return exit_code


def main():
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
file = open_analysis_file(analysis_file_location)
return read_analysis_file(file)


if __name__ == '__main__':
sys.exit(main())
3 changes: 3 additions & 0 deletions codebuild/spec/buildspec_valgrind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@ phases:
CTEST_OUTPUT_ON_FAILURE=1 \
cmake --build build/ --target test \
-- ARGS="--test-action memcheck"
- cd codebuild/bin
- echo Test for leaking file descriptors
boquan-fang marked this conversation as resolved.
Show resolved Hide resolved
- python3 s2n_open_fds_test.py
Loading