]> SALOME platform Git repositories - modules/kernel.git/blob - src/SALOMESDS/TestSalomeSDS.py
Salome HOME
442007ebf8ad5d16185f2c298eba355d908e032a
[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,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 testTransaction8(self):
352     """ EDF 16833 """
353     scopeName="ScopePP"
354     dsm=salome.naming_service.Resolve("/DataServerManager")
355     dsm.cleanScopesInNS()
356     if scopeName in dsm.listScopes():
357         dsm.removeDataScope(scopeName)
358     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
359     self.assertTrue(isCreated)
360
361     value={"a":1,"b":2}
362     value2={'a':1,'c':3,'b':2}
363
364     varName="abc"
365     t0=dss.createRdExtVarFreeStyleTransac(varName,obj2Str(value),"sha1".encode()) # sha1 is the key used to compare the initial value
366     dss.atomicApply([t0])
367     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value)
368     t1=dss.addMultiKeyValueSession(varName)
369     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("c"),obj2Str(3))
370     dss.atomicApply([t1])
371     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value2)
372     t2=dss.createRdExtVarFreeStyleTransac(varName,obj2Str(value),"sha1".encode()) # key is the same as original one -> OK
373     dss.atomicApply([t2])
374     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value2) # value2 remains untouched
375     t3=dss.createRdExtVarFreeStyleTransac(varName,obj2Str(value),"sha2".encode())
376     self.assertRaises(SALOME.SALOME_Exception,dss.atomicApply,[t3]) # sha2 != sha1 -> rejected
377     pass
378   
379   def testTransaction9(self):
380     """ EDF 16833 : use case 2. Trying to createRdExt during add key session"""
381     scopeName="ScopePP"
382     dsm=salome.naming_service.Resolve("/DataServerManager")
383     dsm.cleanScopesInNS()
384     if scopeName in dsm.listScopes():
385         dsm.removeDataScope(scopeName)
386     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
387     self.assertTrue(isCreated)
388
389     value={"a":1,"b":2}
390     value2={'a':1,'c':3,'b':2}
391
392     varName="abc"
393     t0=dss.createRdExtVarFreeStyleTransac(varName,obj2Str(value),"sha1".encode())
394     dss.atomicApply([t0])
395     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value)
396     t1=dss.addMultiKeyValueSession(varName)
397     t2=dss.createRdExtVarFreeStyleTransac(varName,obj2Str(value),"sha1".encode())
398     dss.atomicApply([t2])
399     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value)
400     t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("c"),obj2Str(3))
401     dss.atomicApply([t1])
402     self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),value2)
403     pass
404
405     
406   def testLockToDump(self):
407     """ Test to check that holdRequests method. This method wait for clean server status and hold it until activeRequests is called.
408     Warning this method expects a not overloaded machine to be run because test is based on ellapse time.
409     """
410     scopeName="Scope1"
411     varName="ab"
412     zeObj={"ab":[5,6]}
413     dsm=salome.naming_service.Resolve("/DataServerManager")
414     dsm.cleanScopesInNS()
415     if scopeName in dsm.listScopes():
416         dsm.removeDataScope(scopeName)
417     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
418     self.assertTrue(isCreated)
419     cv=mp.Condition(mp.Lock())
420     cv2=mp.Condition(mp.Lock()) # sharedNum & cv2 & cv3 for the barrier
421     cv3=mp.Condition(mp.Lock())
422     sharedNum=mp.Value('b',False)
423     p=mp.Process(target=func_test7,args=(scopeName,cv,cv2,cv3,sharedNum))
424     p.start()
425     #
426     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
427     self.assertTrue(not isCreated)
428     t0=dss.createRdWrVarTransac(varName,obj2Str(zeObj))
429     dss.atomicApply([t0])
430     rs=dss.getRequestSwitcher()
431     self.assertTrue(not isCreated)
432     ######## Barrier
433     with cv2:
434       if not sharedNum.value:
435         cv2.wait()
436       sharedNum.value=False
437       pass
438     with cv3:
439       cv3.notify_all()
440     ####### End Barrier
441     rs.holdRequests() # The aim of the test
442     self.assertEqual(rs.listVars(),[varName]) # call whereas holdRequest is called
443     time.sleep(nbOfSecWait)
444     rs.activeRequests() # The aim of the test
445     ######### micro-test3 - check that holdRequests is able to wait for a non finished job
446     with cv:
447       cv.wait()
448       s=datetime.now()
449       time.sleep(0.01) # let main proc the priority
450       rs.holdRequests() # the aim of the test is here. main process is occupied 1s -> holdRequests is Expected to wait
451       s=(datetime.now()-s).total_seconds()
452       self.assertTrue(str2Obj(rs.fetchSerializedContent(varName))==zeObj) # call whereas holdRequest is called
453       rs.activeRequests()
454       self.assertTrue(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked
455     # finishing
456     p.join()
457     pass
458
459   def setUp(self):
460     salome.salome_init()
461     pass
462   
463   pass
464
465 if __name__=="__main__":
466   unittest.main()
467