blob: f6ee3717504d4ef9dd4be9d3c20cfcf7b0ce4ed1 [file] [log] [blame]
Thomas Wouters89f507f2006-12-13 04:49:30 +00001from test.test_support import TESTFN, run_unittest
Andrew M. Kuchlinge81b9cf2000-03-30 21:15:29 +00002import mmap
Thomas Wouters89f507f2006-12-13 04:49:30 +00003import unittest
Fred Drake62787992001-05-11 14:29:21 +00004import os, re
Andrew M. Kuchlinge81b9cf2000-03-30 21:15:29 +00005
6PAGESIZE = mmap.PAGESIZE
7
Thomas Wouters89f507f2006-12-13 04:49:30 +00008class MmapTests(unittest.TestCase):
Fred Drake004d5e62000-10-23 17:22:08 +00009
Thomas Wouters89f507f2006-12-13 04:49:30 +000010 def setUp(self):
11 if os.path.exists(TESTFN):
12 os.unlink(TESTFN)
Fred Drake004d5e62000-10-23 17:22:08 +000013
Thomas Wouters89f507f2006-12-13 04:49:30 +000014 def tearDown(self):
Tim Petersfd692082001-05-10 20:03:04 +000015 try:
Fred Drake62787992001-05-11 14:29:21 +000016 os.unlink(TESTFN)
Tim Petersfd692082001-05-10 20:03:04 +000017 except OSError:
18 pass
19
Thomas Wouters89f507f2006-12-13 04:49:30 +000020 def test_basic(self):
21 # Test mmap module on Unix systems and Windows
22
23 # Create a file to be mmap'ed.
Guido van Rossumb358a2c2007-07-16 19:29:02 +000024 f = open(TESTFN, 'bw+')
Thomas Wouters89f507f2006-12-13 04:49:30 +000025 try:
26 # Write 2 pages worth of data to the file
Guido van Rossumb358a2c2007-07-16 19:29:02 +000027 f.write(b'\0'* PAGESIZE)
28 f.write(b'foo')
29 f.write(b'\0'* (PAGESIZE-3) )
Thomas Wouters89f507f2006-12-13 04:49:30 +000030 f.flush()
31 m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
Guido van Rossum456fe5d2007-07-16 19:42:05 +000032 finally:
Thomas Wouters89f507f2006-12-13 04:49:30 +000033 f.close()
34
Guido van Rossum456fe5d2007-07-16 19:42:05 +000035 # Simple sanity checks
Thomas Wouters89f507f2006-12-13 04:49:30 +000036
Guido van Rossum456fe5d2007-07-16 19:42:05 +000037 tp = str(type(m)) # SF bug 128713: segfaulted on Linux
38 self.assertEqual(m.find('foo'), PAGESIZE)
Thomas Wouters89f507f2006-12-13 04:49:30 +000039
Guido van Rossum456fe5d2007-07-16 19:42:05 +000040 self.assertEqual(len(m), 2*PAGESIZE)
Thomas Wouters89f507f2006-12-13 04:49:30 +000041
Guido van Rossum98297ee2007-11-06 21:34:58 +000042 self.assertEqual(m[0], 0)
Guido van Rossum456fe5d2007-07-16 19:42:05 +000043 self.assertEqual(m[0:3], b'\0\0\0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000044
Guido van Rossum456fe5d2007-07-16 19:42:05 +000045 # Modify the file's content
Guido van Rossum98297ee2007-11-06 21:34:58 +000046 m[0] = b'3'[0]
Guido van Rossum456fe5d2007-07-16 19:42:05 +000047 m[PAGESIZE +3: PAGESIZE +3+3] = b'bar'
Thomas Wouters89f507f2006-12-13 04:49:30 +000048
Guido van Rossum456fe5d2007-07-16 19:42:05 +000049 # Check that the modification worked
Guido van Rossum98297ee2007-11-06 21:34:58 +000050 self.assertEqual(m[0], b'3'[0])
Guido van Rossum456fe5d2007-07-16 19:42:05 +000051 self.assertEqual(m[0:3], b'3\0\0')
52 self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], b'\0foobar\0')
Thomas Wouters89f507f2006-12-13 04:49:30 +000053
Guido van Rossum456fe5d2007-07-16 19:42:05 +000054 m.flush()
Thomas Wouters89f507f2006-12-13 04:49:30 +000055
Guido van Rossum456fe5d2007-07-16 19:42:05 +000056 # Test doing a regular expression match in an mmap'ed file
57 match = re.search('[A-Za-z]+', m)
58 if match is None:
59 self.fail('regex match on mmap failed!')
60 else:
61 start, end = match.span(0)
62 length = end - start
Thomas Wouters89f507f2006-12-13 04:49:30 +000063
Guido van Rossum456fe5d2007-07-16 19:42:05 +000064 self.assertEqual(start, PAGESIZE)
65 self.assertEqual(end, PAGESIZE + 6)
Thomas Wouters89f507f2006-12-13 04:49:30 +000066
Guido van Rossum456fe5d2007-07-16 19:42:05 +000067 # test seeking around (try to overflow the seek implementation)
68 m.seek(0,0)
69 self.assertEqual(m.tell(), 0)
70 m.seek(42,1)
71 self.assertEqual(m.tell(), 42)
72 m.seek(0,2)
73 self.assertEqual(m.tell(), len(m))
Thomas Wouters89f507f2006-12-13 04:49:30 +000074
Guido van Rossum456fe5d2007-07-16 19:42:05 +000075 # Try to seek to negative position...
76 self.assertRaises(ValueError, m.seek, -1)
Thomas Wouters89f507f2006-12-13 04:49:30 +000077
Guido van Rossum456fe5d2007-07-16 19:42:05 +000078 # Try to seek beyond end of mmap...
79 self.assertRaises(ValueError, m.seek, 1, 2)
Thomas Wouters89f507f2006-12-13 04:49:30 +000080
Guido van Rossum456fe5d2007-07-16 19:42:05 +000081 # Try to seek to negative position...
82 self.assertRaises(ValueError, m.seek, -len(m)-1, 2)
Thomas Wouters89f507f2006-12-13 04:49:30 +000083
Guido van Rossum456fe5d2007-07-16 19:42:05 +000084 # Try resizing map
85 try:
86 m.resize(512)
87 except SystemError:
88 # resize() not supported
89 # No messages are printed, since the output of this test suite
90 # would then be different across platforms.
91 pass
92 else:
93 # resize() is supported
94 self.assertEqual(len(m), 512)
95 # Check that we can no longer seek beyond the new size.
96 self.assertRaises(ValueError, m.seek, 513, 0)
97
98 # Check that the underlying file is truncated too
99 # (bug #728515)
100 f = open(TESTFN)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000101 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000102 f.seek(0, 2)
103 self.assertEqual(f.tell(), 512)
Guido van Rossum456fe5d2007-07-16 19:42:05 +0000104 finally:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000105 f.close()
Guido van Rossum456fe5d2007-07-16 19:42:05 +0000106 self.assertEqual(m.size(), 512)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000107
Guido van Rossum456fe5d2007-07-16 19:42:05 +0000108 m.close()
Thomas Wouters89f507f2006-12-13 04:49:30 +0000109
110 def test_access_parameter(self):
111 # Test for "access" keyword parameter
Tim Peters5ebfd362001-11-13 23:11:19 +0000112 mapsize = 10
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000113 open(TESTFN, "wb").write(b"a"*mapsize)
Tim Peters5ebfd362001-11-13 23:11:19 +0000114 f = open(TESTFN, "rb")
115 m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000116 self.assertEqual(m[:], b'a'*mapsize, "Readonly memory map data incorrect.")
Tim Peters5ebfd362001-11-13 23:11:19 +0000117
Thomas Wouters89f507f2006-12-13 04:49:30 +0000118 # Ensuring that readonly mmap can't be slice assigned
Tim Peters5ebfd362001-11-13 23:11:19 +0000119 try:
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000120 m[:] = b'b'*mapsize
Tim Peters5ebfd362001-11-13 23:11:19 +0000121 except TypeError:
122 pass
123 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000124 self.fail("Able to write to readonly memory map")
Tim Peters5ebfd362001-11-13 23:11:19 +0000125
Thomas Wouters89f507f2006-12-13 04:49:30 +0000126 # Ensuring that readonly mmap can't be item assigned
Tim Peters5ebfd362001-11-13 23:11:19 +0000127 try:
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000128 m[0] = b'b'
Tim Peters5ebfd362001-11-13 23:11:19 +0000129 except TypeError:
130 pass
131 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000132 self.fail("Able to write to readonly memory map")
Tim Peters5ebfd362001-11-13 23:11:19 +0000133
Thomas Wouters89f507f2006-12-13 04:49:30 +0000134 # Ensuring that readonly mmap can't be write() to
Tim Peters5ebfd362001-11-13 23:11:19 +0000135 try:
136 m.seek(0,0)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000137 m.write(b'abc')
Tim Peters5ebfd362001-11-13 23:11:19 +0000138 except TypeError:
139 pass
140 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000141 self.fail("Able to write to readonly memory map")
Tim Peters5ebfd362001-11-13 23:11:19 +0000142
Thomas Wouters89f507f2006-12-13 04:49:30 +0000143 # Ensuring that readonly mmap can't be write_byte() to
Tim Peters5ebfd362001-11-13 23:11:19 +0000144 try:
145 m.seek(0,0)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000146 m.write_byte(b'd')
Tim Peters5ebfd362001-11-13 23:11:19 +0000147 except TypeError:
148 pass
149 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000150 self.fail("Able to write to readonly memory map")
Tim Peters5ebfd362001-11-13 23:11:19 +0000151
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 # Ensuring that readonly mmap can't be resized
Tim Peters5ebfd362001-11-13 23:11:19 +0000153 try:
154 m.resize(2*mapsize)
155 except SystemError: # resize is not universally supported
156 pass
157 except TypeError:
158 pass
159 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000160 self.fail("Able to resize readonly memory map")
Tim Peters5ebfd362001-11-13 23:11:19 +0000161 del m, f
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000162 self.assertEqual(open(TESTFN, "rb").read(), b'a'*mapsize,
Tim Peters5ebfd362001-11-13 23:11:19 +0000163 "Readonly memory map data file was modified")
164
Thomas Wouters89f507f2006-12-13 04:49:30 +0000165 # Opening mmap with size too big
Neal Norwitzb5673922002-09-05 21:48:07 +0000166 import sys
167 f = open(TESTFN, "r+b")
168 try:
169 m = mmap.mmap(f.fileno(), mapsize+1)
170 except ValueError:
171 # we do not expect a ValueError on Windows
Tim Peters4f4f4d72002-09-10 20:49:15 +0000172 # CAUTION: This also changes the size of the file on disk, and
173 # later tests assume that the length hasn't changed. We need to
174 # repair that.
Neal Norwitzb5673922002-09-05 21:48:07 +0000175 if sys.platform.startswith('win'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000176 self.fail("Opening mmap with size+1 should work on Windows.")
Neal Norwitzb5673922002-09-05 21:48:07 +0000177 else:
178 # we expect a ValueError on Unix, but not on Windows
179 if not sys.platform.startswith('win'):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000180 self.fail("Opening mmap with size+1 should raise ValueError.")
Barry Warsawccd9e752002-09-11 02:56:42 +0000181 m.close()
Tim Peters4f4f4d72002-09-10 20:49:15 +0000182 f.close()
183 if sys.platform.startswith('win'):
184 # Repair damage from the resizing test.
185 f = open(TESTFN, 'r+b')
186 f.truncate(mapsize)
187 f.close()
Neal Norwitzb5673922002-09-05 21:48:07 +0000188
Thomas Wouters89f507f2006-12-13 04:49:30 +0000189 # Opening mmap with access=ACCESS_WRITE
Tim Peters5ebfd362001-11-13 23:11:19 +0000190 f = open(TESTFN, "r+b")
191 m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000192 # Modifying write-through memory map
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000193 m[:] = b'c'*mapsize
194 self.assertEqual(m[:], b'c'*mapsize,
Tim Peters5ebfd362001-11-13 23:11:19 +0000195 "Write-through memory map memory not updated properly.")
196 m.flush()
Tim Peters1b5112a2002-09-10 21:19:55 +0000197 m.close()
198 f.close()
Tim Peters4f4f4d72002-09-10 20:49:15 +0000199 f = open(TESTFN, 'rb')
200 stuff = f.read()
201 f.close()
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000202 self.assertEqual(stuff, b'c'*mapsize,
Tim Peters5ebfd362001-11-13 23:11:19 +0000203 "Write-through memory map data file not updated properly.")
204
Thomas Wouters89f507f2006-12-13 04:49:30 +0000205 # Opening mmap with access=ACCESS_COPY
Tim Peters5ebfd362001-11-13 23:11:19 +0000206 f = open(TESTFN, "r+b")
207 m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000208 # Modifying copy-on-write memory map
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000209 m[:] = b'd'*mapsize
210 self.assertEqual(m[:], b'd' * mapsize,
Tim Peters5ebfd362001-11-13 23:11:19 +0000211 "Copy-on-write memory map data not written correctly.")
212 m.flush()
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000213 self.assertEqual(open(TESTFN, "rb").read(), b'c'*mapsize,
Tim Peters5ebfd362001-11-13 23:11:19 +0000214 "Copy-on-write test data file should not be modified.")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000215 # Ensuring copy-on-write maps cannot be resized
216 self.assertRaises(TypeError, m.resize, 2*mapsize)
Tim Peters5ebfd362001-11-13 23:11:19 +0000217 del m, f
Thomas Wouters89f507f2006-12-13 04:49:30 +0000218
219 # Ensuring invalid access parameter raises exception
220 f = open(TESTFN, "r+b")
221 self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
222 f.close()
Tim Peters5ebfd362001-11-13 23:11:19 +0000223
224 if os.name == "posix":
Tim Peters00cafa02001-11-13 23:39:47 +0000225 # Try incompatible flags, prot and access parameters.
226 f = open(TESTFN, "r+b")
Thomas Wouters89f507f2006-12-13 04:49:30 +0000227 self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize,
228 flags=mmap.MAP_PRIVATE,
Tim Peters5ebfd362001-11-13 23:11:19 +0000229 prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
Tim Peters5379dea2002-04-18 04:30:18 +0000230 f.close()
Tim Peters5ebfd362001-11-13 23:11:19 +0000231
Thomas Wouters89f507f2006-12-13 04:49:30 +0000232 def test_bad_file_desc(self):
233 # Try opening a bad file descriptor...
234 self.assertRaises(mmap.error, mmap.mmap, -2, 4096)
Neal Norwitz3b4fff82006-01-11 08:54:45 +0000235
Thomas Wouters89f507f2006-12-13 04:49:30 +0000236 def test_tougher_find(self):
237 # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
238 # searching for data with embedded \0 bytes didn't work.
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000239 f = open(TESTFN, 'wb+')
Tim Petersc9ffa062002-03-08 05:43:32 +0000240
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000241 data = b'aabaac\x00deef\x00\x00aa\x00'
Tim Petersc9ffa062002-03-08 05:43:32 +0000242 n = len(data)
243 f.write(data)
Tim Peters5379dea2002-04-18 04:30:18 +0000244 f.flush()
Tim Petersc9ffa062002-03-08 05:43:32 +0000245 m = mmap.mmap(f.fileno(), n)
246 f.close()
247
248 for start in range(n+1):
249 for finish in range(start, n+1):
250 slice = data[start : finish]
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251 self.assertEqual(m.find(slice), data.find(slice))
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000252 self.assertEqual(m.find(slice + b'x'), -1)
Tim Petersddc82ea2003-01-13 21:38:45 +0000253 m.close()
Tim Petersc9ffa062002-03-08 05:43:32 +0000254
Georg Brandlfceab5a2008-01-19 20:08:23 +0000255 def test_find_end(self):
256 # test the new 'end' parameter works as expected
257 f = open(TESTFN, 'w+')
258 data = 'one two ones'
259 n = len(data)
260 f.write(data)
261 f.flush()
262 m = mmap.mmap(f.fileno(), n)
263 f.close()
264
265 self.assertEqual(m.find('one'), 0)
266 self.assertEqual(m.find('ones'), 8)
267 self.assertEqual(m.find('one', 0, -1), 0)
268 self.assertEqual(m.find('one', 1), 8)
269 self.assertEqual(m.find('one', 1, -1), 8)
270 self.assertEqual(m.find('one', 1, -2), -1)
271
272
273 def test_rfind(self):
274 # test the new 'end' parameter works as expected
275 f = open(TESTFN, 'w+')
276 data = 'one two ones'
277 n = len(data)
278 f.write(data)
279 f.flush()
280 m = mmap.mmap(f.fileno(), n)
281 f.close()
282
283 self.assertEqual(m.rfind('one'), 8)
284 self.assertEqual(m.rfind('one '), 0)
285 self.assertEqual(m.rfind('one', 0, -1), 8)
286 self.assertEqual(m.rfind('one', 0, -2), 0)
287 self.assertEqual(m.rfind('one', 1, -1), 8)
288 self.assertEqual(m.rfind('one', 1, -2), -1)
289
290
Thomas Wouters89f507f2006-12-13 04:49:30 +0000291 def test_double_close(self):
292 # make sure a double close doesn't crash on Solaris (Bug# 665913)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000293 f = open(TESTFN, 'wb+')
Tim Petersc9ffa062002-03-08 05:43:32 +0000294
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000295 f.write(2**16 * b'a') # Arbitrary character
Neal Norwitze604c022003-01-10 20:52:16 +0000296 f.close()
297
298 f = open(TESTFN)
Tim Petersddc82ea2003-01-13 21:38:45 +0000299 mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ)
Neal Norwitze604c022003-01-10 20:52:16 +0000300 mf.close()
301 mf.close()
302 f.close()
303
Thomas Wouters89f507f2006-12-13 04:49:30 +0000304 def test_entire_file(self):
305 # test mapping of entire file by passing 0 for map length
306 if hasattr(os, "stat"):
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000307 f = open(TESTFN, "wb+")
Tim Petersc9ffa062002-03-08 05:43:32 +0000308
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000309 f.write(2**16 * b'm') # Arbitrary character
Martin v. Löwis7fe60c02005-03-03 11:22:44 +0000310 f.close()
311
312 f = open(TESTFN, "rb+")
Tim Peterseba28be2005-03-28 01:08:02 +0000313 mf = mmap.mmap(f.fileno(), 0)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000314 self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000315 self.assertEqual(mf.read(2**16), 2**16 * b"m")
Martin v. Löwis7fe60c02005-03-03 11:22:44 +0000316 mf.close()
317 f.close()
318
Thomas Wouters89f507f2006-12-13 04:49:30 +0000319 def test_move(self):
320 # make move works everywhere (64-bit format problem earlier)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000321 f = open(TESTFN, 'wb+')
Tim Peterseba28be2005-03-28 01:08:02 +0000322
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000323 f.write(b"ABCDEabcde") # Arbitrary character
Neal Norwitz8856fb72005-12-18 03:34:22 +0000324 f.flush()
325
326 mf = mmap.mmap(f.fileno(), 10)
327 mf.move(5, 0, 5)
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000328 self.assertEqual(mf[:], b"ABCDEABCDE", "Map move should have duplicated front 5")
Neal Norwitz8856fb72005-12-18 03:34:22 +0000329 mf.close()
330 f.close()
331
Thomas Wouters89f507f2006-12-13 04:49:30 +0000332 def test_anonymous(self):
333 # anonymous mmap.mmap(-1, PAGE)
334 m = mmap.mmap(-1, PAGESIZE)
Guido van Rossum805365e2007-05-07 22:24:25 +0000335 for x in range(PAGESIZE):
Guido van Rossum98297ee2007-11-06 21:34:58 +0000336 self.assertEqual(m[x], 0,
337 "anonymously mmap'ed contents should be zero")
Neal Norwitz8856fb72005-12-18 03:34:22 +0000338
Guido van Rossum805365e2007-05-07 22:24:25 +0000339 for x in range(PAGESIZE):
Guido van Rossum98297ee2007-11-06 21:34:58 +0000340 b = x & 0xff
Guido van Rossumb358a2c2007-07-16 19:29:02 +0000341 m[x] = b
342 self.assertEqual(m[x], b)
Neal Norwitz0e6bc8c2006-02-05 05:45:43 +0000343
Thomas Woutersed03b412007-08-28 21:37:11 +0000344 def test_extended_getslice(self):
345 # Test extended slicing by comparing with list slicing.
346 s = bytes(reversed(range(256)))
347 m = mmap.mmap(-1, len(s))
348 m[:] = s
349 self.assertEqual(m[:], s)
350 indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
351 for start in indices:
352 for stop in indices:
353 # Skip step 0 (invalid)
354 for step in indices[1:]:
355 self.assertEqual(m[start:stop:step],
356 s[start:stop:step])
357
358 def test_extended_set_del_slice(self):
359 # Test extended slicing by comparing with list slicing.
360 s = bytes(reversed(range(256)))
361 m = mmap.mmap(-1, len(s))
362 indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
363 for start in indices:
364 for stop in indices:
365 # Skip invalid step 0
366 for step in indices[1:]:
367 m[:] = s
368 self.assertEqual(m[:], s)
369 L = list(s)
370 # Make sure we have a slice of exactly the right length,
371 # but with different data.
372 data = L[start:stop:step]
373 data = bytes(reversed(data))
374 L[start:stop:step] = data
375 m[start:stop:step] = data
376 self.assertEquals(m[:], bytes(L))
377
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000378 def make_mmap_file (self, f, halfsize):
379 # Write 2 pages worth of data to the file
380 f.write (b'\0' * halfsize)
381 f.write (b'foo')
382 f.write (b'\0' * (halfsize - 3))
383 f.flush ()
384 return mmap.mmap (f.fileno(), 0)
385
386 def test_offset (self):
387 f = open (TESTFN, 'w+b')
388
389 try: # unlink TESTFN no matter what
390 halfsize = mmap.ALLOCATIONGRANULARITY
391 m = self.make_mmap_file (f, halfsize)
392 m.close ()
393 f.close ()
394
395 mapsize = halfsize * 2
396 # Try invalid offset
397 f = open(TESTFN, "r+b")
398 for offset in [-2, -1, None]:
399 try:
400 m = mmap.mmap(f.fileno(), mapsize, offset=offset)
401 self.assertEqual(0, 1)
402 except (ValueError, TypeError, OverflowError):
403 pass
404 else:
405 self.assertEqual(0, 0)
406 f.close()
407
408 # Try valid offset, hopefully 8192 works on all OSes
409 f = open(TESTFN, "r+b")
410 m = mmap.mmap(f.fileno(), mapsize - halfsize, offset=halfsize)
411 self.assertEqual(m[0:3], b'foo')
412 f.close()
413 m.close()
414
415 finally:
416 f.close()
417 try:
418 os.unlink(TESTFN)
419 except OSError:
420 pass
421
Christian Heimes1af737c2008-01-23 08:24:23 +0000422 def test_subclass(self):
423 class anon_mmap(mmap.mmap):
424 def __new__(klass, *args, **kwargs):
425 return mmap.mmap.__new__(klass, -1, *args, **kwargs)
426 anon_mmap(PAGESIZE)
427
428
Thomas Wouters89f507f2006-12-13 04:49:30 +0000429def test_main():
430 run_unittest(MmapTests)
Andrew M. Kuchlinge81b9cf2000-03-30 21:15:29 +0000431
Thomas Wouters89f507f2006-12-13 04:49:30 +0000432if __name__ == '__main__':
433 test_main()