#!/usr/bin/env python

# coding: UTF-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# This script checks the valgrind output for errors.
# The track-fds does not cause an error if there are too many FDs open,
# therefore we parse the output and fail if there are open FDs

import sys
import subprocess
import os.path
import re

logfile = sys.argv[1]

valgrind_command = ' '.join('"' + item + '"' for item in sys.argv[2:])

# Execute a command and output its stdout text
def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline().decode('utf-8')
        if nextline == '' and process.poll() is not None:
            break
        sys.stdout.write(nextline)
        sys.stdout.flush()

    return process.returncode

ret_code = execute(valgrind_command)

if not os.path.isfile(logfile):
    print("### PYTHON ERROR: Valgrind logfile does not exist: " + logfile)
    exit(1)

log_content = ""
with open(logfile, 'r') as content_file:
    log_content = content_file.read()

if len(log_content) == 0:
    print("### PYTHON ERROR: Valgrind logfile is empty: " + logfile)
    exit(1)

# Try to parse the output. Look for the following line:
# ==17054== FILE DESCRIPTORS: 5 open at exit.
descriptors_re = re.compile(r"^==(\d+)==\s+FILE DESCRIPTORS: (\d+) open at exit.$", re.MULTILINE)
m = descriptors_re.match(log_content)

if not m:
    print("### PYTHON ERROR: File descriptors header not found: " + logfile)
    print(log_content)
    exit(1)

log_content = descriptors_re.sub('', log_content)

valgrind_number = m.group(1)
open_count = int(m.group(2))

# Remove the open file descriptors which are inherited from parent. they look like this:
#==21343== Open file descriptor 3: /home/user/open62541/build/bin/tests/discovery.log
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 2:
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 1:
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 0: /dev/pts/1
#==21343==    <inherited from parent>

replace_re = re.compile(r"^=="+str(valgrind_number)+r"==\s+Open file descriptor \d+:\s*[^\s]*$\n^=="+str(valgrind_number)+r"==\s+<inherited from parent>$\n(^=="+str(valgrind_number)+r"==\s+$\n)*", re.MULTILINE)
log_content = replace_re.sub('', log_content)

# Valgrind detected a memleak if ret_code != 0
if ret_code != 0:
    print(log_content)
    exit(ret_code)

# No issues by valgrind
if log_content.isspace():
    exit(0)

# There is something fishy in the valgrind output, so error-exit
print(log_content)
exit(1)

#!/usr/bin/env python

# coding: UTF-8
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# This script checks the valgrind output for errors.
# The track-fds does not cause an error if there are too many FDs open,
# therefore we parse the output and fail if there are open FDs

import sys
import subprocess
import os.path
import re

logfile = sys.argv[1]

valgrind_command = ' '.join('"' + item + '"' for item in sys.argv[2:])

# Execute a command and output its stdout text
def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline().decode('utf-8')
        if nextline == '' and process.poll() is not None:
            break
        sys.stdout.write(nextline)
        sys.stdout.flush()

    return process.returncode

ret_code = execute(valgrind_command)

if not os.path.isfile(logfile):
    print("### PYTHON ERROR: Valgrind logfile does not exist: " + logfile)
    exit(1)

log_content = ""
with open(logfile, 'r') as content_file:
    log_content = content_file.read()

if len(log_content) == 0:
    print("### PYTHON ERROR: Valgrind logfile is empty: " + logfile)
    exit(1)

# Try to parse the output. Look for the following line:
# ==17054== FILE DESCRIPTORS: 5 open at exit.
descriptors_re = re.compile(r"^==(\d+)==\s+FILE DESCRIPTORS: (\d+) open at exit.$", re.MULTILINE)
m = descriptors_re.match(log_content)

if not m:
    print("### PYTHON ERROR: File descriptors header not found: " + logfile)
    print(log_content)
    exit(1)

log_content = descriptors_re.sub('', log_content)

valgrind_number = m.group(1)
open_count = int(m.group(2))

# Remove the open file descriptors which are inherited from parent. they look like this:
#==21343== Open file descriptor 3: /home/user/open62541/build/bin/tests/discovery.log
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 2:
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 1:
#==21343==    <inherited from parent>
#==21343==
#==21343== Open file descriptor 0: /dev/pts/1
#==21343==    <inherited from parent>

replace_re = re.compile(r"^=="+str(valgrind_number)+r"==\s+Open file descriptor \d+:\s*[^\s]*$\n^=="+str(valgrind_number)+r"==\s+<inherited from parent>$\n(^=="+str(valgrind_number)+r"==\s+$\n)*", re.MULTILINE)
log_content = replace_re.sub('', log_content)

# Valgrind detected a memleak if ret_code != 0
if ret_code != 0:
    print(log_content)
    exit(ret_code)

# No issues by valgrind
if log_content.isspace():
    exit(0)

# There is something fishy in the valgrind output, so error-exit
print(log_content)
exit(1)

#!/usr/bin/env python # coding: UTF-8 # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # This script checks the valgrind output for errors. # The track-fds does not cause an error if there are too many FDs open, # therefore we parse the output and fail if there are open FDs # Execute a command and output its stdout text # Poll process for new output until finished ## PYTHON ERROR: Valgrind logfile does not exist: " + logfile) ## PYTHON ERROR: Valgrind logfile is empty: " + logfile) # Try to parse the output. Look for the following line: # ==17054== FILE DESCRIPTORS: 5 open at exit. ## PYTHON ERROR: File descriptors header not found: " + logfile) # Remove the open file descriptors which are inherited from parent. they look like this: #==21343== Open file descriptor 3: /home/user/open62541/build/bin/tests/discovery.log #==21343==    <inherited from parent> #==21343== #==21343== Open file descriptor 2: #==21343==    <inherited from parent> #==21343== #==21343== Open file descriptor 1: #==21343==    <inherited from parent> #==21343== #==21343== Open file descriptor 0: /dev/pts/1 #==21343==    <inherited from parent> # Valgrind detected a memleak if ret_code != 0 # No issues by valgrind # There is something fishy in the valgrind output, so error-exit