]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
[EDF29852] : add a new test of management of SIGKILL in containers
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 26 Mar 2024 16:50:58 +0000 (17:50 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 26 Mar 2024 16:50:58 +0000 (17:50 +0100)
src/Basics/KernelBasis.i
src/Container/SALOME_ContainerHelper.py
src/Container/SALOME_PyNode.py
src/Launcher/Test/CMakeLists.txt
src/Launcher/Test/CTestTestfileInstall.cmake
src/Launcher/Test/testCrashProofContainer.py [new file with mode: 0644]

index 904878e3b5b1f01a7827f00745b5592ed28c4739..8979e3eabd55da968786eb375e05d95e50f8e8f0 100644 (file)
@@ -33,6 +33,7 @@ using namespace SALOME;
 %include std_vector.i
 
 %template(dvec) std::vector<double>;
+%template(strvec) std::vector<std::string>;
 
 %exception {
    try 
index 70bd9d6f6a8ffb6635c088e04306d3e3034d04f9..82bef6bfad5b04865e6fe31ef592e3dbf1c34797 100644 (file)
@@ -432,9 +432,14 @@ class ScriptInfoAbstract:
   
 class ScriptInfoClt(ScriptInfoAbstract):
   def __init__(self, scriptPtr):
+      def unPickledSafe( dataPickled ):
+        if len(dataPickled) > 0:
+          return pickle.loads(dataPickled)
+        else:
+           return None  
       self._node_name = scriptPtr.getName()
       self._code = scriptPtr.getCode()
-      self._exec = [pickle.loads(elt.getObj()) for elt in scriptPtr.listOfExecs()]
+      self._exec = [unPickledSafe(elt.getObj()) for elt in scriptPtr.listOfExecs()]
 
 class ScriptInfo(ScriptInfoAbstract):
   def __init__(self, nodeName, code, execs):
index 80ad94c7539e516c71106d24bfeff617fe11448b..02cfb9188695d6bb75e76ea9f340c728734dd005 100644 (file)
@@ -767,17 +767,24 @@ class PythonFunctionEvaluatorParams:
     import os
     return "To clean files : ( cd {} && rm {} )".format( os.path.dirname(self._main_filename)," ".join( [os.path.basename(self._main_filename),self._code_filename,self._in_context_filename] ) )
 
-  def strDependingOnReturnCode(self, returnCode):
+  def strDependingOnReturnCode(self, keepFilesToReplay, returnCode):
     if returnCode == -1:
       return f"return with non zero code ({returnCode})"
     else:
       banner = 200*"*"
-      return f"""return with non zero code ({returnCode})
+      if keepFilesToReplay:
+        return f"""return with non zero code ({returnCode})
 {banner}
-Looks like a hard crash as returnCode {returnCode} != 1
+Looks like a hard crash as returnCode {returnCode} != 0
 {self.replayCmd}
 {self.cleanOperations}
 {banner}
+"""
+      else:
+        return f"""return with non zero code ({returnCode})
+{banner}
+Looks like a hard crash as returnCode {returnCode} != 0
+{banner}
 """
 
 def ExecCrashProofGeneric( code, context, outargsname, instanceOfLogOfCurrentSession, keepFilesToReplay ):
@@ -843,7 +850,7 @@ def ExecCrashProofGeneric( code, context, outargsname, instanceOfLogOfCurrentSes
       evParams.destroyOnKO()
     else:
       evParams.destroyOnOK()
-    raise RuntimeError(f"Subprocess launched {evParams.strDependingOnReturnCode(returnCode)}stdout :\n{stdout}\nstderr :\n{stderr}")
+    raise RuntimeError(f"Subprocess launched {evParams.strDependingOnReturnCode(keepFilesToReplay,returnCode)}stdout :\n{stdout}\nstderr :\n{stderr}")
 
 def ExecCrashProofWithReplay( code, context, outargsname, instanceOfLogOfCurrentSession ):
   return ExecCrashProofGeneric(code, context, outargsname, instanceOfLogOfCurrentSession, True)
index b266d0ce765e84d218e4b660df26c80cbc3e403d..0271f039b73157c01ae648105a7a90e48842dcdc 100644 (file)
@@ -22,7 +22,7 @@
 IF(NOT WIN32)
 
   INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_launcher.py ${CMAKE_CURRENT_SOURCE_DIR}/TestSSLAttached.py
-  ${CMAKE_CURRENT_SOURCE_DIR}/testPerfLogManager1.py DESTINATION ${KERNEL_TEST_DIR}/Launcher)
+  ${CMAKE_CURRENT_SOURCE_DIR}/testPerfLogManager1.py ${CMAKE_CURRENT_SOURCE_DIR}/testCrashProofContainer.py DESTINATION ${KERNEL_TEST_DIR}/Launcher)
 
   INSTALL(FILES CTestTestfileInstall.cmake
           DESTINATION ${KERNEL_TEST_DIR}/Launcher
index add4238744952cd16f3cf5a2b5b5eb9d649da0ee..69f747159447f77f02f781d9aca310f243da3de7 100644 (file)
@@ -33,6 +33,10 @@ IF(NOT WIN32)
   SET(TEST_NAME ${COMPONENT_NAME}_PerfLogManager1)
   ADD_TEST(${TEST_NAME} ${PYTHON_TEST_DRIVER} 2000 testPerfLogManager1.py)
   SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+  
+  SET(TEST_NAME ${COMPONENT_NAME}_testCrashProofContainer)
+  ADD_TEST(${TEST_NAME} ${PYTHON_TEST_DRIVER} 2000 testCrashProofContainer.py)
+  SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
   # /!\ DO NOT SET TIMEOUT PROPERTY IF USING ${SALOME_TEST_DRIVER}
   #     BUT PASS TIMEOUT VALUE TO THE DRIVER
 
diff --git a/src/Launcher/Test/testCrashProofContainer.py b/src/Launcher/Test/testCrashProofContainer.py
new file mode 100644 (file)
index 0000000..cb17204
--- /dev/null
@@ -0,0 +1,111 @@
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2024  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
+#
+
+import unittest
+import os
+import salome
+import Engines
+import pylauncher
+import SALOME_PyNode
+import KernelBasis
+import SALOME
+
+import glob
+import pickle
+import tempfile
+import logging
+from datetime import datetime
+
+
+killMeCode = """
+import os
+j = 7 * i
+os.kill( os.getpid() , signal.SIGKILL)# the aim of test is here
+"""
+
+normalCode = """
+j = 8 * i
+my_log_4_this_session.addFreestyleAndFlush( ("a",777) ) # to check that hidden var is still accessible
+"""
+
+class testPerfLogManager1(unittest.TestCase):
+    def tess0(self):
+        """
+        EDF29852 : Kill container with OutOfProcessNoReplay mode and see if container still responds.
+        """
+        salome.salome_init()
+        assert(isinstance(KernelBasis.GetAllPyExecutionModes(),tuple))
+        KernelBasis.SetPyExecutionMode("OutOfProcessNoReplay") # the aim of test is here
+        hostname = "localhost"
+        cp = pylauncher.GetRequestForGiveContainer(hostname,"container_crash_test")
+        salome.cm.SetOverrideEnvForContainersSimple(env = [("SALOME_BIG_OBJ_ON_DISK_THRES","1000")])
+        cont = salome.cm.GiveContainer(cp)
+        poa = salome.orb.resolve_initial_references("RootPOA")
+        obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["i"],{"i": 3} ) )) ; id_o = poa.activate_object(obj) ; refPtr = poa.id_to_reference(id_o)
+        pyscript2 = cont.createPyScriptNode("testScript2",killMeCode)
+        pyscript2.executeFirst(refPtr)
+        self.assertRaises(SALOME.SALOME_Exception,pyscript2.executeSecond,["j"]) # an agressive SIGKILL has been received and container is still alive :) - it throws an exception :)
+        pyscript2.UnRegister()
+        pyscript3 = cont.createPyScriptNode("testScript3",normalCode)
+        obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["i"],{"i": 3} ) )) ; id_o = poa.activate_object(obj) ; refPtr = poa.id_to_reference(id_o)
+        pyscript3.executeFirst(refPtr)
+        ret = pyscript3.executeSecond(["j"])
+        ret = pickle.loads( SALOME_PyNode.SeqByteReceiver(ret[0]).data() )
+        self.assertEqual(ret,24) # container has received a SIGKILL but it kindly continue to respond :)
+        a = salome.logm.NaiveFetch()
+        self.assertEqual(a[0][2][0].get().freestyle,[('a',777)])
+        cont.Shutdown()
+
+    def test1(self):
+        """
+        EDF29852 : Same than test0 Kill container with OutOfProcessWithReplay mode and see if container still responds. But in addition we test if the python script is runnable !
+        """
+        salome.salome_init()
+        assert(isinstance(KernelBasis.GetAllPyExecutionModes(),tuple))
+        KernelBasis.SetPyExecutionMode("OutOfProcessWithReplay") # the aim of test is here
+        hostname = "localhost"
+        cp = pylauncher.GetRequestForGiveContainer(hostname,"container_crash_test")
+        salome.cm.SetOverrideEnvForContainersSimple(env = [("SALOME_BIG_OBJ_ON_DISK_THRES","1000")])
+        cont = salome.cm.GiveContainer(cp)
+        poa = salome.orb.resolve_initial_references("RootPOA")
+        obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["i"],{"i": 3} ) )) ; id_o = poa.activate_object(obj) ; refPtr = poa.id_to_reference(id_o)
+        pyscript2 = cont.createPyScriptNode("testScript2",killMeCode)
+        pyscript2.executeFirst(refPtr)
+        self.assertRaises(SALOME.SALOME_Exception,pyscript2.executeSecond,["j"]) # an agressive SIGKILL has been received and container is still alive :) - it throws an exception :)
+        pyscript2.UnRegister()
+        pyscript3 = cont.createPyScriptNode("testScript3",normalCode)
+        obj = SALOME_PyNode.SenderByte_i(poa,pickle.dumps( (["i"],{"i": 3} ) )) ; id_o = poa.activate_object(obj) ; refPtr = poa.id_to_reference(id_o)
+        pyscript3.executeFirst(refPtr)
+        ret = pyscript3.executeSecond(["j"])
+        ret = pickle.loads( SALOME_PyNode.SeqByteReceiver(ret[0]).data() )
+        self.assertEqual(ret,24) # container has received a SIGKILL but it kindly continue to respond :)
+        a = salome.logm.NaiveFetch()
+        self.assertEqual(a[0][2][0].get().freestyle,[('a',777)])
+        cont.Shutdown()
+
+if __name__ == '__main__':
+    from salome_utils import positionVerbosityOfLoggerRegardingState,setVerboseLevel,setVerbose
+    salome.standalone()
+    salome.salome_init()
+    setVerbose(True)
+    setVerboseLevel(logging.DEBUG)
+    positionVerbosityOfLoggerRegardingState()
+    unittest.main()
+