Salome HOME
[EDF30399] : Expose replay-dir parameter to define directory holding scenarii in...
[modules/yacs.git] / src / yacsloader_swig / Test / testSaveLoadRun.py
index ed08ddb6a616ed6720aa855c72d5e413187579d2..c84ce3dce45c7f8d894ea4f62c9266fa90d07c74 100755 (executable)
@@ -1,4 +1,5 @@
-# Copyright (C) 2006-2016  CEA/DEN, EDF R&D
+#!/usr/bin/env python3
+# Copyright (C) 2006-2024  CEA, EDF
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 #
 
 import unittest
+import tempfile
+import os
+
 import pilot
 import SALOMERuntime
 import loader
+import salome
 
 import datetime
 
@@ -28,21 +33,31 @@ class TestSaveLoadRun(unittest.TestCase):
   def setUp(self):
     SALOMERuntime.RuntimeSALOME.setRuntime()
     self.r=SALOMERuntime.getSALOMERuntime()
+    self.workdir = tempfile.mkdtemp(suffix=".yacstest")
+    pass
+
+  def tearDown(self):
+    salome.salome_init()
+    cm = salome.lcc.getContainerManager()
+    cm.ShutdownContainers()
+    salome.dsm.shutdownScopes()
     pass
 
   def test0(self):
     """First test of HP Container no loop here only the 3 sorts of python nodes (the Distributed is it still used and useful ?) """
-    fname="TestSaveLoadRun0.xml"
+    fname=os.path.join(self.workdir, "TestSaveLoadRun0.xml")
     nbOfNodes=8
     sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
     l=loader.YACSLoader()
     p=self.r.createProc("prTest0")
     td=p.createType("double","double")
     ti=p.createType("int","int")
+    pg=pilot.PlayGround()
+    pg.setData([("localhost",4)])
     cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(4)
     cont.setProperty("name","localhost")
     cont.setProperty("hostname","localhost")
+    cont.setProperty("nb_proc_per_node","1")
     script0="""
 def ff(nb,dbg):
     from math import cos
@@ -107,6 +122,7 @@ print("coucou from script1-%i  -> %s"%(dbg,str(datetime.datetime.now()-ref)))
     ex=pilot.ExecutorSwig()
     self.assertEqual(p.getState(),pilot.READY)
     st=datetime.datetime.now()
+    p.propagePlayGround(pg)
     # 1st exec
     ex.RunW(p,0)
     print("Time spend of test0 to run 1st %s"%(str(datetime.datetime.now()-st)))
@@ -125,18 +141,20 @@ print("coucou from script1-%i  -> %s"%(dbg,str(datetime.datetime.now()-ref)))
 
   def test1(self):
     """ HP Container again like test0 but the initialization key of HPContainer is used here."""
-    fname="TestSaveLoadRun1.xml"
+    fname=os.path.join(self.workdir, "TestSaveLoadRun1.xml")
     nbOfNodes=8
     sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
     l=loader.YACSLoader()
     p=self.r.createProc("prTest1")
     td=p.createType("double","double")
     ti=p.createType("int","int")
+    pg=pilot.PlayGround()
+    pg.setData([("localhost",4)])
     cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(4)
     cont.setProperty("InitializeScriptKey","aa=123.456")
     cont.setProperty("name","localhost")
     cont.setProperty("hostname","localhost")
+    cont.setProperty("nb_proc_per_node","1")
     script0="""
 def ff(nb,dbg):
     from math import cos
@@ -193,6 +211,7 @@ aa+=1.
     p.saveSchema(fname)
     p=l.load(fname)
     self.assertEqual(p.edGetDirectDescendants()[0].getContainer().getProperty("InitializeScriptKey"),"aa=123.456")
+    p.propagePlayGround(pg)
     # 1st exec
     ex=pilot.ExecutorSwig()
     self.assertEqual(p.getState(),pilot.READY)
