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