Merge lp:~nataliabidart/ubuntuone-client/stable-3-0-update-2.99.91.1 into lp:ubuntuone-client/stable-3-0

Proposed by Natalia Bidart
Status: Merged
Approved by: dobey
Approved revision: 1180
Merged at revision: 1179
Proposed branch: lp:~nataliabidart/ubuntuone-client/stable-3-0-update-2.99.91.1
Merge into: lp:ubuntuone-client/stable-3-0
Diff against target: 235 lines (+114/-8)
6 files modified
tests/platform/windows/test_os_helper.py (+8/-0)
tests/proxy/test_tunnel_server.py (+30/-0)
tests/syncdaemon/test_tunnel_runner.py (+55/-2)
ubuntuone/platform/windows/os_helper.py (+6/-2)
ubuntuone/proxy/tunnel_server.py (+2/-3)
ubuntuone/syncdaemon/tunnel_runner.py (+13/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/stable-3-0-update-2.99.91.1
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+99549@code.launchpad.net

Commit message

[ Alejandro J. Cura <email address hidden> ]
  - reactor.spawnProcess throws an error on windows if it can't find
    the binary to run (LP: #965897).
  - Stop the proxy tunnel when stopping the reactor (LP: #963485).
  - Don't write the proxy credentials to the log (LP: #963568).

[ Brian Curtin <email address hidden> ]
  - Loosen the is_root check on Windows to allow Windows XP users,
    who commonly run with Administrator rights, to start U1 properly
    (LP: #930398).

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/platform/windows/test_os_helper.py'
2--- tests/platform/windows/test_os_helper.py 2012-01-10 18:09:30 +0000
3+++ tests/platform/windows/test_os_helper.py 2012-03-27 15:49:21 +0000
4@@ -20,6 +20,7 @@
5 import os
6 import shutil
7 import sys
8+import platform
9
10 from twisted.internet import defer
11 from twisted.trial.unittest import TestCase
12@@ -478,3 +479,10 @@
13 self.patch(os_helper.shell, 'IsUserAnAdmin', lambda: expected)
14 actual = os_helper.is_root()
15 self.assertEqual(expected, actual)
16+
17+ def test_is_root_on_xp(self):
18+ """Test that os_helper.is_root always returns False on XP"""
19+ expected = False
20+ self.patch(platform, "version", "5.1.2600")
21+ actual = os_helper.is_root()
22+ self.assertEqual(expected, actual)
23
24=== modified file 'tests/proxy/test_tunnel_server.py'
25--- tests/proxy/test_tunnel_server.py 2012-03-16 13:40:59 +0000
26+++ tests/proxy/test_tunnel_server.py 2012-03-27 15:49:21 +0000
27@@ -51,6 +51,15 @@
28 }
29 }
30
31+FAKE_AUTH_SETTINGS = {
32+ "http": {
33+ "host": "myhost",
34+ "port": 8888,
35+ "username": "fake_user",
36+ "password": "fake_password",
37+ }
38+}
39+
40 SAMPLE_HOST = "samplehost.com"
41 SAMPLE_PORT = 443
42
43@@ -296,6 +305,27 @@
44 lambda _, domain: defer.succeed(FAKE_CREDS))
45 yield self.proto.headers_done()
46
47+ def test_creds_are_not_logged(self):
48+ """The proxy credentials are not logged."""
49+ log = []
50+ self.patch(tunnel_server.logger, "info",
51+ lambda text, *args: log.append(text % args))
52+ proxy = tunnel_server.build_proxy(FAKE_AUTH_SETTINGS)
53+ authenticator = QAuthenticator()
54+ username = FAKE_AUTH_SETTINGS["http"]["username"]
55+ password = FAKE_AUTH_SETTINGS["http"]["password"]
56+ self.proto.proxy_credentials = {
57+ "username": username,
58+ "password": password,
59+ }
60+ self.proto.proxy_domain = proxy.hostName()
61+
62+ self.proto.proxy_auth_required(proxy, authenticator)
63+
64+ for line in log:
65+ self.assertNotIn(username, line)
66+ self.assertNotIn(password, line)
67+
68
69 class FakeServerTunnelProtocol(object):
70 """A fake ServerTunnelProtocol."""
71
72=== modified file 'tests/syncdaemon/test_tunnel_runner.py'
73--- tests/syncdaemon/test_tunnel_runner.py 2012-03-19 03:31:10 +0000
74+++ tests/syncdaemon/test_tunnel_runner.py 2012-03-27 15:49:21 +0000
75@@ -47,6 +47,28 @@
76 client = yield tr.get_client()
77 self.assertEqual(client, reactor)
78
79+ @defer.inlineCallbacks
80+ def test_executable_not_found(self):
81+ """The executable is not found anywhere."""
82+ self.patch(tunnel_runner, "TUNNEL_EXECUTABLE", "this_does_not_exist")
83+ tr = tunnel_runner.TunnelRunner(FAKE_HOST, FAKE_PORT)
84+ client = yield tr.get_client()
85+ self.assertEqual(client, reactor)
86+
87+
88+class FakeProcessTransport(object):
89+ """A fake ProcessTransport."""
90+
91+ pid = 0
92+
93+ def __init__(self):
94+ """Initialize this fake."""
95+ self._signals_sent = []
96+
97+ def signalProcess(self, signalID):
98+ """Send a signal to the process."""
99+ self._signals_sent.append(signalID)
100+
101
102 class TunnelRunnerTestCase(TestCase):
103 """Tests for the TunnelRunner."""
104@@ -58,8 +80,22 @@
105 """Initialize this testcase."""
106 yield super(TunnelRunnerTestCase, self).setUp()
107 self.spawned = []
108- self.patch(tunnel_client.reactor, "spawnProcess",
109- lambda *args, **kwargs: self.spawned.append((args, kwargs)))
110+ self.triggers = []
111+ self.fake_process_transport = FakeProcessTransport()
112+
113+ def fake_spawn_process(*args, **kwargs):
114+ """A fake spawnProcess."""
115+ self.spawned.append((args, kwargs))
116+ return self.fake_process_transport
117+
118+ self.patch(tunnel_client.reactor, "spawnProcess", fake_spawn_process)
119+
120+ def fake_add_system_event_trigger(*args, **kwargs):
121+ """A fake addSystemEventTrigger."""
122+ self.triggers.append((args, kwargs))
123+
124+ self.patch(tunnel_client.reactor, "addSystemEventTrigger",
125+ fake_add_system_event_trigger)
126 self.process_protocol = None
127 self.process_protocol_class = tunnel_client.TunnelProcessProtocol
128 self.patch(tunnel_client, "TunnelProcessProtocol",
129@@ -76,6 +112,23 @@
130 self.assertEqual(len(self.spawned), 1,
131 "The tunnel process is started.")
132
133+ def test_system_event_finished(self):
134+ """An event is added to stop the process with the reactor."""
135+ expected = [(("before", "shutdown", self.tr.stop), {})]
136+ self.assertEqual(self.triggers, expected)
137+
138+ def test_stop_process(self):
139+ """The process is stopped if still running."""
140+ self.tr.process_transport.pid = 1234
141+ self.tr.stop()
142+ self.assertEqual(self.fake_process_transport._signals_sent, ["KILL"])
143+
144+ def test_not_stopped_if_already_finished(self):
145+ """Do not stop the tunnel process if it's already finished."""
146+ self.tr.process_transport.pid = None
147+ self.tr.stop()
148+ self.assertEqual(self.fake_process_transport._signals_sent, [])
149+
150 @defer.inlineCallbacks
151 def test_tunnel_process_get_client_yielded_twice(self):
152 """The get_client method can be yielded twice."""
153
154=== modified file 'ubuntuone/platform/windows/os_helper.py'
155--- ubuntuone/platform/windows/os_helper.py 2012-01-10 18:09:30 +0000
156+++ ubuntuone/platform/windows/os_helper.py 2012-03-27 15:49:21 +0000
157@@ -23,6 +23,7 @@
158 import stat
159 import sys
160
161+from platform import version
162 from contextlib import contextmanager
163 from functools import wraps
164
165@@ -872,10 +873,13 @@
166
167 def is_root():
168 """Return if the user is running as root."""
169- # This solution works on Windows XP, Vista and 7
170+ # On Windows XP (v5.1), always return False. Nearly all users run with
171+ # Administrator access, so this would restrict too many users.
172+ # On Vista (v6.0) and 7 (v6.1), return the real Administrator value.
173 # The MSDN docs say this may go away in a later version, but look at what
174 # the alternative is: http://bit.ly/rXbIwc
175- return shell.IsUserAnAdmin()
176+ is_xp = version()[0] == "5"
177+ return False if is_xp else shell.IsUserAnAdmin()
178
179
180 @windowspath()
181
182=== modified file 'ubuntuone/proxy/tunnel_server.py'
183--- ubuntuone/proxy/tunnel_server.py 2012-03-16 13:40:59 +0000
184+++ ubuntuone/proxy/tunnel_server.py 2012-03-27 15:49:21 +0000
185@@ -201,11 +201,10 @@
186
187 def proxy_auth_required(self, proxy, authenticator):
188 """Proxy authentication is required."""
189- logger.info("auth_required %r, %r, %r", self.proxy_credentials,
190+ logger.info("auth_required %r, %r",
191 proxy.hostName(), self.proxy_domain)
192 if self.proxy_credentials and proxy.hostName() == self.proxy_domain:
193- logger.info("Credentials added to authenticator: %r.",
194- self.proxy_credentials)
195+ logger.info("Credentials added to authenticator.")
196 authenticator.setUser(self.proxy_credentials["username"])
197 authenticator.setPassword(self.proxy_credentials["password"])
198 else:
199
200=== modified file 'ubuntuone/syncdaemon/tunnel_runner.py'
201--- ubuntuone/syncdaemon/tunnel_runner.py 2012-03-19 13:20:36 +0000
202+++ ubuntuone/syncdaemon/tunnel_runner.py 2012-03-27 15:49:21 +0000
203@@ -33,11 +33,15 @@
204 def __init__(self, host, port):
205 """Start this runner instance."""
206 self.client_d = defer.Deferred()
207+ self.process_transport = None
208 try:
209 self.start_process(host, port)
210 except ImportError:
211 logger.info("Proxy support not installed.")
212 self.client_d.callback(reactor)
213+ except Exception:
214+ logger.exception("Error while starting tunnel process:")
215+ self.client_d.callback(reactor)
216
217 def start_process(self, host, port):
218 """Start the tunnel process."""
219@@ -45,7 +49,15 @@
220 protocol = TunnelProcessProtocol(self.client_d)
221 process_path = self.get_process_path()
222 args = [TUNNEL_EXECUTABLE, host, str(port)]
223- reactor.spawnProcess(protocol, process_path, env=None, args=args)
224+ self.process_transport = reactor.spawnProcess(protocol, process_path,
225+ env=None, args=args)
226+ reactor.addSystemEventTrigger("before", "shutdown", self.stop)
227+
228+ def stop(self):
229+ """Stop the tunnel process if still running."""
230+ logger.info("Stopping process %r", self.process_transport.pid)
231+ if self.process_transport.pid is not None:
232+ self.process_transport.signalProcess("KILL")
233
234 def get_process_path(self):
235 """Get the path to the tunnel process."""

Subscribers

People subscribed via source and target branches