File: s2n_open_fds_test.py

package info (click to toggle)
aws-crt-python 0.24.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 75,932 kB
  • sloc: ansic: 418,984; python: 23,626; makefile: 6,035; sh: 4,075; ruby: 208; java: 82; perl: 73; cpp: 25; xml: 11
file content (65 lines) | stat: -rw-r--r-- 2,541 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# This script parses the LastDynamicAnalysis file generated by Valgrind running through CTest memcheck.
# It identifies any leaking file descriptors and triggers an error when detected.
# This enhances the capabilities of existing Valgrind checks.
# Output snippet for open file descriptors:
#  ==6652== FILE DESCRIPTORS: 6 open (3 std) at exit.
#  ==6652== Open AF_INET socket 6: 127.0.0.1:36915 <-> unbound
#  ==6652==    at 0x498B2EB: socket (syscall-template.S:120)
#  ==6652==    by 0x16CD16: s2n_new_inet_socket_pair (s2n_self_talk_ktls_test.c:69)
#  ==6652==    by 0x15DBB2: main (s2n_self_talk_ktls_test.c:168)
#  ==6652==
import os
import sys

EXIT_SUCCESS = 0
# Exit with error code 1 if leaking fds are detected.
ERROR_EXIT_CODE = 1
# This test is designed to be informational only, so we only print fifteen lines of error messages when a leak is detected.
NUM_OF_LINES_TO_PRINT = 15


def find_log_file(path):
    for f in os.listdir(path):
        if "LastDynamicAnalysis" in f:
            return os.path.join(path, f)

    raise FileNotFoundError("LastDynamicAnalysis log file is not found!")


def detect_leak(file):
    fd_leak_detected = False
    lines = file.readlines()
    for i in range(len(lines)):
        if "FILE DESCRIPTORS:" in lines[i]:
            # Example line: `==6096== FILE DESCRIPTORS: 4 open (3 std) at exit.`
            line_elements = lines[i].split()
            open_fd_count = line_elements[line_elements.index("DESCRIPTORS:") + 1]
            std_fd_count = line_elements[line_elements.index("std)") - 1][1:]
            # CTest memcheck writes to a LastDynamicAnslysis log file.
            # We allow that fd to remain opened.
            if int(open_fd_count) > int(std_fd_count) + 1:
                for j in range(NUM_OF_LINES_TO_PRINT):
                    print(lines[i + j], end="")
                print()
                fd_leak_detected = True
    return fd_leak_detected


def main():
    # Print banner of the test
    print("############################################################################")
    print("################# Test for Leaking File Descriptors ########################")
    print("############################################################################")

    with open(find_log_file(sys.argv[1]), 'r') as file:
        if detect_leak(file):
            sys.exit(ERROR_EXIT_CODE)

    return EXIT_SUCCESS


if __name__ == '__main__':
    main()