]> SALOME platform Git repositories - modules/yacs.git/blob - src/SALOMESDS/TestSalomeSDS.py
Salome HOME
Merge 'master' branch into 'V9_dev' branch
[modules/yacs.git] / src / SALOMESDS / TestSalomeSDS.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 # Author : Anthony Geay
21
22 import SalomeSDSClt
23 import SALOME
24 import salome
25 import unittest
26 import pickle
27 import gc
28 import time
29 from datetime import datetime
30 import multiprocessing as mp
31
32 nbOfSecWait=1.
33
34 def obj2Str(obj):
35   return pickle.dumps(obj,pickle.HIGHEST_PROTOCOL)
36 def str2Obj(strr):
37   return pickle.loads(strr)
38 def generateKey(varName,scopeName):
39   dsm=salome.naming_service.Resolve("/DataServerManager")
40   dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
41   assert(not isCreated)
42   t=dss.addKeyValueInVarHard(varName,obj2Str("ef"),obj2Str([11,14,100]))
43   time.sleep(3)
44   dss.atomicApply([t])
45 def work(t):
46   i,varName,scopeName=t
47   if i==0:
48     generateKey(varName,scopeName)
49     return 0
50   else:
51     import TestSalomeSDSHelper0
52     import os,subprocess
53     fname=os.path.splitext(TestSalomeSDSHelper0.__file__)[0]+".py"
54     proc = subprocess.Popen(["python3", fname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55     out,err=proc.communicate()
56     if proc.returncode!=0:
57       print("-------------- work -----------")
58       print(out)
59       print(err)
60       print("~~~~~~~~~~~~~~ work ~~~~~~~~~~~")
61     return proc.returncode
62   
63 def func_test7(scopeName,cv,cv2,cv3,sharedNum):
64     salome.salome_init()
65     varName="a"
66     zeValue={"ab":[4,5,6]}
67     dsm=salome.naming_service.Resolve("/DataServerManager")
68     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName) # should be suspended nbOfSecWait s by main process
69     assert(not isCreated)
70     ######### micro-test1 - check that all requests are suspended
71     ######## Barrier
72     with cv2:
73       cv2.notify_all()
74       sharedNum.value=True
75     with cv3:
76       cv3.wait()
77     ####### End Barrier
78     s=datetime.now()
79     t0=dss.createRdWrVarTransac(varName,obj2Str(zeValue))
80     s=(datetime.now()-s).total_seconds()
81     assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to wait nearly nbOfSecWait seconds
82     dss.atomicApply([t0])
83     ######### end of micro-test1
84     ######### micro-test2 - after activeRequests everything work well
85     s=datetime.now()
86     st=dss.fetchSerializedContent(varName)
87     assert(str2Obj(st)==zeValue)
88     s=(datetime.now()-s).total_seconds()
89     assert(s>=0. and s<0.05) # expect to be not locked
90     ######### end of micro-test2
91     with cv:
92       cv.notify_all()
93     dss.takeANap(nbOfSecWait) # emulate a DataServer occupation
94     pass
95   
96 class SalomeSDSTest(unittest.TestCase):
97   
98   def testList1(self):
99     a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
100     self.assertEqual(a.local_copy(),[])
101     a.append(5)
102     self.assertEqual(a.local_copy(),[5])
103     self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
104     a.append(["rt"])
105     self.assertEqual(a.local_copy(),[5,["rt"]])
106     a[1].append(8)
107     self.assertEqual(a.local_copy(),[5,["rt",8]])
108     a.extend(a)
109     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
110     a.extend(a[3:])
111     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
112     a[4].append(7)
113     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
114     a.ptr().getMyDataScopeServer().deleteVar("a")
115     pass
116   
117   def testDict1(self):
118     a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
119     a["ab"]=4
120     self.assertEqual(a.local_copy(),{"ab":4})
121     a["cd"]=[5]
122     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
123     a["cd"].append(77)
124     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
125     a.__setitem__("ef",["a","bb"])
126     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
127     self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb"])
128     self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb","ccc"])
129     a["ef"].append("ccc")
130     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
131     a["gh"]=a
132     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
133     a["gh"]["cd"].append(99) ; a["cd"].append(88)
134     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77,99],"ef":["a","bb","ccc"]}})
135     a.ptr().getMyDataScopeServer().deleteVar("a")
136     pass
137
138   def testReadOnly1(self):
139     a=SalomeSDSClt.CreateRdOnlyGlobalVar({"ab":4,"cd":[5,77]},"a","Scope0")
140     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
141     self.assertRaises(Exception,a.__getitem__,"ab")
142     a.ptr().getMyDataScopeServer().deleteVar("a")
143
144   def testTransaction1(self):
145     scopeName="Scope1"
146     varName="a"
147     dsm=salome.naming_service.Resolve("/DataServerManager")
148     dsm.cleanScopesInNS()
149     if scopeName in dsm.listScopes():
150       dsm.removeDataScope(scopeName)
151     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
152     self.assertTrue(isCreated)
153     #
154     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
155     dss.atomicApply([t0])
156     #
157     self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
158     #
159     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
160     dss.atomicApply([t1])
161     #
162     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
163     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
164     wk.waitFor()
165     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
166     #
167     nbProc=8
168     pool=mp.Pool(processes=nbProc)
169     asyncResult=pool.map_async(work,[(i,varName,scopeName) for i in range(nbProc)])
170     print("asyncResult=", asyncResult)
171     self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here !
172     dsm.removeDataScope(scopeName)
173
174   def testTransaction2(self):
175     scopeName="Scope1"
176     varName="a"
177     dsm=salome.naming_service.Resolve("/DataServerManager")
178     dsm.cleanScopesInNS()
179     if scopeName in dsm.listScopes():
180       dsm.removeDataScope(scopeName)
181     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
182     self.assertTrue(isCreated)
183     #
184     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
185     dss.atomicApply([t0])
186     #
187     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
188     #
189     self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
190     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
191     dss.atomicApply([t1])
192     #
193     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
194     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
195     wk.waitFor()
196     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
197
198   def testTransaction3(self):
199     scopeName="Scope1"
200     varName="a"
201     dsm=salome.naming_service.Resolve("/DataServerManager")
202     dsm.cleanScopesInNS()
203     if scopeName in dsm.listScopes():
204       dsm.removeDataScope(scopeName)
205     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
206     self.assertTrue(isCreated)
207     #
208     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
209     dss.atomicApply([t0])
210     #
211     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
212     dss.atomicApply([t1])
213     #
214     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
215     #
216     t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
217     dss.atomicApply([t2])
218     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
219
220   def testTransaction4(self):
221     scopeName="Scope1"
222     varName="a"
223     dsm=salome.naming_service.Resolve("/DataServerManager")
224     dsm.cleanScopesInNS()
225     if scopeName in dsm.listScopes():
226       dsm.removeDataScope(scopeName)
227     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
228     self.assertTrue(isCreated)
229     #
230     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
231     dss.atomicApply([t0])
232     #
233     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
234     dss.atomicApply([t1])
235     #
236     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
237     wk,t2=dss.waitForKeyInVarAndKillIt(varName,obj2Str("cd"))
238     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
239     wk.waitFor()
240     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
241     dss.atomicApply([t2])
242     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
243
244   def testTransaction5(self):
245     """ Like testTransaction2 but without transactions. """
246     scopeName="Scope1"
247     varName="a"
248     dsm=salome.naming_service.Resolve("/DataServerManager")
249     dsm.cleanScopesInNS()
250     if scopeName in dsm.listScopes():
251       dsm.removeDataScope(scopeName)
252     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
253     self.assertTrue(isCreated)
254     #
255     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
256     dss.atomicApply([t0])
257     #
258     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
259     t1=dss.addMultiKeyValueSession(varName)
260     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
261     self.assertRaises(SALOME.SALOME_Exception,t1.addKeyValueInVarErrorIfAlreadyExistingNow,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
262     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
263     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
264     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
265     wk.waitFor()
266     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
267     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
268     dss.atomicApply([t1])
269     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
270     #
271     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
272     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
273     wk.waitFor()
274     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
275     keys=[str2Obj(elt) for elt in dss.getAllKeysOfVarWithTypeDict(varName)]
276     self.assertEqual(set(keys),set(['ab','cd']))
277
278   def testTransaction6(self):
279     """ Test to test RdWr global vars with transaction"""
280     scopeName="Scope1"
281     varName="a"
282     dsm=salome.naming_service.Resolve("/DataServerManager")
283     dsm.cleanScopesInNS()
284     if scopeName in dsm.listScopes():
285       dsm.removeDataScope(scopeName)
286     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
287     self.assertTrue(isCreated)
288     #
289     t0=dss.createWorkingVarTransac(varName,obj2Str({}))
290     a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
291     self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
292     # play
293     a["ab"]=4
294     self.assertEqual(a.local_copy(),{"ab":4})
295     a.assign({"ab":5})
296     self.assertEqual(a.local_copy(),{"ab":5})
297     a.assign({"ab":4})
298     a["cd"]=[5]
299     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
300     a["cd"].append(77)
301     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
302     a.__setitem__("ef",["a","bb"])
303     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
304     a["ef"].append("ccc")
305     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
306     a["gh"]=a
307     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
308     a["gh"]["cd"].append(99) ; a["cd"].append(88)
309     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77,99],"ef":["a","bb","ccc"]}})
310     # WARNING here not problem to overwrite
311     a["gh"]=7
312     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
313     # end of play
314     self.assertTrue(isinstance(a,SalomeSDSClt.Dict))
315     self.assertTrue(isinstance(a,SalomeSDSClt.WrappedType))# important for EEM
316     # commit : RdWr->RdOnly
317     dss.atomicApply([t0])
318     #
319     self.assertEqual(dss.getAccessOfVar(varName),"RdOnly") # after atomicApply the var is readOnly. Impossible to change its value !
320     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
321     dsm.cleanScopesInNS()
322     del a # very important kill Ref before removingDataScope...
323     if scopeName in dsm.listScopes():
324       dsm.removeDataScope(scopeName)
325     pass
326
327   def testTransaction7(self):
328     """Like testTransaction5 but after a recovery."""
329     scopeName="Scope1"
330     varName="a"
331     dsm=salome.naming_service.Resolve("/DataServerManager")
332     dsm.cleanScopesInNS()
333     if scopeName in dsm.listScopes():
334       dsm.removeDataScope(scopeName)
335     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
336     self.assertTrue(isCreated)
337     #
338     t0=dss.createRdExtInitVarTransac(varName,obj2Str({"ab":[4,5,6]}))
339     dss.atomicApply([t0])
340     #
341     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
342     t1=dss.addMultiKeyValueSession(varName)
343     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
344     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
345     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
346     dss.atomicApply([t1])
347     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
348     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
349     pass
350
351   def testLockToDump(self):
352     """ Test to check that holdRequests method. This method wait for clean server status and hold it until activeRequests is called.
353     Warning this method expects a not overloaded machine to be run because test is based on ellapse time.
354     """
355     scopeName="Scope1"
356     varName="ab"
357     zeObj={"ab":[5,6]}
358     dsm=salome.naming_service.Resolve("/DataServerManager")
359     dsm.cleanScopesInNS()
360     if scopeName in dsm.listScopes():
361         dsm.removeDataScope(scopeName)
362     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
363     self.assertTrue(isCreated)
364     cv=mp.Condition(mp.Lock())
365     cv2=mp.Condition(mp.Lock()) # sharedNum & cv2 & cv3 for the barrier
366     cv3=mp.Condition(mp.Lock())
367     sharedNum=mp.Value('b',False)
368     p=mp.Process(target=func_test7,args=(scopeName,cv,cv2,cv3,sharedNum))
369     p.start()
370     #
371     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
372     self.assertTrue(not isCreated)
373     t0=dss.createRdWrVarTransac(varName,obj2Str(zeObj))
374     dss.atomicApply([t0])
375     rs=dss.getRequestSwitcher()
376     self.assertTrue(not isCreated)
377     ######## Barrier
378     with cv2:
379       if not sharedNum.value:
380         cv2.wait()
381       sharedNum.value=False
382       pass
383     with cv3:
384       cv3.notify_all()
385     ####### End Barrier
386     rs.holdRequests() # The aim of the test
387     self.assertEqual(rs.listVars(),[varName]) # call whereas holdRequest is called
388     time.sleep(nbOfSecWait)
389     rs.activeRequests() # The aim of the test
390     ######### micro-test3 - check that holdRequests is able to wait for a non finished job
391     with cv:
392       cv.wait()
393       s=datetime.now()
394       time.sleep(0.01) # let main proc the priority
395       rs.holdRequests() # the aim of the test is here. main process is occupied 1s -> holdRequests is Expected to wait
396       s=(datetime.now()-s).total_seconds()
397       self.assertTrue(str2Obj(rs.fetchSerializedContent(varName))==zeObj) # call whereas holdRequest is called
398       rs.activeRequests()
399       self.assertTrue(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked
400     # finishing
401     p.join()
402     pass
403
404   def setUp(self):
405     salome.salome_init()
406     pass
407   
408   pass
409
410 if __name__=="__main__":
411   unittest.main()
412