From f1c8a1c9f0c3677b3855ee588b137206cb5dab1d Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Aguerre?= Date: Thu, 24 Apr 2014 16:33:35 +0200 Subject: [PATCH] add salome_starter.py for application folder detection --- bin/appliskel/CMakeLists.txt | 1 + bin/appliskel/salome | 61 ++----------- bin/appliskel/salome_starter.py | 73 +++++++++++++++ .../TestConcurrentSession.py | 15 ++- .../usecase_concurrent_single_appli.sh | 91 +++++++++++++++++++ .../tests/launcher/TestLauncherSessionArgs.py | 8 +- .../tests/launcher/TestLauncherSimple.py | 53 +++++++++++ bin/salomeContext.py | 4 +- 8 files changed, 246 insertions(+), 60 deletions(-) create mode 100644 bin/appliskel/salome_starter.py create mode 100644 bin/appliskel/tests/concurrentSession/usecase_concurrent_single_appli.sh create mode 100644 bin/appliskel/tests/launcher/TestLauncherSimple.py diff --git a/bin/appliskel/CMakeLists.txt b/bin/appliskel/CMakeLists.txt index cb345a342..785287b0f 100755 --- a/bin/appliskel/CMakeLists.txt +++ b/bin/appliskel/CMakeLists.txt @@ -36,6 +36,7 @@ SET(SCRIPTS update_catalogs.py kill_remote_containers.py salome # this is the Python launcher (without .py extension to avoid conflicts when importing salome python package) + salome_starter.py ) SALOME_INSTALL_SCRIPTS("${SCRIPTS}" ${SALOME_INSTALL_SCRIPT_SCRIPTS}/appliskel) diff --git a/bin/appliskel/salome b/bin/appliskel/salome index b9819eb14..31f0da6bb 100755 --- a/bin/appliskel/salome +++ b/bin/appliskel/salome @@ -22,60 +22,14 @@ import os import sys -def __detectAppliPath(fromPath): - detection_criterion = "USERS" # the application folder is found if it contains a USERS subfolder - - users_folder = os.path.join(fromPath, detection_criterion) - if os.path.isdir(users_folder): - return fromPath - - pattern = "/bin/salome/appliskel" - if fromPath.endswith(pattern): - currentPath = __detectAppliPath(fromPath[:-len(pattern)]) - if not currentPath is None: - return currentPath - - if sys.platform.startswith("linux"): - filename = os.path.basename(__file__) - link_target = os.readlink(os.path.join(fromPath,filename)) # LINUX ONLY - currentPath = os.path.dirname(os.path.abspath(link_target)) - return __detectAppliPath(currentPath) - - return None -# - -# Preliminary work to initialize path to SALOME Python modules -def __initialize(): - currentPath = os.path.dirname( os.path.abspath( __file__ ) ) - homePath = os.path.realpath(os.path.expanduser('~')) - - appliPath = __detectAppliPath(currentPath) - - if appliPath is None: - print "ERROR: Unable to find application folder" - sys.exit(0) - - appliPath = os.path.relpath(appliPath, homePath) - absoluteAppliPath = os.path.join(homePath, appliPath) - os.environ['APPLI'] = appliPath # needed to convert .sh environment files - os.environ['ABSOLUTE_APPLI_PATH'] = absoluteAppliPath - - sys.path[:0] = [absoluteAppliPath+'/bin/salome'] - - # define folder to store omniorb config (initially in virtual application folder) - try: - from salomeContextUtils import setOmniOrbUserPath - setOmniOrbUserPath() - except Exception, e: - print e - sys.exit(1) -# End of preliminary work - def main(args): # Identify application path then locate configuration files - __initialize() + currentPath = os.path.dirname( os.path.abspath( __file__ ) ) + launcherFile = os.path.basename(__file__) + from salome_starter import initialize + initialize(currentPath, launcherFile) - if args == ['--help']: + if len(args) == 1 and args[0] in ['--help', 'help', '-h', '--h']: from salomeContext import usage usage() sys.exit(0) @@ -100,14 +54,11 @@ def main(args): # Start SALOME, parsing command line arguments (out, err), returncode = context.runSalome(args) - #print 'Thank you for using SALOME!' - if out: sys.stdout.write(out) - if err: sys.stderr.write(err) - + #print 'Thank you for using SALOME!' sys.exit(returncode) except SalomeContextException, e: import logging diff --git a/bin/appliskel/salome_starter.py b/bin/appliskel/salome_starter.py new file mode 100644 index 000000000..215a49e8d --- /dev/null +++ b/bin/appliskel/salome_starter.py @@ -0,0 +1,73 @@ +#! /usr/bin/env python + +# Copyright (C) 2014 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 +# + +import os +import sys + +# This file is imported by launchers to help with application folder detection. +# Import is possible because Python automatically add to sys.path the folder of +# a running script (here a launcher). + +def __detectAppliPath(fromPath, launcherFile): + detection_criterion = "USERS" # the application folder is found if it contains a USERS subfolder + + users_folder = os.path.join(fromPath, detection_criterion) + if os.path.isdir(users_folder): + return fromPath + + pattern = "/bin/salome/appliskel" + if fromPath.endswith(pattern): + currentPath = __detectAppliPath(fromPath[:-len(pattern)], launcherFile) + if not currentPath is None: + return currentPath + + if sys.platform.startswith("linux"): + link_target = os.readlink(os.path.join(fromPath,launcherFile)) # LINUX ONLY + currentPath = os.path.dirname(os.path.abspath(link_target)) + return __detectAppliPath(currentPath, launcherFile) + + return None +# + +# Preliminary work to initialize path to SALOME Python modules +def initialize(launcherPath, launcherFile): + homePath = os.path.realpath(os.path.expanduser('~')) + appliPath = __detectAppliPath(launcherPath, launcherFile) + + if appliPath is None: + print "ERROR: Unable to find application folder" + sys.exit(0) + + appliPath = os.path.relpath(appliPath, homePath) + absoluteAppliPath = os.path.join(homePath, appliPath) + os.environ['APPLI'] = appliPath # needed to convert .sh environment files + os.environ['ABSOLUTE_APPLI_PATH'] = absoluteAppliPath + + sys.path[:0] = [absoluteAppliPath+'/bin/salome'] + + # define folder to store omniorb config (initially in virtual application folder) + try: + from salomeContextUtils import setOmniOrbUserPath + setOmniOrbUserPath() + except Exception, e: + print e + sys.exit(1) +# End of preliminary work diff --git a/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py b/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py index 9e70667d3..aab1777af 100644 --- a/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py +++ b/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py @@ -32,6 +32,7 @@ class TestConcurrentLaunch(unittest.TestCase): # Initialize path to SALOME application path_to_launcher = os.getenv("SALOME_LAUNCHER") appli_dir = os.path.dirname(path_to_launcher) + sys.path[:0] = [os.path.join(appli_dir, "bin", "salome", "appliskel")] # Configure session startup self.SALOME = imp.load_source("SALOME", os.path.join(appli_dir,"salome")) @@ -42,10 +43,20 @@ class TestConcurrentLaunch(unittest.TestCase): pass # def appli(self, args=[]): - self.SALOME.main(self.SALOME_appli_args + args) + try: + self.SALOME.main(self.SALOME_appli_args + args) + except SystemExit, e: + if str(e) != '0': + logging.error(e) + pass # def session(self, args=[]): - self.SALOME.main(self.SALOME_shell_args + args) + try: + self.SALOME.main(self.SALOME_shell_args + args) + except SystemExit, e: + if str(e) != '0': + logging.error(e) + pass # def test01_SingleSession(self): print "** Testing single session **" diff --git a/bin/appliskel/tests/concurrentSession/usecase_concurrent_single_appli.sh b/bin/appliskel/tests/concurrentSession/usecase_concurrent_single_appli.sh new file mode 100644 index 000000000..1bd7b2da2 --- /dev/null +++ b/bin/appliskel/tests/concurrentSession/usecase_concurrent_single_appli.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +echo "This is a script that can be run concurrently." +echo "It takes as single argument the number of concurrent executions:" +echo "Usage: " $0 " " +echo +echo "Here is what executed code contents looks like:" +echo " - do some stuff" +echo " - run SALOME in terminal mode, and log port number to a file" +echo " - run some scripts (Python, binary), each in a dedicated SALOME session on a specific port" +echo " - do some stuff" +echo + + +if [ $# != 2 ]; then + echo "Usage:" $0 " " + exit 1 +fi + +NB_COMP=$1 +OUTPUT_FOLDER=$2 +BASE_DIR=`pwd` +SALOME_PORT=-1 + +case ${OUTPUT_FOLDER} in + /*) ;; # OUTPUT_FOLDER is given as an absolute path + *) OUTPUT_FOLDER=${BASE_DIR}/${OUTPUT_FOLDER} ;; # build absolute path +esac + +if [ "x${SALOME_APPLI_FOLDER}" == "x" ]; then + echo "SALOME_APPLI_FOLDER variable is not set (or empty)." + echo "Try to locate SALOME launcher in current directory." + SALOME_APPLI_FOLDER=`pwd` + if ! [ -f ${SALOME_APPLI_FOLDER}/salome ]; then + echo "Unable to locate salome command." + exit 1 + fi +fi + +start_salome() { + ${SALOME_APPLI_FOLDER}/salome start -t --ns-port-log=${OUTPUT_FOLDER}/session.log + SALOME_PORT=`cat ${OUTPUT_FOLDER}/session.log` + echo "SALOME is running on port" ${SALOME_PORT} +} + +stop_salome() { + ${SALOME_APPLI_FOLDER}/salome shell -p ${SALOME_PORT} ${SALOME_APPLI_FOLDER}/bin/salome/killSalomeWithPort.py args:${SALOME_PORT} +} + +run_command() { + WORK_DIR=`pwd` # a pushd has been done before calling this function + echo "Run command in folder:" ${WORK_DIR} + ${SALOME_APPLI_FOLDER}/salome shell -p ${SALOME_PORT} ${SALOME_APPLI_FOLDER}/bin/salome/waitContainers.py + ${SALOME_APPLI_FOLDER}/salome shell -p ${SALOME_PORT} ${BASE_DIR}/myscript.py args:${WORK_DIR} + echo "Execution terminated in folder:" ${WORK_DIR} +} + + +# make myscript.py +echo " +#!/usr/bin/env python +import os +import sys +import time +work_dir = sys.argv[1] +logfile = os.path.join(work_dir, 'myscript.log') +msg = 'Waiting for 3s in folder %s'%work_dir +time.sleep(3) +with open(logfile, 'w') as f: + f.write(msg) +" > ${BASE_DIR}/myscript.py + +# Build output folders +typeset -i i=${NB_COMP} +while (( $i > 0 )) +do + mkdir -p ${OUTPUT_FOLDER}/execution_$i + let "i=i-1" +done + +# Start execution +start_salome +typeset -i i=${NB_COMP} +while (( $i > 0 )) +do + pushd ${OUTPUT_FOLDER}/execution_$i > /dev/null + run_command & + popd > /dev/null + let "i=i-1" +done +stop_salome diff --git a/bin/appliskel/tests/launcher/TestLauncherSessionArgs.py b/bin/appliskel/tests/launcher/TestLauncherSessionArgs.py index 0a050bfed..20445e9df 100644 --- a/bin/appliskel/tests/launcher/TestLauncherSessionArgs.py +++ b/bin/appliskel/tests/launcher/TestLauncherSessionArgs.py @@ -55,6 +55,7 @@ class TestSessionArgs(unittest.TestCase): path_to_launcher = os.getenv("SALOME_LAUNCHER") appli_dir = os.path.dirname(path_to_launcher) envd_dir = os.path.join(appli_dir, "env.d") + sys.path[:0] = [os.path.join(appli_dir, "bin", "salome", "appliskel")] # Configure session startup self.SALOME = imp.load_source("SALOME", os.path.join(appli_dir,"salome")) @@ -67,7 +68,12 @@ class TestSessionArgs(unittest.TestCase): self.removeLogFile() # def session(self, args=[]): - self.SALOME.main(self.SALOME_args + args) + try: + self.SALOME.main(self.SALOME_args + args) + except SystemExit, e: + if str(e) != '0': + logger.error(e) + pass # def removeLogFile(self): try: diff --git a/bin/appliskel/tests/launcher/TestLauncherSimple.py b/bin/appliskel/tests/launcher/TestLauncherSimple.py new file mode 100644 index 000000000..28a07ceac --- /dev/null +++ b/bin/appliskel/tests/launcher/TestLauncherSimple.py @@ -0,0 +1,53 @@ +# Copyright (C) 2013-2014 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 +# + +import unittest + +import os +import sys +import imp +import logging + +class TestLauncher(unittest.TestCase): + + def setUp(self): + path_to_launcher = os.getenv("SALOME_LAUNCHER") + appli_dir = os.path.dirname(path_to_launcher) + sys.path[:0] = [os.path.join(appli_dir, "bin", "salome", "appliskel")] + + self.SALOME = imp.load_source("SALOME", os.path.join(appli_dir,"salome")) + # + + def testHello(self): + try: + self.SALOME.main(["shell", "hello.py"]) + except SystemExit, e: + if str(e) != '0': + logging.error(e) + # +# + +if __name__ == "__main__": + path_to_launcher = os.getenv("SALOME_LAUNCHER") + if not path_to_launcher: + msg = "Error: please set SALOME_LAUNCHER variable to the salome command of your application folder." + raise Exception(msg) + + unittest.main() +# diff --git a/bin/salomeContext.py b/bin/salomeContext.py index c8b5f6d41..5e89ba15c 100644 --- a/bin/salomeContext.py +++ b/bin/salomeContext.py @@ -343,7 +343,6 @@ class SalomeContext: # def _killAll(self, args=[]): - absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','') try: import PortManager # mandatory from multiprocessing import Process @@ -415,7 +414,8 @@ class SalomeContext: if not hasattr(self, '_logger'): self._logger = logging.getLogger(__name__) #self._logger.setLevel(logging.DEBUG) - self._logger.setLevel(logging.WARNING) + #self._logger.setLevel(logging.WARNING) + self._logger.setLevel(logging.ERROR) return self._logger # -- 2.39.2