]> SALOME platform Git repositories - modules/kernel.git/blob - src/SALOMESDS/TestSalomeSDS.py
Salome HOME
3caceef906eb4c17a3775ac5fff76496c0b76ed6
[modules/kernel.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,l,l2,cv):
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     l.release() # tell manager that I'm ready
71     l2.acquire() # wait for manager to start micro-test1
72     ######### micro-test1 - check that all requests are suspended
73     s=datetime.now()
74     t0=dss.createRdWrVarTransac(varName,obj2Str(zeValue))
75     s=(datetime.now()-s).total_seconds()
76     assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to wait nearly nbOfSecWait seconds
77     dss.atomicApply([t0])
78     ######### end of micro-test1
79     ######### micro-test2 - after activeRequests everything work well
80     s=datetime.now()
81     st=dss.fetchSerializedContent(varName)
82     assert(str2Obj(st)==zeValue)
83     s=(datetime.now()-s).total_seconds()
84     assert(s>=0. and s<0.05) # expect to be not locked
85     ######### end of micro-test2
86     with cv:
87       cv.notify_all()
88     dss.takeANap(nbOfSecWait) # emulate a DataServer occupation
89     pass
90   
91 class SalomeSDSTest(unittest.TestCase):
92   
93   def testList1(self):
94     a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
95     self.assertEqual(a.local_copy(),[])
96     a.append(5)
97     self.assertEqual(a.local_copy(),[5])
98     self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
99     a.append(["rt"])
100     self.assertEqual(a.local_copy(),[5,["rt"]])
101     a[1].append(8)
102     self.assertEqual(a.local_copy(),[5,["rt",8]])
103     a.extend(a)
104     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
105     a.extend(a[3:])
106     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
107     a[4].append(7)
108     self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
109     a.ptr().getMyDataScopeServer().deleteVar("a")
110     pass
111   
112   def testDict1(self):
113     a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
114     a["ab"]=4
115     self.assertEqual(a.local_copy(),{"ab":4})
116     a["cd"]=[5]
117     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
118     a["cd"].append(77)
119     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
120     a.__setitem__("ef",["a","bb"])
121     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
122     self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb"])
123     self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb","ccc"])
124     a["ef"].append("ccc")
125     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
126     a["gh"]=a
127     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
128     a["gh"]["cd"].append(99) ; a["cd"].append(88)
129     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"]}})
130     a.ptr().getMyDataScopeServer().deleteVar("a")
131     pass
132
133   def testReadOnly1(self):
134     a=SalomeSDSClt.CreateRdOnlyGlobalVar({"ab":4,"cd":[5,77]},"a","Scope0")
135     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
136     self.assertRaises(Exception,a.__getitem__,"ab")
137     a.ptr().getMyDataScopeServer().deleteVar("a")
138
139   def testTransaction1(self):
140     scopeName="Scope1"
141     varName="a"
142     dsm=salome.naming_service.Resolve("/DataServerManager")
143     dsm.cleanScopesInNS()
144     if scopeName in dsm.listScopes():
145       dsm.removeDataScope(scopeName)
146     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
147     self.assertTrue(isCreated)
148     #
149     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
150     dss.atomicApply([t0])
151     #
152     self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
153     #
154     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
155     dss.atomicApply([t1])
156     #
157     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
158     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
159     wk.waitFor()
160     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
161     #
162     nbProc=8
163     pool=mp.Pool(processes=nbProc)
164     asyncResult=pool.map_async(work,[(i,varName,scopeName) for i in range(nbProc)])
165     print("asyncResult=", asyncResult)
166     self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here !
167     dsm.removeDataScope(scopeName)
168
169   def testTransaction2(self):
170     scopeName="Scope1"
171     varName="a"
172     dsm=salome.naming_service.Resolve("/DataServerManager")
173     dsm.cleanScopesInNS()
174     if scopeName in dsm.listScopes():
175       dsm.removeDataScope(scopeName)
176     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
177     self.assertTrue(isCreated)
178     #
179     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
180     dss.atomicApply([t0])
181     #
182     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
183     #
184     self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
185     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
186     dss.atomicApply([t1])
187     #
188     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
189     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
190     wk.waitFor()
191     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
192
193   def testTransaction3(self):
194     scopeName="Scope1"
195     varName="a"
196     dsm=salome.naming_service.Resolve("/DataServerManager")
197     dsm.cleanScopesInNS()
198     if scopeName in dsm.listScopes():
199       dsm.removeDataScope(scopeName)
200     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
201     self.assertTrue(isCreated)
202     #
203     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
204     dss.atomicApply([t0])
205     #
206     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
207     dss.atomicApply([t1])
208     #
209     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
210     #
211     t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
212     dss.atomicApply([t2])
213     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
214
215   def testTransaction4(self):
216     scopeName="Scope1"
217     varName="a"
218     dsm=salome.naming_service.Resolve("/DataServerManager")
219     dsm.cleanScopesInNS()
220     if scopeName in dsm.listScopes():
221       dsm.removeDataScope(scopeName)
222     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
223     self.assertTrue(isCreated)
224     #
225     t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
226     dss.atomicApply([t0])
227     #
228     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
229     dss.atomicApply([t1])
230     #
231     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
232     wk,t2=dss.waitForKeyInVarAndKillIt(varName,obj2Str("cd"))
233     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
234     wk.waitFor()
235     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
236     dss.atomicApply([t2])
237     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
238
239   def testTransaction5(self):
240     """ Like testTransaction2 but without transactions. """
241     scopeName="Scope1"
242     varName="a"
243     dsm=salome.naming_service.Resolve("/DataServerManager")
244     dsm.cleanScopesInNS()
245     if scopeName in dsm.listScopes():
246       dsm.removeDataScope(scopeName)
247     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
248     self.assertTrue(isCreated)
249     #
250     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
251     dss.atomicApply([t0])
252     #
253     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
254     t1=dss.addMultiKeyValueSession(varName)
255     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
256     self.assertRaises(SALOME.SALOME_Exception,t1.addKeyValueInVarErrorIfAlreadyExistingNow,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
257     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
258     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
259     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
260     wk.waitFor()
261     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
262     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
263     dss.atomicApply([t1])
264     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
265     #
266     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
267     wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
268     wk.waitFor()
269     self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
270     keys=[str2Obj(elt) for elt in dss.getAllKeysOfVarWithTypeDict(varName)]
271     self.assertEqual(set(keys),set(['ab','cd']))
272
273   def testTransaction6(self):
274     """ Test to test RdWr global vars with transaction"""
275     scopeName="Scope1"
276     varName="a"
277     dsm=salome.naming_service.Resolve("/DataServerManager")
278     dsm.cleanScopesInNS()
279     if scopeName in dsm.listScopes():
280       dsm.removeDataScope(scopeName)
281     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
282     self.assertTrue(isCreated)
283     #
284     t0=dss.createWorkingVarTransac(varName,obj2Str({}))
285     a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
286     self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
287     # play
288     a["ab"]=4
289     self.assertEqual(a.local_copy(),{"ab":4})
290     a.assign({"ab":5})
291     self.assertEqual(a.local_copy(),{"ab":5})
292     a.assign({"ab":4})
293     a["cd"]=[5]
294     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
295     a["cd"].append(77)
296     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
297     a.__setitem__("ef",["a","bb"])
298     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
299     a["ef"].append("ccc")
300     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
301     a["gh"]=a
302     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
303     a["gh"]["cd"].append(99) ; a["cd"].append(88)
304     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"]}})
305     # WARNING here not problem to overwrite
306     a["gh"]=7
307     self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
308     # end of play
309     self.assertTrue(isinstance(a,SalomeSDSClt.Dict))
310     self.assertTrue(isinstance(a,SalomeSDSClt.WrappedType))# important for EEM
311     # commit : RdWr->RdOnly
312     dss.atomicApply([t0])
313     #
314     self.assertEqual(dss.getAccessOfVar(varName),"RdOnly") # after atomicApply the var is readOnly. Impossible to change its value !
315     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
316     dsm.cleanScopesInNS()
317     del a # very important kill Ref before removingDataScope...
318     if scopeName in dsm.listScopes():
319       dsm.removeDataScope(scopeName)
320     pass
321
322   def testTransaction7(self):
323     """Like testTransaction5 but after a recovery."""
324     scopeName="Scope1"
325     varName="a"
326     dsm=salome.naming_service.Resolve("/DataServerManager")
327     dsm.cleanScopesInNS()
328     if scopeName in dsm.listScopes():
329       dsm.removeDataScope(scopeName)
330     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
331     self.assertTrue(isCreated)
332     #
333     t0=dss.createRdExtInitVarTransac(varName,obj2Str({"ab":[4,5,6]}))
334     dss.atomicApply([t0])
335     #
336     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
337     t1=dss.addMultiKeyValueSession(varName)
338     self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
339     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
340     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
341     dss.atomicApply([t1])
342     self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
343     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
344     pass
345
346   def testLockToDump(self):
347     """ Test to check that holdRequests method. This method wait for clean server status and hold it until activeRequests is called.
348     Warning this method expects a not overloaded machine to be run because test is based on ellapse time.
349     """
350     scopeName="Scope1"
351     dsm=salome.naming_service.Resolve("/DataServerManager")
352     dsm.cleanScopesInNS()
353     if scopeName in dsm.listScopes():
354         dsm.removeDataScope(scopeName)
355     # l is for main process sync. to be sure to launch test when sub process is ready
356     # l2 lock is for sub process sync.
357     l=mp.Lock(); l2=mp.Lock()
358     l.acquire() ; l2.acquire()
359     cv=mp.Condition(mp.Lock())
360     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
361     #assert(isCreated)
362     p=mp.Process(target=func_test7,args=(scopeName,l,l2,cv))
363     p.start()
364     l.acquire()
365     rs=dss.getRequestSwitcher() ; rs.holdRequests() # The aim of the test
366     l2.release() # tell slave process that it's ready for micro-test1
367     time.sleep(nbOfSecWait)
368     rs.activeRequests() # The aim of the test
369     ######### micro-test3 - check that holdRequests is able to wait for a non finished job
370     with cv:
371       cv.wait()
372       s=datetime.now()
373       time.sleep(0.01) # let main proc the priority
374       rs.holdRequests() # the aim of the test is here. main process is occupied 1s -> holdRequests is Expected to wait
375       s=(datetime.now()-s).total_seconds()
376       rs.activeRequests()
377       assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked
378     # finishing
379     p.join()
380     pass
381
382   def setUp(self):
383     salome.salome_init()
384     pass
385   
386   pass
387
388 unittest.main()
389