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,l,l2,cv):
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 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
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
76 ######### end of micro-test1
77 ######### micro-test2 - after activeRequests everything work well
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
86 dss.takeANap(nbOfSecWait) # emulate a DataServer occupation
89 class SalomeSDSTest(unittest.TestCase):
92 a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
93 self.assertEqual(a.local_copy(),[])
95 self.assertEqual(a.local_copy(),[5])
96 self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
98 self.assertEqual(a.local_copy(),[5,["rt"]])
100 self.assertEqual(a.local_copy(),[5,["rt",8]])
102 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
104 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
106 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
107 a.ptr().getMyDataScopeServer().deleteVar("a")
111 a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
113 self.assertEqual(a.local_copy(),{"ab":4})
115 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
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"]})
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")
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")
137 def testTransaction1(self):
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)
147 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
148 dss.atomicApply([t0])
150 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
152 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
153 dss.atomicApply([t1])
155 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
156 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
158 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
161 pool=mp.Pool(processes=nbProc)
162 asyncResult=pool.map_async(work,[(i,varName,scopeName) for i in xrange(nbProc)])
163 self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here !
164 dsm.removeDataScope(scopeName)
166 def testTransaction2(self):
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)
176 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
177 dss.atomicApply([t0])
179 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
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])
185 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
186 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
188 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
190 def testTransaction3(self):
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)
200 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
201 dss.atomicApply([t0])
203 t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
204 dss.atomicApply([t1])
206 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
208 t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
209 dss.atomicApply([t2])
210 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
212 def testTransaction4(self):
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)
222 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
223 dss.atomicApply([t0])
225 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
226 dss.atomicApply([t1])
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]})
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]})
236 def testTransaction5(self):
237 """ Like testTransaction2 but without transactions. """
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)
247 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
248 dss.atomicApply([t0])
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]))
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")
263 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
264 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
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'])
270 def testTransaction6(self):
271 """ Test to test RdWr global vars with transaction"""
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)
281 t0=dss.createWorkingVarTransac(varName,obj2Str({}))
282 a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
283 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
286 self.assertEqual(a.local_copy(),{"ab":4})
288 self.assertEqual(a.local_copy(),{"ab":5})
291 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
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"]})
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
304 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
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])
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)
319 def testTransaction7(self):
320 """Like testTransaction5 but after a recovery."""
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)
330 t0=dss.createRdExtInitVarTransac(varName,obj2Str({"ab":[4,5,6]}))
331 dss.atomicApply([t0])
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]})
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.
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)
359 p=mp.Process(target=func_test7,args=(scopeName,l,l2,cv))
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
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()
374 assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked