Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 22c4763

Browse files
OsOps::write method is corrected (#183)
LocalOperations - [BUG FIX] (read_write=true and truncate=false) writes to begging of a file - Preparation of data is added (verification/encoding/decoding/eol) RemoteOperations - Preparation of data is corrected (verification/encoding/decoding/eol) - Temp file is always opened with "w+"/"w+b" modes. Tests are added.
1 parent 4493d69 commit 22c4763

File tree

4 files changed

+201
-25
lines changed

4 files changed

+201
-25
lines changed

testgres/operations/local_ops.py

+40-13
Original file line numberDiff line numberDiff line change
@@ -235,27 +235,54 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
235235
Args:
236236
filename: The file path where the data will be written.
237237
data: The data to be written to the file.
238-
truncate: If True, the file will be truncated before writing ('w' or 'wb' option);
239-
if False (default), data will be appended ('a' or 'ab' option).
240-
binary: If True, the data will be written in binary mode ('wb' or 'ab' option);
241-
if False (default), the data will be written in text mode ('w' or 'a' option).
242-
read_and_write: If True, the file will be opened with read and write permissions ('r+' option);
243-
if False (default), only write permission will be used ('w', 'a', 'wb', or 'ab' option)
238+
truncate: If True, the file will be truncated before writing ('w' option);
239+
if False (default), data will be appended ('a' option).
240+
binary: If True, the data will be written in binary mode ('b' option);
241+
if False (default), the data will be written in text mode.
242+
read_and_write: If True, the file will be opened with read and write permissions ('+' option);
243+
if False (default), only write permission will be used.
244244
"""
245-
# If it is a bytes str or list
246245
if isinstance(data, bytes) or isinstance(data, list) and all(isinstance(item, bytes) for item in data):
247246
binary = True
248-
mode = "wb" if binary else "w"
249-
if not truncate:
250-
mode = "ab" if binary else "a"
247+
248+
mode = "w" if truncate else "a"
249+
251250
if read_and_write:
252-
mode = "r+b" if binary else "r+"
251+
mode += "+"
252+
253+
# If it is a bytes str or list
254+
if binary:
255+
mode += "b"
256+
257+
assert type(mode) == str # noqa: E721
258+
assert mode != ""
253259

254260
with open(filename, mode) as file:
255261
if isinstance(data, list):
256-
file.writelines(data)
262+
data2 = [__class__._prepare_line_to_write(s, binary) for s in data]
263+
file.writelines(data2)
257264
else:
258-
file.write(data)
265+
data2 = __class__._prepare_data_to_write(data, binary)
266+
file.write(data2)
267+
268+
def _prepare_line_to_write(data, binary):
269+
data = __class__._prepare_data_to_write(data, binary)
270+
271+
if binary:
272+
assert type(data) == bytes # noqa: E721
273+
return data.rstrip(b'\n') + b'\n'
274+
275+
assert type(data) == str # noqa: E721
276+
return data.rstrip('\n') + '\n'
277+
278+
def _prepare_data_to_write(data, binary):
279+
if isinstance(data, bytes):
280+
return data if binary else data.decode()
281+
282+
if isinstance(data, str):
283+
return data if not binary else data.encode()
284+
285+
raise InvalidOperationException("Unknown type of data type [{0}].".format(type(data).__name__))
259286

260287
def touch(self, filename):
261288
"""

testgres/operations/remote_ops.py

+23-12
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,6 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
278278
if not encoding:
279279
encoding = get_default_encoding()
280280
mode = "wb" if binary else "w"
281-
if not truncate:
282-
mode = "ab" if binary else "a"
283-
if read_and_write:
284-
mode = "r+b" if binary else "r+"
285281

286282
with tempfile.NamedTemporaryFile(mode=mode, delete=False) as tmp_file:
287283
# For scp the port is specified by a "-P" option
@@ -292,16 +288,12 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
292288
subprocess.run(scp_cmd, check=False) # The file might not exist yet
293289
tmp_file.seek(0, os.SEEK_END)
294290

295-
if isinstance(data, bytes) and not binary:
296-
data = data.decode(encoding)
297-
elif isinstance(data, str) and binary:
298-
data = data.encode(encoding)
299-
300291
if isinstance(data, list):
301-
data = [(s if isinstance(s, str) else s.decode(get_default_encoding())).rstrip('\n') + '\n' for s in data]
302-
tmp_file.writelines(data)
292+
data2 = [__class__._prepare_line_to_write(s, binary, encoding) for s in data]
293+
tmp_file.writelines(data2)
303294
else:
304-
tmp_file.write(data)
295+
data2 = __class__._prepare_data_to_write(data, binary, encoding)
296+
tmp_file.write(data2)
305297

306298
tmp_file.flush()
307299
scp_cmd = ['scp'] + scp_args + [tmp_file.name, f"{self.ssh_dest}:{filename}"]
@@ -313,6 +305,25 @@ def write(self, filename, data, truncate=False, binary=False, read_and_write=Fal
313305

314306
os.remove(tmp_file.name)
315307

308+
def _prepare_line_to_write(data, binary, encoding):
309+
data = __class__._prepare_data_to_write(data, binary, encoding)
310+
311+
if binary:
312+
assert type(data) == bytes # noqa: E721
313+
return data.rstrip(b'\n') + b'\n'
314+
315+
assert type(data) == str # noqa: E721
316+
return data.rstrip('\n') + '\n'
317+
318+
def _prepare_data_to_write(data, binary, encoding):
319+
if isinstance(data, bytes):
320+
return data if binary else data.decode(encoding)
321+
322+
if isinstance(data, str):
323+
return data if not binary else data.encode(encoding)
324+
325+
raise InvalidOperationException("Unknown type of data type [{0}].".format(type(data).__name__))
326+
316327
def touch(self, filename):
317328
"""
318329
Create a new file or update the access and modification times of an existing file on the remote server.

tests/test_local.py

+69
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44
import re
5+
import tempfile
56

67
from testgres import ExecUtilException
78
from testgres import InvalidOperationException
@@ -273,3 +274,71 @@ def test_cwd(self):
273274

274275
# Comp result
275276
assert v == expectedValue
277+
278+
class tagWriteData001:
279+
def __init__(self, sign, source, cp_rw, cp_truncate, cp_binary, cp_data, result):
280+
self.sign = sign
281+
self.source = source
282+
self.call_param__rw = cp_rw
283+
self.call_param__truncate = cp_truncate
284+
self.call_param__binary = cp_binary
285+
self.call_param__data = cp_data
286+
self.result = result
287+
288+
sm_write_data001 = [
289+
tagWriteData001("A001", "1234567890", False, False, False, "ABC", "1234567890ABC"),
290+
tagWriteData001("A002", b"1234567890", False, False, True, b"ABC", b"1234567890ABC"),
291+
292+
tagWriteData001("B001", "1234567890", False, True, False, "ABC", "ABC"),
293+
tagWriteData001("B002", "1234567890", False, True, False, "ABC1234567890", "ABC1234567890"),
294+
tagWriteData001("B003", b"1234567890", False, True, True, b"ABC", b"ABC"),
295+
tagWriteData001("B004", b"1234567890", False, True, True, b"ABC1234567890", b"ABC1234567890"),
296+
297+
tagWriteData001("C001", "1234567890", True, False, False, "ABC", "1234567890ABC"),
298+
tagWriteData001("C002", b"1234567890", True, False, True, b"ABC", b"1234567890ABC"),
299+
300+
tagWriteData001("D001", "1234567890", True, True, False, "ABC", "ABC"),
301+
tagWriteData001("D002", "1234567890", True, True, False, "ABC1234567890", "ABC1234567890"),
302+
tagWriteData001("D003", b"1234567890", True, True, True, b"ABC", b"ABC"),
303+
tagWriteData001("D004", b"1234567890", True, True, True, b"ABC1234567890", b"ABC1234567890"),
304+
305+
tagWriteData001("E001", "\0001234567890\000", False, False, False, "\000ABC\000", "\0001234567890\000\000ABC\000"),
306+
tagWriteData001("E002", b"\0001234567890\000", False, False, True, b"\000ABC\000", b"\0001234567890\000\000ABC\000"),
307+
308+
tagWriteData001("F001", "a\nb\n", False, False, False, ["c", "d"], "a\nb\nc\nd\n"),
309+
tagWriteData001("F002", b"a\nb\n", False, False, True, [b"c", b"d"], b"a\nb\nc\nd\n"),
310+
311+
tagWriteData001("G001", "a\nb\n", False, False, False, ["c\n\n", "d\n"], "a\nb\nc\nd\n"),
312+
tagWriteData001("G002", b"a\nb\n", False, False, True, [b"c\n\n", b"d\n"], b"a\nb\nc\nd\n"),
313+
]
314+
315+
@pytest.fixture(
316+
params=sm_write_data001,
317+
ids=[x.sign for x in sm_write_data001],
318+
)
319+
def write_data001(self, request):
320+
assert isinstance(request, pytest.FixtureRequest)
321+
assert type(request.param) == __class__.tagWriteData001 # noqa: E721
322+
return request.param
323+
324+
def test_write(self, write_data001):
325+
assert type(write_data001) == __class__.tagWriteData001 # noqa: E721
326+
327+
mode = "w+b" if write_data001.call_param__binary else "w+"
328+
329+
with tempfile.NamedTemporaryFile(mode=mode, delete=True) as tmp_file:
330+
tmp_file.write(write_data001.source)
331+
tmp_file.flush()
332+
333+
self.operations.write(
334+
tmp_file.name,
335+
write_data001.call_param__data,
336+
read_and_write=write_data001.call_param__rw,
337+
truncate=write_data001.call_param__truncate,
338+
binary=write_data001.call_param__binary)
339+
340+
tmp_file.seek(0)
341+
342+
s = tmp_file.read()
343+
344+
assert s == write_data001.result

tests/test_remote.py

+69
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44
import re
5+
import tempfile
56

67
from testgres import ExecUtilException
78
from testgres import InvalidOperationException
@@ -402,3 +403,71 @@ def test_cwd(self):
402403
assert v is not None
403404
assert type(v) == str # noqa: E721
404405
assert v != ""
406+
407+
class tagWriteData001:
408+
def __init__(self, sign, source, cp_rw, cp_truncate, cp_binary, cp_data, result):
409+
self.sign = sign
410+
self.source = source
411+
self.call_param__rw = cp_rw
412+
self.call_param__truncate = cp_truncate
413+
self.call_param__binary = cp_binary
414+
self.call_param__data = cp_data
415+
self.result = result
416+
417+
sm_write_data001 = [
418+
tagWriteData001("A001", "1234567890", False, False, False, "ABC", "1234567890ABC"),
419+
tagWriteData001("A002", b"1234567890", False, False, True, b"ABC", b"1234567890ABC"),
420+
421+
tagWriteData001("B001", "1234567890", False, True, False, "ABC", "ABC"),
422+
tagWriteData001("B002", "1234567890", False, True, False, "ABC1234567890", "ABC1234567890"),
423+
tagWriteData001("B003", b"1234567890", False, True, True, b"ABC", b"ABC"),
424+
tagWriteData001("B004", b"1234567890", False, True, True, b"ABC1234567890", b"ABC1234567890"),
425+
426+
tagWriteData001("C001", "1234567890", True, False, False, "ABC", "1234567890ABC"),
427+
tagWriteData001("C002", b"1234567890", True, False, True, b"ABC", b"1234567890ABC"),
428+
429+
tagWriteData001("D001", "1234567890", True, True, False, "ABC", "ABC"),
430+
tagWriteData001("D002", "1234567890", True, True, False, "ABC1234567890", "ABC1234567890"),
431+
tagWriteData001("D003", b"1234567890", True, True, True, b"ABC", b"ABC"),
432+
tagWriteData001("D004", b"1234567890", True, True, True, b"ABC1234567890", b"ABC1234567890"),
433+
434+
tagWriteData001("E001", "\0001234567890\000", False, False, False, "\000ABC\000", "\0001234567890\000\000ABC\000"),
435+
tagWriteData001("E002", b"\0001234567890\000", False, False, True, b"\000ABC\000", b"\0001234567890\000\000ABC\000"),
436+
437+
tagWriteData001("F001", "a\nb\n", False, False, False, ["c", "d"], "a\nb\nc\nd\n"),
438+
tagWriteData001("F002", b"a\nb\n", False, False, True, [b"c", b"d"], b"a\nb\nc\nd\n"),
439+
440+
tagWriteData001("G001", "a\nb\n", False, False, False, ["c\n\n", "d\n"], "a\nb\nc\nd\n"),
441+
tagWriteData001("G002", b"a\nb\n", False, False, True, [b"c\n\n", b"d\n"], b"a\nb\nc\nd\n"),
442+
]
443+
444+
@pytest.fixture(
445+
params=sm_write_data001,
446+
ids=[x.sign for x in sm_write_data001],
447+
)
448+
def write_data001(self, request):
449+
assert isinstance(request, pytest.FixtureRequest)
450+
assert type(request.param) == __class__.tagWriteData001 # noqa: E721
451+
return request.param
452+
453+
def test_write(self, write_data001):
454+
assert type(write_data001) == __class__.tagWriteData001 # noqa: E721
455+
456+
mode = "w+b" if write_data001.call_param__binary else "w+"
457+
458+
with tempfile.NamedTemporaryFile(mode=mode, delete=True) as tmp_file:
459+
tmp_file.write(write_data001.source)
460+
tmp_file.flush()
461+
462+
self.operations.write(
463+
tmp_file.name,
464+
write_data001.call_param__data,
465+
read_and_write=write_data001.call_param__rw,
466+
truncate=write_data001.call_param__truncate,
467+
binary=write_data001.call_param__binary)
468+
469+
tmp_file.seek(0)
470+
471+
s = tmp_file.read()
472+
473+
assert s == write_data001.result

0 commit comments

Comments
 (0)