diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2019-05-31 18:39:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-31 18:39:47 (GMT) |
commit | aac4d0342c3e692731c189d003dbd73a8c681a34 (patch) | |
tree | b888c0e2423d1b3422765db1cea5f3e0cf5c97f4 /Lib/test | |
parent | 545a3b8814dbf2a5391e830d69e796fb1a1d62ec (diff) | |
download | cpython-aac4d0342c3e692731c189d003dbd73a8c681a34.zip cpython-aac4d0342c3e692731c189d003dbd73a8c681a34.tar.gz cpython-aac4d0342c3e692731c189d003dbd73a8c681a34.tar.bz2 |
bpo-26826: Expose copy_file_range in the os module (GH-7255)
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_os.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index f17a19a..a8eae61 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -231,6 +231,89 @@ class FileTests(unittest.TestCase): except (NotImplementedError, OSError): pass # No OS support or unprivileged user + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range_invalid_values(self): + with self.assertRaises(ValueError): + os.copy_file_range(0, 1, -10) + + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range(self): + TESTFN2 = support.TESTFN + ".3" + data = b'0123456789' + + create_file(support.TESTFN, data) + self.addCleanup(support.unlink, support.TESTFN) + + in_file = open(support.TESTFN, 'rb') + self.addCleanup(in_file.close) + in_fd = in_file.fileno() + + out_file = open(TESTFN2, 'w+b') + self.addCleanup(support.unlink, TESTFN2) + self.addCleanup(out_file.close) + out_fd = out_file.fileno() + + try: + i = os.copy_file_range(in_fd, out_fd, 5) + except OSError as e: + # Handle the case in which Python was compiled + # in a system with the syscall but without support + # in the kernel. + if e.errno != errno.ENOSYS: + raise + self.skipTest(e) + else: + # The number of copied bytes can be less than + # the number of bytes originally requested. + self.assertIn(i, range(0, 6)); + + with open(TESTFN2, 'rb') as in_file: + self.assertEqual(in_file.read(), data[:i]) + + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range_offset(self): + TESTFN4 = support.TESTFN + ".4" + data = b'0123456789' + bytes_to_copy = 6 + in_skip = 3 + out_seek = 5 + + create_file(support.TESTFN, data) + self.addCleanup(support.unlink, support.TESTFN) + + in_file = open(support.TESTFN, 'rb') + self.addCleanup(in_file.close) + in_fd = in_file.fileno() + + out_file = open(TESTFN4, 'w+b') + self.addCleanup(support.unlink, TESTFN4) + self.addCleanup(out_file.close) + out_fd = out_file.fileno() + + try: + i = os.copy_file_range(in_fd, out_fd, bytes_to_copy, + offset_src=in_skip, + offset_dst=out_seek) + except OSError as e: + # Handle the case in which Python was compiled + # in a system with the syscall but without support + # in the kernel. + if e.errno != errno.ENOSYS: + raise + self.skipTest(e) + else: + # The number of copied bytes can be less than + # the number of bytes originally requested. + self.assertIn(i, range(0, bytes_to_copy+1)); + + with open(TESTFN4, 'rb') as in_file: + read = in_file.read() + # seeked bytes (5) are zero'ed + self.assertEqual(read[:out_seek], b'\x00'*out_seek) + # 012 are skipped (in_skip) + # 345678 are copied in the file (in_skip + bytes_to_copy) + self.assertEqual(read[out_seek:], + data[in_skip:in_skip+i]) # Test attributes on return values from os.*stat* family. class StatAttributeTests(unittest.TestCase): |