@@ -234,7 +253,7 @@ o3=0
 """
     script2="""o9=sum(i8)
 """
-    fname="TestSaveLoadRun2.xml"
+    fname=os.path.join(self.workdir, "TestSaveLoadRun2.xml")
     nbOfNodes=8
     sqrtOfNumberOfTurn=1000 # 3000 -> 3.2s/Node, 1000 -> 0.1s/Node
     l=loader.YACSLoader()
@@ -243,11 +262,13 @@ o3=0
     ti=p.createType("int","int")
     tdi=p.createSequenceTc("seqint","seqint",ti)
     tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+    pg=pilot.PlayGround()
+    pg.setData([("localhost",4)])
     cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(4)
     cont.setProperty("InitializeScriptKey","aa=123.456")
     cont.setProperty("name","localhost")
     cont.setProperty("hostname","localhost")
+    cont.setProperty("nb_proc_per_node","1")
     #
     node0=self.r.createFuncNode("Salome","PyFunction0") # PyFuncNode remote
     p.edAddChild(node0)
@@ -289,6 +310,7 @@ o3=0
     # 1st exec
     refExpected=16016013.514623128
     ex=pilot.ExecutorSwig()
+    p.propagePlayGround(pg)
     self.assertEqual(p.getState(),pilot.READY)
     st=datetime.datetime.now()
     ex.RunW(p,0)
@@ -311,14 +333,18 @@ o3=0
 
   def test3(self):
     """ Test that focuses on parallel load of containers."""
-    script0="""def ff():
-    global aa
-    print("%%lf - %%s"%%(aa,str(my_container)))
-    return 100*[%i],0
+    script0="""
+if "aa" not in globals():
+  aa=123.456
+print("%%lf - %%s"%%(aa,str(my_container)))
+o1=100*[%i]
+o2=0
 """
     script1="""from math import cos
 import datetime
 ref=datetime.datetime.now()
+if "aa" not in globals():
+  aa=123.456
 o2=0. ; pas=1./float(i1)
 for i in range(i1):
   for j in range(i1):
@@ -331,24 +357,26 @@ o3=0
 """
     script2="""o9=sum(i8)
 """
-    fname="TestSaveLoadRun3.xml"
     nbOfNodes=8
     sqrtOfNumberOfTurn=10
     l=loader.YACSLoader()
     p=self.r.createProc("prTest1")
+    p.setProperty("executor","workloadmanager")
     td=p.createType("double","double")
     ti=p.createType("int","int")
     tdi=p.createSequenceTc("seqint","seqint",ti)
     tdd=p.createSequenceTc("seqdouble","seqdouble",td)
-    cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(8)
-    cont.setProperty("InitializeScriptKey","aa=123.456")
+    cont=p.createContainer("gg","Salome")
     cont.setProperty("name","localhost")
     cont.setProperty("hostname","localhost")
+    # no limit for the number of containers launched
+    cont.setProperty("nb_proc_per_node","0")
+    cont.setProperty("type","multi")
+    cont.usePythonCache(True)
+    cont.attachOnCloning()
     #
-    node0=self.r.createFuncNode("Salome","PyFunction0") # PyFuncNode remote
+    node0=self.r.createScriptNode("Salome","Node0")
     p.edAddChild(node0)
-    node0.setFname("ff")
     node0.setContainer(cont)
     node0.setScript(script0%(sqrtOfNumberOfTurn))
     out0_0=node0.edAddOutputPort("o1",tdi)
@@ -361,7 +389,7 @@ o3=0
     p.edAddLink(out0_0,node1.edGetSeqOfSamplesPort())
     node1.edGetNbOfBranchesPort().edInitInt(16)
     #
-    node2=self.r.createScriptNode("Salome","PyScript3")
+    node2=self.r.createScriptNode("Salome","Node2")
     node1.edAddChild(node2)
     node2.setContainer(cont)
     node2.setScript(script1)
@@ -371,7 +399,7 @@ o3=0
     out1_2=node2.edAddOutputPort("o3",ti)
     node2.setExecutionMode("remote")
     #
-    node3=self.r.createScriptNode("Salome","PyScript7")
+    node3=self.r.createScriptNode("Salome","Node3")
     p.edAddChild(node3)
     node3.setScript(script2)
     p.edAddCFLink(node1,node3)
@@ -379,10 +407,10 @@ o3=0
     o9=node3.edAddOutputPort("o9",td)
     p.edAddLink(out0_2,i8)
     #
+    fname=os.path.join(self.workdir, "t3_new.xml")
     p.saveSchema(fname)
     p=l.load(fname)
-    o9=p.getChildByName("PyScript7").getOutputPort("o9")
-    self.assertTrue(len(p.edGetDirectDescendants()[1].getChildByName("PyScript3").getContainer().getProperty("InitializeScriptKey"))!=0)
+    o9=p.getChildByName("Node3").getOutputPort("o9")
     # 1st exec
     refExpected=11000.008377058712
     ex=pilot.ExecutorSwig()
@@ -405,10 +433,10 @@ o3=0
     self.assertEqual(p.getState(),pilot.DONE)
     self.assertAlmostEqual(refExpected,o9.getPyObj(),5)
     pass
-  
+
   def test4(self):
-    """Non regression test of multi pyScriptNode, pyFuncNode sharing the same HPContainer instance."""
-    fname="TestSaveLoadRun4.xml"
+    """Double foreach."""
+    fname=os.path.join(self.workdir, "TestSaveLoadRun4.xml")
     script1="""nb=7
 ii=0
 o1=nb*[None]
@@ -424,8 +452,14 @@ for i in range(nb):
     l=loader.YACSLoader()
     ex=pilot.ExecutorSwig()
     p=self.r.createProc("pr")
-    cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(10)
+    p.setProperty("executor","workloadmanager")
+    cont=p.createContainer("gg","Salome")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    # no limit for the number of containers launched
+    cont.setProperty("nb_proc_per_node","0")
+    cont.setProperty("type","multi")
+    cont.attachOnCloning()
     td=p.createType("int","int")
     td2=p.createSequenceTc("seqint","seqint",td)
     td3=p.createSequenceTc("seqintvec","seqintvec",td2)
@@ -493,7 +527,9 @@ for i in range(nb):
 
   def test5(self):
     """Non regression test 2 of multi pyNode, pyFuncNode sharing the same HPContainer instance."""
-    fname="TestSaveLoadRun5.xml"
+    # TODO : This test is DEPRECATED. HPContainer will be removed.
+    self.skipTest("HPContainer deprecated.")
+    fname=os.path.join(self.workdir, "TestSaveLoadRun5.xml")
     script1="""nb=7
 ii=0
 o1=nb*[None]
@@ -509,8 +545,10 @@ for i in range(nb):
     l=loader.YACSLoader()
     ex=pilot.ExecutorSwig()
     p=self.r.createProc("pr")
+    pg=pilot.PlayGround()
+    pg.setData([("localhost",10)])
     cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(10)
+    cont.setProperty("nb_proc_per_node","1")
     td=p.createType("int","int")
     td2=p.createSequenceTc("seqint","seqint",td)
     td3=p.createSequenceTc("seqintvec","seqintvec",td2)
@@ -570,6 +608,7 @@ for i in range(nb):
     p.edAddLink(o15,i8)
     p.saveSchema(fname)
     p=l.load(fname)
+    p.propagePlayGround(pg)
     ex = pilot.ExecutorSwig()
     self.assertEqual(p.getState(),pilot.READY)
     ex.RunW(p,0)
@@ -579,7 +618,7 @@ for i in range(nb):
     pass
 
   def test6(self):
-    fname="test6.xml"
+    fname=os.path.join(self.workdir, "test6.xml")
     p=self.r.createProc("prTest0")
     td=p.createType("double","double")
     ti=p.createType("int","int")
@@ -626,7 +665,7 @@ for i in range(nb):
     pass
 
   def test7(self):
-    fname="test7.xml"
+    fname=os.path.join(self.workdir, "test7.xml")
     p=self.r.createProc("prTest1")
     cont=p.createContainer("gg","Salome")
     cont.setProperty("name","localhost")
@@ -687,7 +726,7 @@ else:
 
   def test8(self):
     from datetime import datetime
-    fname="test8.xml"
+    fname=os.path.join(self.workdir, "test8.xml")
     p=self.r.createProc("prTest2")
     cont=p.createContainer("gg","Salome")
     cont.setProperty("name","localhost")
@@ -773,7 +812,7 @@ else:
 
   def test9(self):
     """ Test of assignation of already computed values for foreach node."""
-    fname="test9.xml"
+    fname=os.path.join(self.workdir, "test9.xml")
     from datetime import datetime
     p=self.r.createProc("prTest2")
     cont=p.createContainer("gg","Salome")
@@ -855,7 +894,7 @@ o2=7*i1
     pass
 
   def test10(self):
-    fname="test10.xml"
+    fname=os.path.join(self.workdir, "test10.xml")
     from datetime import datetime
     p=self.r.createProc("prTest2")
     cont=p.createContainer("gg","Salome")
@@ -945,7 +984,7 @@ else:
 
   def test11(self):
     "test if we do not restart from the begining of the schema after an error in a foreach"
-    fname="test11.xml"
+    fname=os.path.join(self.workdir, "test11.xml")
     from datetime import datetime
     p=self.r.createProc("prTest2")
     cont=p.createContainer("gg","Salome")
@@ -1173,7 +1212,7 @@ for i in i8:
 
   def test14(self):
     """ Non regression EDF11027. Problem after Save/Load of a foreach node with type pyobj with input "SmplsCollection" manually set before. Correction in convertToYacsObjref from XML->Neutral. Objref can hide a string !"""
-    xmlFileName="test14.xml"
+    xmlFileName=os.path.join(self.workdir, "test14.xml")
     SALOMERuntime.RuntimeSALOME_setRuntime()
     r=pilot.getRuntime()
     n0=r.createProc("test23/zeRun")
@@ -1214,10 +1253,16 @@ for i in i8:
     pass
 
   def test15(self):
-    fname="BugInConcurrentLaunchDftCont.xml"
+    from SALOME_PyNode import UnProxyObjectSimple
+    #fname=os.path.join(self.workdir, "BugInConcurrentLaunchDftCont.xml")
     p=self.r.createProc("pr")
     ti=p.createType("int","int")
     cont=p.createContainer("DefaultContainer","Salome")
+    # enable WorkloadManager mode because containers are not registered right
+    # in classical mode (4 containers with the same name are launched at the
+    # same time).
+    p.setProperty("executor", "WorkloadManager")
+    cont.setProperty("type", "multi")
     cont.setProperty("container_name","FactoryServer")
     b=self.r.createBloc("Bloc") ; p.edAddChild(b)
     #
