1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 # Author : Anthony Geay
29 from datetime import datetime
30 import multiprocessing as mp
35 return cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL)
37 return cPickle.loads(strr)
38 def generateKey(varName,scopeName):
39 dsm=salome.naming_service.Resolve("/DataServerManager")
40 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
42 t=dss.addKeyValueInVarHard(varName,obj2Str("ef"),obj2Str([11,14,100]))
48 generateKey(varName,scopeName)
51 import TestSalomeSDSHelper0
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:
59 return proc.returncode
61 def func_test7(scopeName,cv,cv2,cv3,sharedNum):
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
68 ######### micro-test1 - check that all requests are suspended
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
81 ######### end of micro-test1
82 ######### micro-test2 - after activeRequests everything work well
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
91 dss.takeANap(nbOfSecWait) # emulate a DataServer occupation
94 class SalomeSDSTest(unittest.TestCase):
97 a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
98 self.assertEqual(a.local_copy(),[])
100 self.assertEqual(a.local_copy(),[5])
101 self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
103 self.assertEqual(a.local_copy(),[5,["rt"]])
105 self.assertEqual(a.local_copy(),[5,["rt",8]])
107 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
109 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
111 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
112 a.ptr().getMyDataScopeServer().deleteVar("a")
116 a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
118 self.assertEqual(a.local_copy(),{"ab":4})
120 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
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"]})
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")
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")
142 def testTransaction1(self):
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)
152 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
153 dss.atomicApply([t0])
155 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
157 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
158 dss.atomicApply([t1])
160 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
161 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
163 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
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)
171 def testTransaction2(self):
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)
181 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
182 dss.atomicApply([t0])
184 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
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])
190 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
191 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
193 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
195 def testTransaction3(self):
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)
205 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
206 dss.atomicApply([t0])
208 t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
209 dss.atomicApply([t1])
211 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
213 t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
214 dss.atomicApply([t2])
215 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
217 def testTransaction4(self):
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)
227 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
228 dss.atomicApply([t0])
230 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
231 dss.atomicApply([t1])
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]})
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]})
241 def testTransaction5(self):
242 """ Like testTransaction2 but without transactions. """
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)
252 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
253 dss.atomicApply([t0])
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]))
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")
268 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
269 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
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'])
275 def testTransaction6(self):
276 """ Test to test RdWr global vars with transaction"""
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)
286 t0=dss.createWorkingVarTransac(varName,obj2Str({}))
287 a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
288 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
291 self.assertEqual(a.local_copy(),{"ab":4})
293 self.assertEqual(a.local_copy(),{"ab":5})
296 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
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"]})
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
309 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
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])
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)
324 def testTransaction7(self):
325 """Like testTransaction5 but after a recovery."""
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)
335 t0=dss.createRdExtInitVarTransac(varName,obj2Str({"ab":[4,5,6]}))
336 dss.atomicApply([t0])
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]})
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.
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))
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)
376 if not sharedNum.value:
378 sharedNum.value=False
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
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
396 self.assertTrue(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked
407 if __name__=="__main__":