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

Proposed by Free Ekanayaka
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 674
Merged at revision: 674
Proposed branch: lp:~free.ekanayaka/landscape-client/amp-test-readability
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 781 lines (+168/-275)
2 files modified
landscape/lib/amp.py (+5/-5)
landscape/lib/tests/test_amp.py (+163/-270)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-client/amp-test-readability
Reviewer Review Type Date Requested Status
Chris Glass (community) Approve
Christopher Armstrong (community) Approve
Review via email: mp+163525@code.launchpad.net

Commit message

This is the last branch I have around cleaning up the AMP-based machinery in the client. It essentially just change the tests:

- Drop the Words class, which had a bunch of ad-hoc methods used to exercise the behavior of the MethodCall protocol. Essentially each method was associated with a test, but the context was not clear by reading the test itself (you'd have to go and read the implementation in the Words class).

- Modify most methods to define the remotely-exposed method being tested, so the context is clear.

- Partially re-wrote RemoteObjectTest, which had a bunch of tests which were only duplicating tests from MethodCallTest. Now this test class has only tests that are really specific to RemoteObject.

Description of the change

This is the last branch I have around cleaning up the AMP-based machinery in the client. It essentially just change the tests:

- Drop the Words class, which had a bunch of ad-hoc methods used to exercise the behavior of the MethodCall protocol. Essentially each method was associated with a test, but the context was not clear by reading the test itself (you'd have to go and read the implementation in the Words class).

- Modify most methods to define the remotely-exposed method being tested, so the context is clear.

- Partially re-wrote RemoteObjectTest, which had a bunch of tests which were only duplicating tests from MethodCallTest. Now this test class has only tests that are really specific to RemoteObject.

To post a comment you must log in.
Revision history for this message
Christopher Armstrong (radix) wrote :

I like code removal :-) Words was really weird. +1

review: Approve
Revision history for this message
Chris Glass (tribaal) wrote :

Nice! +1

[1]
landscape/lib/tests/test_amp.py:6: 'TestCase' imported but unused

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/lib/amp.py'
2--- landscape/lib/amp.py 2013-05-07 15:55:25 +0000
3+++ landscape/lib/amp.py 2013-05-13 12:57:34 +0000
4@@ -216,8 +216,8 @@
5 _chunk_size = MAX_VALUE_LENGTH
6
7 def __init__(self, protocol, clock):
8- self.protocol = protocol
9- self.clock = clock
10+ self._protocol = protocol
11+ self._clock = clock
12
13 def _call_remote_with_timeout(self, command, **kwargs):
14 """Send an L{AMP} command that will errback in case of a timeout.
15@@ -240,9 +240,9 @@
16 # The peer didn't respond on time, raise an error.
17 deferred.errback(MethodCallError("timeout"))
18
19- call = self.clock.callLater(self.timeout, handle_timeout)
20+ call = self._clock.callLater(self.timeout, handle_timeout)
21
22- result = self.protocol.callRemote(command, **kwargs)
23+ result = self._protocol.callRemote(command, **kwargs)
24 result.addBoth(handle_response)
25 return deferred
26
27@@ -273,7 +273,7 @@
28 for chunk in chunks[:-1]:
29
30 def create_send_chunk(sequence, chunk):
31- send_chunk = lambda x: self.protocol.callRemote(
32+ send_chunk = lambda x: self._protocol.callRemote(
33 MethodCallChunk, sequence=sequence, chunk=chunk)
34 return send_chunk
35
36
37=== modified file 'landscape/lib/tests/test_amp.py'
38--- landscape/lib/tests/test_amp.py 2013-05-06 18:17:43 +0000
39+++ landscape/lib/tests/test_amp.py 2013-05-13 12:57:34 +0000
40@@ -88,102 +88,18 @@
41 self.connection.lose(self, Failure(ConnectionDone()))
42
43
44-class WordsException(Exception):
45- """Test exception."""
46-
47-
48-class Words(object):
49- """
50- Test class to be used as target object of a L{MethodCallServerFactory}.
51- """
52-
53- def __init__(self, clock=None):
54- self._clock = clock
55-
56- def secret(self):
57- raise RuntimeError("I'm not supposed to be called!")
58-
59- def empty(self):
60- pass
61-
62- def motd(self):
63- return "Words are cool"
64-
65- def capitalize(self, word):
66- return word.capitalize()
67-
68- def is_short(self, word):
69- return len(word) < 4
70-
71- def concatenate(self, word1, word2):
72- return word1 + word2
73-
74- def lower_case(self, word, index=None):
75- if index is None:
76- return word.lower()
77- else:
78- return word[:index] + word[index:].lower()
79-
80- def multiply_alphabetically(self, word_times):
81- result = ""
82- for word, times in sorted(word_times.iteritems()):
83- result += word * times
84- return result
85-
86- def meaning_of_life(self):
87-
88- class Complex(object):
89- pass
90- return Complex()
91-
92- def _check(self, word, seed, value=3):
93- if seed == "cool" and value == 4:
94- return "Guessed!"
95-
96- def guess(self, word, *args, **kwargs):
97- return self._check(word, *args, **kwargs)
98-
99- def translate(self, word):
100- raise WordsException("Unknown word")
101-
102- def google(self, word):
103- deferred = Deferred()
104- if word == "Landscape":
105- self._clock.callLater(0.01, lambda: deferred.callback("Cool!"))
106- elif word == "Easy query":
107- deferred.callback("Done!")
108- elif word == "Weird stuff":
109- error = Exception("bad")
110- self._clock.callLater(0.01, lambda: deferred.errback(error))
111- elif word == "Censored":
112- deferred.errback(Exception("very bad"))
113- elif word == "Long query":
114- # Do nothing, the deferred won't be fired at all
115- pass
116- elif word == "Slowish query":
117- # Fire the result after a while.
118- self._clock.callLater(120.0, lambda: deferred.callback("Done!"))
119- return deferred
120-
121-
122-METHODS = ["empty",
123- "motd",
124- "capitalize",
125- "is_short",
126- "concatenate",
127- "lower_case",
128- "multiply_alphabetically",
129- "translate",
130- "meaning_of_life",
131- "guess",
132- "google"]
133+class DummyObject(object):
134+
135+ method = None
136
137
138 class MethodCallTest(LandscapeTest):
139
140 def setUp(self):
141 super(MethodCallTest, self).setUp()
142- server = MethodCallServerProtocol(Words(), METHODS)
143+ self.methods = ["method"]
144+ self.object = DummyObject()
145+ server = MethodCallServerProtocol(self.object, self.methods)
146 client = MethodCallClientProtocol()
147 self.connection = FakeConnection(client, server)
148 self.connection.make()
149@@ -195,7 +111,8 @@
150 If a method is not included in L{MethodCallServerFactory.methods} it
151 can't be called.
152 """
153- deferred = self.sender.send_method_call(method="secret",
154+ self.methods.remove("method")
155+ deferred = self.sender.send_method_call(method="method",
156 args=[],
157 kwargs={})
158 self.connection.flush()
159@@ -206,7 +123,8 @@
160 A connected client can issue a L{MethodCall} without arguments and
161 with an empty response.
162 """
163- deferred = self.sender.send_method_call(method="empty",
164+ self.object.method = lambda: None
165+ deferred = self.sender.send_method_call(method="method",
166 args=[],
167 kwargs={})
168 self.connection.flush()
169@@ -217,18 +135,20 @@
170 A connected client can issue a L{MethodCall} targeted to an
171 object method with a return value.
172 """
173- deferred = self.sender.send_method_call(method="motd",
174+ self.object.method = lambda: "Cool result"
175+ deferred = self.sender.send_method_call(method="method",
176 args=[],
177 kwargs={})
178 self.connection.flush()
179- self.assertEqual("Words are cool", self.successResultOf(deferred))
180+ self.assertEqual("Cool result", self.successResultOf(deferred))
181
182 def test_with_one_argument(self):
183 """
184 A connected AMP client can issue a L{MethodCall} with one argument and
185 a response value.
186 """
187- deferred = self.sender.send_method_call(method="capitalize",
188+ self.object.method = lambda word: word.capitalize()
189+ deferred = self.sender.send_method_call(method="method",
190 args=["john"],
191 kwargs={})
192 self.connection.flush()
193@@ -238,7 +158,8 @@
194 """
195 The return value of a L{MethodCall} argument can be a boolean.
196 """
197- deferred = self.sender.send_method_call(method="is_short",
198+ self.object.method = lambda word: len(word) < 3
199+ deferred = self.sender.send_method_call(method="method",
200 args=["hi"],
201 kwargs={})
202 self.connection.flush()
203@@ -248,7 +169,8 @@
204 """
205 A connected client can issue a L{MethodCall} with many arguments.
206 """
207- deferred = self.sender.send_method_call(method="concatenate",
208+ self.object.method = lambda word1, word2: word1 + word2
209+ deferred = self.sender.send_method_call(method="method",
210 args=["We ", "rock"],
211 kwargs={})
212 self.connection.flush()
213@@ -259,7 +181,8 @@
214 A connected client can issue a L{MethodCall} for methods having
215 default arguments.
216 """
217- deferred = self.sender.send_method_call(method="lower_case",
218+ self.object.method = lambda word, index=0: word[index:].lower()
219+ deferred = self.sender.send_method_call(method="method",
220 args=["OHH"],
221 kwargs={})
222 self.connection.flush()
223@@ -271,29 +194,34 @@
224 having default values in the target object. If a value is specified by
225 the caller it will be used in place of the default value
226 """
227- deferred = self.sender.send_method_call(method="lower_case",
228- args=["OHH"],
229+ self.object.method = lambda word, index=0: word[index:].lower()
230+ deferred = self.sender.send_method_call(method="method",
231+ args=["ABC"],
232 kwargs={"index": 2})
233 self.connection.flush()
234- self.assertEqual("OHh", self.successResultOf(deferred))
235+ self.assertEqual("c", self.successResultOf(deferred))
236
237 def test_with_dictionary_arguments(self):
238 """
239 Method arguments passed to a L{MethodCall} can be dictionaries.
240 """
241- deferred = self.sender.send_method_call(method="multiply_"
242- "alphabetically",
243- args=[{"foo": 2, "bar": 3}],
244+ self.object.method = lambda d: "".join(d.keys()) * sum(d.values())
245+ deferred = self.sender.send_method_call(method="method",
246+ args=[{"foo": 1, "bar": 2}],
247 kwargs={})
248 self.connection.flush()
249- self.assertEqual("barbarbarfoofoo", self.successResultOf(deferred))
250+ self.assertEqual("foobarfoobarfoobar", self.successResultOf(deferred))
251
252 def test_with_non_serializable_return_value(self):
253 """
254 If the target object method returns an object that can't be serialized,
255- the L{MethodCall} result is C{None}.
256+ the L{MethodCall} raises an error.
257 """
258- deferred = self.sender.send_method_call(method="meaning_of_life",
259+ class Complex(object):
260+ pass
261+
262+ self.object.method = lambda: Complex()
263+ deferred = self.sender.send_method_call(method="method",
264 args=[],
265 kwargs={})
266 self.connection.flush()
267@@ -304,206 +232,106 @@
268 The L{MethodCall} protocol supports sending method calls with arguments
269 bigger than the maximum AMP parameter value size.
270 """
271- deferred = self.sender.send_method_call(method="is_short",
272+ self.object.method = lambda word: len(word) == 65535
273+ deferred = self.sender.send_method_call(method="method",
274 args=["!" * 65535],
275 kwargs={})
276 self.connection.flush()
277- self.assertFalse(self.successResultOf(deferred))
278+ self.assertTrue(self.successResultOf(deferred))
279
280 def test_with_long_argument_multiple_calls(self):
281 """
282 The L{MethodCall} protocol supports concurrently sending multiple
283 method calls with arguments bigger than the maximum AMP value size.
284 """
285- deferred1 = self.sender.send_method_call(method="is_short",
286+ self.object.method = lambda word: len(word)
287+ deferred1 = self.sender.send_method_call(method="method",
288 args=["!" * 80000],
289 kwargs={})
290- deferred2 = self.sender.send_method_call(method="is_short",
291+ deferred2 = self.sender.send_method_call(method="method",
292 args=["*" * 90000],
293 kwargs={})
294
295 self.connection.flush()
296- self.assertFalse(self.successResultOf(deferred1))
297- self.assertFalse(self.successResultOf(deferred2))
298+ self.assertEqual(80000, self.successResultOf(deferred1))
299+ self.assertEqual(90000, self.successResultOf(deferred2))
300
301- def test_translate(self):
302+ def test_with_exception(self):
303 """
304 If the target object method raises an exception, the remote call fails
305 with a L{MethodCallError}.
306 """
307- deferred = self.sender.send_method_call(method="translate",
308- args=["hi"],
309+ self.object.method = lambda a, b: a / b
310+ deferred = self.sender.send_method_call(method="method",
311+ args=[1, 0],
312 kwargs={})
313 self.connection.flush()
314 self.failureResultOf(deferred).trap(MethodCallError)
315
316-
317-class RemoteObjectTest(LandscapeTest):
318-
319- def setUp(self):
320- super(RemoteObjectTest, self).setUp()
321- self.clock = Clock()
322- self.factory = MethodCallClientFactory(self.clock)
323- server_factory = MethodCallServerFactory(Words(self.clock), METHODS)
324- self.connector = FakeConnector(self.factory, server_factory)
325- self.connector.connect()
326- self.remote = self.successResultOf(self.factory.getRemoteObject())
327-
328- def test_method_call_sender_with_forbidden_method(self):
329- """
330- A L{RemoteObject} can send L{MethodCall}s without arguments and withj
331- an empty response.
332- """
333- deferred = self.remote.secret()
334- self.failureResultOf(deferred).trap(MethodCallError)
335-
336- def test_with_no_arguments(self):
337- """
338- A L{RemoteObject} can send L{MethodCall}s without arguments and withj
339- an empty response.
340- """
341- deferred = self.remote.empty()
342- self.assertIs(None, self.successResultOf(deferred))
343-
344- def test_with_return_value(self):
345- """
346- A L{RemoteObject} can send L{MethodCall}s without arguments and get
347- back the value of the commands's response.
348- """
349- deferred = self.remote.motd()
350- self.assertEqual("Words are cool", self.successResultOf(deferred))
351-
352- def test_with_one_argument(self):
353- """
354- A L{RemoteObject} can send L{MethodCall}s with one argument and get
355- the response value.
356- """
357- deferred = self.remote.capitalize("john")
358- self.assertEqual("John", self.successResultOf(deferred))
359-
360- def test_with_one_keyword_argument(self):
361- """
362- A L{RemoteObject} can send L{MethodCall}s with a named argument.
363- """
364- deferred = self.remote.capitalize(word="john")
365- self.assertEqual("John", self.successResultOf(deferred))
366-
367- def test_with_boolean_return_value(self):
368- """
369- The return value of a L{MethodCall} argument can be a boolean.
370- """
371- return self.assertSuccess(self.remote.is_short("hi"), True)
372-
373- def test_with_many_arguments(self):
374- """
375- A L{RemoteObject} can send L{MethodCall}s with more than one argument.
376- """
377- deferred = self.remote.concatenate("You ", "rock")
378- self.assertEqual("You rock", self.successResultOf(deferred))
379-
380- def test_with_many_keyword_arguments(self):
381- """
382- A L{RemoteObject} can send L{MethodCall}s with several
383- named arguments.
384- """
385- deferred = self.remote.concatenate(word2="rock", word1="You ")
386- self.assertEqual("You rock", self.successResultOf(deferred))
387-
388- def test_with_default_arguments(self):
389- """
390- A L{RemoteObject} can send a L{MethodCall} having an argument with
391- a default value.
392- """
393- deferred = self.remote.lower_case("OHH")
394- self.assertEqual("ohh", self.successResultOf(deferred))
395-
396- def test_with_overriden_default_arguments(self):
397- """
398- A L{RemoteObject} can send L{MethodCall}s overriding the default
399- value of an argument.
400- """
401- deferred = self.remote.lower_case("OHH", 2)
402- self.assertEqual("OHh", self.successResultOf(deferred))
403-
404- def test_with_dictionary_arguments(self):
405- """
406- A L{RemoteObject} can send a L{MethodCall}s for methods requiring
407- a dictionary arguments.
408- """
409- deferred = self.remote.multiply_alphabetically({"foo": 2, "bar": 3})
410- self.assertEqual("barbarbarfoofoo", self.successResultOf(deferred))
411-
412- def test_with_generic_args_and_kwargs(self):
413- """
414- A L{RemoteObject} behaves well with L{MethodCall}s for methods
415- having generic C{*args} and C{**kwargs} arguments.
416- """
417- deferred = self.remote.guess("word", "cool", value=4)
418- self.assertEqual("Guessed!", self.successResultOf(deferred))
419-
420 def test_with_successful_deferred(self):
421 """
422 If the target object method returns a L{Deferred}, it is handled
423 transparently.
424 """
425+ self.object.deferred = Deferred()
426+ self.object.method = lambda: self.object.deferred
427 result = []
428- deferred = self.remote.google("Landscape")
429+ deferred = self.sender.send_method_call(method="method",
430+ args=[],
431+ kwargs={})
432 deferred.addCallback(result.append)
433
434+ self.connection.flush()
435+
436 # At this point the receiver is waiting for method to complete, so
437 # the deferred has not fired yet
438 self.assertEqual([], result)
439
440- # Simulate time advancing and the receiver responding
441- self.clock.advance(0.5)
442- self.connector.connection.flush()
443+ # Fire the deferred and let the receiver respond
444+ self.object.deferred.callback("Hey!")
445+ self.connection.flush()
446
447- self.assertEqual(["Cool!"], result)
448+ self.assertEqual(["Hey!"], result)
449
450 def test_with_failing_deferred(self):
451 """
452 If the target object method returns a failing L{Deferred}, a
453 L{MethodCallError} is raised.
454 """
455+ self.object.deferred = Deferred()
456+ self.object.method = lambda: self.object.deferred
457 result = []
458- deferred = self.remote.google("Weird stuff")
459+ deferred = self.sender.send_method_call(method="method",
460+ args=[],
461+ kwargs={})
462 deferred.addErrback(result.append)
463
464+ self.connection.flush()
465+
466 # At this point the receiver is waiting for method to complete, so
467 # the deferred has not fired yet
468 self.assertEqual([], result)
469
470 # Simulate time advancing and the receiver responding
471- self.clock.advance(0.5)
472- self.connector.connection.flush()
473+ self.object.deferred.errback(Exception())
474+ self.connection.flush()
475
476 [failure] = result
477 failure.trap(MethodCallError)
478
479- def test_with_already_callback_deferred(self):
480- """
481- The target object method can return an already fired L{Deferred}.
482- """
483- deferred = self.remote.google("Easy query")
484- self.assertEqual("Done!", self.successResultOf(deferred))
485-
486- def test_with_already_errback_deferred(self):
487- """
488- If the target object method can return an already failed L{Deferred}.
489- """
490- deferred = self.remote.google("Censored")
491- self.failureResultOf(deferred).trap(MethodCallError)
492-
493 def test_with_deferred_timeout(self):
494 """
495 If the peer protocol doesn't send a response for a deferred within
496 the given timeout, the method call fails.
497 """
498+ self.object.method = lambda: Deferred()
499 result = []
500- deferred = self.remote.google("Long query")
501+ deferred = self.sender.send_method_call(method="method",
502+ args=[],
503+ kwargs={})
504 deferred.addErrback(result.append)
505
506- self.clock.advance(60.0)
507+ self.clock.advance(60)
508
509 [failure] = result
510 failure.trap(MethodCallError)
511@@ -513,15 +341,71 @@
512 If the peer protocol sends a late response for a request that has
513 already timeout, that response is ignored.
514 """
515+ self.object.deferred = Deferred()
516+ self.object.method = lambda: self.object.deferred
517 result = []
518- deferred = self.remote.google("Slowish query")
519+ deferred = self.sender.send_method_call(method="method",
520+ args=[],
521+ kwargs={})
522 deferred.addErrback(result.append)
523
524- self.clock.advance(120.0)
525+ self.clock.advance(60)
526+ self.object.deferred.callback("late")
527
528 [failure] = result
529 failure.trap(MethodCallError)
530
531+
532+class RemoteObjectTest(LandscapeTest):
533+
534+ def setUp(self):
535+ super(RemoteObjectTest, self).setUp()
536+ self.methods = ["method"]
537+ self.object = DummyObject()
538+ self.clock = Clock()
539+ self.factory = MethodCallClientFactory(self.clock)
540+ server_factory = MethodCallServerFactory(self.object, self.methods)
541+ self.connector = FakeConnector(self.factory, server_factory)
542+ self.connector.connect()
543+ self.remote = self.successResultOf(self.factory.getRemoteObject())
544+
545+ def test_with_forbidden_method(self):
546+ """
547+ A L{RemoteObject} can send L{MethodCall}s without arguments and withj
548+ an empty response.
549+ """
550+ self.methods.remove("method")
551+ deferred = self.remote.method()
552+ failure = self.failureResultOf(deferred)
553+ self.assertEqual("Forbidden method 'method'", str(failure.value))
554+
555+ def test_with_no_arguments(self):
556+ """
557+ A L{RemoteObject} can send L{MethodCall}s without arguments and with
558+ an empty response.
559+ """
560+ self.object.method = lambda: None
561+ deferred = self.remote.method()
562+ self.assertIs(None, self.successResultOf(deferred))
563+
564+ def test_with_return_value(self):
565+ """
566+ A L{RemoteObject} can send L{MethodCall}s without arguments and get
567+ back the value of the commands's response.
568+ """
569+ self.object.method = lambda: "Cool"
570+ deferred = self.remote.method()
571+ self.assertEqual("Cool", self.successResultOf(deferred))
572+
573+ def test_with_arguments(self):
574+ """
575+ A L{RemoteObject} can send L{MethodCall}s with one argument and get
576+ the response value.
577+ """
578+ self.object.method = lambda word, times=2: word * times
579+ deferred = self.remote.method("hi", times=3)
580+ self.assertEqual("hihihi", self.successResultOf(deferred))
581+
582 def test_method_call_error(self):
583 """
584 If a L{MethodCall} fails due to a L{MethodCallError},
585@@ -529,8 +413,9 @@
586 C{retryOnReconnect} error is set, as a L{MethodCallError} is a
587 permanent failure that is not likely to ever succeed.
588 """
589+ self.methods.remove("method")
590 self.factory.retryOnReconnect = True
591- deferred = self.remote.secret()
592+ deferred = self.remote.method()
593 self.failureResultOf(deferred).trap(MethodCallError)
594
595 def test_retry(self):
596@@ -539,10 +424,11 @@
597 factory, the L{RemoteObject} will transparently retry to perform
598 the L{MethodCall} requests that failed due to the broken connections.
599 """
600+ self.object.method = lambda word: word.capitalize()
601 self.factory.factor = 0.19
602 self.factory.retryOnReconnect = True
603 self.connector.disconnect()
604- deferred = self.remote.capitalize("john")
605+ deferred = self.remote.method("john")
606
607 # The deferred has not fired yet, because it's been put in the pending
608 # queue, until the call gets a chance to be retried upon reconnection
609@@ -560,10 +446,11 @@
610 the L{RemoteObject} will properly propagate the error to the original
611 caller.
612 """
613+ self.methods.remove("method")
614 self.factory.factor = 0.19
615 self.factory.retryOnReconnect = True
616 self.connector.disconnect()
617- deferred = self.remote.secret()
618+ deferred = self.remote.method()
619
620 # The deferred has not fired yet, because it's been put in the pending
621 # queue, until the call gets a chance to be retried upon reconnection
622@@ -573,7 +460,7 @@
623 self.clock.advance(1)
624
625 failure = self.failureResultOf(deferred)
626- self.assertEqual("Forbidden method 'secret'", str(failure.value))
627+ self.assertEqual("Forbidden method 'method'", str(failure.value))
628
629
630 class MethodCallClientFactoryTest(LandscapeTest):
631@@ -657,26 +544,30 @@
632 If the connection is lost, the L{RemoteObject} created by the creator
633 will transparently handle the reconnection.
634 """
635- server_factory = MethodCallServerFactory(Words(self.clock), METHODS)
636+ dummy_object = DummyObject()
637+ dummy_object.method = lambda: None
638+ server_factory = MethodCallServerFactory(dummy_object, ["method"])
639 connector = FakeConnector(self.factory, server_factory)
640 connector.connect()
641 remote = self.successResultOf(self.factory.getRemoteObject())
642
643 connector.disconnect()
644 self.clock.advance(5)
645- deferred = remote.empty()
646+ deferred = remote.method()
647 self.assertIsNone(self.successResultOf(deferred))
648
649
650-class MethodCallFunctionalTest(TestCase):
651+class MethodCallFunctionalTest(LandscapeTest):
652
653 def setUp(self):
654 super(MethodCallFunctionalTest, self).setUp()
655+ self.methods = ["method"]
656+ self.object = DummyObject()
657+ self.object.method = lambda word: word.capitalize()
658 self.socket = self.mktemp()
659- self.server = MethodCallServerFactory(Words(reactor), METHODS)
660+ self.server = MethodCallServerFactory(self.object, self.methods)
661 self.client = MethodCallClientFactory(reactor)
662 self.port = reactor.listenUNIX(self.socket, self.server)
663- #self.client.maxRetries = 0 # By default, don't try to reconnect
664
665 def tearDown(self):
666 super(MethodCallFunctionalTest, self).tearDown()
667@@ -691,7 +582,7 @@
668 """
669 connector = reactor.connectUNIX(self.socket, self.client)
670 remote = yield self.client.getRemoteObject()
671- result = yield remote.capitalize("john")
672+ result = yield remote.method("john")
673 self.assertEqual(result, "John")
674 self.client.stopTrying()
675 connector.disconnect()
676@@ -724,7 +615,7 @@
677 yield deferred
678
679 # The remote object is still working
680- result = yield remote.capitalize("john")
681+ result = yield remote.method("john")
682 self.assertEqual(result, "John")
683 self.client.stopTrying()
684 connector.disconnect()
685@@ -745,7 +636,7 @@
686 connector.disconnect()
687
688 # This call will fail but it's transparently retried
689- result = yield remote.capitalize("john")
690+ result = yield remote.method("john")
691 self.assertEqual(result, "John")
692 self.client.stopTrying()
693 connector.disconnect()
694@@ -757,6 +648,7 @@
695 the L{RemoteObject} will properly propagate the error to the original
696 caller.
697 """
698+ self.methods.remove("method")
699 self.client.factor = 0.01 # Try reconnecting very quickly
700 self.client.retryOnReconnect = True
701 connector = reactor.connectUNIX(self.socket, self.client)
702@@ -766,7 +658,7 @@
703 connector.disconnect()
704
705 # A method call error is not retried
706- yield self.assertFailure(remote.secret(), MethodCallError)
707+ yield self.assertFailure(remote.method(), MethodCallError)
708 self.client.stopTrying()
709 connector.disconnect()
710
711@@ -777,6 +669,7 @@
712 connection is ready. If for whatever reason the connection drops
713 again very quickly, the C{_retry} method will behave as expected.
714 """
715+ self.methods.remove("method")
716 self.client.factor = 0.01 # Try reconnecting very quickly
717 self.client.retryOnReconnect = True
718 connector = reactor.connectUNIX(self.socket, self.client)
719@@ -787,7 +680,7 @@
720
721 def handle_reconnect(protocol):
722 # In this precise moment we have a newly connected protocol
723- remote._sender.protocol = protocol
724+ remote._sender._protocol = protocol
725
726 # Pretend that the connection is lost again very quickly
727 protocol.transport.loseConnection()
728@@ -800,14 +693,14 @@
729 self.client.notifyOnConnect(remote._handle_connect)
730
731 def assert_failure(error):
732- self.assertEqual(str(error), "Forbidden method 'secret'")
733+ self.assertEqual(str(error), "Forbidden method 'method'")
734
735 # Use our own reconnect handler
736 self.client.dontNotifyOnConnect(remote._handle_connect)
737 self.client.notifyOnConnect(handle_reconnect)
738
739- error = yield self.assertFailure(remote.secret(), MethodCallError)
740- self.assertEqual(str(error), "Forbidden method 'secret'")
741+ error = yield self.assertFailure(remote.method(), MethodCallError)
742+ self.assertEqual(str(error), "Forbidden method 'method'")
743
744 self.client.stopTrying()
745 connector.disconnect()
746@@ -827,11 +720,11 @@
747 # Disconnect
748 connector.disconnect()
749
750- result1 = yield remote.guess("word", "cool", value=4)
751- result2 = yield remote.motd()
752+ result1 = yield remote.method("john")
753+ result2 = yield remote.method("bill")
754
755- self.assertEqual(result1, "Guessed!")
756- self.assertEqual(result2, "Words are cool")
757+ self.assertEqual(result1, "John")
758+ self.assertEqual(result2, "Bill")
759 self.client.stopTrying()
760 connector.disconnect()
761
762@@ -855,8 +748,8 @@
763
764 # Wait for reconnection and peform another call
765 yield deferred
766- result = yield remote.motd()
767- self.assertEqual(result, "Words are cool")
768+ result = yield remote.method("john")
769+ self.assertEqual(result, "John")
770
771 self.client.stopTrying()
772 connector.disconnect()
773@@ -877,7 +770,7 @@
774 # Disconnect
775 connector.disconnect()
776
777- error = yield self.assertFailure(remote.modt(), MethodCallError)
778+ error = yield self.assertFailure(remote.method("foo"), MethodCallError)
779 self.assertEqual("timeout", str(error))
780
781 self.client.stopTrying()

Subscribers

People subscribed via source and target branches

to all changes: