Merge lp:~gocept/landscape-client/fetch-strings-and-bytes into lp:~landscape/landscape-client/trunk

Proposed by Steffen Allner
Status: Merged
Approved by: Данило Шеган
Approved revision: 959
Merged at revision: 960
Proposed branch: lp:~gocept/landscape-client/fetch-strings-and-bytes
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 99 lines (+40/-27)
2 files modified
landscape/broker/tests/test_transport.py (+37/-26)
landscape/lib/fetch.py (+3/-1)
To merge this branch: bzr merge lp:~gocept/landscape-client/fetch-strings-and-bytes
Reviewer Review Type Date Requested Status
Данило Шеган (community) Approve
Michael Howitz (community) Approve
🤖 Landscape Builder test results Approve
Landscape Pending
Review via email: mp+319898@code.launchpad.net

Commit message

Fix UnicodeDecodeError (bug #1672720) when exchanging message with the server.

Encode unicode strings in landscape.lib.fetch before passing over to libcurl.

Description of the change

Now also allow bytes as data to be fetched. This should enable to use bpickled unicode data. I also added a new test to cover that.

Testing instructions:
* Use the client in communication with a server as reported in the bug.

To post a comment you must log in.
Revision history for this message
🤖 Landscape Builder (landscape-builder) :
review: Abstain (executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: TRIAL_ARGS=-j4 make check
Result: Fail
Revno: 958
Branch: lp:~gocept/landscape-client/fetch-strings-and-bytes
Jenkins: https://ci.lscape.net/job/latch-test-xenial/3623/

review: Needs Fixing (test results)
Revision history for this message
Steffen Allner (sallner) wrote :

Hm, I cannot reproduce that failure on my machine and I actually cannot image, how the code change could have influenced the test so that it fails. Do you see a connection Danilo? Otherwise could you please restart the test?

Revision history for this message
🤖 Landscape Builder (landscape-builder) :
review: Abstain (executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 958
Branch: lp:~gocept/landscape-client/fetch-strings-and-bytes
Jenkins: https://ci.lscape.net/job/latch-test-xenial/3625/

review: Approve (test results)
Revision history for this message
🤖 Landscape Builder (landscape-builder) :
review: Abstain (executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 958
Branch: lp:~gocept/landscape-client/fetch-strings-and-bytes
Jenkins: https://ci.lscape.net/job/latch-test-xenial/3626/

review: Approve (test results)
Revision history for this message
Michael Howitz (mh-gocept) wrote :

I'd suggest to reduce the duplicate code.

review: Needs Fixing
959. By Steffen Allner

Refactor to use helper method for common code in tests.

Revision history for this message
Steffen Allner (sallner) wrote :

I added a helper method.

Revision history for this message
🤖 Landscape Builder (landscape-builder) :
review: Abstain (executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 959
Branch: lp:~gocept/landscape-client/fetch-strings-and-bytes
Jenkins: https://ci.lscape.net/job/latch-test-xenial/3629/

review: Approve (test results)
Revision history for this message
Michael Howitz (mh-gocept) wrote :

Looks good now.

review: Approve
Revision history for this message
Данило Шеган (danilo) wrote :

We are not huge fans of asserts in helpers in the Landscape team: it's too easy to break the code so the asserts are never fired.

I am fine with a helper that sends a request for a payload, but got_result() should live in each individual test, and the unicode test should not check any of the headers but only the content: they are not the point of that test.

With those changes, I think there will be less value in a helper, but if you still think it's worth it, I am happy with that too.

I'll do a quick run to ensure this fixes the problem we've seen before giving my final stamp of approval.

Revision history for this message
Данило Шеган (danilo) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/broker/tests/test_transport.py'
2--- landscape/broker/tests/test_transport.py 2017-03-06 10:38:07 +0000
3+++ landscape/broker/tests/test_transport.py 2017-03-16 09:56:25 +0000
4@@ -1,3 +1,4 @@
5+# -*- coding: utf-8 -*-
6 import os
7
8 from landscape import VERSION
9@@ -49,6 +50,34 @@
10 for port in self.ports:
11 port.stopListening()
12
13+ def request_with_payload(self, payload):
14+ resource = DataCollectingResource()
15+ port = reactor.listenTCP(
16+ 0, server.Site(resource), interface="127.0.0.1")
17+ self.ports.append(port)
18+ transport = HTTPTransport(
19+ None, "http://localhost:%d/" % (port.getHost().port,))
20+ result = deferToThread(transport.exchange, payload, computer_id="34",
21+ exchange_token="abcd-efgh", message_api="X.Y")
22+
23+ def got_result(ignored):
24+ try:
25+ get_header = resource.request.requestHeaders.getRawHeaders
26+ except AttributeError:
27+ # For backwards compatibility with Twisted versions
28+ # without requestHeaders
29+ def get_header(header):
30+ return [resource.request.received_headers[header]]
31+
32+ self.assertEqual(get_header(u"x-computer-id"), ["34"])
33+ self.assertEqual(get_header("x-exchange-token"), ["abcd-efgh"])
34+ self.assertEqual(
35+ get_header("user-agent"), ["landscape-client/%s" % (VERSION,)])
36+ self.assertEqual(get_header("x-message-api"), ["X.Y"])
37+ self.assertEqual(bpickle.loads(resource.content), payload)
38+ result.addCallback(got_result)
39+ return result
40+
41 def test_get_url(self):
42 url = "http://example/ooga"
43 transport = HTTPTransport(None, url)
44@@ -66,32 +95,14 @@
45 message API version as HTTP headers, and the payload as a
46 bpickled request body.
47 """
48- resource = DataCollectingResource()
49- port = reactor.listenTCP(
50- 0, server.Site(resource), interface="127.0.0.1")
51- self.ports.append(port)
52- transport = HTTPTransport(
53- None, "http://localhost:%d/" % (port.getHost().port,))
54- result = deferToThread(transport.exchange, "HI", computer_id="34",
55- exchange_token="abcd-efgh", message_api="X.Y")
56-
57- def got_result(ignored):
58- try:
59- get_header = resource.request.requestHeaders.getRawHeaders
60- except AttributeError:
61- # For backwards compatibility with Twisted versions
62- # without requestHeaders
63- def get_header(header):
64- return [resource.request.received_headers[header]]
65-
66- self.assertEqual(get_header(u"x-computer-id"), ["34"])
67- self.assertEqual(get_header("x-exchange-token"), ["abcd-efgh"])
68- self.assertEqual(
69- get_header("user-agent"), ["landscape-client/%s" % (VERSION,)])
70- self.assertEqual(get_header("x-message-api"), ["X.Y"])
71- self.assertEqual(bpickle.loads(resource.content), "HI")
72- result.addCallback(got_result)
73- return result
74+ return self.request_with_payload(payload="HI")
75+
76+ def test_request_data_unicode(self):
77+ """
78+ When a payload contains unicode characters they are properly handled
79+ by bpickle.
80+ """
81+ return self.request_with_payload(payload=u"проба")
82
83 def test_ssl_verification_positive(self):
84 """
85
86=== modified file 'landscape/lib/fetch.py'
87--- landscape/lib/fetch.py 2017-03-06 15:16:16 +0000
88+++ landscape/lib/fetch.py 2017-03-16 09:56:25 +0000
89@@ -65,7 +65,9 @@
90 @param proxy: The proxy url to use for the request.
91 """
92 import pycurl
93- output = io.BytesIO(networkString(data))
94+ if not isinstance(data, bytes):
95+ data = data.encode("utf-8")
96+ output = io.BytesIO(data)
97 input = io.BytesIO()
98
99 if curl is None:

Subscribers

People subscribed via source and target branches

to all changes: