bpo-37096: Add large-file tests for modules using sendfile(2) (GH-13676) · python/cpython@5bcc6d8

@@ -5,17 +5,19 @@

55

import stat

66

import sys

77

import unittest

8-

from test.support import TESTFN, requires, unlink, bigmemtest

8+

import socket

9+

import shutil

10+

import threading

11+

from test.support import TESTFN, requires, unlink, bigmemtest, find_unused_port

912

import io # C implementation of io

1013

import _pyio as pyio # Python implementation of io

11141215

# size of file to create (>2 GiB; 2 GiB == 2,147,483,648 bytes)

1316

size = 2_500_000_000

17+

TESTFN2 = TESTFN + '2'

18+14191520

class LargeFileTest:

16-

"""Test that each file function works as expected for large

17-

(i.e. > 2 GiB) files.

18-

"""

19212022

def setUp(self):

2123

if os.path.exists(TESTFN):

@@ -44,6 +46,13 @@ def tearDownClass(cls):

4446

if not os.stat(TESTFN)[stat.ST_SIZE] == 0:

4547

raise cls.failureException('File was not truncated by opening '

4648

'with mode "wb"')

49+

unlink(TESTFN2)

50+51+52+

class TestFileMethods(LargeFileTest):

53+

"""Test that each file function works as expected for large

54+

(i.e. > 2 GiB) files.

55+

"""

47564857

# _pyio.FileIO.readall() uses a temporary bytearray then casted to bytes,

4958

# so memuse=2 is needed

@@ -140,6 +149,72 @@ def test_seekable(self):

140149

f.seek(pos)

141150

self.assertTrue(f.seekable())

142151152+153+

class TestCopyfile(LargeFileTest, unittest.TestCase):

154+

open = staticmethod(io.open)

155+156+

def test_it(self):

157+

# Internally shutil.copyfile() can use "fast copy" methods like

158+

# os.sendfile().

159+

size = os.path.getsize(TESTFN)

160+

shutil.copyfile(TESTFN, TESTFN2)

161+

self.assertEqual(os.path.getsize(TESTFN2), size)

162+

with open(TESTFN2, 'rb') as f:

163+

self.assertEqual(f.read(5), b'z\x00\x00\x00\x00')

164+

f.seek(size - 5)

165+

self.assertEqual(f.read(), b'\x00\x00\x00\x00a')

166+167+168+

@unittest.skipIf(not hasattr(os, 'sendfile'), 'sendfile not supported')

169+

class TestSocketSendfile(LargeFileTest, unittest.TestCase):

170+

open = staticmethod(io.open)

171+

timeout = 3

172+173+

def setUp(self):

174+

super().setUp()

175+

self.thread = None

176+177+

def tearDown(self):

178+

super().tearDown()

179+

if self.thread is not None:

180+

self.thread.join(self.timeout)

181+

self.thread = None

182+183+

def tcp_server(self, sock):

184+

def run(sock):

185+

with sock:

186+

conn, _ = sock.accept()

187+

with conn, open(TESTFN2, 'wb') as f:

188+

event.wait(self.timeout)

189+

while True:

190+

chunk = conn.recv(65536)

191+

if not chunk:

192+

return

193+

f.write(chunk)

194+195+

event = threading.Event()

196+

sock.settimeout(self.timeout)

197+

self.thread = threading.Thread(target=run, args=(sock, ))

198+

self.thread.start()

199+

event.set()

200+201+

def test_it(self):

202+

port = find_unused_port()

203+

with socket.create_server(("", port)) as sock:

204+

self.tcp_server(sock)

205+

with socket.create_connection(("127.0.0.1", port)) as client:

206+

with open(TESTFN, 'rb') as f:

207+

client.sendfile(f)

208+

self.tearDown()

209+210+

size = os.path.getsize(TESTFN)

211+

self.assertEqual(os.path.getsize(TESTFN2), size)

212+

with open(TESTFN2, 'rb') as f:

213+

self.assertEqual(f.read(5), b'z\x00\x00\x00\x00')

214+

f.seek(size - 5)

215+

self.assertEqual(f.read(), b'\x00\x00\x00\x00a')

216+217+143218

def setUpModule():

144219

try:

145220

import signal

@@ -176,14 +251,18 @@ def setUpModule():

176251

unlink(TESTFN)

177252178253179-

class CLargeFileTest(LargeFileTest, unittest.TestCase):

254+

class CLargeFileTest(TestFileMethods, unittest.TestCase):

180255

open = staticmethod(io.open)

181256182-

class PyLargeFileTest(LargeFileTest, unittest.TestCase):

257+258+

class PyLargeFileTest(TestFileMethods, unittest.TestCase):

183259

open = staticmethod(pyio.open)

184260261+185262

def tearDownModule():

186263

unlink(TESTFN)

264+

unlink(TESTFN2)

265+187266188267

if __name__ == '__main__':

189268

unittest.main()