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