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 pickle.dumps(obj,pickle.HIGHEST_PROTOCOL)
37 return pickle.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(["python3", fname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55 out,err=proc.communicate()
56 if proc.returncode!=0:
57 print("-------------- work -----------")
60 print("~~~~~~~~~~~~~~ work ~~~~~~~~~~~")
61 return proc.returncode
63 def func_test7(scopeName,l,l2,cv):
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
70 l.release() # tell manager that I'm ready
71 l2.acquire() # wait for manager to start micro-test1
72 ######### micro-test1 - check that all requests are suspended
74 t0=dss.createRdWrVarTransac(varName,obj2Str(zeValue))
75 s=(datetime.now()-s).total_seconds()
76 assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to wait nearly nbOfSecWait seconds
78 ######### end of micro-test1
79 ######### micro-test2 - after activeRequests everything work well
81 st=dss.fetchSerializedContent(varName)
82 assert(str2Obj(st)==zeValue)
83 s=(datetime.now()-s).total_seconds()
84 assert(s>=0. and s<0.05) # expect to be not locked
85 ######### end of micro-test2
88 dss.takeANap(nbOfSecWait) # emulate a DataServer occupation
91 class SalomeSDSTest(unittest.TestCase):
94 a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
95 self.assertEqual(a.local_copy(),[])
97 self.assertEqual(a.local_copy(),[5])
98 self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
100 self.assertEqual(a.local_copy(),[5,["rt"]])
102 self.assertEqual(a.local_copy(),[5,["rt",8]])
104 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
106 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
108 self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
109 a.ptr().getMyDataScopeServer().deleteVar("a")
113 a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
115 self.assertEqual(a.local_copy(),{"ab":4})
117 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
119 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
120 a.__setitem__("ef",["a","bb"])
121 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
122 self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb"])
123 self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb","ccc"])
124 a["ef"].append("ccc")
125 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
127 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
128 a["gh"]["cd"].append(99) ; a["cd"].append(88)
129 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"]}})
130 a.ptr().getMyDataScopeServer().deleteVar("a")
133 def testReadOnly1(self):
134 a=SalomeSDSClt.CreateRdOnlyGlobalVar({"ab":4,"cd":[5,77]},"a","Scope0")
135 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
136 self.assertRaises(Exception,a.__getitem__,"ab")
137 a.ptr().getMyDataScopeServer().deleteVar("a")
139 def testTransaction1(self):
142 dsm=salome.naming_service.Resolve("/DataServerManager")
143 dsm.cleanScopesInNS()
144 if scopeName in dsm.listScopes():
145 dsm.removeDataScope(scopeName)
146 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
147 self.assertTrue(isCreated)
149 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
150 dss.atomicApply([t0])
152 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
154 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
155 dss.atomicApply([t1])
157 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
158 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
160 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
163 pool=mp.Pool(processes=nbProc)
164 asyncResult=pool.map_async(work,[(i,varName,scopeName) for i in range(nbProc)])
165 print("asyncResult=", asyncResult)
166 self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here !
167 dsm.removeDataScope(scopeName)
169 def testTransaction2(self):
172 dsm=salome.naming_service.Resolve("/DataServerManager")
173 dsm.cleanScopesInNS()
174 if scopeName in dsm.listScopes():
175 dsm.removeDataScope(scopeName)
176 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
177 self.assertTrue(isCreated)
179 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
180 dss.atomicApply([t0])
182 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
184 self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
185 t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
186 dss.atomicApply([t1])
188 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
189 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
191 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
193 def testTransaction3(self):
196 dsm=salome.naming_service.Resolve("/DataServerManager")
197 dsm.cleanScopesInNS()
198 if scopeName in dsm.listScopes():
199 dsm.removeDataScope(scopeName)
200 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
201 self.assertTrue(isCreated)
203 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
204 dss.atomicApply([t0])
206 t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
207 dss.atomicApply([t1])
209 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
211 t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
212 dss.atomicApply([t2])
213 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
215 def testTransaction4(self):
218 dsm=salome.naming_service.Resolve("/DataServerManager")
219 dsm.cleanScopesInNS()
220 if scopeName in dsm.listScopes():
221 dsm.removeDataScope(scopeName)
222 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
223 self.assertTrue(isCreated)
225 t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
226 dss.atomicApply([t0])
228 t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
229 dss.atomicApply([t1])
231 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
232 wk,t2=dss.waitForKeyInVarAndKillIt(varName,obj2Str("cd"))
233 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
235 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
236 dss.atomicApply([t2])
237 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
239 def testTransaction5(self):
240 """ Like testTransaction2 but without transactions. """
243 dsm=salome.naming_service.Resolve("/DataServerManager")
244 dsm.cleanScopesInNS()
245 if scopeName in dsm.listScopes():
246 dsm.removeDataScope(scopeName)
247 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
248 self.assertTrue(isCreated)
250 t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
251 dss.atomicApply([t0])
253 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
254 t1=dss.addMultiKeyValueSession(varName)
255 self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
256 self.assertRaises(SALOME.SALOME_Exception,t1.addKeyValueInVarErrorIfAlreadyExistingNow,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
257 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
258 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
259 t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
261 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
262 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
263 dss.atomicApply([t1])
264 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
266 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
267 wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
269 self.assertEqual(str2Obj(dss.waitForMonoThrRev(wk)),[7,8,9,10])
270 keys=[str2Obj(elt) for elt in dss.getAllKeysOfVarWithTypeDict(varName)]
271 self.assertEqual(set(keys),set(['ab','cd']))
273 def testTransaction6(self):
274 """ Test to test RdWr global vars with transaction"""
277 dsm=salome.naming_service.Resolve("/DataServerManager")
278 dsm.cleanScopesInNS()
279 if scopeName in dsm.listScopes():
280 dsm.removeDataScope(scopeName)
281 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
282 self.assertTrue(isCreated)
284 t0=dss.createWorkingVarTransac(varName,obj2Str({}))
285 a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
286 self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
289 self.assertEqual(a.local_copy(),{"ab":4})
291 self.assertEqual(a.local_copy(),{"ab":5})
294 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
296 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
297 a.__setitem__("ef",["a","bb"])
298 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
299 a["ef"].append("ccc")
300 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
302 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
303 a["gh"]["cd"].append(99) ; a["cd"].append(88)
304 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"]}})
305 # WARNING here not problem to overwrite
307 self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
309 self.assertTrue(isinstance(a,SalomeSDSClt.Dict))
310 self.assertTrue(isinstance(a,SalomeSDSClt.WrappedType))# important for EEM
311 # commit : RdWr->RdOnly
312 dss.atomicApply([t0])
314 self.assertEqual(dss.getAccessOfVar(varName),"RdOnly") # after atomicApply the var is readOnly. Impossible to change its value !
315 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
316 dsm.cleanScopesInNS()
317 del a # very important kill Ref before removingDataScope...
318 if scopeName in dsm.listScopes():
319 dsm.removeDataScope(scopeName)
322 def testTransaction7(self):
323 """Like testTransaction5 but after a recovery."""
326 dsm=salome.naming_service.Resolve("/DataServerManager")
327 dsm.cleanScopesInNS()
328 if scopeName in dsm.listScopes():
329 dsm.removeDataScope(scopeName)
330 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
331 self.assertTrue(isCreated)
333 t0=dss.createRdExtInitVarTransac(varName,obj2Str({"ab":[4,5,6]}))
334 dss.atomicApply([t0])
336 self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
337 t1=dss.addMultiKeyValueSession(varName)
338 self.assertEqual(dss.getAccessOfVar(varName),"RdExtInit")
339 t1.addKeyValueInVarErrorIfAlreadyExistingNow(obj2Str("cd"),obj2Str([7,8,9,10]))
340 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})# it is not a bug ! commit of t1 not done !
341 dss.atomicApply([t1])
342 self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
343 self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
346 def testLockToDump(self):
347 """ Test to check that holdRequests method. This method wait for clean server status and hold it until activeRequests is called.
348 Warning this method expects a not overloaded machine to be run because test is based on ellapse time.
351 dsm=salome.naming_service.Resolve("/DataServerManager")
352 dsm.cleanScopesInNS()
353 if scopeName in dsm.listScopes():
354 dsm.removeDataScope(scopeName)
355 # l is for main process sync. to be sure to launch test when sub process is ready
356 # l2 lock is for sub process sync.
357 l=mp.Lock(); l2=mp.Lock()
358 l.acquire() ; l2.acquire()
359 cv=mp.Condition(mp.Lock())
360 dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
362 p=mp.Process(target=func_test7,args=(scopeName,l,l2,cv))
365 rs=dss.getRequestSwitcher() ; rs.holdRequests() # The aim of the test
366 l2.release() # tell slave process that it's ready for micro-test1
367 time.sleep(nbOfSecWait)
368 rs.activeRequests() # The aim of the test
369 ######### micro-test3 - check that holdRequests is able to wait for a non finished job
373 time.sleep(0.01) # let main proc the priority
374 rs.holdRequests() # the aim of the test is here. main process is occupied 1s -> holdRequests is Expected to wait
375 s=(datetime.now()-s).total_seconds()
377 assert(s>=0.99*nbOfSecWait and s<nbOfSecWait*1.01) # expect to be not locked