]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Add tests for SalomeLauncher
authorOvidiu Mircescu <ovidiu.mircescu@edf.fr>
Wed, 26 Nov 2014 17:39:54 +0000 (18:39 +0100)
committerOvidiu Mircescu <ovidiu.mircescu@edf.fr>
Wed, 26 Nov 2014 17:39:54 +0000 (18:39 +0100)
src/Launcher/CMakeLists.txt
src/Launcher/Test/CMakeLists.txt [new file with mode: 0644]
src/Launcher/Test/test_launcher.py [new file with mode: 0755]
src/UnitTests/prepare_test.py [new file with mode: 0755]

index 4a14d049674c1517364dabcdea114709f13a49ee..3f5534a98aa4b2b43600ea4fc276a1e72eed90d8 100755 (executable)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+IF(SALOME_BUILD_TESTS)
+  ADD_SUBDIRECTORY(Test)
+ENDIF(SALOME_BUILD_TESTS)
+
 INCLUDE_DIRECTORIES(
   ${LIBXML2_INCLUDE_DIR}
   ${OMNIORB_INCLUDE_DIR}
diff --git a/src/Launcher/Test/CMakeLists.txt b/src/Launcher/Test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..67563f7
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (C) 2012-2014  CEA/DEN, EDF R&D
+#
+# 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
+#
+
+# --- rules ---
+
+IF(NOT WIN32)
+  ADD_TEST(NAME SalomeLauncher
+           COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../UnitTests/prepare_test.py
+           ${CMAKE_CURRENT_SOURCE_DIR}/test_launcher.py
+           -d KERNEL_ROOT_DIR=${CMAKE_INSTALL_PREFIX}
+          )
+ENDIF()
diff --git a/src/Launcher/Test/test_launcher.py b/src/Launcher/Test/test_launcher.py
new file mode 100755 (executable)
index 0000000..2196ae6
--- /dev/null
@@ -0,0 +1,316 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import unittest
+import os
+import sys
+import time
+
+# Test of SalomeLauncher.
+# This test should be run in the salome environment, using "salome shell"
+# If YACS_ROOT_DIR is not set, the test of submitting a YACS schema will be
+# skiped.
+class TestCompo(unittest.TestCase):
+  @classmethod
+  def setUpClass(cls):
+    # Prepare the test directory
+    import shutil
+    cls.test_dir = os.path.join(os.getcwd(), "test_dir")
+    cls.suffix = time.strftime("-%Y-%m-%d-%H-%M-%S")
+    shutil.rmtree(cls.test_dir, ignore_errors=True)
+    os.mkdir(cls.test_dir)
+    
+  ##############################
+  # test of python_salome job
+  ##############################
+  def test_salome_py_job(self):
+    case_test_dir = os.path.join(TestCompo.test_dir, "salome_py")
+    os.mkdir(case_test_dir)
+    
+    old_dir = os.getcwd()
+    os.chdir(case_test_dir)
+    
+    # job script
+    script_file = "myScript.py"
+    job_script_file = os.path.join(case_test_dir, script_file)
+    script_text = """#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# verify import salome
+import salome
+salome.salome_init()
+
+f = open('result.txt', 'w')
+f.write("Salut!")
+f.close()
+
+import os
+os.mkdir("subdir")
+f = open(os.path.join("subdir",'autre.txt'), 'w')
+f.write("Hello!")
+f.close()
+"""
+    f = open(job_script_file, "w")
+    f.write(script_text)
+    f.close()
+    
+    local_result_dir = os.path.join(case_test_dir, "result_simple_py_job")
+    job_params = salome.JobParameters()
+    job_params.job_name = "MyJob"
+    job_params.job_type = "python_salome"
+    job_params.job_file = job_script_file
+    job_params.in_files = []
+    job_params.out_files = ["result.txt", "subdir"]
+    job_params.result_directory = local_result_dir
+    job_params.resource_required = salome.ResourceParameters()
+    job_params.resource_required.nb_proc = 1
+    
+    job_params.work_directory = "/tmp/job_salome_py" + self.suffix
+    
+    launcher = salome.naming_service.Resolve('/SalomeLauncher')
+    job_id = launcher.createJob(job_params)
+    
+    launcher.launchJob(job_id)
+    
+    import time
+    jobState = launcher.getJobState(job_id)
+    print "Job %d state: %s" % (job_id,jobState)
+    while jobState != "FINISHED" and jobState != "FAILED" :
+      time.sleep(5)
+      jobState = launcher.getJobState(job_id)
+      print "Job %d state: %s" % (job_id,jobState)
+      pass
+    
+    self.assertEqual(jobState, "FINISHED")
+    
+    # getJobResults to default directory (result_directory)
+    launcher.getJobResults(job_id, "")
+    try:
+      f = open(os.path.join(local_result_dir, "result.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "Salut!")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+    
+    try:
+      f = open(os.path.join(local_result_dir, "subdir", "autre.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "Hello!")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+    
+    # getJobResults to a specific directory
+    mydir = os.path.join(case_test_dir, "custom_result_dir")
+    launcher.getJobResults(job_id, mydir)
+    try:
+      f = open(os.path.join(mydir, "result.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "Salut!")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+    
+    try:
+      f = open(os.path.join(mydir, "subdir", "autre.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "Hello!")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+      pass
+    
+    os.chdir(old_dir)
+    
+  ##############################
+  # test of command job type
+  ##############################
+  def test_command(self):
+    case_test_dir = os.path.join(TestCompo.test_dir, "command")
+    os.mkdir(case_test_dir)
+    
+    # job script
+    data_file = "in.txt"
+    script_file = "myEnvScript.py"
+    script_text = """#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os,sys
+
+text_result = os.getenv("ENV_TEST_VAR","")
+
+f = open('result.txt', 'w')
+f.write(text_result)
+f.close()
+
+in_f = open("in.txt", "r")
+in_text = in_f.read()
+in_f.close()
+
+os.mkdir("subdir")
+f = open(os.path.join("subdir",'altul.txt'), 'w')
+f.write(in_text)
+f.close()
+"""
+    abs_script_file = os.path.join(case_test_dir, script_file)
+    f = open(abs_script_file, "w")
+    f.write(script_text)
+    f.close()
+    os.chmod(abs_script_file, 0o755)
+    
+    #environement script
+    env_file = "myEnv.sh"
+    env_text = """export ENV_TEST_VAR="expected"
+"""
+    f = open(os.path.join(case_test_dir, env_file), "w")
+    f.write(env_text)
+    f.close()
+    
+    # write data file
+    f = open(os.path.join(case_test_dir, data_file), "w")
+    f.write("expected data")
+    f.close()
+    
+    # job params
+    local_result_dir = os.path.join(case_test_dir, "resultats_env")
+    job_params = salome.JobParameters()
+    job_params.job_name = "CommandJob"
+    job_params.job_type = "command"
+    job_params.job_file = script_file
+    job_params.env_file = env_file
+    job_params.in_files = [data_file]
+    job_params.out_files = ["result.txt", "subdir"]
+    job_params.local_directory = case_test_dir
+    job_params.result_directory = local_result_dir
+    job_params.resource_required = salome.ResourceParameters()
+    job_params.resource_required.nb_proc = 1
+    job_params.work_directory = "/tmp/command_job" + self.suffix
+    
+    # create and launch the job
+    launcher = salome.naming_service.Resolve('/SalomeLauncher')
+    job_id = launcher.createJob(job_params)
+    launcher.launchJob(job_id)
+    
+    # wait for the end of the job
+    import time
+    jobState = launcher.getJobState(job_id)
+    print "Job %d state: %s" % (job_id,jobState)
+    while jobState != "FINISHED" and jobState != "FAILED" :
+      time.sleep(3)
+      jobState = launcher.getJobState(job_id)
+      print "Job %d state: %s" % (job_id,jobState)
+      pass
+    
+    # verify the results
+    self.assertEqual(jobState, "FINISHED")
+    launcher.getJobResults(job_id, "")
+    try:
+      f = open(os.path.join(local_result_dir, "result.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "expected")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+      
+  ##############################
+  # test of yacs job type
+  ##############################
+  def test_yacs(self):
+    yacs_path = os.getenv("YACS_ROOT_DIR", "")
+    if not os.path.isdir(yacs_path):
+      self.skipTest("Needs YACS module to run. Please define YACS_ROOT_DIR.")
+    
+    case_test_dir = os.path.join(TestCompo.test_dir, "yacs")
+    os.mkdir(case_test_dir)
+    
+    #environement script
+    env_file = "myEnv.sh"
+    env_text = """export ENV_TEST_VAR="expected"
+"""
+    f = open(os.path.join(case_test_dir, env_file), "w")
+    f.write(env_text)
+    f.close()
+    
+    # job script
+    script_text = """<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="newSchema_1">
+   <property name="DefaultStudyID" value="1"/>
+   <container name="DefaultContainer">
+      <property name="container_kind" value="Salome"/>
+      <property name="attached_on_cloning" value="0"/>
+      <property name="container_name" value="FactoryServer"/>
+      <property name="name" value="localhost"/>
+   </container>
+   <inline name="PyScript0">
+      <script><code><![CDATA[import os
+text_result = os.getenv("ENV_TEST_VAR","")
+f = open('result.txt', 'w')
+f.write(text_result)
+f.close()
+]]></code></script>
+      <load container="DefaultContainer"/>
+   </inline>
+</proc>
+"""
+    yacs_file = "mySchema.xml"
+    job_script_file = os.path.join(case_test_dir, yacs_file)
+    f = open(job_script_file, "w")
+    f.write(script_text)
+    f.close()
+    
+    local_result_dir = os.path.join(case_test_dir, "result_yacs_job")
+    job_params = salome.JobParameters()
+    job_params.job_name = "MyYacsJob"
+    job_params.job_type = "yacs_file"
+    job_params.job_file = job_script_file
+    job_params.env_file = os.path.join(case_test_dir,env_file)
+    #job_params.in_files = [case_test_dir]
+    job_params.out_files = ["result.txt"]
+    job_params.result_directory = local_result_dir
+    job_params.resource_required = salome.ResourceParameters()
+    job_params.resource_required.nb_proc = 1
+    
+    job_params.work_directory = "/tmp/job_yacs" + self.suffix
+    
+    launcher = salome.naming_service.Resolve('/SalomeLauncher')
+    job_id = launcher.createJob(job_params)
+    
+    launcher.launchJob(job_id)
+    
+    import time
+    jobState = launcher.getJobState(job_id)
+    print "Job %d state: %s" % (job_id,jobState)
+    while jobState != "FINISHED" and jobState != "FAILED" :
+      time.sleep(5)
+      jobState = launcher.getJobState(job_id)
+      print "Job %d state: %s" % (job_id,jobState)
+      pass
+    
+    self.assertEqual(jobState, "FINISHED")
+    
+    # getJobResults to default directory (result_directory)
+    launcher.getJobResults(job_id, "")
+    try:
+      f = open(os.path.join(local_result_dir, "result.txt"), 'r')
+      text = f.read()
+      f.close()
+      self.assertEqual(text, "expected")
+    except IOError,ex:
+      self.fail("IO exception:" + str(ex));
+    
+if __name__ == '__main__':
+    # creat study
+    import salome
+    salome.salome_init()
+    unittest.main()
+    
+    # load catalogs
+#    mc = salome.naming_service.Resolve('/Kernel/ModulCatalog')
+#    ior = salome.orb.object_to_string(mc)
+#    import SALOMERuntime
+#    SALOMERuntime.RuntimeSALOME_setRuntime()
+#    salome_runtime = SALOMERuntime.getSALOMERuntime()
+#    session_catalog = salome_runtime.loadCatalog("session", ior)
+#    salome_runtime.addCatalog(session_catalog)
+    
diff --git a/src/UnitTests/prepare_test.py b/src/UnitTests/prepare_test.py
new file mode 100755 (executable)
index 0000000..59bc0dc
--- /dev/null
@@ -0,0 +1,117 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+usage="""
+This script prepares the test environment and runs a test script:
+ - clean and create test directory
+ - create a SALOME application
+ - launch salome
+ - launch the test script within SALOME environment
+ - kill salome
+
+ This script uses the following environment variables:
+   - ROOT_SALOME : directory which contains salome_context.cfg.
+                  This variable is usually defined in salome_prerequisites.sh
+   - KERNEL_ROOT_DIR and YACS_ROOT_DIR : directories of modules installation
+                  Those variables are usually defined in salome_modules.sh
+ Environment variables can be passed to the script using the -d option.
+"""
+
+import os
+import sys
+
+class TestEnvironment:
+  def setUp(self):
+    import shutil
+    shutil.rmtree("appli", ignore_errors=True)
+    
+    # create config_appli.xml in current directory
+    salome_path = os.getenv("ROOT_SALOME", "")
+    salome_context_file = os.path.join(salome_path, "salome_context.cfg")
+    if not os.path.isfile(salome_context_file):
+      print "File salome_context.cfg not found."
+      print "Search path:" + salome_path
+      print "This test needs ROOT_SALOME environment variable in order to run"
+      exit(1)
+    
+    config_appli_text = '''<application>
+<context path="''' + salome_context_file + '''"/>
+<modules>
+   <module name="KERNEL" path="'''
+    kernel_path = os.getenv("KERNEL_ROOT_DIR", "")
+    if not os.path.isdir(kernel_path) :
+      print "KERNEL_ROOT_DIR not defined"
+      exit(1)
+      pass
+    
+    config_appli_text += kernel_path + '"/>'
+        
+    # some tests need YACS module.
+    yacs_path = os.getenv("YACS_ROOT_DIR", "")
+    if os.path.isdir(yacs_path):
+      cls.hasYacs = True
+      config_appli_text += '''
+   <module name="YACS" path="'''
+      config_appli_text += yacs_path + '"/>'
+      pass
+    config_appli_text += '''
+</modules>
+</application>'''
+
+    f = open("config_appli.xml", 'w')
+    f.write(config_appli_text)
+    f.close()
+    
+    # create a SALOME application
+    appli_gen_file = os.path.join(kernel_path,
+                                  "bin","salome","appli_gen.py")
+    appli_dir = "appli"
+    os.system(appli_gen_file + " --prefix="+appli_dir+
+                               " --config=config_appli.xml")
+    
+    # start salome
+    import imp
+    sys.path[:0] = [os.path.join(appli_dir, "bin", "salome", "appliskel")]
+    self.salome_module = imp.load_source("SALOME", os.path.join(appli_dir, "salome"))
+    try:
+      self.salome_module.main(["start", "-t"])
+    except SystemExit, e:
+      # There is an exit() call in salome.main. Just ignore it.
+      pass
+    
+  def run(self, script):
+    ret = 0
+    try:
+      ret = self.salome_module.main(["shell", script])
+    except SystemExit, e:
+      # return exit value
+      ret = e.code
+    return ret
+  
+  def tearDown(self):
+    try:
+      self.salome_module.main(["killall"])
+    except SystemExit, e:
+      pass
+    pass
+  pass #class TestEnvironment
+
+if __name__ == '__main__':
+  import argparse
+  parser = argparse.ArgumentParser(description=usage,
+                    formatter_class=argparse.RawDescriptionHelpFormatter)
+  parser.add_argument('command', help="Test command to be run.")
+  parser.add_argument('-d', '--define', action='append', help="VARIABLE=VALUE")
+
+  args = parser.parse_args()
+  for opt in args.define:
+    opts = opt.split('=', 1)
+    os.environ[opts[0]] = opts[1]
+  
+  envTest = TestEnvironment()
+  envTest.setUp()
+  ret = envTest.run(args.command)
+  envTest.tearDown()
+  exit(ret)
+  pass
+