]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
unit tests for concurrent sessions
authorCédric Aguerre <cedric.aguerre@edf.fr>
Fri, 14 Mar 2014 16:29:30 +0000 (17:29 +0100)
committerCédric Aguerre <cedric.aguerre@edf.fr>
Fri, 14 Mar 2014 16:29:30 +0000 (17:29 +0100)
bin/appliskel/tests/CMakeLists.txt
bin/appliskel/tests/concurrentSession/CMakeLists.txt
bin/appliskel/tests/concurrentSession/TestConcurrentSession.py [new file with mode: 0644]
bin/appliskel/tests/concurrentSession/TestMinimalExample.py
bin/appliskel/tests/concurrentSession/testConcurrentSession.py [deleted file]
bin/appliskel/tests/concurrentSession/usecase_concurrent.sh [new file with mode: 0755]
bin/searchFreePort.py

index 4d96e416ae7f30d187b361d8b9fb476bc7a128b5..602a867f97efedf01df11e4e453f15ac70d6e2f9 100644 (file)
@@ -17,5 +17,5 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-#ADD_SUBDIRECTORY(concurrentSession)
+ADD_SUBDIRECTORY(concurrentSession)
 ADD_SUBDIRECTORY(launcher)
index 029ff882fbb18459c53ff09b6ea39f5801adbd58..7ffa4027ef022fa8943aa10000f6606de4b3e618 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-include(CTest)
-ENABLE_TESTING()
+FILE(GLOB py_scripts "${CMAKE_CURRENT_SOURCE_DIR}/*.py")
+FILE(GLOB sh_scripts "${CMAKE_CURRENT_SOURCE_DIR}/*.sh")
 
-# define environment for running tests
-SET(PYTHON_VERSION ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
+LIST(APPEND scripts ${py_scripts} ${sh_scripts})
 
-SET(THIS_PYTHONPATH ${CMAKE_SOURCE_DIR}/bin:$ENV{PYTHONPATH})
-#SET(THIS_LD_LIBRARY_PATH $ENV{LD_LIBRARY_PATH})
-
-# add tests (use make test to run)
-FILE(GLOB tests "${CMAKE_CURRENT_SOURCE_DIR}/Test*.py")
-FOREACH(file ${tests})
-  GET_FILENAME_COMPONENT(testname ${file} NAME_WE)
-  ADD_TEST(${testname} ${PYTHON_EXECUTABLE} "${file}")
-#  SET_PROPERTY(TEST ${testname} APPEND PROPERTY ENVIRONMENT PYTHONPATH=${THIS_PYTHONPATH} LD_LIBRARY_PATH=${THIS_LD_LIBRARY_PATH})
-  SET_PROPERTY(TEST ${testname} APPEND PROPERTY ENVIRONMENT PYTHONPATH=${THIS_PYTHONPATH})
-ENDFOREACH()
-
-# install Python scripts
-FILE(GLOB scripts "${CMAKE_CURRENT_SOURCE_DIR}/*.py")
 SALOME_INSTALL_SCRIPTS("${scripts}" ${SALOME_INSTALL_SCRIPT_SCRIPTS}/appliskel/tests/concurrentSession)
diff --git a/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py b/bin/appliskel/tests/concurrentSession/TestConcurrentSession.py
new file mode 100644 (file)
index 0000000..5f8376a
--- /dev/null
@@ -0,0 +1,101 @@
+# 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 tempfile
+
+import os
+import sys
+import imp
+from cStringIO import StringIO
+import multiprocessing
+
+
+class TestConcurrentLaunch(unittest.TestCase):
+  def setUp(self):
+    # Initialize path to SALOME application
+    path_to_launcher = os.getenv("SALOME_LAUNCHER")
+    appli_dir = os.path.dirname(path_to_launcher)
+
+    # Configure session startup
+    self.SALOME = imp.load_source("SALOME", os.path.join(appli_dir,"salome"))
+    self.SALOME_appli_args = ["start", "-t"]
+    self.SALOME_shell_args = ["shell"]
+  #
+  def tearDown(self):
+    pass
+  #
+  def appli(self, args=[]):
+    self.SALOME.main(self.SALOME_appli_args + args)
+  #
+  def session(self, args=[]):
+    self.SALOME.main(self.SALOME_shell_args + args)
+  #
+  def test01_SingleSession(self):
+    print "** Testing single session **"
+    self.session(["hello.py"])
+  #
+  def test02_MultiSession(self):
+    print "** Testing multi sessions **"
+    jobs = []
+    for i in range(3):
+      p = multiprocessing.Process(target=self.session, args=(["hello.py"],))
+      jobs.append(p)
+      p.start()
+
+    for j in jobs:
+      j.join()
+  #
+  def test03_SingleAppli(self):
+    print "** Testing single appli **"
+    current_directory = os.path.dirname(os.path.abspath(__file__))
+    session_log = tempfile.NamedTemporaryFile(prefix='session_', suffix='.log')
+    self.appli(["--ns-port-log=%s"%session_log.name])
+    port_number = None
+    with open(session_log.name, "r") as f:
+      port_number = f.readline()
+    self.session(["hello.py"])
+    self.session(["-p", port_number, "killSalomeWithPort.py", "args:%s"%port_number])
+    session_log.close()
+  #
+  def test04_MultiAppli(self):
+    print "** Testing multi appli **"
+    jobs = []
+    for i in range(3):
+      p = multiprocessing.Process(target=self.test03_SingleAppli)
+      jobs.append(p)
+      p.start()
+
+    for j in jobs:
+      j.join()
+  #
+#
+
+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)
+
+  if not os.path.isfile("hello.py"):
+    with open("hello.py", "w") as f:
+      f.write("print 'Hello!'")
+
+  unittest.main()
+#
index 8b38d582dafa70aa98bb26fbc9b3db68216e7b05..b740cdd00b88528776982fbcf62be49905f82f8f 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-from PortManager import getPort, releasePort, stopServer
+import os
 import sys
 import multiprocessing
 import unittest
 
-def port_reservation(prefered=None, test=None, expected=None):
+def port_reservation(obtained_ports, prefered=None, test=None, expected=None):
+  from PortManager import getPort
   if prefered:
     port = getPort(prefered)
   else:
     port = getPort()
-  print "port = %s"%port
+  print "obtained port = %s"%port
+
+  obtained_ports.put(port)
 
   if expected:
-    print "expected = %s"%expected
-    test.assertTrue(port == expected)
+    test.assertTrue(port == expected, "used = %s, expected = %s"%(port, expected))
 #
 
 class TestMinimalExample(unittest.TestCase):
-  @classmethod
-  def tearDownClass(cls):
-    stopServer()
-    stopServer() # no effect
-  #
   def testSequential(self):
-    print "BEGIN testSequential"
+    from PortManager import releasePort, getBusyPorts
+    print "\nBEGIN testSequential"
+    print "Busy ports", getBusyPorts()
+    obtained_ports = multiprocessing.Queue()
+
     processes = [
-      multiprocessing.Process(target=port_reservation)
+      multiprocessing.Process(target=port_reservation, args=(obtained_ports,))
       for i in range(3)
       ]
 
@@ -54,51 +55,66 @@ class TestMinimalExample(unittest.TestCase):
     for p in processes:
       p.join()
 
+    print "Busy ports", getBusyPorts()
     # Try to get specific port number
-    expected = 2872
-    p = multiprocessing.Process(target=port_reservation, args=(2872, self,expected,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2872, self, 2872,))
     p.start()
     p.join()
 
     # Try to get specific port number
-    p = multiprocessing.Process(target=port_reservation, args=(2812, self,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2812, self,))
+    p.start()
+    p.join()
+
+    # Try to get specific port number
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2812, self,))
     p.start()
     p.join()
 
     # Release port
+    print "release port 2812"
     p = multiprocessing.Process(target=releasePort, args=(2812,))
     p.start()
     p.join()
 
     # Try to get specific port number
-    expected = 2812
-    p = multiprocessing.Process(target=port_reservation, args=(2812, self,expected,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2812, self, 2812,))
     p.start()
     p.join()
 
+    # Release ports
+    print "Busy ports", getBusyPorts()
+    while not obtained_ports.empty():
+      port = obtained_ports.get()
+      print "release port", port
+      p = multiprocessing.Process(target=releasePort, args=(port,))
+      p.start()
+      p.join()
+
     print "END testSequential"
   #
+
   def testConcurrent(self):
-    print "BEGIN testConcurrent"
+    from PortManager import releasePort, getBusyPorts
+    print "\nBEGIN testConcurrent"
+    print "Busy ports", getBusyPorts()
+    obtained_ports = multiprocessing.Queue()
     processes = [
-      multiprocessing.Process(target=port_reservation)
+      multiprocessing.Process(target=port_reservation, args=(obtained_ports,))
+
       for i in range(3)
       ]
 
     # Try to get specific port number
-    p = multiprocessing.Process(target=port_reservation, args=(2852,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2872, self, 2872,))
     processes.append(p)
 
     # Try to get specific port number
-    p = multiprocessing.Process(target=port_reservation, args=(2812,))
-    processes.append(p)
-
-    # Release port
-    p = multiprocessing.Process(target=releasePort, args=(2812,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2812,))
     processes.append(p)
 
     # Try to get specific port number
-    p = multiprocessing.Process(target=port_reservation, args=(2812,))
+    p = multiprocessing.Process(target=port_reservation, args=(obtained_ports, 2812,))
     processes.append(p)
 
     for p in processes:
@@ -107,8 +123,30 @@ class TestMinimalExample(unittest.TestCase):
     for p in processes:
       p.join()
 
+    # Release ports
+    print "Busy ports", getBusyPorts()
+    while not obtained_ports.empty():
+      port = obtained_ports.get()
+      print "release port", port
+      p = multiprocessing.Process(target=releasePort, args=(port,))
+      p.start()
+      p.join()
+
     print "END testConcurrent"
   #
 #
 
-unittest.main()
+if __name__ == "__main__":
+  omniorb_user_path = os.getenv("OMNIORB_USER_PATH")
+  if not omniorb_user_path:
+    msg = "Error: please set OMNIORB_USER_PATH variable to the salome KERNEL install folder."
+    raise Exception(msg)
+
+  try:
+    import PortManager
+  except ImportError:
+    msg = "Error: can't import PortManager; please check PYTHONPATH variable."
+    raise Exception(msg)
+
+  unittest.main()
+#
diff --git a/bin/appliskel/tests/concurrentSession/testConcurrentSession.py b/bin/appliskel/tests/concurrentSession/testConcurrentSession.py
deleted file mode 100644 (file)
index 93eeee4..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-# 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 os
-import sys
-import unittest
-import multiprocessing
-import imp
-
-def unwrap_self_session(arg, **kwarg):
-  return TestConcurrentLaunch.session(*arg, **kwarg)
-#
-
-class TestConcurrentLaunch(unittest.TestCase):
-  @classmethod
-  def setUpClass(cls):
-    # Initialize path to SALOME application
-    path_to_launcher = os.getenv("SALOME_LAUNCHER")
-    appli_dir = os.path.dirname(path_to_launcher)
-    cls.envd_dir = os.path.join(appli_dir, "env.d")
-
-    # Configure session startup
-    cls.SALOME = imp.load_source("SALOME", os.path.join(appli_dir,"salome"))
-    #cls.SALOME_args = ["shell", "--config="+cls.envd_dir]
-    cls.SALOME_args = ["--config="+cls.envd_dir]
-  #
-  @classmethod
-  def tearDownClass(cls):
-    args = ["killall", "--config="+cls.envd_dir]
-    cls.SALOME.main(args)
-    pass
-  #
-  def session(self, args=[]):
-    self.SALOME.main(self.SALOME_args + args)
-  #
-  def test01_SingleSession(self):
-    print "** Testing single session **"
-    self.session()
-  #
-  def test02_MultiSession(self):
-    print "** Testing multi sessions **"
-
-    jobs = []
-    for i in range(3):
-      p = multiprocessing.Process(target=unwrap_self_session, args=([self],))
-      jobs.append(p)
-      p.start()
-
-    for j in jobs:
-      j.join()
-  #
-#
-
-
-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/appliskel/tests/concurrentSession/usecase_concurrent.sh b/bin/appliskel/tests/concurrentSession/usecase_concurrent.sh
new file mode 100755 (executable)
index 0000000..a730f47
--- /dev/null
@@ -0,0 +1,67 @@
+#!/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 "<nb_execution>"
+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 "<nb_execution> <output_folder>"
+    exit 1
+fi
+
+NB_COMP=$1
+OUTPUT_FOLDER=$2
+BASE_DIR=`pwd`
+
+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
+
+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 start -t --ns-port-log=${WORK_DIR}/session.log
+    ${SALOME_APPLI_FOLDER}/salome shell -p `cat ${WORK_DIR}/session.log` ${SALOME_APPLI_FOLDER}/bin/salome/waitContainers.py
+    ${SALOME_APPLI_FOLDER}/salome shell -p `cat ${WORK_DIR}/session.log` ${BASE_DIR}/hello.py
+    ${SALOME_APPLI_FOLDER}/salome shell -p `cat ${WORK_DIR}/session.log` ${SALOME_APPLI_FOLDER}/bin/salome/killSalomeWithPort.py args:`cat ${WORK_DIR}/session.log`
+    echo "Execution terminated in folder:" ${WORK_DIR}
+}
+
+
+# make hello.py
+echo "
+#!/usr/bin/env python
+print 'Hello\!'
+" > ${BASE_DIR}/hello.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
+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
index 99005ef9d8ba20acc1b4e389369e1bf2640e68b1..999a952e9b28352d8f5f14fec9d69fb99acee29c 100644 (file)
@@ -158,7 +158,6 @@ def __savePortToFile(args):
   if args.has_key('ns_port_log_file'):
     omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
     file_name = os.path.join(omniorbUserPath, args["ns_port_log_file"])
-    print file_name, os.environ['NSPORT']
     with open(file_name, "w") as f:
       f.write(os.environ['NSPORT'])
 #