Merge lp:~gocept/landscape-client/py3-configuration into lp:~landscape/landscape-client/trunk
- py3-configuration
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Eric Snow |
Approved revision: | 981 |
Merged at revision: | 979 |
Proposed branch: | lp:~gocept/landscape-client/py3-configuration |
Merge into: | lp:~landscape/landscape-client/trunk |
Prerequisite: | lp:~gocept/landscape-client/py3-broker-exchange |
Diff against target: |
616 lines (+100/-97) 4 files modified
landscape/compat.py (+2/-0) landscape/configuration.py (+9/-9) landscape/tests/test_configuration.py (+88/-87) py3_ready_tests (+1/-1) |
To merge this branch: | bzr merge lp:~gocept/landscape-client/py3-configuration |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Havlik (community) | Approve | ||
🤖 Landscape Builder | test results | Approve | |
Eric Snow (community) | Approve | ||
Review via email:
|
Commit message
This is the Python 3 port of landscape.
The key change is dealing with the raw_input() builtin function. The solution is the addition of landscape.
Description of the change
The main issue with the landscape.
Additionally, base64 only works with bytes, so the ssl_certificates had to be encoded and decoded before transforming.
Another order issue was solved by adapting the tests to assert the presence only and not the exact order of the handlers.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Landscape Builder (landscape-builder) : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Landscape Builder (landscape-builder) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Eric Snow (ericsnowcurrently) wrote : | # |
LGTM. The approach you took with __builtin_
- 981. By Steffen Allner
-
Write data directly in binary mode instead of encoding.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Landscape Builder (landscape-builder) : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 981
Branch: lp:~gocept/landscape-client/py3-configuration
Jenkins: https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Steffen Allner (sallner) wrote : | # |
I used a helper method for the encoding part. This also ensures, that .close() is called in case of en error.
Preview Diff
1 | === modified file 'landscape/compat.py' |
2 | --- landscape/compat.py 2017-03-17 15:51:41 +0000 |
3 | +++ landscape/compat.py 2017-03-28 06:09:46 +0000 |
4 | @@ -10,6 +10,7 @@ |
5 | |
6 | from io import StringIO |
7 | stringio = cstringio = StringIO |
8 | + from builtins import input |
9 | |
10 | else: |
11 | import cPickle |
12 | @@ -20,6 +21,7 @@ |
13 | from StringIO import StringIO |
14 | stringio = StringIO |
15 | from cStringIO import StringIO as cstringio |
16 | + input = raw_input |
17 | |
18 | |
19 | def coerce_unicode(s, encoding='ascii', errors='strict'): |
20 | |
21 | === modified file 'landscape/configuration.py' |
22 | --- landscape/configuration.py 2017-03-10 08:52:58 +0000 |
23 | +++ landscape/configuration.py 2017-03-28 06:09:46 +0000 |
24 | @@ -13,7 +13,7 @@ |
25 | import pwd |
26 | import sys |
27 | |
28 | -from landscape.compat import StringIO |
29 | +from landscape.compat import StringIO, input |
30 | |
31 | from landscape.lib.tag import is_valid_tag |
32 | |
33 | @@ -21,6 +21,7 @@ |
34 | from landscape.lib.amp import MethodCallError |
35 | from landscape.lib.twisted_util import gather_results |
36 | from landscape.lib.fetch import fetch, FetchError |
37 | +from landscape.lib.fs import create_binary_file |
38 | from landscape.lib.bootstrap import BootstrapList, BootstrapDirectory |
39 | from landscape.lib.persist import Persist |
40 | from landscape.reactor import LandscapeReactor |
41 | @@ -60,7 +61,7 @@ |
42 | """Prompt for a yes/no question and return the answer as bool.""" |
43 | default_msg = "[Y/n]" if default else "[y/N]" |
44 | while True: |
45 | - value = raw_input("{} {}: ".format(message, default_msg)).lower() |
46 | + value = input("{} {}: ".format(message, default_msg)).lower() |
47 | if value: |
48 | if value.startswith("n"): |
49 | return False |
50 | @@ -214,7 +215,7 @@ |
51 | @param required: True if value must be entered |
52 | """ |
53 | while True: |
54 | - value = raw_input(msg) |
55 | + value = input(msg) |
56 | if value: |
57 | return value |
58 | elif not required: |
59 | @@ -226,7 +227,7 @@ |
60 | |
61 | @param option: The attribute of C{self.config} that contains the |
62 | default and which the value will be assigned to. |
63 | - @param msg: The message to prompt the user with (via C{raw_input}). |
64 | + @param msg: The message to prompt the user with (via C{input}). |
65 | @param required: If True, the user will be required to enter a value |
66 | before continuing. |
67 | """ |
68 | @@ -247,7 +248,7 @@ |
69 | |
70 | @param option: The attribute of C{self.config} that contains the |
71 | default and which the value will be assigned to. |
72 | - @param msg: The message to prompt the user with (via C{raw_input}). |
73 | + @param msg: The message to prompt the user with (via C{input}). |
74 | @param required: If True, the user will be required to enter a value |
75 | before continuing. |
76 | """ |
77 | @@ -510,7 +511,8 @@ |
78 | # WARNING: ssl_public_certificate is misnamed, it's not the key of the |
79 | # certificate, but the actual certificate itself. |
80 | if config.ssl_public_key and config.ssl_public_key.startswith("base64:"): |
81 | - decoded_cert = base64.decodestring(config.ssl_public_key[7:]) |
82 | + decoded_cert = base64.decodestring( |
83 | + config.ssl_public_key[7:].encode("ascii")) |
84 | config.ssl_public_key = store_public_key_data( |
85 | config, decoded_cert) |
86 | |
87 | @@ -587,9 +589,7 @@ |
88 | config.data_path, |
89 | os.path.basename(config.get_config_filename() + ".ssl_public_key")) |
90 | print_text("Writing SSL CA certificate to %s..." % key_filename) |
91 | - key_file = open(key_filename, "w") |
92 | - key_file.write(certificate_data) |
93 | - key_file.close() |
94 | + create_binary_file(key_filename, certificate_data) |
95 | return key_filename |
96 | |
97 | |
98 | |
99 | === modified file 'landscape/tests/test_configuration.py' |
100 | --- landscape/tests/test_configuration.py 2017-03-10 08:52:58 +0000 |
101 | +++ landscape/tests/test_configuration.py 2017-03-28 06:09:46 +0000 |
102 | @@ -24,6 +24,7 @@ |
103 | determine_exit_code, is_registered) |
104 | from landscape.lib.amp import MethodCallError |
105 | from landscape.lib.fetch import HTTPCodeError, PyCurlError |
106 | +from landscape.lib.fs import read_binary_file |
107 | from landscape.lib.persist import Persist |
108 | from landscape.sysvconfig import ProcessError |
109 | from landscape.tests.helpers import FakeBrokerServiceHelper |
110 | @@ -237,23 +238,23 @@ |
111 | ("", True)] |
112 | |
113 | for input_string, result in comparisons: |
114 | - with mock.patch("__builtin__.raw_input", |
115 | - return_value=input_string) as mock_raw_input: |
116 | + with mock.patch("landscape.configuration.input", |
117 | + return_value=input_string) as mock_input: |
118 | prompt_yes_no("Foo") |
119 | - mock_raw_input.assert_called_once_with("Foo [Y/n]: ") |
120 | + mock_input.assert_called_once_with("Foo [Y/n]: ") |
121 | |
122 | - @mock.patch("__builtin__.raw_input", return_value="") |
123 | - def test_prompt_yes_no_default(self, mock_raw_input): |
124 | + @mock.patch("landscape.configuration.input", return_value="") |
125 | + def test_prompt_yes_no_default(self, mock_input): |
126 | self.assertFalse(prompt_yes_no("Foo", default=False)) |
127 | - mock_raw_input.assert_called_once_with("Foo [y/N]: ") |
128 | + mock_input.assert_called_once_with("Foo [y/N]: ") |
129 | |
130 | - @mock.patch("__builtin__.raw_input", side_effect=("x", "n")) |
131 | + @mock.patch("landscape.configuration.input", side_effect=("x", "n")) |
132 | @mock.patch("landscape.configuration.show_help") |
133 | - def test_prompt_yes_no_invalid(self, mock_show_help, mock_raw_input): |
134 | + def test_prompt_yes_no_invalid(self, mock_show_help, mock_input): |
135 | self.assertFalse(prompt_yes_no("Foo")) |
136 | mock_show_help.assert_called_once_with("Invalid input.") |
137 | calls = [mock.call("Foo [Y/n]: "), mock.call("Foo [Y/n]: ")] |
138 | - mock_raw_input.assert_has_calls(calls) |
139 | + mock_input.assert_has_calls(calls) |
140 | |
141 | |
142 | class ShowHelpTest(unittest.TestCase): |
143 | @@ -275,41 +276,41 @@ |
144 | self.config = MyLandscapeSetupConfiguration() |
145 | self.script = LandscapeSetupScript(self.config) |
146 | |
147 | - @mock.patch("__builtin__.raw_input", return_value="Desktop") |
148 | - def test_prompt_simple(self, mock_raw_input): |
149 | + @mock.patch("landscape.configuration.input", return_value="Desktop") |
150 | + def test_prompt_simple(self, mock_input): |
151 | self.script.prompt("computer_title", "Message") |
152 | - mock_raw_input.assert_called_once_with("Message: ") |
153 | + mock_input.assert_called_once_with("Message: ") |
154 | self.assertEqual(self.config.computer_title, "Desktop") |
155 | |
156 | - @mock.patch("__builtin__.raw_input", return_value="") |
157 | - def test_prompt_with_default(self, mock_raw_input): |
158 | + @mock.patch("landscape.configuration.input", return_value="") |
159 | + def test_prompt_with_default(self, mock_input): |
160 | self.config.computer_title = "default" |
161 | self.script.prompt("computer_title", "Message") |
162 | |
163 | - mock_raw_input.assert_called_once_with("Message [default]: ") |
164 | + mock_input.assert_called_once_with("Message [default]: ") |
165 | self.assertEqual(self.config.computer_title, "default") |
166 | |
167 | - @mock.patch("__builtin__.raw_input", side_effect=("", "Desktop")) |
168 | + @mock.patch("landscape.configuration.input", side_effect=("", "Desktop")) |
169 | @mock.patch("landscape.configuration.show_help") |
170 | - def test_prompt_with_required(self, mock_show_help, mock_raw_input): |
171 | + def test_prompt_with_required(self, mock_show_help, mock_input): |
172 | self.script.prompt("computer_title", "Message", True) |
173 | mock_show_help.assert_called_once_with( |
174 | "This option is required to configure Landscape.") |
175 | |
176 | calls = [mock.call("Message: "), mock.call("Message: ")] |
177 | - mock_raw_input.assert_has_calls(calls) |
178 | + mock_input.assert_has_calls(calls) |
179 | |
180 | self.assertEqual(self.config.computer_title, "Desktop") |
181 | |
182 | - @mock.patch("__builtin__.raw_input", return_value="") |
183 | - def test_prompt_with_required_and_default(self, mock_raw_input): |
184 | + @mock.patch("landscape.configuration.input", return_value="") |
185 | + def test_prompt_with_required_and_default(self, mock_input): |
186 | self.config.computer_title = "Desktop" |
187 | self.script.prompt("computer_title", "Message", True) |
188 | - mock_raw_input.assert_called_once_with("Message [Desktop]: ") |
189 | + mock_input.assert_called_once_with("Message [Desktop]: ") |
190 | self.assertEqual(self.config.computer_title, "Desktop") |
191 | |
192 | - @mock.patch("__builtin__.raw_input", return_value="Yay") |
193 | - def test_prompt_for_unknown_variable(self, mock_raw_input): |
194 | + @mock.patch("landscape.configuration.input", return_value="Yay") |
195 | + def test_prompt_for_unknown_variable(self, mock_input): |
196 | """ |
197 | It should be possible to prompt() defining a variable that doesn't |
198 | 'exist' in the configuration, and still have it set there. |
199 | @@ -317,7 +318,7 @@ |
200 | self.assertFalse(hasattr(self.config, "variable")) |
201 | |
202 | self.script.prompt("variable", "Variable") |
203 | - mock_raw_input.assert_called_once_with("Variable: ") |
204 | + mock_input.assert_called_once_with("Variable: ") |
205 | self.assertEqual(self.config.variable, "Yay") |
206 | |
207 | @mock.patch("landscape.configuration.getpass.getpass", |
208 | @@ -365,12 +366,12 @@ |
209 | [call] = mock_show_help.mock_calls |
210 | self.assertTrue(call.strip().startswith(help_snippet)) |
211 | |
212 | - @mock.patch("__builtin__.raw_input") |
213 | + @mock.patch("landscape.configuration.input") |
214 | def test_query_computer_title_defined_on_command_line( |
215 | - self, mock_raw_input): |
216 | + self, mock_input): |
217 | self.config.load_command_line(["-t", "Computer title"]) |
218 | self.script.query_computer_title() |
219 | - mock_raw_input.assert_not_called() |
220 | + mock_input.assert_not_called() |
221 | |
222 | @mock.patch("landscape.configuration.show_help") |
223 | def test_query_account_name(self, mock_show_help): |
224 | @@ -384,11 +385,11 @@ |
225 | |
226 | self.script.query_account_name() |
227 | |
228 | - @mock.patch("__builtin__.raw_input") |
229 | - def test_query_account_name_defined_on_command_line(self, mock_raw_input): |
230 | + @mock.patch("landscape.configuration.input") |
231 | + def test_query_account_name_defined_on_command_line(self, mock_input): |
232 | self.config.load_command_line(["-a", "Account name"]) |
233 | self.script.query_account_name() |
234 | - mock_raw_input.assert_not_called() |
235 | + mock_input.assert_not_called() |
236 | |
237 | @mock.patch("landscape.configuration.show_help") |
238 | def test_query_registration_key(self, mock_show_help): |
239 | @@ -419,12 +420,12 @@ |
240 | [call] = mock_show_help.mock_calls |
241 | self.assertTrue(call.strip().startswith(help_snippet)) |
242 | |
243 | - @mock.patch("__builtin__.raw_input") |
244 | - def test_query_proxies_defined_on_command_line(self, mock_raw_input): |
245 | + @mock.patch("landscape.configuration.input") |
246 | + def test_query_proxies_defined_on_command_line(self, mock_input): |
247 | self.config.load_command_line(["--http-proxy", "localhost:8080", |
248 | "--https-proxy", "localhost:8443"]) |
249 | self.script.query_proxies() |
250 | - mock_raw_input.assert_not_called() |
251 | + mock_input.assert_not_called() |
252 | |
253 | @mock.patch("landscape.configuration.show_help") |
254 | def test_query_http_proxy_defined_on_command_line(self, mock_show_help): |
255 | @@ -537,13 +538,13 @@ |
256 | self.assertEqual(self.config.include_manager_plugins, |
257 | "FooPlugin, ScriptExecution") |
258 | |
259 | - @mock.patch("__builtin__.raw_input") |
260 | - def test_query_script_plugin_defined_on_command_line(self, mock_raw_input): |
261 | + @mock.patch("landscape.configuration.input") |
262 | + def test_query_script_plugin_defined_on_command_line(self, mock_input): |
263 | self.config.load_command_line( |
264 | ["--include-manager-plugins", "ScriptExecution", |
265 | "--script-users", "root, nobody"]) |
266 | self.script.query_script_plugin() |
267 | - mock_raw_input.assert_not_called() |
268 | + mock_input.assert_not_called() |
269 | self.assertEqual(self.config.include_manager_plugins, |
270 | "ScriptExecution") |
271 | self.assertEqual(self.config.script_users, "root, nobody") |
272 | @@ -693,25 +694,25 @@ |
273 | calls = [("Tags: ", False), ("Tags: ", False)] |
274 | self.script.prompt_get_input.has_calls(calls) |
275 | |
276 | - @mock.patch("__builtin__.raw_input") |
277 | - def test_tags_defined_on_command_line(self, mock_raw_input): |
278 | + @mock.patch("landscape.configuration.input") |
279 | + def test_tags_defined_on_command_line(self, mock_input): |
280 | """ |
281 | Tags defined on the command line can be verified by the user. |
282 | """ |
283 | self.config.load_command_line(["--tags", u"server,london"]) |
284 | self.script.query_tags() |
285 | self.assertEqual(self.config.tags, u"server,london") |
286 | - mock_raw_input.assert_not_called() |
287 | + mock_input.assert_not_called() |
288 | |
289 | - @mock.patch("__builtin__.raw_input") |
290 | + @mock.patch("landscape.configuration.input") |
291 | def test_invalid_tags_defined_on_command_line_raises_error( |
292 | - self, mock_raw_input): |
293 | + self, mock_input): |
294 | """ |
295 | Invalid tags on the command line raises a ConfigurationError. |
296 | """ |
297 | self.config.load_command_line(["--tags", u"<script>alert();</script>"]) |
298 | self.assertRaises(ConfigurationError, self.script.query_tags) |
299 | - mock_raw_input.assert_not_called() |
300 | + mock_input.assert_not_called() |
301 | |
302 | @mock.patch("landscape.configuration.show_help") |
303 | def test_access_group_not_defined_on_command_line(self, mock_show_help): |
304 | @@ -725,8 +726,8 @@ |
305 | [call] = mock_show_help.mock_calls |
306 | self.assertTrue(call.strip().startswith(help_snippet)) |
307 | |
308 | - @mock.patch("__builtin__.raw_input") |
309 | - def test_access_group_defined_on_command_line(self, mock_raw_input): |
310 | + @mock.patch("landscape.configuration.input") |
311 | + def test_access_group_defined_on_command_line(self, mock_input): |
312 | """ |
313 | When an access group is provided on the command line, do not prompt |
314 | the user for it. |
315 | @@ -734,7 +735,7 @@ |
316 | self.config.load_command_line(["--access-group", u"webservers"]) |
317 | self.script.query_access_group() |
318 | self.assertEqual(self.config.access_group, u"webservers") |
319 | - mock_raw_input.assert_not_called() |
320 | + mock_input.assert_not_called() |
321 | |
322 | @mock.patch("landscape.configuration.show_help") |
323 | def test_show_header(self, mock_show_help): |
324 | @@ -818,8 +819,8 @@ |
325 | |
326 | @mock.patch("landscape.configuration.print_text") |
327 | @mock.patch("landscape.configuration.getpass.getpass") |
328 | - @mock.patch("__builtin__.raw_input") |
329 | - def test_setup(self, mock_raw_input, mock_getpass, mock_print_text): |
330 | + @mock.patch("landscape.configuration.input") |
331 | + def test_setup(self, mock_input, mock_getpass, mock_print_text): |
332 | filename = self.makeFile("[client]\n" |
333 | "computer_title = Old Title\n" |
334 | "account_name = Old Name\n" |
335 | @@ -831,7 +832,7 @@ |
336 | "access_group = webservers\n" |
337 | "tags = london, server") |
338 | |
339 | - def side_effect_raw_input(prompt): |
340 | + def side_effect_input(prompt): |
341 | fixtures = { |
342 | "[Old Title]": "New Title", |
343 | "[Old Name]": "New Name", |
344 | @@ -854,7 +855,7 @@ |
345 | return value |
346 | raise KeyError("Couldn't find answer for {}".format(prompt)) |
347 | |
348 | - mock_raw_input.side_effect = side_effect_raw_input |
349 | + mock_input.side_effect = side_effect_input |
350 | mock_getpass.side_effect = side_effect_getpass |
351 | |
352 | config = self.get_config(["--no-start", "--config", filename]) |
353 | @@ -958,10 +959,10 @@ |
354 | mock_sysvconfig().set_start_on_boot.assert_called_once_with( |
355 | True) |
356 | |
357 | - @mock.patch("__builtin__.raw_input") |
358 | + @mock.patch("landscape.configuration.input") |
359 | @mock.patch("landscape.configuration.SysVConfig") |
360 | def test_silent_script_users_imply_script_execution_plugin( |
361 | - self, mock_sysvconfig, mock_raw_input): |
362 | + self, mock_sysvconfig, mock_input): |
363 | """ |
364 | If C{--script-users} is specified, without C{ScriptExecution} in the |
365 | list of manager plugins, it will be automatically added. |
366 | @@ -980,7 +981,7 @@ |
367 | mock_sysvconfig().set_start_on_boot.assert_called_once_with( |
368 | True) |
369 | mock_sysvconfig().restart_landscape.assert_called_once_with() |
370 | - mock_raw_input.assert_not_called() |
371 | + mock_input.assert_not_called() |
372 | parser = ConfigParser() |
373 | parser.read(filename) |
374 | self.assertEqual( |
375 | @@ -1107,14 +1108,14 @@ |
376 | self.assertEqual(config.http_proxy, "http://config") |
377 | self.assertEqual(config.https_proxy, "https://config") |
378 | |
379 | - @mock.patch("__builtin__.raw_input", return_value="n") |
380 | + @mock.patch("landscape.configuration.input", return_value="n") |
381 | @mock.patch("landscape.configuration.register") |
382 | @mock.patch("landscape.configuration.setup") |
383 | def test_main_no_registration( |
384 | - self, mock_setup, mock_register, mock_raw_input): |
385 | + self, mock_setup, mock_register, mock_input): |
386 | main(["-c", self.make_working_config()], print=noop_print) |
387 | mock_register.assert_not_called() |
388 | - mock_raw_input.assert_called_once_with( |
389 | + mock_input.assert_called_once_with( |
390 | "\nRequest a new registration for this computer now? [Y/n]: ") |
391 | |
392 | @mock.patch("landscape.configuration.register", return_value="success") |
393 | @@ -1138,11 +1139,11 @@ |
394 | mock_setup.assert_called_once_with(mock.ANY) |
395 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
396 | |
397 | - @mock.patch("__builtin__.raw_input", return_value="y") |
398 | + @mock.patch("landscape.configuration.input", return_value="y") |
399 | @mock.patch("landscape.configuration.register", return_value="success") |
400 | @mock.patch("landscape.configuration.setup") |
401 | def test_main_user_interaction_success( |
402 | - self, mock_setup, mock_register, mock_raw_input): |
403 | + self, mock_setup, mock_register, mock_input): |
404 | """The successful result of register() is communicated to the user.""" |
405 | printed = [] |
406 | |
407 | @@ -1155,19 +1156,19 @@ |
408 | self.assertEqual(0, exception.code) |
409 | mock_setup.assert_called_once_with(mock.ANY) |
410 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
411 | - mock_raw_input.assert_called_once_with( |
412 | + mock_input.assert_called_once_with( |
413 | "\nRequest a new registration for this computer now? [Y/n]: ") |
414 | self.assertEqual( |
415 | [("Please wait...", sys.stdout), |
416 | ("System successfully registered.", sys.stdout)], |
417 | printed) |
418 | |
419 | - @mock.patch("__builtin__.raw_input", return_value="y") |
420 | + @mock.patch("landscape.configuration.input", return_value="y") |
421 | @mock.patch( |
422 | "landscape.configuration.register", return_value="unknown-account") |
423 | @mock.patch("landscape.configuration.setup") |
424 | def test_main_user_interaction_failure( |
425 | - self, mock_setup, mock_register, mock_raw_input): |
426 | + self, mock_setup, mock_register, mock_input): |
427 | """The failed result of register() is communicated to the user.""" |
428 | printed = [] |
429 | |
430 | @@ -1180,7 +1181,7 @@ |
431 | self.assertEqual(2, exception.code) |
432 | mock_setup.assert_called_once_with(mock.ANY) |
433 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
434 | - mock_raw_input.assert_called_once_with( |
435 | + mock_input.assert_called_once_with( |
436 | "\nRequest a new registration for this computer now? [Y/n]: ") |
437 | |
438 | # Note that the error is output via sys.stderr. |
439 | @@ -1189,11 +1190,11 @@ |
440 | ("Invalid account name or registration key.", sys.stderr)], |
441 | printed) |
442 | |
443 | - @mock.patch("__builtin__.raw_input") |
444 | + @mock.patch("landscape.configuration.input") |
445 | @mock.patch("landscape.configuration.register", return_value="success") |
446 | @mock.patch("landscape.configuration.setup") |
447 | def test_main_user_interaction_success_silent( |
448 | - self, mock_setup, mock_register, mock_raw_input): |
449 | + self, mock_setup, mock_register, mock_input): |
450 | """A successful result is communicated to the user even with --silent. |
451 | """ |
452 | printed = [] |
453 | @@ -1207,19 +1208,19 @@ |
454 | self.assertEqual(0, exception.code) |
455 | mock_setup.assert_called_once_with(mock.ANY) |
456 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
457 | - mock_raw_input.assert_not_called() |
458 | + mock_input.assert_not_called() |
459 | |
460 | self.assertEqual( |
461 | [("Please wait...", sys.stdout), |
462 | ("System successfully registered.", sys.stdout)], |
463 | printed) |
464 | |
465 | - @mock.patch("__builtin__.raw_input") |
466 | + @mock.patch("landscape.configuration.input") |
467 | @mock.patch( |
468 | "landscape.configuration.register", return_value="unknown-account") |
469 | @mock.patch("landscape.configuration.setup") |
470 | def test_main_user_interaction_failure_silent( |
471 | - self, mock_setup, mock_register, mock_raw_input): |
472 | + self, mock_setup, mock_register, mock_input): |
473 | """ |
474 | A failure result is communicated to the user even with --silent. |
475 | """ |
476 | @@ -1234,7 +1235,7 @@ |
477 | self.assertEqual(2, exception.code) |
478 | mock_setup.assert_called_once_with(mock.ANY) |
479 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
480 | - mock_raw_input.assert_not_called() |
481 | + mock_input.assert_not_called() |
482 | # Note that the error is output via sys.stderr. |
483 | self.assertEqual( |
484 | [("Please wait...", sys.stdout), |
485 | @@ -1252,13 +1253,13 @@ |
486 | "data_path = {}\n" |
487 | "url = http://url\n".format(data_path)) |
488 | |
489 | - @mock.patch("__builtin__.raw_input", return_value="") |
490 | + @mock.patch("landscape.configuration.input", return_value="") |
491 | @mock.patch("landscape.configuration.register") |
492 | @mock.patch("landscape.configuration.LandscapeSetupScript") |
493 | @mock.patch("landscape.configuration.SysVConfig") |
494 | def test_register( |
495 | self, mock_sysvconfig, mock_setup_script, mock_register, |
496 | - mock_raw_input): |
497 | + mock_input): |
498 | mock_sysvconfig().is_configured_to_run.return_value = False |
499 | self.assertRaises( |
500 | SystemExit, main, ["--config", self.make_working_config()], |
501 | @@ -1268,11 +1269,11 @@ |
502 | mock_sysvconfig().restart_landscape.assert_called_once_with() |
503 | mock_setup_script().run.assert_called_once_with() |
504 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
505 | - mock_raw_input.assert_any_call( |
506 | + mock_input.assert_any_call( |
507 | "\nThe Landscape client must be started " |
508 | "on boot to operate correctly.\n\n" |
509 | "Start Landscape client on boot? [Y/n]: ") |
510 | - mock_raw_input.assert_called_with( |
511 | + mock_input.assert_called_with( |
512 | "\nRequest a new registration for this computer now? [Y/n]: ") |
513 | |
514 | @mock.patch("landscape.configuration.print_text") |
515 | @@ -1319,16 +1320,16 @@ |
516 | "This machine will be registered with the provided details when " |
517 | "the client runs.", error=True) |
518 | |
519 | - @mock.patch("__builtin__.raw_input", return_value="") |
520 | + @mock.patch("landscape.configuration.input", return_value="") |
521 | @mock.patch("landscape.configuration.register") |
522 | @mock.patch("landscape.configuration.setup") |
523 | def test_main_with_register( |
524 | - self, mock_setup, mock_register, mock_raw_input): |
525 | + self, mock_setup, mock_register, mock_input): |
526 | self.assertRaises(SystemExit, main, ["-c", self.make_working_config()], |
527 | print=noop_print) |
528 | mock_setup.assert_called_once_with(mock.ANY) |
529 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
530 | - mock_raw_input.assert_called_once_with( |
531 | + mock_input.assert_called_once_with( |
532 | "\nRequest a new registration for this computer now? [Y/n]: ") |
533 | |
534 | @mock.patch("landscape.configuration.SysVConfig") |
535 | @@ -1337,19 +1338,19 @@ |
536 | setup_init_script_and_start_client() |
537 | mock_sysvconfig().set_start_on_boot.assert_called_once_with(True) |
538 | |
539 | - @mock.patch("__builtin__.raw_input") |
540 | + @mock.patch("landscape.configuration.input") |
541 | @mock.patch("landscape.configuration.SysVConfig") |
542 | def test_setup_init_script_and_start_client_silent( |
543 | - self, mock_sysvconfig, mock_raw_input): |
544 | + self, mock_sysvconfig, mock_input): |
545 | setup_init_script_and_start_client() |
546 | - mock_raw_input.assert_not_called() |
547 | + mock_input.assert_not_called() |
548 | mock_sysvconfig().set_start_on_boot.assert_called_once_with(True) |
549 | |
550 | - @mock.patch("__builtin__.raw_input") |
551 | + @mock.patch("landscape.configuration.input") |
552 | @mock.patch("landscape.configuration.register") |
553 | @mock.patch("landscape.configuration.setup") |
554 | def test_register_silent( |
555 | - self, mock_setup, mock_register, mock_raw_input): |
556 | + self, mock_setup, mock_register, mock_input): |
557 | """ |
558 | Silent registration uses specified configuration to attempt a |
559 | registration with the server. |
560 | @@ -1359,17 +1360,17 @@ |
561 | print=noop_print) |
562 | mock_setup.assert_called_once_with(mock.ANY) |
563 | mock_register.assert_called_once_with(mock.ANY, mock.ANY) |
564 | - mock_raw_input.assert_not_called() |
565 | + mock_input.assert_not_called() |
566 | |
567 | - @mock.patch("__builtin__.raw_input") |
568 | + @mock.patch("landscape.configuration.input") |
569 | @mock.patch("landscape.configuration.register") |
570 | @mock.patch("landscape.configuration.stop_client_and_disable_init_script") |
571 | def test_disable( |
572 | - self, mock_stop_client, mock_register, mock_raw_input): |
573 | + self, mock_stop_client, mock_register, mock_input): |
574 | main(["--disable", "-c", self.make_working_config()]) |
575 | mock_stop_client.assert_called_once_with() |
576 | mock_register.assert_not_called() |
577 | - mock_raw_input.assert_not_called() |
578 | + mock_input.assert_not_called() |
579 | |
580 | @mock.patch("landscape.configuration.SysVConfig") |
581 | def test_stop_client_and_disable_init_scripts(self, mock_sysvconfig): |
582 | @@ -2014,10 +2015,10 @@ |
583 | # handlers. |
584 | self.assertEqual(2, len(results.resultList)) |
585 | # Handlers are registered for the events we are interested in. |
586 | - self.assertEqual( |
587 | + self.assertCountEqual( |
588 | ['registration-failed', 'exchange-failed', 'registration-done'], |
589 | faux_remote.handlers.keys()) |
590 | - self.assertEqual( |
591 | + self.assertCountEqual( |
592 | ['failure', 'exchange_failure', 'success'], |
593 | [handler.func.__name__ |
594 | for handler in faux_remote.handlers.values()]) |
595 | @@ -2092,8 +2093,8 @@ |
596 | os.path.basename(config.get_config_filename()) + ".ssl_public_key") |
597 | |
598 | self.assertEqual(key_filename, |
599 | - store_public_key_data(config, "123456789")) |
600 | - self.assertEqual("123456789", open(key_filename, "r").read()) |
601 | + store_public_key_data(config, b"123456789")) |
602 | + self.assertEqual(b"123456789", read_binary_file(key_filename)) |
603 | mock_print_text.assert_called_once_with( |
604 | "Writing SSL CA certificate to %s..." % key_filename) |
605 | |
606 | |
607 | === modified file 'py3_ready_tests' |
608 | --- py3_ready_tests 2017-03-28 06:09:46 +0000 |
609 | +++ py3_ready_tests 2017-03-28 06:09:46 +0000 |
610 | @@ -3,7 +3,7 @@ |
611 | landscape.user.tests |
612 | landscape.package.tests |
613 | |
614 | - |
615 | +landscape.tests.test_configuration |
616 | landscape.tests.test_schema |
617 | |
618 |
Command: TRIAL_ARGS=-j4 make check /ci.lscape. net/job/ latch-test- xenial/ 3785/
Result: Success
Revno: 980
Branch: lp:~gocept/landscape-client/py3-configuration
Jenkins: https:/