Skip to content

Commit 155f6c8

Browse files
Merge pull request #171 from dmitry-lipetsk/D20241225_002--os_ops
OsOps::read methods were corrected (text mode)
2 parents 5b263f3 + 6c514bf commit 155f6c8

File tree

4 files changed

+191
-12
lines changed

4 files changed

+191
-12
lines changed

testgres/operations/local_ops.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import psutil
1111

1212
from ..exceptions import ExecUtilException
13+
from ..exceptions import InvalidOperationException
1314
from .os_ops import ConnectionParams, OsOperations, pglib, get_default_encoding
1415
from .raise_error import RaiseError
1516
from .helpers import Helpers
@@ -266,13 +267,35 @@ def touch(self, filename):
266267
os.utime(filename, None)
267268

268269
def read(self, filename, encoding=None, binary=False):
269-
mode = "rb" if binary else "r"
270-
with open(filename, mode) as file:
270+
assert type(filename) == str # noqa: E721
271+
assert encoding is None or type(encoding) == str # noqa: E721
272+
assert type(binary) == bool # noqa: E721
273+
274+
if binary:
275+
if encoding is not None:
276+
raise InvalidOperationException("Enconding is not allowed for read binary operation")
277+
278+
return self._read__binary(filename)
279+
280+
# python behavior
281+
assert (None or "abc") == "abc"
282+
assert ("" or "abc") == "abc"
283+
284+
return self._read__text_with_encoding(filename, encoding or get_default_encoding())
285+
286+
def _read__text_with_encoding(self, filename, encoding):
287+
assert type(filename) == str # noqa: E721
288+
assert type(encoding) == str # noqa: E721
289+
with open(filename, mode='r', encoding=encoding) as file: # open in a text mode
290+
content = file.read()
291+
assert type(content) == str # noqa: E721
292+
return content
293+
294+
def _read__binary(self, filename):
295+
assert type(filename) == str # noqa: E721
296+
with open(filename, 'rb') as file: # open in a binary mode
271297
content = file.read()
272-
if binary:
273-
return content
274-
if isinstance(content, bytes):
275-
return content.decode(encoding or get_default_encoding())
298+
assert type(content) == bytes # noqa: E721
276299
return content
277300

278301
def readlines(self, filename, num_lines=0, binary=False, encoding=None):

testgres/operations/remote_ops.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import platform
44
import subprocess
55
import tempfile
6+
import io
67

78
# we support both pg8000 and psycopg2
89
try:
@@ -14,6 +15,7 @@
1415
raise ImportError("You must have psycopg2 or pg8000 modules installed")
1516

1617
from ..exceptions import ExecUtilException
18+
from ..exceptions import InvalidOperationException
1719
from .os_ops import OsOperations, ConnectionParams, get_default_encoding
1820
from .raise_error import RaiseError
1921
from .helpers import Helpers
@@ -319,13 +321,39 @@ def touch(self, filename):
319321
self.exec_command("touch {}".format(filename))
320322

321323
def read(self, filename, binary=False, encoding=None):
322-
cmd = "cat {}".format(filename)
323-
result = self.exec_command(cmd, encoding=encoding)
324+
assert type(filename) == str # noqa: E721
325+
assert encoding is None or type(encoding) == str # noqa: E721
326+
assert type(binary) == bool # noqa: E721
324327

325-
if not binary and result:
326-
result = result.decode(encoding or get_default_encoding())
328+
if binary:
329+
if encoding is not None:
330+
raise InvalidOperationException("Enconding is not allowed for read binary operation")
327331

328-
return result
332+
return self._read__binary(filename)
333+
334+
# python behavior
335+
assert (None or "abc") == "abc"
336+
assert ("" or "abc") == "abc"
337+
338+
return self._read__text_with_encoding(filename, encoding or get_default_encoding())
339+
340+
def _read__text_with_encoding(self, filename, encoding):
341+
assert type(filename) == str # noqa: E721
342+
assert type(encoding) == str # noqa: E721
343+
content = self._read__binary(filename)
344+
assert type(content) == bytes # noqa: E721
345+
buf0 = io.BytesIO(content)
346+
buf1 = io.TextIOWrapper(buf0, encoding=encoding)
347+
content_s = buf1.read()
348+
assert type(content_s) == str # noqa: E721
349+
return content_s
350+
351+
def _read__binary(self, filename):
352+
assert type(filename) == str # noqa: E721
353+
cmd = ["cat", filename]
354+
content = self.exec_command(cmd)
355+
assert type(content) == bytes # noqa: E721
356+
return content
329357

330358
def readlines(self, filename, num_lines=0, binary=False, encoding=None):
331359
if num_lines > 0:

tests/test_local.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55

66
from testgres import ExecUtilException
7+
from testgres import InvalidOperationException
78
from testgres import LocalOperations
89

910
from .helpers.run_conditions import RunConditions
@@ -56,6 +57,67 @@ def test_exec_command_failure__expect_error(self):
5657
assert exit_status == 127
5758
assert result == b''
5859

60+
def test_read__text(self):
61+
"""
62+
Test LocalOperations::read for text data.
63+
"""
64+
filename = __file__ # current file
65+
66+
with open(filename, 'r') as file: # open in a text mode
67+
response0 = file.read()
68+
69+
assert type(response0) == str # noqa: E721
70+
71+
response1 = self.operations.read(filename)
72+
assert type(response1) == str # noqa: E721
73+
assert response1 == response0
74+
75+
response2 = self.operations.read(filename, encoding=None, binary=False)
76+
assert type(response2) == str # noqa: E721
77+
assert response2 == response0
78+
79+
response3 = self.operations.read(filename, encoding="")
80+
assert type(response3) == str # noqa: E721
81+
assert response3 == response0
82+
83+
response4 = self.operations.read(filename, encoding="UTF-8")
84+
assert type(response4) == str # noqa: E721
85+
assert response4 == response0
86+
87+
def test_read__binary(self):
88+
"""
89+
Test LocalOperations::read for binary data.
90+
"""
91+
filename = __file__ # current file
92+
93+
with open(filename, 'rb') as file: # open in a binary mode
94+
response0 = file.read()
95+
96+
assert type(response0) == bytes # noqa: E721
97+
98+
response1 = self.operations.read(filename, binary=True)
99+
assert type(response1) == bytes # noqa: E721
100+
assert response1 == response0
101+
102+
def test_read__binary_and_encoding(self):
103+
"""
104+
Test LocalOperations::read for binary data and encoding.
105+
"""
106+
filename = __file__ # current file
107+
108+
with pytest.raises(
109+
InvalidOperationException,
110+
match=re.escape("Enconding is not allowed for read binary operation")):
111+
self.operations.read(filename, encoding="", binary=True)
112+
113+
def test_read__unknown_file(self):
114+
"""
115+
Test LocalOperations::read with unknown file.
116+
"""
117+
118+
with pytest.raises(FileNotFoundError, match=re.escape("[Errno 2] No such file or directory: '/dummy'")):
119+
self.operations.read("/dummy")
120+
59121
def test_read_binary__spec(self):
60122
"""
61123
Test LocalOperations::read_binary.
@@ -95,7 +157,9 @@ def test_read_binary__spec__unk_file(self):
95157
Test LocalOperations::read_binary with unknown file.
96158
"""
97159

98-
with pytest.raises(FileNotFoundError, match=re.escape("[Errno 2] No such file or directory: '/dummy'")):
160+
with pytest.raises(
161+
FileNotFoundError,
162+
match=re.escape("[Errno 2] No such file or directory: '/dummy'")):
99163
self.operations.read_binary("/dummy", 0)
100164

101165
def test_get_file_size(self):

tests/test_remote.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55

66
from testgres import ExecUtilException
7+
from testgres import InvalidOperationException
78
from testgres import RemoteOperations
89
from testgres import ConnectionParams
910

@@ -182,6 +183,69 @@ def test_read_binary_file(self):
182183

183184
assert isinstance(response, bytes)
184185

186+
def test_read__text(self):
187+
"""
188+
Test RemoteOperations::read for text data.
189+
"""
190+
filename = __file__ # current file
191+
192+
with open(filename, 'r') as file: # open in a text mode
193+
response0 = file.read()
194+
195+
assert type(response0) == str # noqa: E721
196+
197+
response1 = self.operations.read(filename)
198+
assert type(response1) == str # noqa: E721
199+
assert response1 == response0
200+
201+
response2 = self.operations.read(filename, encoding=None, binary=False)
202+
assert type(response2) == str # noqa: E721
203+
assert response2 == response0
204+
205+
response3 = self.operations.read(filename, encoding="")
206+
assert type(response3) == str # noqa: E721
207+
assert response3 == response0
208+
209+
response4 = self.operations.read(filename, encoding="UTF-8")
210+
assert type(response4) == str # noqa: E721
211+
assert response4 == response0
212+
213+
def test_read__binary(self):
214+
"""
215+
Test RemoteOperations::read for binary data.
216+
"""
217+
filename = __file__ # current file
218+
219+
with open(filename, 'rb') as file: # open in a binary mode
220+
response0 = file.read()
221+
222+
assert type(response0) == bytes # noqa: E721
223+
224+
response1 = self.operations.read(filename, binary=True)
225+
assert type(response1) == bytes # noqa: E721
226+
assert response1 == response0
227+
228+
def test_read__binary_and_encoding(self):
229+
"""
230+
Test RemoteOperations::read for binary data and encoding.
231+
"""
232+
filename = __file__ # current file
233+
234+
with pytest.raises(
235+
InvalidOperationException,
236+
match=re.escape("Enconding is not allowed for read binary operation")):
237+
self.operations.read(filename, encoding="", binary=True)
238+
239+
def test_read__unknown_file(self):
240+
"""
241+
Test RemoteOperations::read with unknown file.
242+
"""
243+
244+
with pytest.raises(
245+
ExecUtilException,
246+
match=re.escape("cat: /dummy: No such file or directory")):
247+
self.operations.read("/dummy")
248+
185249
def test_read_binary__spec(self):
186250
"""
187251
Test RemoteOperations::read_binary.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy