Merge lp:~gocept/landscape-client/py3-network into lp:~landscape/landscape-client/trunk
- py3-network
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~gocept/landscape-client/py3-network |
Merge into: | lp:~landscape/landscape-client/trunk |
Prerequisite: | lp:~gocept/landscape-client/python3 |
Diff against target: |
522 lines (+139/-81) 9 files modified
landscape/broker/store.py (+1/-1) landscape/broker/tests/test_store.py (+2/-2) landscape/lib/fs.py (+38/-20) landscape/lib/juju.py (+1/-1) landscape/lib/network.py (+27/-15) landscape/lib/tests/test_fs.py (+27/-5) landscape/lib/tests/test_network.py (+34/-31) landscape/lib/tests/test_process.py (+5/-3) landscape/lib/vm_info.py (+4/-3) |
To merge this branch: | bzr merge lp:~gocept/landscape-client/py3-network |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
🤖 Landscape Builder | test results | Needs Fixing | |
Данило Шеган (community) | Needs Fixing | ||
Gocept | Pending | ||
Landscape | Pending | ||
Review via email: mp+319426@code.launchpad.net |
This proposal has been superseded by a proposal from 2017-03-13.
Commit message
Description of the change
We are on the journey to get the Bytes / String story solved for Python 2/3 compatibility.
This MP considers code in the landscape.
🤖 Landscape Builder (landscape-builder) : | # |
🤖 Landscape Builder (landscape-builder) wrote : | # |
🤖 Landscape Builder (landscape-builder) : | # |
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: TRIAL_ARGS=-j4 make check
Result: Fail
Revno: 961
Branch: lp:~gocept/landscape-client/py3-network
Jenkins: https:/
- 962. By Steffen Allner
-
Only decode with Python 3, otherwise a landscape.schema violation occurs.
- 963. By Steffen Allner
-
Opening file in binary mode allows to write and load bpickled data.
Данило Шеган (danilo) wrote : | # |
Looks good but there are a few nits here.
🤖 Landscape Builder (landscape-builder) : | # |
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 963
Branch: lp:~gocept/landscape-client/py3-network
Jenkins: https:/
Steffen Allner (sallner) wrote : | # |
I merged the current trunk and the py3-fs branch and will resubmit the proposal with a new prerequisite branch.
- 964. By Steffen Allner
-
Backmerge from trunk.
- 965. By Steffen Allner
-
Merge landscape.lib.fs with optional encoding.
- 966. By Steffen Allner
-
Improve documentation.
- 967. By Steffen Allner
-
Always ensure ascii characters for interface name.
🤖 Landscape Builder (landscape-builder) : | # |
🤖 Landscape Builder (landscape-builder) wrote : | # |
Command: TRIAL_ARGS=-j4 make check
Result: Fail
Revno: 967
Branch: lp:~gocept/landscape-client/py3-network
Jenkins: https:/
- 968. By Steffen Allner
-
Improve compliance with coding style.
- 969. By Steffen Allner
-
Merge in current l.l.fs
- 970. By Steffen Allner
-
Backout former revision 967 as we need a byte string for Python 2 to satisfy the schema.
Unmerged revisions
Preview Diff
1 | === modified file 'landscape/broker/store.py' |
2 | --- landscape/broker/store.py 2017-03-06 10:38:07 +0000 |
3 | +++ landscape/broker/store.py 2017-03-13 13:20:43 +0000 |
4 | @@ -437,7 +437,7 @@ |
5 | return os.path.join(self._directory, *args) |
6 | |
7 | def _get_content(self, filename): |
8 | - file = open(filename) |
9 | + file = open(filename, 'rb') |
10 | try: |
11 | return file.read() |
12 | finally: |
13 | |
14 | === modified file 'landscape/broker/tests/test_store.py' |
15 | --- landscape/broker/tests/test_store.py 2016-08-17 20:31:48 +0000 |
16 | +++ landscape/broker/tests/test_store.py 2017-03-13 13:20:43 +0000 |
17 | @@ -280,7 +280,7 @@ |
18 | self.store.add({"type": "data", "data": 1}) |
19 | # We simulate it by creating a fake file which raises halfway through |
20 | # writing a file. |
21 | - with mock.patch("__builtin__.open") as mock_open: |
22 | + with mock.patch("landscape.lib.fs.open") as mock_open: |
23 | mocked_file = mock_open.return_value |
24 | mocked_file.write.side_effect = IOError("Sorry, pal!") |
25 | # This kind of ensures that raising an exception is somewhat |
26 | @@ -288,7 +288,7 @@ |
27 | # on special exception-handling in the file-writing code. |
28 | self.assertRaises( |
29 | IOError, self.store.add, {"type": "data", "data": 2}) |
30 | - mock_open.assert_called_with(mock.ANY, "w") |
31 | + mock_open.assert_called_with(mock.ANY, "wb") |
32 | mocked_file.write.assert_called_once_with(mock.ANY) |
33 | self.assertEqual(self.store.get_pending_messages(), |
34 | [{"type": "data", "data": 1, "api": "3.2"}]) |
35 | |
36 | === modified file 'landscape/lib/fs.py' |
37 | --- landscape/lib/fs.py 2013-05-28 08:48:31 +0000 |
38 | +++ landscape/lib/fs.py 2017-03-13 13:20:43 +0000 |
39 | @@ -1,50 +1,68 @@ |
40 | """File-system utils""" |
41 | |
42 | +import codecs |
43 | import os |
44 | import time |
45 | |
46 | |
47 | -def create_file(path, content): |
48 | +from twisted.python.compat import long |
49 | + |
50 | + |
51 | +def create_file(path, content, encoding=None): |
52 | """Create a file with the given content. |
53 | |
54 | @param path: The path to the file. |
55 | @param content: The content to be written in the file. |
56 | + @param encoding: An optional encoding. If set, the content will be encoded |
57 | + with C{encoding} before writing to the file. |
58 | """ |
59 | - fd = open(path, "w") |
60 | - fd.write(content) |
61 | - fd.close() |
62 | + if encoding: |
63 | + content = codecs.encode(content, encoding) |
64 | + # XXX: Due to a very specific mock of `open()` in landscape.broker.tests.\ |
65 | + # test_store.MessageStoreTest.test_atomic_message_writing it is hard to |
66 | + # write this file opening as context manager. |
67 | + fd = open(path, "wb") |
68 | + try: |
69 | + fd.write(content) |
70 | + finally: |
71 | + fd.close() |
72 | |
73 | |
74 | def append_file(path, content): |
75 | - """Append a file with the given content. |
76 | + """Append a file with the given binary content. |
77 | |
78 | The file is created, if it doesn't exist already. |
79 | |
80 | @param path: The path to the file. |
81 | @param content: The content to be written in the file at the end. |
82 | """ |
83 | - fd = open(path, "a") |
84 | - fd.write(content) |
85 | - fd.close() |
86 | - |
87 | - |
88 | -def read_file(path, limit=None): |
89 | + with open(path, "a") as fd: |
90 | + fd.write(content) |
91 | + |
92 | + |
93 | +def read_file(path, limit=None, encoding=None): |
94 | """Return the content of the given file. |
95 | |
96 | @param path: The path to the file. |
97 | @param limit: An optional read limit. If positive, read up to that number |
98 | of bytes from the beginning of the file. If negative, read up to that |
99 | number of bytes from the end of the file. |
100 | - @return content: The content of the file, possibly trimmed to C{limit}. |
101 | + @param encoding: An optional encoding. If set, the content will be returned |
102 | + decoded with C{encoding}. |
103 | + @return content: The content of the file as bytes or unicode string |
104 | + (depending on C{encoding}), possibly trimmed to C{limit}. |
105 | """ |
106 | - fd = open(path, "r") |
107 | - if limit and os.path.getsize(path) > abs(limit): |
108 | - whence = 0 |
109 | - if limit < 0: |
110 | - whence = 2 |
111 | - fd.seek(limit, whence) |
112 | - content = fd.read() |
113 | - fd.close() |
114 | + # Use binary mode since opening a file in text mode in Python 3 does not |
115 | + # allow non-zero offset seek from the end of the file. |
116 | + with open(path, "rb") as fd: |
117 | + if limit and os.path.getsize(path) > abs(limit): |
118 | + whence = 0 |
119 | + if limit < 0: |
120 | + whence = 2 |
121 | + fd.seek(limit, whence) |
122 | + content = fd.read() |
123 | + if encoding: |
124 | + content = codecs.decode(content, encoding) |
125 | return content |
126 | |
127 | |
128 | |
129 | === modified file 'landscape/lib/juju.py' |
130 | --- landscape/lib/juju.py 2014-09-24 08:09:55 +0000 |
131 | +++ landscape/lib/juju.py 2017-03-13 13:20:43 +0000 |
132 | @@ -13,7 +13,7 @@ |
133 | if not os.path.exists(config.juju_filename): |
134 | return |
135 | |
136 | - json_contents = read_file(config.juju_filename) |
137 | + json_contents = read_file(config.juju_filename, encoding="utf-8") |
138 | try: |
139 | juju_info = json.loads(json_contents) |
140 | # Catch any error the json lib could throw, because we don't know or |
141 | |
142 | === modified file 'landscape/lib/network.py' |
143 | --- landscape/lib/network.py 2017-01-10 16:02:02 +0000 |
144 | +++ landscape/lib/network.py 2017-03-13 13:20:43 +0000 |
145 | @@ -8,7 +8,7 @@ |
146 | import errno |
147 | import logging |
148 | |
149 | -from twisted.python.compat import long |
150 | +from twisted.python.compat import long, _PY3 |
151 | |
152 | __all__ = ["get_active_device_info", "get_network_traffic", "is_64"] |
153 | |
154 | @@ -55,7 +55,7 @@ |
155 | max_interfaces = 128 |
156 | |
157 | # Setup an array to hold our response, and initialized to null strings. |
158 | - interfaces = array.array("B", "\0" * max_interfaces * IF_STRUCT_SIZE) |
159 | + interfaces = array.array("B", b"\0" * max_interfaces * IF_STRUCT_SIZE) |
160 | buffer_size = interfaces.buffer_info()[0] |
161 | packed_bytes = struct.pack( |
162 | "iL", max_interfaces * IF_STRUCT_SIZE, buffer_size) |
163 | @@ -69,7 +69,7 @@ |
164 | already_found = set() |
165 | for index in range(0, byte_length, IF_STRUCT_SIZE): |
166 | ifreq_struct = result[index:index + IF_STRUCT_SIZE] |
167 | - interface_name = ifreq_struct[:ifreq_struct.index("\0")] |
168 | + interface_name = ifreq_struct[:ifreq_struct.index(b"\0")] |
169 | if interface_name not in already_found: |
170 | already_found.add(interface_name) |
171 | yield interface_name |
172 | @@ -121,7 +121,16 @@ |
173 | """ |
174 | mac_address = fcntl.ioctl( |
175 | sock.fileno(), SIOCGIFHWADDR, struct.pack("256s", interface[:15])) |
176 | - return "".join(["%02x:" % ord(char) for char in mac_address[18:24]])[:-1] |
177 | + if _PY3: |
178 | + def to_int(char): |
179 | + # We have already bytes, so we do nothing |
180 | + return char |
181 | + else: |
182 | + def to_int(char): |
183 | + # We have a string in python 2 and need the int here. |
184 | + return ord(char) |
185 | + return "".join(["%02x:" % to_int(char) |
186 | + for char in mac_address[18:24]])[:-1] |
187 | |
188 | |
189 | def get_flags(sock, interface): |
190 | @@ -147,13 +156,17 @@ |
191 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, |
192 | socket.IPPROTO_IP) |
193 | for interface in get_active_interfaces(sock): |
194 | - if interface in skipped_interfaces: |
195 | - continue |
196 | - if skip_vlan and "." in interface: |
197 | - continue |
198 | - if skip_alias and ":" in interface: |
199 | - continue |
200 | - interface_info = {"interface": interface} |
201 | + interface_string = interface.decode("ascii") |
202 | + if interface_string in skipped_interfaces: |
203 | + continue |
204 | + if skip_vlan and b"." in interface: |
205 | + continue |
206 | + if skip_alias and b":" in interface: |
207 | + continue |
208 | + # We keep values as byte strings for use in struct.pack() in |
209 | + # different getter methods, and only use the decoded value of the |
210 | + # interface name here. |
211 | + interface_info = {"interface": interface_string} |
212 | interface_info["ip_address"] = get_ip_address(sock, interface) |
213 | interface_info["mac_address"] = get_mac_address(sock, interface) |
214 | interface_info["broadcast_address"] = get_broadcast_address( |
215 | @@ -175,9 +188,8 @@ |
216 | Retrieves an array of information regarding the network activity per |
217 | network interface. |
218 | """ |
219 | - netdev = open(source_file, "r") |
220 | - lines = netdev.readlines() |
221 | - netdev.close() |
222 | + with open(source_file, "r") as netdev: |
223 | + lines = netdev.readlines() |
224 | |
225 | # Parse out the column headers as keys. |
226 | _, receive_columns, transmit_columns = lines[1].split("|") |
227 | @@ -227,7 +239,7 @@ |
228 | * 0: The cable is not connected to the interface. We cannot measure |
229 | interface speed, but could if it was plugged in. |
230 | """ |
231 | - cmd_struct = struct.pack('I39s', ETHTOOL_GSET, '\x00' * 39) |
232 | + cmd_struct = struct.pack('I39s', ETHTOOL_GSET, b'\x00' * 39) |
233 | status_cmd = array.array('B', cmd_struct) |
234 | packed = struct.pack('16sP', interface_name, status_cmd.buffer_info()[0]) |
235 | |
236 | |
237 | === modified file 'landscape/lib/tests/test_fs.py' |
238 | --- landscape/lib/tests/test_fs.py 2016-06-15 16:42:17 +0000 |
239 | +++ landscape/lib/tests/test_fs.py 2017-03-13 13:20:43 +0000 |
240 | @@ -1,7 +1,11 @@ |
241 | +# -*- coding: utf-8 -*- |
242 | +import codecs |
243 | import os |
244 | from mock import patch |
245 | import time |
246 | |
247 | +from twisted.python.compat import long |
248 | + |
249 | from landscape.tests.helpers import LandscapeTest |
250 | |
251 | from landscape.lib.fs import append_file, read_file, touch_file |
252 | @@ -14,7 +18,16 @@ |
253 | With no options L{read_file} reads the whole file passed as argument. |
254 | """ |
255 | path = self.makeFile("foo") |
256 | - self.assertEqual(read_file(path), "foo") |
257 | + self.assertEqual(read_file(path), b"foo") |
258 | + |
259 | + def test_read_file_encoding(self): |
260 | + """ |
261 | + With encoding L{read_file} reads the whole file passed as argument and |
262 | + decodes it. |
263 | + """ |
264 | + utf8_content = codecs.encode(u"foo \N{SNOWMAN}", "utf-8") |
265 | + path = self.makeFile(utf8_content, mode="wb") |
266 | + self.assertEqual(read_file(path, encoding="utf-8"), u"foo ☃") |
267 | |
268 | def test_read_file_with_limit(self): |
269 | """ |
270 | @@ -22,14 +35,23 @@ |
271 | given limit. |
272 | """ |
273 | path = self.makeFile("foo bar") |
274 | - self.assertEqual(read_file(path, limit=3), " bar") |
275 | + self.assertEqual(read_file(path, limit=3), b" bar") |
276 | + |
277 | + def test_read_file_with_limit_encoding(self): |
278 | + """ |
279 | + With a positive limit L{read_file} reads only the bytes after the |
280 | + given limit. |
281 | + """ |
282 | + utf8_content = codecs.encode(u"foo \N{SNOWMAN}", "utf-8") |
283 | + path = self.makeFile(utf8_content, mode="wb") |
284 | + self.assertEqual(read_file(path, limit=3, encoding="utf-8"), u" ☃") |
285 | |
286 | def test_read_file_with_negative_limit(self): |
287 | """ |
288 | With a negative limit L{read_file} reads only the tail of the file. |
289 | """ |
290 | path = self.makeFile("foo bar from end") |
291 | - self.assertEqual(read_file(path, limit=-3), "end") |
292 | + self.assertEqual(read_file(path, limit=-3), b"end") |
293 | |
294 | def test_read_file_with_limit_bigger_than_file(self): |
295 | """ |
296 | @@ -37,8 +59,8 @@ |
297 | file. |
298 | """ |
299 | path = self.makeFile("foo bar from end") |
300 | - self.assertEqual(read_file(path, limit=100), "foo bar from end") |
301 | - self.assertEqual(read_file(path, limit=-100), "foo bar from end") |
302 | + self.assertEqual(read_file(path, limit=100), b"foo bar from end") |
303 | + self.assertEqual(read_file(path, limit=-100), b"foo bar from end") |
304 | |
305 | |
306 | class TouchFileTest(LandscapeTest): |
307 | |
308 | === modified file 'landscape/lib/tests/test_network.py' |
309 | --- landscape/lib/tests/test_network.py 2017-01-23 12:14:33 +0000 |
310 | +++ landscape/lib/tests/test_network.py 2017-03-13 13:20:43 +0000 |
311 | @@ -1,14 +1,13 @@ |
312 | import array |
313 | import socket |
314 | |
315 | -from mock import patch, ANY |
316 | +from mock import patch, ANY, mock_open |
317 | from subprocess import Popen, PIPE |
318 | |
319 | from landscape.tests.helpers import LandscapeTest |
320 | from landscape.lib.network import ( |
321 | get_network_traffic, get_active_device_info, get_active_interfaces, |
322 | get_fqdn, get_network_interface_speed) |
323 | -from landscape.compat import StringIO |
324 | |
325 | |
326 | class NetworkInfoTest(LandscapeTest): |
327 | @@ -24,6 +23,7 @@ |
328 | |
329 | device_info = get_active_device_info() |
330 | result = Popen(["/sbin/ifconfig"], stdout=PIPE).communicate()[0] |
331 | + result = result.decode('ascii') |
332 | interface_blocks = dict( |
333 | [(block.split()[0], block.upper()) for block in |
334 | filter(None, result.split("\n\n"))]) |
335 | @@ -62,7 +62,7 @@ |
336 | def test_skip_vlan(self, mock_get_active_interfaces): |
337 | """VLAN interfaces are not reported by L{get_active_device_info}.""" |
338 | mock_get_active_interfaces.side_effect = lambda sock: ( |
339 | - list(get_active_interfaces(sock)) + ["eth0.1"]) |
340 | + list(get_active_interfaces(sock)) + [b"eth0.1"]) |
341 | device_info = get_active_device_info() |
342 | mock_get_active_interfaces.assert_called_with(ANY) |
343 | interfaces = [i["interface"] for i in device_info] |
344 | @@ -72,7 +72,7 @@ |
345 | def test_skip_alias(self, mock_get_active_interfaces): |
346 | """Interface aliases are not reported by L{get_active_device_info}.""" |
347 | mock_get_active_interfaces.side_effect = lambda sock: ( |
348 | - list(get_active_interfaces(sock)) + ["eth0:foo"]) |
349 | + list(get_active_interfaces(sock)) + [b"eth0:foo"]) |
350 | device_info = get_active_device_info() |
351 | interfaces = [i["interface"] for i in device_info] |
352 | self.assertNotIn("eth0:foo", interfaces) |
353 | @@ -94,23 +94,25 @@ |
354 | # This is a fake response observed to return the same interface several |
355 | # times (here, br1:priv) |
356 | response = ( |
357 | - "lo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" |
358 | - "\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
359 | - "\x00\x00\x00\x00\x00\x00\x00eth1:pub\x00\x00\x00\x00\x00\x00\x00" |
360 | - "\x00\x02\x00\x00\x00\xc8\xb4\xc4.\x00\x00\x00\x00\x00\x00\x00\x00" |
361 | - "\x00\x00\x00\x00\x00\x00\x00\x00br1:metadata\x00\x00\x00\x00\x02" |
362 | - "\x00\x00\x00\xa9\xfe\xa9\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
363 | - "\x00\x00\x00\x00\x00\x00\x00br1:0\x00\x00\x00\x00\x00\x00\x00\x00" |
364 | - "\x00\x00\x00\x02\x00\x00\x00\xc9\x19\x1f\x1d\x00\x00\x00\x00\x00" |
365 | - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00br1\x00\x00\x00\x00" |
366 | - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xc0\xa8d" |
367 | - "\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
368 | - "\x00br1:priv\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xac" |
369 | - "\x13\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
370 | - "\x00\x00\x00br1:priv\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00" |
371 | - "\x00\xac\x13\x02A") |
372 | + b"lo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" |
373 | + b"\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
374 | + b"\x00\x00\x00\x00\x00\x00\x00eth1:pub\x00\x00\x00\x00\x00\x00\x00" |
375 | + b"\x00\x02\x00\x00\x00\xc8\xb4\xc4.\x00\x00\x00\x00\x00\x00\x00" |
376 | + b"\x00" |
377 | + b"\x00\x00\x00\x00\x00\x00\x00\x00br1:metadata\x00\x00\x00\x00\x02" |
378 | + b"\x00\x00\x00\xa9\xfe\xa9\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
379 | + b"\x00\x00\x00\x00\x00\x00\x00br1:0\x00\x00\x00\x00\x00\x00\x00" |
380 | + b"\x00" |
381 | + b"\x00\x00\x00\x02\x00\x00\x00\xc9\x19\x1f\x1d\x00\x00\x00\x00\x00" |
382 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00br1\x00\x00\x00\x00" |
383 | + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xc0\xa8d" |
384 | + b"\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
385 | + b"\x00br1:priv\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xac" |
386 | + b"\x13\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |
387 | + b"\x00\x00\x00br1:priv\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00" |
388 | + b"\x00\xac\x13\x02A") |
389 | |
390 | - fake_array = array.array("B", response + "\0" * 4855) |
391 | + fake_array = array.array("B", response + b"\0" * 4855) |
392 | |
393 | with patch("array.array") as mock_array: |
394 | mock_array.return_value = fake_array |
395 | @@ -126,18 +128,19 @@ |
396 | mock_unpack.assert_called_with("iL", ANY) |
397 | |
398 | self.assertEqual( |
399 | - ["lo", "eth1:pub", "br1:metadata", "br1:0", "br1", "br1:priv"], |
400 | + [b"lo", b"eth1:pub", b"br1:metadata", |
401 | + b"br1:0", b"br1", b"br1:priv"], |
402 | interfaces) |
403 | |
404 | - @patch("__builtin__.open") |
405 | - def test_get_network_traffic(self, mock_open): |
406 | + def test_get_network_traffic(self): |
407 | """ |
408 | Network traffic is assessed via reading /proc/net/dev, verify |
409 | the parsed output against a known sample. |
410 | """ |
411 | - mock_open.return_value = StringIO(test_proc_net_dev_output) |
412 | - traffic = get_network_traffic() |
413 | - mock_open.assert_called_with("/proc/net/dev", "r") |
414 | + m = mock_open(read_data=test_proc_net_dev_output) |
415 | + with patch('landscape.lib.network.open', m): |
416 | + traffic = get_network_traffic() |
417 | + m.assert_called_with("/proc/net/dev", "r") |
418 | self.assertEqual(traffic, test_proc_net_dev_parsed) |
419 | |
420 | |
421 | @@ -221,7 +224,7 @@ |
422 | # ioctl always succeeds |
423 | mock_unpack.return_value = (100, False) |
424 | |
425 | - result = get_network_interface_speed(sock, "eth0") |
426 | + result = get_network_interface_speed(sock, b"eth0") |
427 | |
428 | mock_ioctl.assert_called_with(ANY, ANY, ANY) |
429 | mock_unpack.assert_called_with("12xHB28x", ANY) |
430 | @@ -240,7 +243,7 @@ |
431 | # ioctl always succeeds |
432 | mock_unpack.return_value = (65535, False) |
433 | |
434 | - result = get_network_interface_speed(sock, "eth0") |
435 | + result = get_network_interface_speed(sock, b"eth0") |
436 | |
437 | mock_ioctl.assert_called_with(ANY, ANY, ANY) |
438 | mock_unpack.assert_called_with("12xHB28x", ANY) |
439 | @@ -263,7 +266,7 @@ |
440 | # ioctl always raises |
441 | mock_ioctl.side_effect = theerror |
442 | |
443 | - result = get_network_interface_speed(sock, "eth0") |
444 | + result = get_network_interface_speed(sock, b"eth0") |
445 | |
446 | mock_ioctl.assert_called_with(ANY, ANY, ANY) |
447 | |
448 | @@ -285,7 +288,7 @@ |
449 | # ioctl always raises |
450 | mock_ioctl.side_effect = theerror |
451 | |
452 | - result = get_network_interface_speed(sock, "eth0") |
453 | + result = get_network_interface_speed(sock, b"eth0") |
454 | |
455 | mock_ioctl.assert_called_with(ANY, ANY, ANY) |
456 | |
457 | @@ -306,4 +309,4 @@ |
458 | # ioctl always raises |
459 | mock_ioctl.side_effect = theerror |
460 | |
461 | - self.assertRaises(IOError, get_network_interface_speed, sock, "eth0") |
462 | + self.assertRaises(IOError, get_network_interface_speed, sock, b"eth0") |
463 | |
464 | === modified file 'landscape/lib/tests/test_process.py' |
465 | --- landscape/lib/tests/test_process.py 2017-03-09 10:13:30 +0000 |
466 | +++ landscape/lib/tests/test_process.py 2017-03-13 13:20:43 +0000 |
467 | @@ -25,7 +25,8 @@ |
468 | os.mkdir(process_dir) |
469 | |
470 | cmd_line = "/usr/bin/foo" |
471 | - create_file(os.path.join(process_dir, "cmdline"), cmd_line) |
472 | + create_file( |
473 | + os.path.join(process_dir, "cmdline"), cmd_line, encoding="utf-8") |
474 | |
475 | status = "\n".join([ |
476 | "Name: foo", |
477 | @@ -34,11 +35,12 @@ |
478 | "Gid: 2000", |
479 | "VmSize: 3000", |
480 | "Ignored: value"]) |
481 | - create_file(os.path.join(process_dir, "status"), status) |
482 | + create_file( |
483 | + os.path.join(process_dir, "status"), status, encoding="utf-8") |
484 | |
485 | stat_array = [str(index) for index in range(44)] |
486 | stat = " ".join(stat_array) |
487 | - create_file(os.path.join(process_dir, "stat"), stat) |
488 | + create_file(os.path.join(process_dir, "stat"), stat, encoding="utf-8") |
489 | |
490 | @mock.patch("landscape.lib.process.detect_jiffies", return_value=1) |
491 | @mock.patch("os.listdir") |
492 | |
493 | === modified file 'landscape/lib/vm_info.py' |
494 | --- landscape/lib/vm_info.py 2016-09-23 15:43:36 +0000 |
495 | +++ landscape/lib/vm_info.py 2017-03-13 13:20:43 +0000 |
496 | @@ -34,7 +34,7 @@ |
497 | for filename in ("container_type", "systemd/container"): |
498 | path = os.path.join(run_path, filename) |
499 | if os.path.exists(path): |
500 | - return read_file(path).strip() |
501 | + return read_file(path, encoding="utf-8").strip() |
502 | return "" |
503 | |
504 | |
505 | @@ -52,7 +52,7 @@ |
506 | |
507 | def _get_vm_by_vendor(sys_vendor_path): |
508 | """Return the VM type string (possibly empty) based on the vendor.""" |
509 | - vendor = read_file(sys_vendor_path).lower() |
510 | + vendor = read_file(sys_vendor_path, encoding="utf-8").lower() |
511 | # Use lower-key string for vendors, since we do case-insentive match. |
512 | content_vendors_map = ( |
513 | ("bochs", "kvm"), |
514 | @@ -72,7 +72,8 @@ |
515 | def _get_vm_legacy(root_path): |
516 | """Check if the host is virtualized looking at /proc/cpuinfo content.""" |
517 | try: |
518 | - cpuinfo = read_file(os.path.join(root_path, "proc/cpuinfo")) |
519 | + cpuinfo = read_file( |
520 | + os.path.join(root_path, "proc/cpuinfo"), encoding="utf-8") |
521 | except (IOError, OSError): |
522 | return "" |
523 |
Command: TRIAL_ARGS=-j4 make check /ci.lscape. net/job/ latch-test- precise/ 899/
Result: Fail
Revno: 961
Branch: lp:~gocept/landscape-client/py3-network
Jenkins: https:/