1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import inspect
17 from gofer import proxy
18 from gofer import Singleton
19 from gofer.messaging import Options
20 from gofer.rmi.stub import Stub
21 from threading import RLock
22
23
24 -def agent(uuid, **options):
25 """
26 Get a (mock) proxy for the remote Agent.
27 @param uuid: An agent ID.
28 @type uuid: str
29 @return: A (mock) agent proxy.
30 @rtype: L{MockContainer}
31 """
32 return MockContainer(uuid, None, **options)
33
39
45
52
58
60 """
61 Get all mock container instances.
62 @return: A list of mock container instances.
63 @rtype: L{MockContainer}
64 """
65 return MockContainer.all()
66
79
82 """
83 The (mock) stub container
84 @ivar __id: The peer ID.
85 @type __id: str
86 @ivar __options: Container options.
87 @type __options: L{Options}
88 @ivar __stubs: A cache of stubs.
89 @type __stubs: dict
90 """
91
92 __metaclass__ = MetaContainer
93
94 - def __init__(self, uuid, producer=None, **options):
95 """
96 @param uuid: The peer ID.
97 @type uuid: str
98 @param producer: An AMQP producer (unused).
99 @type producer: L{gofer.messaging.producer.Producer}
100 @param options: keyword options.
101 @type options: dict
102 """
103 self.__id = uuid
104 self.__options = Options()
105 self.__options += options
106 self.__stubs = {}
107
109 """
110 Get a stub by name.
111 @param name: The name of a stub class.
112 @type name: str
113 @return: A stub object.
114 @rtype: L{MockStub}
115 """
116 stub = self.__stubs.get(name)
117 if stub is None:
118 stub = Factory.stub(name)
119 if not stub:
120 raise AttributeError(name)
121 self.__stubs[name] = stub
122 return stub
123
125 """
126 Get a stub by name.
127 @param name: The name of a stub class.
128 @type name: str
129 @return: A stub object.
130 @rtype: L{MockStub}
131 """
132 return getattr(self, name)
133
135 return '{%s/%s} opt:%s' % \
136 (id(self),
137 self.__id,
138 repr(self.__options))
139
142
145 """
146 Call object.
147 @ivar call: The call tuple (args,kwargs)
148 @type call: tuple
149 """
150
152 """
153 @param call: The call tuple.
154 @type call: tuple
155 """
156 self.call = call
157
158 @property
160 """
161 Get the call argument list.
162 """
163 return self.call[0]
164
165 @property
167 """
168 Get the keyword arguments.
169 """
170 return self.call[1]
171
174
176 return iter(self.call)
177
179 return str(self.call)
180
182 return repr(self.call)
183
186 """
187 Mock stub.
188 """
189
190 @classmethod
192 for m in inspect.getmembers(inst, inspect.ismethod):
193 setattr(inst, m[0], Method(m[1]))
194 return inst
195
200
203
206
208 return getattr(self, name)
209
212
215
218 """
219 Method wrapper.
220 @ivar __method: The (wrapped) method.
221 @type __method: instancemethod
222 @ivar __history: The call history
223 @type __history: list
224 @ivar __mutex: The object mutex
225 @type __mutex: RLock
226 """
227
229 """
230 @param method: A (wrapped) method.
231 @type method: instancemethod
232 """
233 self.__method = [method]
234 self.__history = []
235 self.__mutex = RLock()
236
238 self.__lock()
239 try:
240 call = (args, options)
241 self.__history.append(call)
242 method = self.pop()
243 return method(*args, **options)
244 finally:
245 self.__unlock()
246
247 - def push(self, method):
248 """
249 Push a function, exception to be evaluated on next call.
250 @param method: A function/exception
251 @type method: function/exception
252 """
253 self.__lock()
254 try:
255 self.__method.append(method)
256 finally:
257 self.__unlock()
258
260 """
261 Pop the next method to be executed.
262 It could be an exception in which case, it is raised.
263 @return: The next method.
264 @rtype: callable
265 """
266 self.__lock()
267 try:
268 method = self.__method[0]
269 if len(self.__method) > 1:
270 method = self.__method.pop()
271 if isinstance(method, Exception):
272 raise method
273 return method
274 finally:
275 self.__unlock()
276
278 """
279 Purge the call history.
280 """
281 self.__lock()
282 try:
283 self.__history = []
284 finally:
285 self.__unlock()
286
288 """
289 Get the call history.
290 @return: A list of L{Call}
291 @rtype: list
292 """
293 self.__lock()
294 try:
295 history = []
296 for h in self.__history:
297 history.append(Call(h))
298 return history
299 finally:
300 self.__unlock()
301
304
307
310 """
311 Stub factory
312 @cvar mocks: The registered stubs.
313 @type mocks: dict
314 """
315
316 mocks = {}
317
318 @classmethod
320 """
321 Register an I{mock} to be used instead of
322 creating a real stub.
323 """
324 cls.mocks.update(mocks)
325
326 @classmethod
328 """
329 purge registered mocks.
330 """
331 mocks = {}
332
333 @classmethod
334 - def stub(cls, name):
335 """
336 Get a (mock) stub by name.
337 @param name: The stub class (or module) name.
338 @type name: str
339 @return: A stub instance.
340 @rtype: L{Stub}
341 """
342 stub = cls.mocks.get(name)
343 if stub:
344 return Stub(stub)
345 else:
346 return None
347