@@ -1250,7 +1295,7 @@ for i in i8:
       ex = pilot.ExecutorSwig()
       self.assertEqual(p.getState(),pilot.READY)
       ex.RunW(p,0)
-      self.assertEqual(res.get(),6)
+      self.assertEqual(UnProxyObjectSimple( res.getPyObj() ),6)
       self.assertEqual(p.getState(),pilot.DONE)
     pass
 
@@ -1318,10 +1363,11 @@ for i in i8:
     
   def test19(self):
     """This test checks the mechanism of YACS that allow PythonNodes to know their DynParaLoop context."""
-    fname="test19.xml"
+    fname=os.path.join(self.workdir, "test19.xml")
     l=loader.YACSLoader()
     #
     p=self.r.createProc("PROC")
+    p.setProperty("executor","workloadmanager")
     ti=p.createType("int","int")
     tdi=p.createSequenceTc("seqint","seqint",ti)
     # Level0
@@ -1332,7 +1378,7 @@ for i in i8:
     fe0_end.setScript("""assert([elt[0] for elt in my_dpl_localization]==["FE0"])
 assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<4)""")
     n0=self.r.createScriptNode("Salome","n0") ; p.edAddChild(n0)
-    n0.setScript("o1=range(10)")
+    n0.setScript("o1=list(range(10))")
     a=n0.edAddOutputPort("o1",tdi)
     p.edAddLink(a,fe0.edGetSeqOfSamplesPort()) ; p.edAddCFLink(n0,fe0)
     # Level1
@@ -1340,7 +1386,7 @@ assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<4)""")
     n1=self.r.createScriptNode("Salome","n1") ; b0.edAddChild(n1)
     n1.setScript("""assert([elt[0] for elt in my_dpl_localization]==["FE0"])
 assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<4)
-o1=range(10)""")
+o1=list(range(10))""")
     b=n1.edAddOutputPort("o1",tdi)
     fe1=self.r.createForEachLoop("FE1",ti) ; b0.edAddChild(fe1)
     fe1.edGetNbOfBranchesPort().edInitInt(3)
@@ -1371,11 +1417,16 @@ assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<3)
 
     # run remote
     p=l.load(fname)
-    cont=p.createContainer("gg","HPSalome")
-    cont.setSizeOfPool(2)
+    cont=p.createContainer("gg","Salome")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    # no limit for the number of containers launched
+    cont.setProperty("nb_proc_per_node","0")
+    cont.setProperty("type","multi")
+    #cont.usePythonCache(True)
+    cont.attachOnCloning()
     n1=p.getChildByName("FE0.b0.n1") ; n1.setExecutionMode("remote") ; n1.setContainer(cont)
     n2=p.getChildByName("FE0.b0.FE1.n2") ; n2.setExecutionMode("remote") ; n2.setContainer(cont)
-    
     p.init()
     self.assertEqual(p.getState(),pilot.READY)
     ex.RunW(p,0)
@@ -1389,9 +1440,16 @@ assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<3)
       pass
     xmlFileName="test20.xml"
     p=self.r.createProc("test26")
+    p.setProperty("executor","workloadmanager")
     #
-    cont=p.createContainer("gg","HPSalome") # very important ! HP Container needed for the test !
-    cont.setSizeOfPool(8) # important make this figure >= 6
+    cont=p.createContainer("gg","Salome")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    # no limit for the number of containers launched
+    cont.setProperty("nb_proc_per_node","0")
+    cont.setProperty("type","multi")
+    cont.usePythonCache(True)
+    cont.attachOnCloning()
     #
     po=p.createInterfaceTc("python:obj:1.0","pyobj",[])
     sop=p.createSequenceTc("list[pyobj]","list[pyobj]",po)
@@ -1399,7 +1457,7 @@ assert(my_dpl_localization[0][1]>=0 and my_dpl_localization[0][1]<3)
     b0=self.r.createBloc("test26/main") ; p.edAddChild(b0)
     n0=self.r.createScriptNode("Salome","test26/n0") ; assignCont(n0,cont) # 1
     n0.setScript("""import os
-dd=range(10)""")
+dd=list( range(10) )""")
     dd=n0.edAddOutputPort("dd",sop) ; b0.edAddChild(n0)
     fe0=self.r.createForEachLoop("test26/FE0",po) ; b0.edAddChild(fe0)
     fe0.edGetNbOfBranchesPort().edInitInt(1) # very important for the test : 1 !
@@ -1448,6 +1506,7 @@ dd=range(10)""")
     p.edAddLink(dd,fe0.edGetSeqOfSamplesPort())
     p.edAddLink(fe0.edGetSamplePort(),c1)
     #
+    #xmlFileName="test20.xml"
     #p.saveSchema(xmlFileName)
     p.getChildByName("test26/main.test26/FE0").edGetNbOfBranchesPort().edInitInt(1) # very important 1 !
     #
@@ -1461,8 +1520,8 @@ dd=range(10)""")
 
   def test21(self):
     "test if we restart from a saved state in a foreach loop"
-    fname="test21.xml"
-    xmlStateFileName="saveState21.xml"
+    fname=os.path.join(self.workdir, "test21.xml")
+    xmlStateFileName=os.path.join(self.workdir, "saveState21.xml")
     from datetime import datetime
     p=self.r.createProc("prTest21")
     cont=p.createContainer("gg","Salome")
@@ -1484,7 +1543,7 @@ dd=range(10)""")
     n1.edAddChild(n10)
     n10.setScript("""
 import time
-time.sleep(2)
+time.sleep(9)
 o2=2*i1
 """)
     i1=n10.edAddInputPort("i1",ti)
@@ -1515,7 +1574,7 @@ o2=2*i1
     myRun=threading.Thread(None, ex.RunW, None, (p,0))
     myRun.start()
     import time
-    time.sleep(5)
+    time.sleep(15)
     SALOMERuntime.schemaSaveState(p, ex, xmlStateFileName)
     a,b,c=n1.getPassedResults(ex)
     myRun.join()
@@ -1537,22 +1596,14 @@ o2=5*i1
     p.getChildByName("n1").assignPassedResults(a,b,c)
     p.exUpdateState();
     #
-    startt=datetime.now()
     ex.RunW(p,0,False)
-    t1=datetime.now()-startt
     #
     self.assertEqual(n1.getState(),pilot.DONE)
     self.assertEqual(p.getState(),pilot.DONE)
     self.assertEqual(p.getChildByName("n2").getOutputPort("o4").getPyObj(),[0,2,10,15,20,25])
-    pass
-  pass
 
-  def test22(self):
-    """Restart from a saved state in a foreach loop without using assignPassedResults.
-       This test uses the files test21.xml and saveState21.xml produced by test21.
-    """
-    fname="test21.xml"
-    xmlStateFileName="saveState21.xml"
+    # Restart from a saved state in a foreach loop without using assignPassedResults.
+    # This test uses the files test21.xml and saveState21.xml produced by test21.
 
     ex=pilot.ExecutorSwig()
     l=loader.YACSLoader()
@@ -1576,15 +1627,13 @@ o4=i3
     #
     self.assertEqual(q.getChildByName("n1").getState(),pilot.DONE)
     self.assertEqual(q.getState(),pilot.DONE)
-    self.assertEqual(q.getChildByName("n2").getOutputPort("o4").getPyObj(),[0L,2L,10L,15L,20L,25L])
+    self.assertEqual(q.getChildByName("n2").getOutputPort("o4").getPyObj(),[0,2,10,15,20,25])
     pass
 
   def test23(self):
     """ test focused on weight attribut after a dump and reload from a xml file
     """
-    fname="test23.xml"
-    xmlStateFileName="saveState23.xml"
-    from datetime import datetime
+    fname=os.path.join(self.workdir, "test23.xml")
     p=self.r.createProc("prTest23")
     cont=p.createContainer("gg","Salome")
     cont.setProperty("name","localhost")
@@ -1609,6 +1658,7 @@ import time
 time.sleep(2)
 o2=2*i1
 """)
+    n10.setWeight(4.)
     i1=n10.edAddInputPort("i1",ti)
     o2=n10.edAddOutputPort("o2",ti)
     p.edAddChild(n1)
@@ -1628,15 +1678,185 @@ o2=2*i1
     #
     l=loader.YACSLoader()
     p=l.load(fname)
-    self.assertEqual(p.getChildByName("n1").getWeight(),3.0)
+    self.assertEqual(p.getChildByName("n1").getWeight().getSimpleLoopWeight(),3.0)
+    self.assertEqual(p.getChildByName("n1").getChildByName("n10").getWeight().getElementaryWeight(),4.0)
     pass
 
-  pass
+  def test24(self):
+    """ Non regression test EDF17470"""
+    SALOMERuntime.RuntimeSALOME.setRuntime()
+    r=SALOMERuntime.getSALOMERuntime()
+    p=r.createProc("prTest2")
+    #
+    cont1=p.createContainer("cont1","Salome")
+    cont1.setProperty("name","localhost")
+    cont1.setProperty("hostname","localhost")
+    cont1.setProperty("type","multi")
+    cont1.setProperty("container_name","container1")
+    #
+    cont2=p.createContainer("cont2","Salome")
+    cont2.setProperty("name","localhost")
+    cont2.setProperty("hostname","localhost")
+    cont2.setProperty("type","multi")
+    cont2.setProperty("container_name","container2")
+    #
+    td=p.createType("double","double")
+    ti=p.createType("int","int")
+    ts=p.createType("string","string")
+    n0=r.createScriptNode("","n0")
+    n0.setScript("""import SalomeSDSClt
+import SALOME
+import salome
+import unittest
+import pickle
+import gc
+import time
+
+def obj2Str(obj):
+  return pickle.dumps(obj,pickle.HIGHEST_PROTOCOL)
+def str2Obj(strr):
+  return pickle.loads(strr)
+
+
+salome.salome_init()
+scopeName="Scope1"
+varName="a"
+dsm=salome.naming_service.Resolve("/DataServerManager")
+dsm.cleanScopesInNS()
+if scopeName in dsm.listScopes():
+  dsm.removeDataScope(scopeName)
+dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
+#
+t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+dss.atomicApply([t0])
+""")
+    n0_sn=n0.edAddOutputPort("scopeName",ts)
+    n0_vn=n0.edAddOutputPort("varName",ts)
+    #
+    n1=r.createScriptNode("","n1")
+    n1_sn=n1.edAddInputPort("scopeName",ts)
+    n1_vn=n1.edAddInputPort("varName",ts)
+    n1.setScript("""import SalomeSDSClt
+import SALOME
+import salome
+import unittest
+import pickle
+import gc
+import time
+
+
+def obj2Str(obj):
+  return pickle.dumps(obj,pickle.HIGHEST_PROTOCOL)
+def str2Obj(strr):
+  return pickle.loads(strr)
+
+salome.salome_init()
+dsm=salome.naming_service.Resolve("/DataServerManager")
+dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
+assert(not isCreated)
+
+t1=dss.addMultiKeyValueSession(varName)
+# lecture 'ef'
+wk2=dss.waitForKeyInVar(varName,obj2Str("ef"))
+wk2.waitFor()
+assert(str2Obj(dss.waitForMonoThrRev(wk2))==[11,12])""")
+    n1.setContainer(cont1)
+    n1.setExecutionMode("remote")
+    #
+    n2=r.createScriptNode("","n2")
+    n2_sn=n2.edAddInputPort("scopeName",ts)
+    n2_vn=n2.edAddInputPort("varName",ts)
+    n2.setScript("""import SalomeSDSClt
+import SALOME
+import salome
+import unittest
+import pickle
+import gc
+import time
+
+
+def obj2Str(obj):
+  return pickle.dumps(obj,pickle.HIGHEST_PROTOCOL)
+def str2Obj(strr):
+  return pickle.loads(strr)
+
+salome.salome_init()
+dsm=salome.naming_service.Resolve("/DataServerManager")
+dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
+assert(not isCreated)
+time.sleep(3.)
+t1=dss.addMultiKeyValueSession(varName)
+t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
+t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("ef"),obj2Str([11,12]))
+""")
+    n2.setContainer(cont2)
+    n2.setExecutionMode("remote")
+    #
+    p.edAddChild(n0)
+    p.edAddChild(n1)
+    p.edAddChild(n2)
+    p.edAddCFLink(n0,n1)
+    p.edAddCFLink(n0,n2)
+    p.edAddLink(n0_sn,n1_sn)
+    p.edAddLink(n0_vn,n1_vn)
+    p.edAddLink(n0_sn,n2_sn)
+    p.edAddLink(n0_vn,n2_vn)
+    #
+    ex=pilot.ExecutorSwig()
+    ex.RunW(p,0)
+    self.assertEqual(p.getState(),pilot.DONE)
+    pass
+
+  def test25(self):
+    fname=os.path.join(self.workdir, "test25.xml")
+    p=self.r.createProc("p0")
+    tp=p.createInterfaceTc("python:obj:1.0","pyobj",[])
+    n1_0_sc=self.r.createScriptNode("Salome","n1_0_sc")
+    p.edAddChild(n1_0_sc)
+    n1_0_sc.setExecutionMode("remote")
+    n1_0_sc.setScript("""""")
+    i1_0_sc=n1_0_sc.edAddInputPort("i1",tp)
+    i1_0_sc.edInitPy(list(range(4)))
+
+    cont=p.createContainer("gg","Salome")
+    cont.setProperty("name","localhost")
+    cont.setProperty("hostname","localhost")
+    n1_0_sc.setContainer(cont)
+
+    p.saveSchema(fname)
+    l=loader.YACSLoader()
+    p=l.load(fname)
+    ex=pilot.ExecutorSwig()
+    self.assertEqual(p.getState(),pilot.READY)
+    ex.RunW(p,0)
+    self.assertEqual(p.getState(),pilot.DONE)
+    pass
+
+  def test27(self):
+    """ 
+    This test is here to check that old (<=930) graphs are always loadable.
+    So an xml file coming from test14 in 930 has been generated and converted into home made "base64" like format.
+    This test puts unbased64 byte array into test_930.xml and load it to check that everything is OK.
+    """
+    import os
+    content_of_file = b'DDkShXM2PeNCndPqRfnYX5EAt.GaRgPq7dNqtfnYZgvqh=kQf7moXCE2z5lED.tCxgM2RcOqdfl29ePC9YnAx3uaGetqF5lE=.E2D0uS1eM2RcOqdfl2FjPqBYE2pdNq7fl2FjPqBYHoT3.2=.Ew9dsCdUFqVfOaj2Eaxet4BeN2=BOKRWOwF0PqfYMqdYHoT3.2=.EwxYNKHeNa=5O4heOwF4OKBeN2=7Maj2FaZXOaFDFwI.E2=1kibUua=5O4heOwF7Nq9YE2pdNq7fl2ZbMiFDFwI.E2=1nqFZNCdaM2RcOqdfl21dvqFZN2=7Maj2ECbWsKxbNQxYNKL6lo12HoT3.2=.EwneOCfeNqleM2RcOqdfl2BdPC9hcCbjN4Jfd2=APqRWuaRWuwF.uSxYNKFDFwI.E2=1kibUua=5O4heOwFAsiHdNqtYE2pdNq7fl2nWtCZbPaFDFwI.E2=1n4xbMiVdNqdYs2RcOqdfl26eNaVesq9g9qRWu4ZbOaHYFwI.E2=.E2=1kCHjMCdYsibUFqVfOaj2H4xbMiVdNqdYvupdNq7YE2PcMqfeOwFAe4BjOqdYHoT3.2=.E2=.Ew1Yvq1eNC9ds2RcOqdfl2VWsiVgMKdWPuxbPulXPqRdNqtYE2PcMqfeOwF.l2x5lE=.E2=.E2D.tCxUuaHWuS=5O4heOwFAPqRWu4ZbOaHjdqVfOaF.FiVXOidfl2McP49jNCbgeaHauaHYHoT3.2=.E2=.Ew1Yvq1eNC9ds2RcOqdfl2RcOqdYE2PcMqfeOwF1PqlcMq3jPC9YHoT3.2=.EwxAPqRWu4ZbOaHblE=.E2D2MqxgM2RcOqdfl29ePC9YnAx9O4ZbN2T3.2=.E2=.EwFXPqlUFqVfOaj2EidgsiHAnoHetqF5lE=.E2=.E2=.E2D4PqHeO4lVM2RcOqdfl29ePC9YnAx48WF.FqFYu4RgMKj2FAF.EqxjMCueOKtVMij2GoX2E29dsCdfl21dvqFZN2T3.2=.E2=.E2=.E2=.EwZbMqZbOa=5O4heOwF0uanWtAnDFCfbPuZbMidYtqVXN2T3.2=.E2=.E2=.E2=.E2=.EwngNCZUsiT1n4xWOaT1m2qg6WUWe0qjMAj7MAp7OAifdwDDH4xWOaT1nongNCZUsiT3.2=.E2=.E2=.E2=.E2=.EwZbMCxYsi=5O4heOwF7MAF.EibUuaj2ECbjN4JYHoT3.2=.E2=.E2=.E2=.E2=.EwZbMCxYsi=5O4heOwF7OAF.EibUuaj2ECbjN4JYHoT3.2=.E2=.E2=.E2=.E2=.Ewxesi1jNC9UFqVfOaj2Hq12E29dsCdfl21dvqFZN2x5lE=.E2=.E2=.E2=.E2DDGKRXOKReNwI.E2=.E2=.E2=1noNjNCdcP43blE=.E2=.E2=.E2D0O49cMqZbPK=APqRWtCxXOwF4O4BguaF5lE=.E2=.E2=.E2=.E2D4NCxfNqxWOaT0uanWtAnDFWcXnoNYvqhbPq7eNw=1laHjOq1jNC9bmaPcMqmcOq1XOanXnoNYvqhUvqHWtwI.E2=.E2=.E2=.E2=1kixbPq7eNw9ePC9YnAx48WR0uanWtAnDFCfbPuZbMidYtqVXMwx0vqRjMadbk2D0vq1jNC9bmK11no9jMCxYsiT3.2=.E2=.E2=.Ewx0O49cMqZbPKT3.2=.E2=.Ewx2MqxgNwI.E2=.E2=1mKRXOKReM2RcOqdfl29ePC9YnAxAMKdgPKF5lE=.E2=.E2=.E2DAv4HdMC9bkwljMadbkwVBf06c6eUhfqX9mKH9euT1noljMadbkwxAv4HdMC9blE=.E2=.E2=.E2D7Nq1jNC9UFqVfOaj2GKH2E29dsCdfl2BdPC9hcCbjN4Jfd2x5lE=.E2=.E2=.E2DDOi9UvqHWs2RcOqdfl2xcl2=0uS1eOwF1OKnWvO1dvqFZOuFDFwI.E2=.E2=1noZbMqZbOaT3.2=.E2=.EwljNq9YvqBbk2D4NCxfNqxWOaT0uanWtAnDFCfbMwx4NCxfNqxWOaT.Ew9jNqxWOaT0uanWtAnDH43eP4pXno9jNqxWOaT.EwxAPqRWtCxXNwI.E2=.E2=1kaVWu4BdNqpUH4xbMiHjMqj2FaVXPCdYFwI.E2=.E2=.E2=1laHjOqRjMadbkidgsiHAnoHetqR0uanWtAnDFWcbEidgsiHAnoHetqydNq9eNCRcMqDDFaHjOqRjMadbk2D4NCxfMCxYsiTDMADDFaHjOq1jNC9blE=.E2=.E2=.E2D0vqRjMadbkidgsiHAnolVOalhMwx0vqRjMadbk2D0vq1jNC9bmKH1no9jMCxYsiT3.2=.E2=.Ewx0O49cMqZbPKT3.2=.Ewx2MqxgNwI.E2=1kCVYu4heMidYtwI.E2=.E2=1kixbPq7eNw9ePC9YnAx9O4ZbNo9ePC9YnAx2uiRbEidgsiHAnoMe6wx0vqRjMadbkw9jMCxYsiT5N4EYu4RgMKdgswx0vq1jNC9blE=.E2=.E2D4u4BeuaT1mKRWtwH1noZbMiT1noPcMqfeNwI.E2=1no1cNCVfOa9eNCT3.2=.Ew1cNCVfOa9eNCT3.2=.E2=.Ew9jNqxWOaT0uanWtAnDGqVdNqR0uanWtAnDFCfbNo9ePC9YnAx48WDDEixbPq7eNwD0vq1jNC9bn8hUsqng9qBXOalWuKxbMwx0vq1jNC9blE=.E2=.E2D4u4BeuaT1m4HYu4bbkw7cMiVblED4u4BeuaT1nC9YuKRiNwAUkmI5EwxAsiHdNqtbkwx4u4BeuaT3.wPcMqfeNwDAsiHdNqtbkmX17ER1nonWtCZbPaT1noPcMqfeNwI1liVXOidbkwnWtCZbPaT17AAZ=oDDHC9YuKRiNwDDFiVXOidblED4u4BeuaT1nC9YuKRiNwAgkmI5EwxAsiHdNqtbkwx4u4BeuaT3.wPcMqfeNwDAsiHdNqtbkm917ER1nonWtCZbPaT1noPcMqfeNwI1liVXOidbkwnWtCZbPaT18gAZ=oDDHC9YuKRiNwDDFiVXOidblED4u4BeuaT1nC9YuKRiNwAakmI5EwxAsiHdNqtbkwx4u4BeuaT3.wPcMqfeNwDAsiHdNqtbkmv17ER1nonWtCZbPaT1noPcMqfeNwI1liVXOidbkwnWtCZbPaT16QAZ=oDDHC9YuKRiNwDDFiVXOidblED4u4BeuaT1nC9YuKRiNwAdkmI5EwxAsiHdNqtbkwx4u4BeuaT3.wx0O49cNwDDG4HYu4bbkwx4u4BeuaT3.2=.Ewx.u4HcOqdWuaHblE=.E2D.u4HcOqdWuaHblE=.E2=.E2D0vqRjMadbkidgsiHAnohcOKRbEidgsiHAnoHetqR0uanWtAnDFWcbEidgsiHAnoHetqydNq9eNCRcMqDDEixbPq7eNwD0vq1jNC9bmKX1no9jMCxYsiT3.2=.E2=.EwPcMqfeNwDDN4JYuaNbkwVBf06c6eUhcmn17ER9euT1noxYNKHeNaT1noPcMqfeNwI.E2=1no1cNCVfOa9eNCT3.wx.tCxgNwI3'
+
+    fname=os.path.join(self.workdir, "test_930.xml")
+    with open(fname,"wb") as f:
+      f.write( pilot.FromBase64Swig(content_of_file) )
+
+    SALOMERuntime.RuntimeSALOME_setRuntime()
+    l=loader.YACSLoader()
+    p=l.load(fname)
+    self.assertTrue(p.getChildByName("test23/main").getChildByName("test23/run").getChildByName("test23/FE").getChildByName("test23/run_internal").getInputPort("i1").getPyObj() == 3)
+    self.assertTrue(p.getChildByName("test23/main").getChildByName("test23/run").getChildByName("test23/FE").edGetSeqOfSamplesPort().getPyObj()==list(range(10)))
+    os.remove(fname)
+    pass
 
 if __name__ == '__main__':
-  import os,sys
-  U = os.getenv('USER')
-  with open("/tmp/" + U + "/UnitTestsResult", 'a') as f:
+  dir_test = tempfile.mkdtemp(suffix=".yacstest")
+  file_test = os.path.join(dir_test,"UnitTestsResult")
+  with open(file_test, 'a') as f:
       f.write("  --- TEST src/yacsloader: testSaveLoadRun.py\n")
       suite = unittest.makeSuite(TestSaveLoadRun)
       result=unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite)