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

+29-6
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

+33-5
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

+65-1
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

+64
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)