Merge lp:~free.ekanayaka/landscape-client/amp-cleanup into lp:~landscape/landscape-client/trunk

Proposed by Free Ekanayaka
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 662
Merged at revision: 662
Proposed branch: lp:~free.ekanayaka/landscape-client/amp-cleanup
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 621 lines (+102/-93)
4 files modified
landscape/lib/amp.py (+46/-49)
landscape/lib/tests/test_amp.py (+52/-41)
landscape/tests/test_amp.py (+1/-1)
landscape/tests/test_configuration.py (+3/-2)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-client/amp-cleanup
Reviewer Review Type Date Requested Status
Geoff Teale (community) Approve
Alberto Donato (community) Approve
Review via email: mp+159799@code.launchpad.net

Commit message

This is almost a trivial change, in preparation of some follow-up cleanup work. It's mostly about cosmetics and little details in landscape.lib.amp:

- Change the module docstring to reflect how this machinery's API will change (note
  that it hasn't been implemented yet tho). The new style is a bit more Twisted-y,
  and doesn't force the use to use unix sockets.

- MethodCallSender.send_method_call now returns directly the result of the remote
  method invokation, rather then MethodCall.response low-level dict. Tests have been
  updated accordingly.

- MethodCallSender.protocol is now public, and can be set by calling code.

Description of the change

This is almost a trivial change, in preparation of some follow-up cleanup work. It's mostly about cosmetics and little details in landscape.lib.amp:

- Change the module docstring to reflect how this machinery's API will change (note
  that it hasn't been implemented yet tho). The new style is a bit more Twisted-y,
  and doesn't force the use to use unix sockets.

- MethodCallSender.send_method_call now returns directly the result of the remote
  method invokation, rather then MethodCall.response low-level dict. Tests have been
  updated accordingly.

- MethodCallSender.protocol is now public, and can be set by calling code.

To post a comment you must log in.
Revision history for this message
Alberto Donato (ack) wrote :

Nice! +1

review: Approve
Revision history for this message
Geoff Teale (tealeg) wrote :

Clean as a whistle +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'landscape/lib/amp.py'
--- landscape/lib/amp.py 2013-04-15 11:00:01 +0000
+++ landscape/lib/amp.py 2013-04-19 11:37:27 +0000
@@ -18,29 +18,21 @@
18Process A can "publish" the greeter object by defining which methods are18Process A can "publish" the greeter object by defining which methods are
19exposed remotely and opening a Unix socket for incoming connections::19exposed remotely and opening a Unix socket for incoming connections::
2020
21 class GreeterProtocol(MethodCallProtocol):21 factory = MethodCallServerFactory(greeter, ["hello"])
22
23 methods = ["hello"]
24
25 factory = MethodCallFactory(object=greeter)
26 factory.protocol = GreeterProtocol
27 reactor.listenUNIX("/some/socket/path", factory)22 reactor.listenUNIX("/some/socket/path", factory)
2823
29Then a second Python process "B" can connect to that socket and build a24Then a second Python process "B" can connect to that socket and build a
30"remote" greeter object, i.e. a proxy that forwards method calls to the25"remote" greeter object, i.e. a proxy that forwards method calls to the
31real greeter object living in process A::26real greeter object living in process A::
3227
33 connector = ClientCreator(reactor, GreeterProtocol)28 factory = MethodCallClientFactory()
34 connected = connector.connectUNIX("/some/socket/path")29 reactor.connectUNIX("/some/socket/path", factory)
3530
36 def got_connection(protocol):31 def got_remote(remote_greeter):
37
38 remote_greeter = RemoteObject(protocol)
39
40 deferred = remote_greeter.hello("Ted")32 deferred = remote_greeter.hello("Ted")
41 deferred.addCallback(lambda result: ... # result == "hi Ted!")33 deferred.addCallback(lambda result: ... # result == "hi Ted!")
4234
43 connected.addCallback(got_connection)35 factory.getRemoteObject().addCallback(got_remote)
4436
45Note that when invoking a method via the remote proxy, the parameters37Note that when invoking a method via the remote proxy, the parameters
46are required to be serializable with bpickle, so that they can be sent38are required to be serializable with bpickle, so that they can be sent
@@ -111,14 +103,6 @@
111 errors = {MethodCallError: "METHOD_CALL_ERROR"}103 errors = {MethodCallError: "METHOD_CALL_ERROR"}
112104
113105
114class MethodCallServerProtocol(AMP):
115 """XXX Placeholder"""
116
117
118class MethodCallClientProtocol(AMP):
119 """XXX Placeholder"""
120
121
122class MethodCallReceiver(CommandLocator):106class MethodCallReceiver(CommandLocator):
123 """Expose methods of a local object over AMP.107 """Expose methods of a local object over AMP.
124108
@@ -196,22 +180,20 @@
196180
197181
198class MethodCallSender(object):182class MethodCallSender(object):
199 """Calls methods of a remote object over L{AMP}.183 """Call methods on a remote object over L{AMP} and return the result.
200184
201 @note: If the remote method returns a deferred, the associated local185 @param protocol: A connected C{AMP} protocol.
202 deferred returned by L{send_method_call} will result in the same186 @param clock: An object implementing the C{IReactorTime} interface.
203 callback value of the remote deferred.187
204 @cvar timeout: A timeout for remote methods returning L{Deferred}s, if a188 @ivar timeout: A timeout for remote method class, see L{send_method_call}.
205 response for the deferred is not received within this amount of
206 seconds, the remote method call will errback with a L{MethodCallError}.
207 """189 """
208 timeout = 60190 timeout = 60
209 chunk_size = MAX_VALUE_LENGTH191
192 _chunk_size = MAX_VALUE_LENGTH
210193
211 def __init__(self, protocol, clock):194 def __init__(self, protocol, clock):
212 self._protocol = protocol195 self.protocol = protocol
213 self._clock = clock196 self.clock = clock
214 self._pending_responses = []
215 self._sequence = 0197 self._sequence = 0
216198
217 def _create_sequence(self):199 def _create_sequence(self):
@@ -223,8 +205,8 @@
223 """Send an L{AMP} command that will errback in case of a timeout.205 """Send an L{AMP} command that will errback in case of a timeout.
224206
225 @return: A deferred resulting in the command's response (or failure) if207 @return: A deferred resulting in the command's response (or failure) if
226 the peer responds within L{MethodClientProtocol.timeout} seconds,208 the peer responds within C{self.timeout} seconds, or that errbacks
227 or that errbacks with a L{MethodCallError} otherwise.209 with a L{MethodCallError} otherwise.
228 """210 """
229 deferred = Deferred()211 deferred = Deferred()
230212
@@ -240,25 +222,32 @@
240 # The peer didn't respond on time, raise an error.222 # The peer didn't respond on time, raise an error.
241 deferred.errback(MethodCallError("timeout"))223 deferred.errback(MethodCallError("timeout"))
242224
243 call = self._clock.callLater(self.timeout, handle_timeout)225 call = self.clock.callLater(self.timeout, handle_timeout)
244226
245 result = self._protocol.callRemote(command, **kwargs)227 result = self.protocol.callRemote(command, **kwargs)
246 result.addBoth(handle_response)228 result.addBoth(handle_response)
247 return deferred229 return deferred
248230
249 def send_method_call(self, method, args=[], kwargs={}):231 def send_method_call(self, method, args=[], kwargs={}):
250 """Send a L{MethodCall} command with the given arguments.232 """Send a L{MethodCall} command with the given arguments.
251233
234 If a response from the server is not received within C{self.timeout}
235 seconds, the returned deferred will errback with a L{MethodCallError}.
236
252 @param method: The name of the remote method to invoke.237 @param method: The name of the remote method to invoke.
253 @param args: The positional arguments to pass to the remote method.238 @param args: The positional arguments to pass to the remote method.
254 @param kwargs: The keyword arguments to pass to the remote method.239 @param kwargs: The keyword arguments to pass to the remote method.
240
241 @return: A C{Deferred} firing with the return value of the method
242 invoked on the remote object. If the remote method itself returns
243 a deferred, we fire with the callback value of such deferred.
255 """244 """
256 arguments = dumps((args, kwargs))245 arguments = dumps((args, kwargs))
257 sequence = self._create_sequence()246 sequence = self._create_sequence()
258247
259 # Split the given arguments in one or more chunks248 # Split the given arguments in one or more chunks
260 chunks = [arguments[i:i + self.chunk_size]249 chunks = [arguments[i:i + self._chunk_size]
261 for i in xrange(0, len(arguments), self.chunk_size)]250 for i in xrange(0, len(arguments), self._chunk_size)]
262251
263 result = Deferred()252 result = Deferred()
264 if len(chunks) > 1:253 if len(chunks) > 1:
@@ -266,7 +255,7 @@
266 for chunk in chunks[:-1]:255 for chunk in chunks[:-1]:
267256
268 def create_send_chunk(sequence, chunk):257 def create_send_chunk(sequence, chunk):
269 send_chunk = lambda x: self._protocol.callRemote(258 send_chunk = lambda x: self.protocol.callRemote(
270 MethodCallChunk, sequence=sequence, chunk=chunk)259 MethodCallChunk, sequence=sequence, chunk=chunk)
271 return send_chunk260 return send_chunk
272261
@@ -278,10 +267,19 @@
278 MethodCall, sequence=sequence, method=method, arguments=chunk)267 MethodCall, sequence=sequence, method=method, arguments=chunk)
279268
280 result.addCallback(send_last_chunk)269 result.addCallback(send_last_chunk)
270 result.addCallback(lambda response: response["result"])
281 result.callback(None)271 result.callback(None)
282 return result272 return result
283273
284274
275class MethodCallServerProtocol(AMP):
276 """XXX Placeholder"""
277
278
279class MethodCallClientProtocol(AMP):
280 """XXX Placeholder"""
281
282
285class MethodCallProtocol(MethodCallServerProtocol, MethodCallClientProtocol):283class MethodCallProtocol(MethodCallServerProtocol, MethodCallClientProtocol):
286 """Can be used both for sending and receiving L{MethodCall}s."""284 """Can be used both for sending and receiving L{MethodCall}s."""
287285
@@ -410,22 +408,21 @@
410 args=args,408 args=args,
411 kwargs=kwargs)409 kwargs=kwargs)
412 deferred = Deferred()410 deferred = Deferred()
413 result.addCallback(self._handle_response, deferred)411 result.addCallback(self._handle_result, deferred)
414 result.addErrback(self._handle_failure, method, args, kwargs,412 result.addErrback(self._handle_failure, method, args, kwargs,
415 deferred)413 deferred)
416 return deferred414 return deferred
417415
418 return send_method_call416 return send_method_call
419417
420 def _handle_response(self, response, deferred, call=None):418 def _handle_result(self, result, deferred, call=None):
421 """Handles a successful L{MethodCall} response.419 """Handles a successful C{send_method_call} result.
422420
423 @param response: The L{MethodCall} response.421 @param response: The L{MethodCall} response.
424 @param deferred: The deferred that was returned to the caller.422 @param deferred: The deferred that was returned to the caller.
425 @param call: If not C{None}, the scheduled timeout call associated with423 @param call: If not C{None}, the scheduled timeout call associated with
426 the given deferred.424 the given deferred.
427 """425 """
428 result = response["result"]
429 if call is not None:426 if call is not None:
430 call.cancel() # This is a successful retry, cancel the timeout.427 call.cancel() # This is a successful retry, cancel the timeout.
431 deferred.callback(result)428 deferred.callback(result)
@@ -478,7 +475,7 @@
478475
479 @param protocol: The newly connected protocol instance.476 @param protocol: The newly connected protocol instance.
480 """477 """
481 self._sender._protocol = protocol478 self._sender.protocol = protocol
482 if self._retry_on_reconnect:479 if self._retry_on_reconnect:
483 self._retry()480 self._retry()
484481
@@ -495,7 +492,7 @@
495 while requests:492 while requests:
496 deferred, (method, args, kwargs, call) = requests.popitem()493 deferred, (method, args, kwargs, call) = requests.popitem()
497 result = self._sender.send_method_call(method, args, kwargs)494 result = self._sender.send_method_call(method, args, kwargs)
498 result.addCallback(self._handle_response,495 result.addCallback(self._handle_result,
499 deferred=deferred, call=call)496 deferred=deferred, call=call)
500 result.addErrback(self._handle_failure, method, args, kwargs,497 result.addErrback(self._handle_failure, method, args, kwargs,
501 deferred=deferred, call=call)498 deferred=deferred, call=call)
@@ -564,6 +561,6 @@
564 if self._factory:561 if self._factory:
565 self._factory.stopTrying()562 self._factory.stopTrying()
566 if self._remote:563 if self._remote:
567 if self._remote._sender._protocol.transport:564 if self._remote._sender.protocol.transport:
568 self._remote._sender._protocol.transport.loseConnection()565 self._remote._sender.protocol.transport.loseConnection()
569 self._remote = None566 self._remote = None
570567
=== modified file 'landscape/lib/tests/test_amp.py'
--- landscape/lib/tests/test_amp.py 2013-04-15 11:00:01 +0000
+++ landscape/lib/tests/test_amp.py 2013-04-19 11:37:27 +0000
@@ -160,6 +160,19 @@
160 factory = WordsFactory160 factory = WordsFactory
161161
162162
163METHODS = ["empty",
164 "motd",
165 "capitalize",
166 "is_short",
167 "concatenate",
168 "lower_case",
169 "multiply_alphabetically",
170 "translate",
171 "meaning_of_life",
172 "guess",
173 "google"]
174
175
163class MethodCallTest(LandscapeTest):176class MethodCallTest(LandscapeTest):
164177
165 def setUp(self):178 def setUp(self):
@@ -190,7 +203,7 @@
190 args=[],203 args=[],
191 kwargs={})204 kwargs={})
192 self.connection.flush()205 self.connection.flush()
193 self.assertEqual({"result": None}, self.successResultOf(deferred))206 self.assertIs(None, self.successResultOf(deferred))
194207
195 def test_with_return_value(self):208 def test_with_return_value(self):
196 """209 """
@@ -201,8 +214,7 @@
201 args=[],214 args=[],
202 kwargs={})215 kwargs={})
203 self.connection.flush()216 self.connection.flush()
204 self.assertEqual({"result": "Words are cool"},217 self.assertEqual("Words are cool", self.successResultOf(deferred))
205 self.successResultOf(deferred))
206218
207 def test_with_one_argument(self):219 def test_with_one_argument(self):
208 """220 """
@@ -213,7 +225,7 @@
213 args=["john"],225 args=["john"],
214 kwargs={})226 kwargs={})
215 self.connection.flush()227 self.connection.flush()
216 self.assertEqual({"result": "John"}, self.successResultOf(deferred))228 self.assertEqual("John", self.successResultOf(deferred))
217229
218 def test_with_boolean_return_value(self):230 def test_with_boolean_return_value(self):
219 """231 """
@@ -223,7 +235,7 @@
223 args=["hi"],235 args=["hi"],
224 kwargs={})236 kwargs={})
225 self.connection.flush()237 self.connection.flush()
226 self.assertEqual({"result": True}, self.successResultOf(deferred))238 self.assertTrue(self.successResultOf(deferred))
227239
228 def test_with_many_arguments(self):240 def test_with_many_arguments(self):
229 """241 """
@@ -233,7 +245,7 @@
233 args=["We ", "rock"],245 args=["We ", "rock"],
234 kwargs={})246 kwargs={})
235 self.connection.flush()247 self.connection.flush()
236 self.assertEqual({"result": "We rock"}, self.successResultOf(deferred))248 self.assertEqual("We rock", self.successResultOf(deferred))
237249
238 def test_with_default_arguments(self):250 def test_with_default_arguments(self):
239 """251 """
@@ -244,7 +256,7 @@
244 args=["OHH"],256 args=["OHH"],
245 kwargs={})257 kwargs={})
246 self.connection.flush()258 self.connection.flush()
247 self.assertEqual({"result": "ohh"}, self.successResultOf(deferred))259 self.assertEqual("ohh", self.successResultOf(deferred))
248260
249 def test_with_overriden_default_arguments(self):261 def test_with_overriden_default_arguments(self):
250 """262 """
@@ -256,7 +268,7 @@
256 args=["OHH"],268 args=["OHH"],
257 kwargs={"index": 2})269 kwargs={"index": 2})
258 self.connection.flush()270 self.connection.flush()
259 self.assertEqual({"result": "OHh"}, self.successResultOf(deferred))271 self.assertEqual("OHh", self.successResultOf(deferred))
260272
261 def test_with_dictionary_arguments(self):273 def test_with_dictionary_arguments(self):
262 """274 """
@@ -267,8 +279,7 @@
267 args=[{"foo": 2, "bar": 3}],279 args=[{"foo": 2, "bar": 3}],
268 kwargs={})280 kwargs={})
269 self.connection.flush()281 self.connection.flush()
270 self.assertEqual({"result": "barbarbarfoofoo"},282 self.assertEqual("barbarbarfoofoo", self.successResultOf(deferred))
271 self.successResultOf(deferred))
272283
273 def test_with_non_serializable_return_value(self):284 def test_with_non_serializable_return_value(self):
274 """285 """
@@ -290,7 +301,7 @@
290 args=["!" * 65535],301 args=["!" * 65535],
291 kwargs={})302 kwargs={})
292 self.connection.flush()303 self.connection.flush()
293 self.assertEqual({"result": False}, self.successResultOf(deferred))304 self.assertFalse(self.successResultOf(deferred))
294305
295 def test_with_long_argument_multiple_calls(self):306 def test_with_long_argument_multiple_calls(self):
296 """307 """
@@ -305,8 +316,8 @@
305 kwargs={})316 kwargs={})
306317
307 self.connection.flush()318 self.connection.flush()
308 self.assertEqual({"result": False}, self.successResultOf(deferred1))319 self.assertFalse(self.successResultOf(deferred1))
309 self.assertEqual({"result": False}, self.successResultOf(deferred2))320 self.assertFalse(self.successResultOf(deferred2))
310321
311 def test_translate(self):322 def test_translate(self):
312 """323 """
@@ -339,14 +350,14 @@
339 return deferred350 return deferred
340351
341 sender.send_method_call = synchronous_send_method_call352 sender.send_method_call = synchronous_send_method_call
342 self.words = RemoteObject(sender)353 self.remote = RemoteObject(sender)
343354
344 def test_method_call_sender_with_forbidden_method(self):355 def test_method_call_sender_with_forbidden_method(self):
345 """356 """
346 A L{RemoteObject} can send L{MethodCall}s without arguments and withj357 A L{RemoteObject} can send L{MethodCall}s without arguments and withj
347 an empty response.358 an empty response.
348 """359 """
349 deferred = self.words.secret()360 deferred = self.remote.secret()
350 self.failureResultOf(deferred).trap(MethodCallError)361 self.failureResultOf(deferred).trap(MethodCallError)
351362
352 def test_with_no_arguments(self):363 def test_with_no_arguments(self):
@@ -354,7 +365,7 @@
354 A L{RemoteObject} can send L{MethodCall}s without arguments and withj365 A L{RemoteObject} can send L{MethodCall}s without arguments and withj
355 an empty response.366 an empty response.
356 """367 """
357 deferred = self.words.empty()368 deferred = self.remote.empty()
358 self.assertIs(None, self.successResultOf(deferred))369 self.assertIs(None, self.successResultOf(deferred))
359370
360 def test_with_return_value(self):371 def test_with_return_value(self):
@@ -362,7 +373,7 @@
362 A L{RemoteObject} can send L{MethodCall}s without arguments and get373 A L{RemoteObject} can send L{MethodCall}s without arguments and get
363 back the value of the commands's response.374 back the value of the commands's response.
364 """375 """
365 deferred = self.words.motd()376 deferred = self.remote.motd()
366 self.assertEqual("Words are cool", self.successResultOf(deferred))377 self.assertEqual("Words are cool", self.successResultOf(deferred))
367378
368 def test_with_one_argument(self):379 def test_with_one_argument(self):
@@ -370,27 +381,27 @@
370 A L{RemoteObject} can send L{MethodCall}s with one argument and get381 A L{RemoteObject} can send L{MethodCall}s with one argument and get
371 the response value.382 the response value.
372 """383 """
373 deferred = self.words.capitalize("john")384 deferred = self.remote.capitalize("john")
374 self.assertEqual("John", self.successResultOf(deferred))385 self.assertEqual("John", self.successResultOf(deferred))
375386
376 def test_with_one_keyword_argument(self):387 def test_with_one_keyword_argument(self):
377 """388 """
378 A L{RemoteObject} can send L{MethodCall}s with a named argument.389 A L{RemoteObject} can send L{MethodCall}s with a named argument.
379 """390 """
380 deferred = self.words.capitalize(word="john")391 deferred = self.remote.capitalize(word="john")
381 self.assertEqual("John", self.successResultOf(deferred))392 self.assertEqual("John", self.successResultOf(deferred))
382393
383 def test_with_boolean_return_value(self):394 def test_with_boolean_return_value(self):
384 """395 """
385 The return value of a L{MethodCall} argument can be a boolean.396 The return value of a L{MethodCall} argument can be a boolean.
386 """397 """
387 return self.assertSuccess(self.words.is_short("hi"), True)398 return self.assertSuccess(self.remote.is_short("hi"), True)
388399
389 def test_with_many_arguments(self):400 def test_with_many_arguments(self):
390 """401 """
391 A L{RemoteObject} can send L{MethodCall}s with more than one argument.402 A L{RemoteObject} can send L{MethodCall}s with more than one argument.
392 """403 """
393 deferred = self.words.concatenate("You ", "rock")404 deferred = self.remote.concatenate("You ", "rock")
394 self.assertEqual("You rock", self.successResultOf(deferred))405 self.assertEqual("You rock", self.successResultOf(deferred))
395406
396 def test_with_many_keyword_arguments(self):407 def test_with_many_keyword_arguments(self):
@@ -398,7 +409,7 @@
398 A L{RemoteObject} can send L{MethodCall}s with several409 A L{RemoteObject} can send L{MethodCall}s with several
399 named arguments.410 named arguments.
400 """411 """
401 deferred = self.words.concatenate(word2="rock", word1="You ")412 deferred = self.remote.concatenate(word2="rock", word1="You ")
402 self.assertEqual("You rock", self.successResultOf(deferred))413 self.assertEqual("You rock", self.successResultOf(deferred))
403414
404 def test_with_default_arguments(self):415 def test_with_default_arguments(self):
@@ -406,7 +417,7 @@
406 A L{RemoteObject} can send a L{MethodCall} having an argument with417 A L{RemoteObject} can send a L{MethodCall} having an argument with
407 a default value.418 a default value.
408 """419 """
409 deferred = self.words.lower_case("OHH")420 deferred = self.remote.lower_case("OHH")
410 self.assertEqual("ohh", self.successResultOf(deferred))421 self.assertEqual("ohh", self.successResultOf(deferred))
411422
412 def test_with_overriden_default_arguments(self):423 def test_with_overriden_default_arguments(self):
@@ -414,7 +425,7 @@
414 A L{RemoteObject} can send L{MethodCall}s overriding the default425 A L{RemoteObject} can send L{MethodCall}s overriding the default
415 value of an argument.426 value of an argument.
416 """427 """
417 deferred = self.words.lower_case("OHH", 2)428 deferred = self.remote.lower_case("OHH", 2)
418 self.assertEqual("OHh", self.successResultOf(deferred))429 self.assertEqual("OHh", self.successResultOf(deferred))
419430
420 def test_with_dictionary_arguments(self):431 def test_with_dictionary_arguments(self):
@@ -422,7 +433,7 @@
422 A L{RemoteObject} can send a L{MethodCall}s for methods requiring433 A L{RemoteObject} can send a L{MethodCall}s for methods requiring
423 a dictionary arguments.434 a dictionary arguments.
424 """435 """
425 deferred = self.words.multiply_alphabetically({"foo": 2, "bar": 3})436 deferred = self.remote.multiply_alphabetically({"foo": 2, "bar": 3})
426 self.assertEqual("barbarbarfoofoo", self.successResultOf(deferred))437 self.assertEqual("barbarbarfoofoo", self.successResultOf(deferred))
427438
428 def test_with_generic_args_and_kwargs(self):439 def test_with_generic_args_and_kwargs(self):
@@ -430,7 +441,7 @@
430 A L{RemoteObject} behaves well with L{MethodCall}s for methods441 A L{RemoteObject} behaves well with L{MethodCall}s for methods
431 having generic C{*args} and C{**kwargs} arguments.442 having generic C{*args} and C{**kwargs} arguments.
432 """443 """
433 deferred = self.words.guess("word", "cool", value=4)444 deferred = self.remote.guess("word", "cool", value=4)
434 self.assertEqual("Guessed!", self.successResultOf(deferred))445 self.assertEqual("Guessed!", self.successResultOf(deferred))
435446
436 def test_with_successful_deferred(self):447 def test_with_successful_deferred(self):
@@ -439,7 +450,7 @@
439 transparently.450 transparently.
440 """451 """
441 result = []452 result = []
442 deferred = self.words.google("Landscape")453 deferred = self.remote.google("Landscape")
443 deferred.addCallback(result.append)454 deferred.addCallback(result.append)
444455
445 # At this point the receiver is waiting for method to complete, so456 # At this point the receiver is waiting for method to complete, so
@@ -458,7 +469,7 @@
458 L{MethodCallError} is raised.469 L{MethodCallError} is raised.
459 """470 """
460 result = []471 result = []
461 deferred = self.words.google("Weird stuff")472 deferred = self.remote.google("Weird stuff")
462 deferred.addErrback(result.append)473 deferred.addErrback(result.append)
463474
464 # At this point the receiver is waiting for method to complete, so475 # At this point the receiver is waiting for method to complete, so
@@ -476,14 +487,14 @@
476 """487 """
477 The target object method can return an already fired L{Deferred}.488 The target object method can return an already fired L{Deferred}.
478 """489 """
479 deferred = self.words.google("Easy query")490 deferred = self.remote.google("Easy query")
480 self.assertEqual("Done!", self.successResultOf(deferred))491 self.assertEqual("Done!", self.successResultOf(deferred))
481492
482 def test_with_already_errback_deferred(self):493 def test_with_already_errback_deferred(self):
483 """494 """
484 If the target object method can return an already failed L{Deferred}.495 If the target object method can return an already failed L{Deferred}.
485 """496 """
486 deferred = self.words.google("Censored")497 deferred = self.remote.google("Censored")
487 self.failureResultOf(deferred).trap(MethodCallError)498 self.failureResultOf(deferred).trap(MethodCallError)
488499
489 def test_with_deferred_timeout(self):500 def test_with_deferred_timeout(self):
@@ -492,7 +503,7 @@
492 the given timeout, the method call fails.503 the given timeout, the method call fails.
493 """504 """
494 result = []505 result = []
495 deferred = self.words.google("Long query")506 deferred = self.remote.google("Long query")
496 deferred.addErrback(result.append)507 deferred.addErrback(result.append)
497508
498 self.clock.advance(60.0)509 self.clock.advance(60.0)
@@ -506,7 +517,7 @@
506 already timeout, that response is ignored.517 already timeout, that response is ignored.
507 """518 """
508 result = []519 result = []
509 deferred = self.words.google("Slowish query")520 deferred = self.remote.google("Slowish query")
510 deferred.addErrback(result.append)521 deferred.addErrback(result.append)
511522
512 self.clock.advance(120.0)523 self.clock.advance(120.0)
@@ -520,7 +531,7 @@
520 def setUp(self):531 def setUp(self):
521 super(MethodCallFactoryTest, self).setUp()532 super(MethodCallFactoryTest, self).setUp()
522 self.clock = Clock()533 self.clock = Clock()
523 self.factory = WordsFactory(reactor=self.clock)534 self.factory = MethodCallFactory(reactor=self.clock)
524535
525 def test_max_delay(self):536 def test_max_delay(self):
526 """537 """
@@ -669,7 +680,7 @@
669 If the connection is lost, the L{RemoteObject} created by the creator680 If the connection is lost, the L{RemoteObject} created by the creator
670 will transparently handle the reconnection.681 will transparently handle the reconnection.
671 """682 """
672 self.words._sender._protocol.transport.loseConnection()683 self.words._sender.protocol.transport.loseConnection()
673 self.port.stopListening()684 self.port.stopListening()
674685
675 def restart_listening():686 def restart_listening():
@@ -698,7 +709,7 @@
698 will transparently retry to perform the L{MethodCall} requests that709 will transparently retry to perform the L{MethodCall} requests that
699 failed due to the broken connection.710 failed due to the broken connection.
700 """711 """
701 self.words._sender._protocol.transport.loseConnection()712 self.words._sender.protocol.transport.loseConnection()
702 self.port.stopListening()713 self.port.stopListening()
703714
704 def restart_listening():715 def restart_listening():
@@ -713,7 +724,7 @@
713 the L{RemoteObject} will properly propagate the error to the original724 the L{RemoteObject} will properly propagate the error to the original
714 caller.725 caller.
715 """726 """
716 self.words._sender._protocol.transport.loseConnection()727 self.words._sender.protocol.transport.loseConnection()
717 self.port.stopListening()728 self.port.stopListening()
718729
719 def restart_listening():730 def restart_listening():
@@ -733,12 +744,12 @@
733 connection is ready. If for whatever reason the connection drops744 connection is ready. If for whatever reason the connection drops
734 again very quickly, the C{_retry} method will behave as expected.745 again very quickly, the C{_retry} method will behave as expected.
735 """746 """
736 self.words._sender._protocol.transport.loseConnection()747 self.words._sender.protocol.transport.loseConnection()
737 self.port.stopListening()748 self.port.stopListening()
738749
739 def handle_reconnect(protocol):750 def handle_reconnect(protocol):
740 # In this precise moment we have a newly connected protocol751 # In this precise moment we have a newly connected protocol
741 self.words._sender._protocol = protocol752 self.words._sender.protocol = protocol
742753
743 # Pretend that the connection is lost again very quickly754 # Pretend that the connection is lost again very quickly
744 protocol.transport.loseConnection()755 protocol.transport.loseConnection()
@@ -773,7 +784,7 @@
773 will be all eventually completed when the connection gets established784 will be all eventually completed when the connection gets established
774 again.785 again.
775 """786 """
776 self.words._sender._protocol.transport.loseConnection()787 self.words._sender.protocol.transport.loseConnection()
777 self.port.stopListening()788 self.port.stopListening()
778789
779 def restart_listening():790 def restart_listening():
@@ -804,7 +815,7 @@
804 retry to perform requests which failed because the connection was815 retry to perform requests which failed because the connection was
805 lost, however requests made after a reconnection will still succeed.816 lost, however requests made after a reconnection will still succeed.
806 """817 """
807 self.words._sender._protocol.transport.loseConnection()818 self.words._sender.protocol.transport.loseConnection()
808 self.port.stopListening()819 self.port.stopListening()
809820
810 def restart_listening():821 def restart_listening():
@@ -829,7 +840,7 @@
829 L{MethodCall}s after that amount of seconds, without retrying them when840 L{MethodCall}s after that amount of seconds, without retrying them when
830 the connection established again.841 the connection established again.
831 """842 """
832 self.words._sender._protocol.transport.loseConnection()843 self.words._sender.protocol.transport.loseConnection()
833 self.port.stopListening()844 self.port.stopListening()
834845
835 def restart_listening():846 def restart_listening():
836847
=== modified file 'landscape/tests/test_amp.py'
--- landscape/tests/test_amp.py 2013-04-15 09:03:43 +0000
+++ landscape/tests/test_amp.py 2013-04-19 11:37:27 +0000
@@ -118,7 +118,7 @@
118 ports.append(self.reactor.listen_unix(socket, factory))118 ports.append(self.reactor.listen_unix(socket, factory))
119119
120 def connected(remote):120 def connected(remote):
121 remote._sender._protocol.transport.loseConnection()121 remote._sender.protocol.transport.loseConnection()
122 ports[0].stopListening()122 ports[0].stopListening()
123 self.reactor._reactor.callLater(0.01, listen_again)123 self.reactor._reactor.callLater(0.01, listen_again)
124124
125125
=== modified file 'landscape/tests/test_configuration.py'
--- landscape/tests/test_configuration.py 2013-03-27 22:58:20 +0000
+++ landscape/tests/test_configuration.py 2013-04-19 11:37:27 +0000
@@ -6,6 +6,7 @@
66
7from twisted.internet.defer import succeed, fail7from twisted.internet.defer import succeed, fail
88
9from landscape.lib.amp import MethodCallSender
9from landscape.reactor import TwistedReactor10from landscape.reactor import TwistedReactor
10from landscape.lib.fetch import HTTPCodeError, PyCurlError11from landscape.lib.fetch import HTTPCodeError, PyCurlError
11from landscape.configuration import (12from landscape.configuration import (
@@ -19,7 +20,7 @@
19from landscape.tests.helpers import (20from landscape.tests.helpers import (
20 LandscapeTest, BrokerServiceHelper, EnvironSaverHelper)21 LandscapeTest, BrokerServiceHelper, EnvironSaverHelper)
21from landscape.tests.mocker import ARGS, ANY, MATCH, CONTAINS, expect22from landscape.tests.mocker import ARGS, ANY, MATCH, CONTAINS, expect
22from landscape.broker.amp import RemoteBroker, BrokerClientProtocol23from landscape.broker.amp import RemoteBroker
2324
2425
25class LandscapeConfigurationTest(LandscapeTest):26class LandscapeConfigurationTest(LandscapeTest):
@@ -1784,7 +1785,7 @@
1784 reactor_mock = self.mocker.patch(TwistedReactor)1785 reactor_mock = self.mocker.patch(TwistedReactor)
1785 remote_mock = self.mocker.patch(RemoteBroker)1786 remote_mock = self.mocker.patch(RemoteBroker)
17861787
1787 protocol_mock = self.mocker.patch(BrokerClientProtocol)1788 protocol_mock = self.mocker.patch(MethodCallSender)
1788 protocol_mock.timeout1789 protocol_mock.timeout
1789 self.mocker.result(0.1)1790 self.mocker.result(0.1)
1790 self.mocker.count(0, None)1791 self.mocker.count(0, None)

Subscribers

People subscribed via source and target branches

to all changes: