Merge lp:~fcorrea/landscape-client/wait-for-valid-session-id-on-resynchronize into lp:~landscape/landscape-client/trunk
- wait-for-valid-session-id-on-resynchronize
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Fernando Correa Neto | ||||
Approved revision: | 829 | ||||
Merged at revision: | 826 | ||||
Proposed branch: | lp:~fcorrea/landscape-client/wait-for-valid-session-id-on-resynchronize | ||||
Merge into: | lp:~landscape/landscape-client/trunk | ||||
Diff against target: |
249 lines (+64/-25) 4 files modified
landscape/broker/client.py (+2/-2) landscape/broker/tests/test_client.py (+11/-0) landscape/monitor/tests/test_usermonitor.py (+44/-20) landscape/monitor/usermonitor.py (+7/-3) |
||||
To merge this branch: | bzr merge lp:~fcorrea/landscape-client/wait-for-valid-session-id-on-resynchronize | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chad Smith | Approve | ||
Free Ekanayaka (community) | Approve | ||
Benji York (community) | Approve | ||
Review via email: mp+282483@code.launchpad.net |
Commit message
Changes the user monitor plugin to wait on a valid session id.
Description of the change
With the scope resync work, the user monitor plugin stopped working.
Since now we rely on a valid session id in order to send a message to the server, the user monitor plugin must wait until it gets a valid session.
The fix was provided by Free and a test and some cleanups were added as well.
Free Ekanayaka (free.ekanayaka) : | # |
- 828. By Fernando Correa Neto
-
- fix the unit test so it can actually fail if the fix is removed.
- improve test coveration for BrokerClientPlugin base class
Fernando Correa Neto (fcorrea) wrote : | # |
Free
Thanks for reviewing it.
I've changed the test as we discussed to make sure it will fail when the fix is reverted. Please, take a look.
Free Ekanayaka (free.ekanayaka) wrote : | # |
+1 with a nit
- 829. By Fernando Correa Neto
-
- rename test and address review comment
Fernando Correa Neto (fcorrea) : | # |
Chad Smith (chad.smith) wrote : | # |
Good work here and additional unit tests. It took a while for me to go through upgrade path testing w/ broken released client TO patched trunk client.
Looks like a plain upgrade of a broken existing released client will still sit missing the initial delta of all system users. But, those broken clients will properly send any users or groups that were modified after the initial registration of that client.
To truly "fix" the broken clients, the customer would have to upgrade landscape-client and click the resynch button for that computer as a support person.
+1. This was tough.
Preview Diff
1 | === modified file 'landscape/broker/client.py' | |||
2 | --- landscape/broker/client.py 2013-07-25 13:54:29 +0000 | |||
3 | +++ landscape/broker/client.py 2016-01-15 16:29:39 +0000 | |||
4 | @@ -1,6 +1,6 @@ | |||
5 | 1 | from logging import info, exception | 1 | from logging import info, exception |
6 | 2 | 2 | ||
8 | 3 | from twisted.internet.defer import maybeDeferred | 3 | from twisted.internet.defer import maybeDeferred, succeed |
9 | 4 | 4 | ||
10 | 5 | from landscape.log import format_object | 5 | from landscape.log import format_object |
11 | 6 | from landscape.lib.twisted_util import gather_results | 6 | from landscape.lib.twisted_util import gather_results |
12 | @@ -67,7 +67,7 @@ | |||
13 | 67 | """ | 67 | """ |
14 | 68 | if not (scopes is None or self.scope in scopes): | 68 | if not (scopes is None or self.scope in scopes): |
15 | 69 | # This resynchronize event is out of scope for us. Do nothing | 69 | # This resynchronize event is out of scope for us. Do nothing |
17 | 70 | return | 70 | return succeed(None) |
18 | 71 | 71 | ||
19 | 72 | # Because the broker will drop session IDs already associated to scope | 72 | # Because the broker will drop session IDs already associated to scope |
20 | 73 | # of the resynchronisation, it isn't safe to send messages until the | 73 | # of the resynchronisation, it isn't safe to send messages until the |
21 | 74 | 74 | ||
22 | === modified file 'landscape/broker/tests/test_client.py' | |||
23 | --- landscape/broker/tests/test_client.py 2013-07-19 09:57:57 +0000 | |||
24 | +++ landscape/broker/tests/test_client.py 2016-01-15 16:29:39 +0000 | |||
25 | @@ -47,6 +47,17 @@ | |||
26 | 47 | self.client.add(plugin) | 47 | self.client.add(plugin) |
27 | 48 | self.assertEqual(test_session_id, plugin._session_id) | 48 | self.assertEqual(test_session_id, plugin._session_id) |
28 | 49 | 49 | ||
29 | 50 | def test_resynchronizing_out_of_scope(self): | ||
30 | 51 | """ | ||
31 | 52 | When a 'reysnchronize' event happens and the plugin scope is not part | ||
32 | 53 | of the scopes that were passed, BrokerClientPlugin succeeds. | ||
33 | 54 | """ | ||
34 | 55 | plugin = BrokerClientPlugin() | ||
35 | 56 | plugin.scope = "foo" | ||
36 | 57 | self.client.add(plugin) | ||
37 | 58 | deferred = self.client_reactor.fire("resynchronize", scopes=["bar"])[0] | ||
38 | 59 | self.assertIsNone(self.successResultOf(deferred)) | ||
39 | 60 | |||
40 | 50 | def test_resynchronizing_refreshes_session_id(self): | 61 | def test_resynchronizing_refreshes_session_id(self): |
41 | 51 | """ | 62 | """ |
42 | 52 | When a 'reysnchronize' event fires a new session ID is acquired as the | 63 | When a 'reysnchronize' event fires a new session ID is acquired as the |
43 | 53 | 64 | ||
44 | === modified file 'landscape/monitor/tests/test_usermonitor.py' | |||
45 | --- landscape/monitor/tests/test_usermonitor.py 2016-01-11 18:34:49 +0000 | |||
46 | +++ landscape/monitor/tests/test_usermonitor.py 2016-01-15 16:29:39 +0000 | |||
47 | @@ -23,13 +23,13 @@ | |||
48 | 23 | def got_result(result): | 23 | def got_result(result): |
49 | 24 | self.assertMessages( | 24 | self.assertMessages( |
50 | 25 | self.broker_service.message_store.get_pending_messages(), | 25 | self.broker_service.message_store.get_pending_messages(), |
52 | 26 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 26 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
53 | 27 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 27 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
54 | 28 | "create-users": [{"enabled": True, "home-phone": None, | 28 | "create-users": [{"enabled": True, "home-phone": None, |
55 | 29 | "location": None, "name": u"JD", | 29 | "location": None, "name": u"JD", |
56 | 30 | "primary-gid": 1000, "uid": 1000, | 30 | "primary-gid": 1000, "uid": 1000, |
57 | 31 | "username": u"jdoe", "work-phone": None}], | 31 | "username": u"jdoe", "work-phone": None}], |
59 | 32 | "type": "users"}]) | 32 | "type": "users"}]) |
60 | 33 | plugin.stop() | 33 | plugin.stop() |
61 | 34 | 34 | ||
62 | 35 | users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] | 35 | users = [("jdoe", "x", 1000, 1000, "JD,,,,", "/home/jdoe", "/bin/sh")] |
63 | @@ -91,20 +91,20 @@ | |||
64 | 91 | self.assertTrue(persist.get("groups")) | 91 | self.assertTrue(persist.get("groups")) |
65 | 92 | self.assertMessages( | 92 | self.assertMessages( |
66 | 93 | self.broker_service.message_store.get_pending_messages(), | 93 | self.broker_service.message_store.get_pending_messages(), |
68 | 94 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 94 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
69 | 95 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 95 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
70 | 96 | "create-users": [{"enabled": True, "home-phone": None, | 96 | "create-users": [{"enabled": True, "home-phone": None, |
71 | 97 | "location": None, "name": u"JD", | 97 | "location": None, "name": u"JD", |
72 | 98 | "primary-gid": 1000, "uid": 1000, | 98 | "primary-gid": 1000, "uid": 1000, |
73 | 99 | "username": u"jdoe", "work-phone": None}], | 99 | "username": u"jdoe", "work-phone": None}], |
75 | 100 | "type": "users"}]) | 100 | "type": "users"}]) |
76 | 101 | self.broker_service.message_store.delete_all_messages() | 101 | self.broker_service.message_store.delete_all_messages() |
77 | 102 | deferred = self.monitor.reactor.fire( | 102 | deferred = self.monitor.reactor.fire( |
78 | 103 | "resynchronize", scopes=["users"])[0] | 103 | "resynchronize", scopes=["users"])[0] |
79 | 104 | self.successResultOf(deferred) | 104 | self.successResultOf(deferred) |
80 | 105 | self.assertMessages( | 105 | self.assertMessages( |
81 | 106 | self.broker_service.message_store.get_pending_messages(), | 106 | self.broker_service.message_store.get_pending_messages(), |
83 | 107 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 107 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
84 | 108 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 108 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
85 | 109 | "create-users": [{"enabled": True, "home-phone": None, | 109 | "create-users": [{"enabled": True, "home-phone": None, |
86 | 110 | "location": None, "name": u"JD", | 110 | "location": None, "name": u"JD", |
87 | @@ -113,6 +113,29 @@ | |||
88 | 113 | "work-phone": None}], | 113 | "work-phone": None}], |
89 | 114 | "type": "users"}]) | 114 | "type": "users"}]) |
90 | 115 | 115 | ||
91 | 116 | def test_new_message_after_resynchronize_event(self): | ||
92 | 117 | """ | ||
93 | 118 | When a 'resynchronize' reactor event is fired, a new session is | ||
94 | 119 | created and the UserMonitor creates a new message. | ||
95 | 120 | """ | ||
96 | 121 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", | ||
97 | 122 | "/home/jdoe", "/bin/sh")] | ||
98 | 123 | self.provider.groups = [("webdev", "x", 1000, ["jdoe"])] | ||
99 | 124 | self.broker_service.message_store.set_accepted_types(["users"]) | ||
100 | 125 | self.monitor.add(self.plugin) | ||
101 | 126 | self.plugin.client.broker.message_store.drop_session_ids() | ||
102 | 127 | deferred = self.reactor.fire("resynchronize")[0] | ||
103 | 128 | self.successResultOf(deferred) | ||
104 | 129 | self.assertMessages( | ||
105 | 130 | self.broker_service.message_store.get_pending_messages(), | ||
106 | 131 | [{"create-group-members": {u"webdev": [u"jdoe"]}, | ||
107 | 132 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | ||
108 | 133 | "create-users": [{"enabled": True, "home-phone": None, | ||
109 | 134 | "location": None, "name": u"JD", | ||
110 | 135 | "primary-gid": 1000, "uid": 1000, | ||
111 | 136 | "username": u"jdoe", "work-phone": None}], | ||
112 | 137 | "type": "users"}]) | ||
113 | 138 | |||
114 | 116 | def test_wb_resynchronize_event_with_global_scope(self): | 139 | def test_wb_resynchronize_event_with_global_scope(self): |
115 | 117 | """ | 140 | """ |
116 | 118 | When a C{resynchronize} event, with global scope, occurs we act exactly | 141 | When a C{resynchronize} event, with global scope, occurs we act exactly |
117 | @@ -129,19 +152,19 @@ | |||
118 | 129 | self.assertTrue(persist.get("groups")) | 152 | self.assertTrue(persist.get("groups")) |
119 | 130 | self.assertMessages( | 153 | self.assertMessages( |
120 | 131 | self.broker_service.message_store.get_pending_messages(), | 154 | self.broker_service.message_store.get_pending_messages(), |
122 | 132 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 155 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
123 | 133 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 156 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
124 | 134 | "create-users": [{"enabled": True, "home-phone": None, | 157 | "create-users": [{"enabled": True, "home-phone": None, |
125 | 135 | "location": None, "name": u"JD", | 158 | "location": None, "name": u"JD", |
126 | 136 | "primary-gid": 1000, "uid": 1000, | 159 | "primary-gid": 1000, "uid": 1000, |
127 | 137 | "username": u"jdoe", "work-phone": None}], | 160 | "username": u"jdoe", "work-phone": None}], |
129 | 138 | "type": "users"}]) | 161 | "type": "users"}]) |
130 | 139 | self.broker_service.message_store.delete_all_messages() | 162 | self.broker_service.message_store.delete_all_messages() |
131 | 140 | deferred = self.monitor.reactor.fire("resynchronize")[0] | 163 | deferred = self.monitor.reactor.fire("resynchronize")[0] |
132 | 141 | self.successResultOf(deferred) | 164 | self.successResultOf(deferred) |
133 | 142 | self.assertMessages( | 165 | self.assertMessages( |
134 | 143 | self.broker_service.message_store.get_pending_messages(), | 166 | self.broker_service.message_store.get_pending_messages(), |
136 | 144 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 167 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
137 | 145 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 168 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
138 | 146 | "create-users": [{"enabled": True, "home-phone": None, | 169 | "create-users": [{"enabled": True, "home-phone": None, |
139 | 147 | "location": None, "name": u"JD", | 170 | "location": None, "name": u"JD", |
140 | @@ -166,7 +189,7 @@ | |||
141 | 166 | self.assertTrue(persist.get("groups")) | 189 | self.assertTrue(persist.get("groups")) |
142 | 167 | self.assertMessages( | 190 | self.assertMessages( |
143 | 168 | self.broker_service.message_store.get_pending_messages(), | 191 | self.broker_service.message_store.get_pending_messages(), |
145 | 169 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 192 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
146 | 170 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 193 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
147 | 171 | "create-users": [{"enabled": True, "home-phone": None, | 194 | "create-users": [{"enabled": True, "home-phone": None, |
148 | 172 | "location": None, "name": u"JD", | 195 | "location": None, "name": u"JD", |
149 | @@ -189,13 +212,13 @@ | |||
150 | 189 | def got_result(result): | 212 | def got_result(result): |
151 | 190 | self.assertMessages( | 213 | self.assertMessages( |
152 | 191 | self.broker_service.message_store.get_pending_messages(), | 214 | self.broker_service.message_store.get_pending_messages(), |
154 | 192 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 215 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
155 | 193 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 216 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
156 | 194 | "create-users": [{"enabled": True, "home-phone": None, | 217 | "create-users": [{"enabled": True, "home-phone": None, |
157 | 195 | "location": None, "name": u"JD", | 218 | "location": None, "name": u"JD", |
158 | 196 | "primary-gid": 1000, "uid": 1000, | 219 | "primary-gid": 1000, "uid": 1000, |
159 | 197 | "username": u"jdoe", "work-phone": None}], | 220 | "username": u"jdoe", "work-phone": None}], |
161 | 198 | "type": "users"}]) | 221 | "type": "users"}]) |
162 | 199 | 222 | ||
163 | 200 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", | 223 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", |
164 | 201 | "/home/jdoe", "/bin/sh")] | 224 | "/home/jdoe", "/bin/sh")] |
165 | @@ -230,14 +253,14 @@ | |||
166 | 230 | def got_result(result): | 253 | def got_result(result): |
167 | 231 | self.assertMessages( | 254 | self.assertMessages( |
168 | 232 | self.broker_service.message_store.get_pending_messages(), | 255 | self.broker_service.message_store.get_pending_messages(), |
170 | 233 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 256 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
171 | 234 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 257 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
172 | 235 | "create-users": [{"enabled": True, "home-phone": None, | 258 | "create-users": [{"enabled": True, "home-phone": None, |
173 | 236 | "location": None, "name": u"JD", | 259 | "location": None, "name": u"JD", |
174 | 237 | "primary-gid": 1000, "uid": 1000, | 260 | "primary-gid": 1000, "uid": 1000, |
175 | 238 | "username": u"jdoe", "work-phone": None}], | 261 | "username": u"jdoe", "work-phone": None}], |
178 | 239 | "operation-id": 1001, | 262 | "operation-id": 1001, |
179 | 240 | "type": "users"}]) | 263 | "type": "users"}]) |
180 | 241 | 264 | ||
181 | 242 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", | 265 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", |
182 | 243 | "/home/jdoe", "/bin/sh")] | 266 | "/home/jdoe", "/bin/sh")] |
183 | @@ -253,12 +276,12 @@ | |||
184 | 253 | def got_result(result): | 276 | def got_result(result): |
185 | 254 | self.assertMessages( | 277 | self.assertMessages( |
186 | 255 | self.broker_service.message_store.get_pending_messages(), | 278 | self.broker_service.message_store.get_pending_messages(), |
188 | 256 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 279 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
189 | 257 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 280 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
190 | 258 | "create-users": [{"enabled": True, "home-phone": None, | 281 | "create-users": [{"enabled": True, "home-phone": None, |
191 | 259 | "location": None, "name": u"JD", | 282 | "location": None, "name": u"JD", |
192 | 260 | "primary-gid": 1000, "uid": 1000, | 283 | "primary-gid": 1000, "uid": 1000, |
194 | 261 | "username": u"jdoe", "work-phone": None}], | 284 | "username": u"jdoe", "work-phone": None}], |
195 | 262 | "type": "users"}]) | 285 | "type": "users"}]) |
196 | 263 | 286 | ||
197 | 264 | self.broker_service.message_store.set_accepted_types(["users"]) | 287 | self.broker_service.message_store.set_accepted_types(["users"]) |
198 | @@ -283,7 +306,7 @@ | |||
199 | 283 | def got_result(result): | 306 | def got_result(result): |
200 | 284 | self.assertMessages( | 307 | self.assertMessages( |
201 | 285 | self.broker_service.message_store.get_pending_messages(), | 308 | self.broker_service.message_store.get_pending_messages(), |
203 | 286 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 309 | [{"create-group-members": {u"webdev": [u"jdoe"]}, |
204 | 287 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 310 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
205 | 288 | "create-users": [{"enabled": True, "home-phone": None, | 311 | "create-users": [{"enabled": True, "home-phone": None, |
206 | 289 | "location": None, "name": u"JD", | 312 | "location": None, "name": u"JD", |
207 | @@ -332,8 +355,9 @@ | |||
208 | 332 | 355 | ||
209 | 333 | def got_result(result): | 356 | def got_result(result): |
210 | 334 | mstore = self.broker_service.message_store | 357 | mstore = self.broker_service.message_store |
213 | 335 | self.assertMessages(mstore.get_pending_messages(), | 358 | self.assertMessages( |
214 | 336 | [{"create-group-members": {u"webdev":[u"jdoe"]}, | 359 | mstore.get_pending_messages(), |
215 | 360 | [{"create-group-members": {u"webdev": [u"jdoe"]}, | ||
216 | 337 | "create-groups": [{"gid": 1000, "name": u"webdev"}], | 361 | "create-groups": [{"gid": 1000, "name": u"webdev"}], |
217 | 338 | "create-users": [{"enabled": True, "home-phone": None, | 362 | "create-users": [{"enabled": True, "home-phone": None, |
218 | 339 | "location": None, "name": u"JD", | 363 | "location": None, "name": u"JD", |
219 | @@ -376,7 +400,7 @@ | |||
220 | 376 | self.mocker.replay() | 400 | self.mocker.replay() |
221 | 377 | 401 | ||
222 | 378 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", | 402 | self.provider.users = [("jdoe", "x", 1000, 1000, "JD,,,,", |
224 | 379 | "/home/jdoe", "/bin/sh")] | 403 | "/home/jdoe", "/bin/sh")] |
225 | 380 | self.provider.groups = [("webdev", "x", 1000, ["jdoe"])] | 404 | self.provider.groups = [("webdev", "x", 1000, ["jdoe"])] |
226 | 381 | self.monitor.add(self.plugin) | 405 | self.monitor.add(self.plugin) |
227 | 382 | connector = RemoteUserMonitorConnector(self.reactor, self.config) | 406 | connector = RemoteUserMonitorConnector(self.reactor, self.config) |
228 | 383 | 407 | ||
229 | === modified file 'landscape/monitor/usermonitor.py' | |||
230 | --- landscape/monitor/usermonitor.py 2016-01-11 18:34:49 +0000 | |||
231 | +++ landscape/monitor/usermonitor.py 2016-01-15 16:29:39 +0000 | |||
232 | @@ -39,10 +39,14 @@ | |||
233 | 39 | self._publisher.stop() | 39 | self._publisher.stop() |
234 | 40 | self._publisher = None | 40 | self._publisher = None |
235 | 41 | 41 | ||
237 | 42 | def _reset(self): | 42 | def _resynchronize(self, scopes=None): |
238 | 43 | """Reset user and group data.""" | 43 | """Reset user and group data.""" |
241 | 44 | super(UserMonitor, self)._reset() | 44 | deferred = super(UserMonitor, self)._resynchronize(scopes=scopes) |
242 | 45 | return self._run_detect_changes() | 45 | # Wait for the superclass' asynchronous _resynchronize method to |
243 | 46 | # complete, so we have a new session ID at hand and we can craft a | ||
244 | 47 | # valid message (l.broker.client.BrokerClientPlugin._resynchronize). | ||
245 | 48 | deferred.addCallback(lambda _: self._run_detect_changes()) | ||
246 | 49 | return deferred | ||
247 | 46 | 50 | ||
248 | 47 | @remote | 51 | @remote |
249 | 48 | def detect_changes(self, operation_id=None): | 52 | def detect_changes(self, operation_id=None): |
Thanks for the branch, it looks good.