Merge lp:~tribaal/landscape-client/fix-1429888-wrong-credentials-stacktrace into lp:~landscape/landscape-client/trunk

Proposed by Chris Glass
Status: Merged
Approved by: Chris Glass
Approved revision: 821
Merged at revision: 814
Proposed branch: lp:~tribaal/landscape-client/fix-1429888-wrong-credentials-stacktrace
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 144 lines (+72/-17)
2 files modified
landscape/configuration.py (+11/-6)
landscape/tests/test_configuration.py (+61/-11)
To merge this branch: bzr merge lp:~tribaal/landscape-client/fix-1429888-wrong-credentials-stacktrace
Reviewer Review Type Date Requested Status
Björn Tillenius (community) Approve
Adam Collard (community) Approve
Review via email: mp+252703@code.launchpad.net

Commit message

This branch fixes the related bug, where inappropriate account/password combinations made client registration badly.

Description of the change

This branch fixes the related bug, where inappropriate account/password combinations made client registration badly.

Test with:
- Spin up an LXC
- Install landscape-client
- symlink /usr/lib/python2.7/dist-packages/landscape to a checkout of this branch
- run landscape-config, enter a wrong registration password
- re-run landscape-config, enter a correct registration password.
- The client registers.

To post a comment you must log in.
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Once this lands, please remove the skip tag from the robot test in landscape/trunk (server):

=== modified file 'robot/system/test/client/upgrade.txt'
--- robot/system/test/client/upgrade.txt 2015-03-10 18:45:51 +0000
+++ robot/system/test/client/upgrade.txt 2015-03-12 16:07:01 +0000
@@ -5,8 +5,7 @@
 Suite Setup Client Upgrade Suite Setup
 Suite Teardown Client Upgrade Suite Teardown
 Test Setup Default Setup
-# XXX remove skip tag after #1429888 is fixed
-Force Tags client-upgrade skip
+Force Tags client-upgrade

 *** Variables ***

Revision history for this message
Adam Collard (adam-collard) wrote :

Question inline

review: Needs Information
Revision history for this message
Chris Glass (tribaal) :
Revision history for this message
Chris Glass (tribaal) :
817. By Chris Glass

Made tests more explicit (hopefully)

Revision history for this message
Adam Collard (adam-collard) wrote :

Spellings

Revision history for this message
Adam Collard (adam-collard) wrote :

Two inline comments

Revision history for this message
Benji York (benji) :
Revision history for this message
Chris Glass (tribaal) :
818. By Chris Glass

PEP-257

819. By Chris Glass

Fixed comments.

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

All comments should be addressed.

Revision history for this message
Adam Collard (adam-collard) wrote :

Looks good, +1.

FWIW I tested by making packages and then installing those :)

review: Approve
Revision history for this message
Björn Tillenius (bjornt) wrote :

I think we need to try to test this better. The style of testing you use is the same style that didn't caught this error, so I don't have much confidence in those tests. IMO, they don't test that things actually work, they test that the code is written in a certain way.

I think you should try to add a test in RegisterRealFunctionTest suite, so that we can see that register() actually returns a sane error. I would trust that more than I trust the comment you added.

Note that you will have to change FakeRemoteBroker, so that you can tell it to make register() to fail. But it shouldn't be too hard. Ping me if you have any problems.

review: Needs Fixing
820. By Chris Glass

Added test. No idea why this one fails.

821. By Chris Glass

The test passes now. Thanks for the insight Bjorn!

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

All comments should be addressed.

Revision history for this message
Björn Tillenius (bjornt) wrote :

Thanks for the added test. +1.

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

For the record I removed the skip tag in the server's robot test now that this landed, see: https://bazaar.launchpad.net/~landscape/landscape/trunk/revision/8616

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/configuration.py'
2--- landscape/configuration.py 2015-03-10 16:53:24 +0000
3+++ landscape/configuration.py 2015-03-19 13:44:35 +0000
4@@ -601,11 +601,17 @@
5 add_result("non-ssl-error")
6
7
8-def handle_registration_errors(add_result, connector, failure):
9- """HAndle a failed registration by recording the kind of failure."""
10- # We'll get invalid credentials through the signal.
11+def handle_registration_errors(failure, connector):
12+ """Handle invalid credentials.
13+
14+ The connection to the broker succeeded but the registration itself
15+ failed, because of invalid credentials. We need to trap the exceptions
16+ so they don't stacktrace (we know what is going on), and try to cleanly
17+ disconnect from the broker.
18+
19+ Note: "results" contains a failure indication already (or will shortly)
20+ since the registration-failed signal will fire."""
21 failure.trap(InvalidCredentialsError, MethodCallError)
22- add_result("registration-error")
23 connector.disconnect()
24
25
26@@ -627,8 +633,7 @@
27 "exchange-failed": partial(exchange_failure, add_result)}
28 deferreds = [
29 remote.call_on_event(handlers),
30- remote.register().addErrback(
31- handle_registration_errors, add_result, connector)]
32+ remote.register().addErrback(handle_registration_errors, connector)]
33 results = gather_results(deferreds)
34 results.addCallback(done, connector, reactor)
35 return results
36
37=== modified file 'landscape/tests/test_configuration.py'
38--- landscape/tests/test_configuration.py 2015-03-10 16:53:24 +0000
39+++ landscape/tests/test_configuration.py 2015-03-19 13:44:35 +0000
40@@ -7,7 +7,7 @@
41 import sys
42 import unittest
43
44-from twisted.internet.defer import succeed
45+from twisted.internet.defer import succeed, fail, Deferred
46
47 from landscape.broker.registration import InvalidCredentialsError
48 from landscape.broker.tests.helpers import RemoteBrokerHelper
49@@ -82,11 +82,10 @@
50
51 class HandleRegistrationErrorsTests(unittest.TestCase):
52
53- def test_handle_registration_errors(self):
54+ def test_handle_registration_errors_traps(self):
55 """
56- The handle_registration_errors() function handles
57- InvalidCredentialsError and MethodCallError errors and records the
58- type of failure and disconnects.
59+ The handle_registration_errors() function traps InvalidCredentialsError
60+ and MethodCallError errors.
61 """
62 class FauxFailure(object):
63 def trap(self, *trapped):
64@@ -95,16 +94,49 @@
65 faux_connector = FauxConnector()
66 faux_failure = FauxFailure()
67
68- results = []
69- self.assertNotEqual(0,
70- handle_registration_errors(
71- results.append, faux_connector, faux_failure))
72- self.assertEqual(["registration-error"], results)
73- self.assertTrue(faux_connector.was_disconnected)
74+ self.assertNotEqual(
75+ 0, handle_registration_errors(faux_failure, faux_connector))
76 self.assertTrue(
77 [InvalidCredentialsError, MethodCallError],
78 faux_failure.trapped_exceptions)
79
80+ def test_handle_registration_errors_disconnects_cleanly(self):
81+ """
82+ The handle_registration_errors function disconnects the broker
83+ connector cleanly.
84+ """
85+ class FauxFailure(object):
86+ def trap(self, *trapped):
87+ pass
88+
89+ faux_connector = FauxConnector()
90+ faux_failure = FauxFailure()
91+
92+ self.assertNotEqual(
93+ 0, handle_registration_errors(faux_failure, faux_connector))
94+ self.assertTrue(faux_connector.was_disconnected)
95+
96+ def test_handle_registration_errors_as_errback(self):
97+ """
98+ The handle_registration_errors functions works as an errback.
99+
100+ This test was put in place to assert the parameters passed to the
101+ function when used as an errback are in the correct order.
102+ """
103+ faux_connector = FauxConnector()
104+ calls = []
105+
106+ def i_raise(result):
107+ calls.append(True)
108+ return InvalidCredentialsError("Bad mojo")
109+
110+ deferred = Deferred()
111+ deferred.addCallback(i_raise)
112+ deferred.addErrback(handle_registration_errors, faux_connector)
113+ deferred.callback("") # This kicks off the callback chain.
114+
115+ self.assertEqual([True], calls)
116+
117
118 class DoneTests(unittest.TestCase):
119
120@@ -1933,6 +1965,24 @@
121 self.config, self.reactor, connector_factory, max_retries=99)
122 self.assertEqual("success", result)
123
124+ def test_register_registration_error(self):
125+ """
126+ If we get a registration error, the register() function returns
127+ "failure".
128+ """
129+ self.reactor.call_later(0, self.reactor.fire, "registration-failed")
130+
131+ def fail_register():
132+ return fail(InvalidCredentialsError("Nope."))
133+
134+ self.remote.register = fail_register
135+
136+ connector_factory = FakeConnectorFactory(self.remote)
137+ result = register(
138+ config=self.config, reactor=self.reactor,
139+ connector_factory=connector_factory, max_retries=99)
140+ self.assertEqual("failure", result)
141+
142
143 class FauxConnection(object):
144 def __init__(self):

Subscribers

People subscribed via source and target branches

to all changes: