From f6120c1bdb84ed1cc827ffab8284c0ac2709189f Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 11 Aug 2021 16:04:45 +0200 Subject: [PATCH] python_test_driver.py declination of salome_test_driver.py for SSL mode (timeout management) --- bin/appliskel/salome_tester/CMakeLists.txt | 1 + .../salome_tester/python_test_driver.py | 148 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100755 bin/appliskel/salome_tester/python_test_driver.py diff --git a/bin/appliskel/salome_tester/CMakeLists.txt b/bin/appliskel/salome_tester/CMakeLists.txt index a9745f541..a8dc6c26a 100644 --- a/bin/appliskel/salome_tester/CMakeLists.txt +++ b/bin/appliskel/salome_tester/CMakeLists.txt @@ -20,4 +20,5 @@ SALOME_INSTALL_SCRIPTS(salome_instance.py ${SALOME_INSTALL_SCRIPT_SCRIPTS}) SALOME_INSTALL_SCRIPTS(salome_test_driver.py ${SALOME_INSTALL_SCRIPT_SCRIPTS}/appliskel) +SALOME_INSTALL_SCRIPTS(python_test_driver.py ${SALOME_INSTALL_SCRIPT_SCRIPTS}/appliskel) SALOME_INSTALL_SCRIPTS(salome_test_driver_gui.py ${SALOME_INSTALL_SCRIPT_SCRIPTS}/appliskel) diff --git a/bin/appliskel/salome_tester/python_test_driver.py b/bin/appliskel/salome_tester/python_test_driver.py new file mode 100755 index 000000000..f6d9c571c --- /dev/null +++ b/bin/appliskel/salome_tester/python_test_driver.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +# Copyright (C) 2015-2021 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +""" +Usage: python_test_driver.py [test command arguments] +""" + +import sys +import os +import subprocess +import signal +from contextlib import suppress + +# Run test +def runTestBegin(command): + print("Running:", " ".join(command)) + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return p + +def runTestEffective(process): + out, err = process.communicate() + res = process.returncode + # About res value: + # A negative value -N indicates that the child was terminated by signal N (Unix only). + # On Unix, the value 11 generally corresponds to a segmentation fault. + return res, out, err +# + +# Display output and errors +def processResult(res, out, err): + # Decode output + out = out.decode('utf_8', errors='ignore') if out else '' + err = err.decode('utf_8', errors='ignore') if err else '' + + # Execute hook if it is installed + if getattr(processResult, '__hook', None): + res, out, err = getattr(processResult, '__hook')(res, out, err) + + # Print standard output + if out: + print(out) + + # Print standard error + if err: + print(" ** Detected error **") + print("Error code: ", res) + print(err, end=' \n') + print(" ** end of message **") + + return res +# + +def installHook(hook=None): + """Install custome hook to process test result.""" + with suppress(AttributeError, IndexError): + hook = hook.split(',') + hook_path = hook.pop(0) + hook_func = hook.pop(0) + if os.path.exists(hook_path) and hook_func: + with open(hook_path, 'rb') as hook_script: + dic = {} + exec(hook_script.read(), dic) + processResult.__hook = dic.get(hook_func) + print("Custom hook has been installed") +# + +subPIDToKill = None + +# Timeout management +class TimeoutException(Exception): + """Exception raised when test timeout is reached.""" +# +def timeoutHandler(signum, frame): + if subPIDToKill: + try: + os.kill(subPIDToKill, signal.SIGTERM) + except: + pass + raise TimeoutException() +# + +if __name__ == "__main__": + timeout_delay = sys.argv[1] + args = sys.argv[2:] + + # Install hook if supplied via command line + with suppress(IndexError, ValueError): + index = args.index('--hook') + args.pop(index) + hook = args.pop(index) + installHook(hook) + + # Add explicit call to python executable if a Python script is passed as + # first argument + if not args: + print("Invalid arguments for python_test_driver.py. No command defined.") + sys.exit(1) + _, ext = os.path.splitext(args[0]) + if ext == ".py": + test_and_args = [sys.executable] + args + else: + test_and_args = args + + # Set timeout handler + print("Test timeout explicitly set to: %s seconds"%timeout_delay) + timeout_sec = abs(int(timeout_delay)-10) + if sys.platform == 'win32': + from threading import Timer + timer = Timer(timeout_sec, timeoutHandler) + timer.start() + else: + signal.alarm(timeout_sec) + signal.signal(signal.SIGALRM, timeoutHandler) + + res = 1 + try: + process = runTestBegin(test_and_args) + subPIDToKill = process.pid + res, out, err = runTestEffective(process) + res = processResult(res, out, err) + except TimeoutException: + print("FAILED : timeout(%s) is reached"%timeout_delay) + except: + import traceback + traceback.print_exc() + pass + if sys.platform == 'win32': + timer.cancel() + print("Exit test with status code:", res) + sys.exit(res) +# -- 2.39.2