| Nadeem Vawda | 0d837ef | 2011-05-07 13:17:16 +0200 | [diff] [blame] | 1 | from test.test_support import (TESTFN, run_unittest, import_module, unlink, | 
| Serhiy Storchaka | cbee972 | 2014-08-19 17:03:42 +0300 | [diff] [blame] | 2 |                                requires, _2G, _4G, gc_collect, cpython_only) | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 3 | import unittest | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 4 | import os, re, itertools, socket, sys | 
| Andrew M. Kuchling | e81b9cf | 2000-03-30 21:15:29 +0000 | [diff] [blame] | 5 |  | 
| R. David Murray | 59beec3 | 2009-03-30 19:04:00 +0000 | [diff] [blame] | 6 | mmap = import_module('mmap') | 
 | 7 |  | 
| Andrew M. Kuchling | e81b9cf | 2000-03-30 21:15:29 +0000 | [diff] [blame] | 8 | PAGESIZE = mmap.PAGESIZE | 
 | 9 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 10 | class MmapTests(unittest.TestCase): | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 11 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 12 |     def setUp(self): | 
 | 13 |         if os.path.exists(TESTFN): | 
 | 14 |             os.unlink(TESTFN) | 
| Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 15 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 16 |     def tearDown(self): | 
| Tim Peters | fd69208 | 2001-05-10 20:03:04 +0000 | [diff] [blame] | 17 |         try: | 
| Fred Drake | 6278799 | 2001-05-11 14:29:21 +0000 | [diff] [blame] | 18 |             os.unlink(TESTFN) | 
| Tim Peters | fd69208 | 2001-05-10 20:03:04 +0000 | [diff] [blame] | 19 |         except OSError: | 
 | 20 |             pass | 
 | 21 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 22 |     def test_basic(self): | 
 | 23 |         # Test mmap module on Unix systems and Windows | 
 | 24 |  | 
 | 25 |         # Create a file to be mmap'ed. | 
 | 26 |         f = open(TESTFN, 'w+') | 
 | 27 |         try: | 
 | 28 |             # Write 2 pages worth of data to the file | 
 | 29 |             f.write('\0'* PAGESIZE) | 
 | 30 |             f.write('foo') | 
 | 31 |             f.write('\0'* (PAGESIZE-3) ) | 
 | 32 |             f.flush() | 
 | 33 |             m = mmap.mmap(f.fileno(), 2 * PAGESIZE) | 
 | 34 |             f.close() | 
 | 35 |  | 
 | 36 |             # Simple sanity checks | 
 | 37 |  | 
 | 38 |             tp = str(type(m))  # SF bug 128713:  segfaulted on Linux | 
 | 39 |             self.assertEqual(m.find('foo'), PAGESIZE) | 
 | 40 |  | 
 | 41 |             self.assertEqual(len(m), 2*PAGESIZE) | 
 | 42 |  | 
 | 43 |             self.assertEqual(m[0], '\0') | 
 | 44 |             self.assertEqual(m[0:3], '\0\0\0') | 
 | 45 |  | 
| Hirokazu Yamamoto | f6bbd0e | 2009-02-17 10:12:10 +0000 | [diff] [blame] | 46 |             # Shouldn't crash on boundary (Issue #5292) | 
 | 47 |             self.assertRaises(IndexError, m.__getitem__, len(m)) | 
 | 48 |             self.assertRaises(IndexError, m.__setitem__, len(m), '\0') | 
 | 49 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 50 |             # Modify the file's content | 
 | 51 |             m[0] = '3' | 
 | 52 |             m[PAGESIZE +3: PAGESIZE +3+3] = 'bar' | 
 | 53 |  | 
 | 54 |             # Check that the modification worked | 
 | 55 |             self.assertEqual(m[0], '3') | 
 | 56 |             self.assertEqual(m[0:3], '3\0\0') | 
 | 57 |             self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0') | 
 | 58 |  | 
 | 59 |             m.flush() | 
 | 60 |  | 
 | 61 |             # Test doing a regular expression match in an mmap'ed file | 
 | 62 |             match = re.search('[A-Za-z]+', m) | 
 | 63 |             if match is None: | 
 | 64 |                 self.fail('regex match on mmap failed!') | 
 | 65 |             else: | 
 | 66 |                 start, end = match.span(0) | 
 | 67 |                 length = end - start | 
 | 68 |  | 
 | 69 |                 self.assertEqual(start, PAGESIZE) | 
 | 70 |                 self.assertEqual(end, PAGESIZE + 6) | 
 | 71 |  | 
 | 72 |             # test seeking around (try to overflow the seek implementation) | 
 | 73 |             m.seek(0,0) | 
 | 74 |             self.assertEqual(m.tell(), 0) | 
 | 75 |             m.seek(42,1) | 
 | 76 |             self.assertEqual(m.tell(), 42) | 
 | 77 |             m.seek(0,2) | 
 | 78 |             self.assertEqual(m.tell(), len(m)) | 
 | 79 |  | 
 | 80 |             # Try to seek to negative position... | 
 | 81 |             self.assertRaises(ValueError, m.seek, -1) | 
 | 82 |  | 
 | 83 |             # Try to seek beyond end of mmap... | 
 | 84 |             self.assertRaises(ValueError, m.seek, 1, 2) | 
 | 85 |  | 
 | 86 |             # Try to seek to negative position... | 
 | 87 |             self.assertRaises(ValueError, m.seek, -len(m)-1, 2) | 
 | 88 |  | 
 | 89 |             # Try resizing map | 
 | 90 |             try: | 
 | 91 |                 m.resize(512) | 
 | 92 |             except SystemError: | 
 | 93 |                 # resize() not supported | 
 | 94 |                 # No messages are printed, since the output of this test suite | 
 | 95 |                 # would then be different across platforms. | 
 | 96 |                 pass | 
 | 97 |             else: | 
 | 98 |                 # resize() is supported | 
 | 99 |                 self.assertEqual(len(m), 512) | 
 | 100 |                 # Check that we can no longer seek beyond the new size. | 
 | 101 |                 self.assertRaises(ValueError, m.seek, 513, 0) | 
 | 102 |  | 
 | 103 |                 # Check that the underlying file is truncated too | 
 | 104 |                 # (bug #728515) | 
 | 105 |                 f = open(TESTFN) | 
 | 106 |                 f.seek(0, 2) | 
 | 107 |                 self.assertEqual(f.tell(), 512) | 
 | 108 |                 f.close() | 
 | 109 |                 self.assertEqual(m.size(), 512) | 
 | 110 |  | 
 | 111 |             m.close() | 
 | 112 |  | 
 | 113 |         finally: | 
 | 114 |             try: | 
 | 115 |                 f.close() | 
 | 116 |             except OSError: | 
 | 117 |                 pass | 
 | 118 |  | 
 | 119 |     def test_access_parameter(self): | 
 | 120 |         # Test for "access" keyword parameter | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 121 |         mapsize = 10 | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 122 |         open(TESTFN, "wb").write("a"*mapsize) | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 123 |         f = open(TESTFN, "rb") | 
 | 124 |         m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ) | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 125 |         self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.") | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 126 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 127 |         # Ensuring that readonly mmap can't be slice assigned | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 128 |         try: | 
 | 129 |             m[:] = 'b'*mapsize | 
 | 130 |         except TypeError: | 
 | 131 |             pass | 
 | 132 |         else: | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 133 |             self.fail("Able to write to readonly memory map") | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 134 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 135 |         # Ensuring that readonly mmap can't be item assigned | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 136 |         try: | 
 | 137 |             m[0] = 'b' | 
 | 138 |         except TypeError: | 
 | 139 |             pass | 
 | 140 |         else: | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 141 |             self.fail("Able to write to readonly memory map") | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 142 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 143 |         # Ensuring that readonly mmap can't be write() to | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 144 |         try: | 
 | 145 |             m.seek(0,0) | 
 | 146 |             m.write('abc') | 
 | 147 |         except TypeError: | 
 | 148 |             pass | 
 | 149 |         else: | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 150 |             self.fail("Able to write to readonly memory map") | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 151 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 152 |         # Ensuring that readonly mmap can't be write_byte() to | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 153 |         try: | 
 | 154 |             m.seek(0,0) | 
 | 155 |             m.write_byte('d') | 
 | 156 |         except TypeError: | 
 | 157 |             pass | 
 | 158 |         else: | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 159 |             self.fail("Able to write to readonly memory map") | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 160 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 161 |         # Ensuring that readonly mmap can't be resized | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 162 |         try: | 
 | 163 |             m.resize(2*mapsize) | 
 | 164 |         except SystemError:   # resize is not universally supported | 
 | 165 |             pass | 
 | 166 |         except TypeError: | 
 | 167 |             pass | 
 | 168 |         else: | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 169 |             self.fail("Able to resize readonly memory map") | 
| Neal Norwitz | d48a2f7 | 2008-04-01 05:40:43 +0000 | [diff] [blame] | 170 |         f.close() | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 171 |         del m, f | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 172 |         self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 173 |                "Readonly memory map data file was modified") | 
 | 174 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 175 |         # Opening mmap with size too big | 
| Neal Norwitz | b567392 | 2002-09-05 21:48:07 +0000 | [diff] [blame] | 176 |         import sys | 
 | 177 |         f = open(TESTFN, "r+b") | 
 | 178 |         try: | 
 | 179 |             m = mmap.mmap(f.fileno(), mapsize+1) | 
 | 180 |         except ValueError: | 
 | 181 |             # we do not expect a ValueError on Windows | 
| Tim Peters | 4f4f4d7 | 2002-09-10 20:49:15 +0000 | [diff] [blame] | 182 |             # CAUTION:  This also changes the size of the file on disk, and | 
 | 183 |             # later tests assume that the length hasn't changed.  We need to | 
 | 184 |             # repair that. | 
| Neal Norwitz | b567392 | 2002-09-05 21:48:07 +0000 | [diff] [blame] | 185 |             if sys.platform.startswith('win'): | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 186 |                 self.fail("Opening mmap with size+1 should work on Windows.") | 
| Neal Norwitz | b567392 | 2002-09-05 21:48:07 +0000 | [diff] [blame] | 187 |         else: | 
 | 188 |             # we expect a ValueError on Unix, but not on Windows | 
 | 189 |             if not sys.platform.startswith('win'): | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 190 |                 self.fail("Opening mmap with size+1 should raise ValueError.") | 
| Barry Warsaw | ccd9e75 | 2002-09-11 02:56:42 +0000 | [diff] [blame] | 191 |             m.close() | 
| Tim Peters | 4f4f4d7 | 2002-09-10 20:49:15 +0000 | [diff] [blame] | 192 |         f.close() | 
 | 193 |         if sys.platform.startswith('win'): | 
 | 194 |             # Repair damage from the resizing test. | 
 | 195 |             f = open(TESTFN, 'r+b') | 
 | 196 |             f.truncate(mapsize) | 
 | 197 |             f.close() | 
| Neal Norwitz | b567392 | 2002-09-05 21:48:07 +0000 | [diff] [blame] | 198 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 199 |         # Opening mmap with access=ACCESS_WRITE | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 200 |         f = open(TESTFN, "r+b") | 
 | 201 |         m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE) | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 202 |         # Modifying write-through memory map | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 203 |         m[:] = 'c'*mapsize | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 204 |         self.assertEqual(m[:], 'c'*mapsize, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 205 |                "Write-through memory map memory not updated properly.") | 
 | 206 |         m.flush() | 
| Tim Peters | 1b5112a | 2002-09-10 21:19:55 +0000 | [diff] [blame] | 207 |         m.close() | 
 | 208 |         f.close() | 
| Tim Peters | 4f4f4d7 | 2002-09-10 20:49:15 +0000 | [diff] [blame] | 209 |         f = open(TESTFN, 'rb') | 
 | 210 |         stuff = f.read() | 
 | 211 |         f.close() | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 212 |         self.assertEqual(stuff, 'c'*mapsize, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 213 |                "Write-through memory map data file not updated properly.") | 
 | 214 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 215 |         # Opening mmap with access=ACCESS_COPY | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 216 |         f = open(TESTFN, "r+b") | 
 | 217 |         m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY) | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 218 |         # Modifying copy-on-write memory map | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 219 |         m[:] = 'd'*mapsize | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 220 |         self.assertEqual(m[:], 'd' * mapsize, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 221 |                "Copy-on-write memory map data not written correctly.") | 
 | 222 |         m.flush() | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 223 |         self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 224 |                "Copy-on-write test data file should not be modified.") | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 225 |         # Ensuring copy-on-write maps cannot be resized | 
 | 226 |         self.assertRaises(TypeError, m.resize, 2*mapsize) | 
| Neal Norwitz | d48a2f7 | 2008-04-01 05:40:43 +0000 | [diff] [blame] | 227 |         f.close() | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 228 |         del m, f | 
| Tim Peters | abd8a33 | 2006-11-03 02:32:46 +0000 | [diff] [blame] | 229 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 230 |         # Ensuring invalid access parameter raises exception | 
 | 231 |         f = open(TESTFN, "r+b") | 
 | 232 |         self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4) | 
 | 233 |         f.close() | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 234 |  | 
 | 235 |         if os.name == "posix": | 
| Tim Peters | 00cafa0 | 2001-11-13 23:39:47 +0000 | [diff] [blame] | 236 |             # Try incompatible flags, prot and access parameters. | 
 | 237 |             f = open(TESTFN, "r+b") | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 238 |             self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, | 
 | 239 |                               flags=mmap.MAP_PRIVATE, | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 240 |                               prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE) | 
| Tim Peters | 5379dea | 2002-04-18 04:30:18 +0000 | [diff] [blame] | 241 |             f.close() | 
| Tim Peters | 5ebfd36 | 2001-11-13 23:11:19 +0000 | [diff] [blame] | 242 |  | 
| Antoine Pitrou | d6f3a3e | 2011-03-06 02:03:34 +0100 | [diff] [blame] | 243 |             # Try writing with PROT_EXEC and without PROT_WRITE | 
 | 244 |             prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) | 
 | 245 |             with open(TESTFN, "r+b") as f: | 
 | 246 |                 m = mmap.mmap(f.fileno(), mapsize, prot=prot) | 
 | 247 |                 self.assertRaises(TypeError, m.write, b"abcdef") | 
 | 248 |                 self.assertRaises(TypeError, m.write_byte, 0) | 
 | 249 |                 m.close() | 
 | 250 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 251 |     def test_bad_file_desc(self): | 
 | 252 |         # Try opening a bad file descriptor... | 
 | 253 |         self.assertRaises(mmap.error, mmap.mmap, -2, 4096) | 
| Neal Norwitz | 3b4fff8 | 2006-01-11 08:54:45 +0000 | [diff] [blame] | 254 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 255 |     def test_tougher_find(self): | 
 | 256 |         # Do a tougher .find() test.  SF bug 515943 pointed out that, in 2.2, | 
 | 257 |         # searching for data with embedded \0 bytes didn't work. | 
 | 258 |         f = open(TESTFN, 'w+') | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 259 |  | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 260 |         data = 'aabaac\x00deef\x00\x00aa\x00' | 
 | 261 |         n = len(data) | 
 | 262 |         f.write(data) | 
| Tim Peters | 5379dea | 2002-04-18 04:30:18 +0000 | [diff] [blame] | 263 |         f.flush() | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 264 |         m = mmap.mmap(f.fileno(), n) | 
 | 265 |         f.close() | 
 | 266 |  | 
 | 267 |         for start in range(n+1): | 
 | 268 |             for finish in range(start, n+1): | 
 | 269 |                 slice = data[start : finish] | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 270 |                 self.assertEqual(m.find(slice), data.find(slice)) | 
 | 271 |                 self.assertEqual(m.find(slice + 'x'), -1) | 
| Tim Peters | ddc82ea | 2003-01-13 21:38:45 +0000 | [diff] [blame] | 272 |         m.close() | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 273 |  | 
| Andrew M. Kuchling | 5c60bfc | 2008-01-19 18:18:41 +0000 | [diff] [blame] | 274 |     def test_find_end(self): | 
 | 275 |         # test the new 'end' parameter works as expected | 
 | 276 |         f = open(TESTFN, 'w+') | 
 | 277 |         data = 'one two ones' | 
 | 278 |         n = len(data) | 
 | 279 |         f.write(data) | 
 | 280 |         f.flush() | 
 | 281 |         m = mmap.mmap(f.fileno(), n) | 
 | 282 |         f.close() | 
 | 283 |  | 
 | 284 |         self.assertEqual(m.find('one'), 0) | 
 | 285 |         self.assertEqual(m.find('ones'), 8) | 
 | 286 |         self.assertEqual(m.find('one', 0, -1), 0) | 
 | 287 |         self.assertEqual(m.find('one', 1), 8) | 
 | 288 |         self.assertEqual(m.find('one', 1, -1), 8) | 
 | 289 |         self.assertEqual(m.find('one', 1, -2), -1) | 
 | 290 |  | 
 | 291 |  | 
 | 292 |     def test_rfind(self): | 
 | 293 |         # test the new 'end' parameter works as expected | 
 | 294 |         f = open(TESTFN, 'w+') | 
 | 295 |         data = 'one two ones' | 
 | 296 |         n = len(data) | 
 | 297 |         f.write(data) | 
 | 298 |         f.flush() | 
 | 299 |         m = mmap.mmap(f.fileno(), n) | 
 | 300 |         f.close() | 
 | 301 |  | 
 | 302 |         self.assertEqual(m.rfind('one'), 8) | 
 | 303 |         self.assertEqual(m.rfind('one '), 0) | 
 | 304 |         self.assertEqual(m.rfind('one', 0, -1), 8) | 
 | 305 |         self.assertEqual(m.rfind('one', 0, -2), 0) | 
 | 306 |         self.assertEqual(m.rfind('one', 1, -1), 8) | 
 | 307 |         self.assertEqual(m.rfind('one', 1, -2), -1) | 
 | 308 |  | 
 | 309 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 310 |     def test_double_close(self): | 
 | 311 |         # make sure a double close doesn't crash on Solaris (Bug# 665913) | 
 | 312 |         f = open(TESTFN, 'w+') | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 313 |  | 
| Tim Peters | ddc82ea | 2003-01-13 21:38:45 +0000 | [diff] [blame] | 314 |         f.write(2**16 * 'a') # Arbitrary character | 
| Neal Norwitz | e604c02 | 2003-01-10 20:52:16 +0000 | [diff] [blame] | 315 |         f.close() | 
 | 316 |  | 
 | 317 |         f = open(TESTFN) | 
| Tim Peters | ddc82ea | 2003-01-13 21:38:45 +0000 | [diff] [blame] | 318 |         mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ) | 
| Neal Norwitz | e604c02 | 2003-01-10 20:52:16 +0000 | [diff] [blame] | 319 |         mf.close() | 
 | 320 |         mf.close() | 
 | 321 |         f.close() | 
 | 322 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 323 |     @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()") | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 324 |     def test_entire_file(self): | 
 | 325 |         # test mapping of entire file by passing 0 for map length | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 326 |         f = open(TESTFN, "w+") | 
| Tim Peters | c9ffa06 | 2002-03-08 05:43:32 +0000 | [diff] [blame] | 327 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 328 |         f.write(2**16 * 'm') # Arbitrary character | 
 | 329 |         f.close() | 
| Martin v. Löwis | 7fe60c0 | 2005-03-03 11:22:44 +0000 | [diff] [blame] | 330 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 331 |         f = open(TESTFN, "rb+") | 
 | 332 |         mf = mmap.mmap(f.fileno(), 0) | 
 | 333 |         self.assertEqual(len(mf), 2**16, "Map size should equal file size.") | 
 | 334 |         self.assertEqual(mf.read(2**16), 2**16 * "m") | 
 | 335 |         mf.close() | 
 | 336 |         f.close() | 
| Martin v. Löwis | 7fe60c0 | 2005-03-03 11:22:44 +0000 | [diff] [blame] | 337 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 338 |     @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()") | 
| Antoine Pitrou | 9989d85 | 2011-01-15 16:18:57 +0000 | [diff] [blame] | 339 |     def test_length_0_offset(self): | 
 | 340 |         # Issue #10916: test mapping of remainder of file by passing 0 for | 
 | 341 |         # map length with an offset doesn't cause a segfault. | 
| Antoine Pitrou | 533aa25 | 2011-01-15 17:40:00 +0000 | [diff] [blame] | 342 |         # NOTE: allocation granularity is currently 65536 under Win64, | 
 | 343 |         # and therefore the minimum offset alignment. | 
 | 344 |         with open(TESTFN, "wb") as f: | 
 | 345 |             f.write((65536 * 2) * b'm') # Arbitrary character | 
| Antoine Pitrou | 9989d85 | 2011-01-15 16:18:57 +0000 | [diff] [blame] | 346 |  | 
 | 347 |         with open(TESTFN, "rb") as f: | 
| Antoine Pitrou | 533aa25 | 2011-01-15 17:40:00 +0000 | [diff] [blame] | 348 |             mf = mmap.mmap(f.fileno(), 0, offset=65536, access=mmap.ACCESS_READ) | 
 | 349 |             try: | 
 | 350 |                 self.assertRaises(IndexError, mf.__getitem__, 80000) | 
 | 351 |             finally: | 
 | 352 |                 mf.close() | 
| Antoine Pitrou | 9989d85 | 2011-01-15 16:18:57 +0000 | [diff] [blame] | 353 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 354 |     @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()") | 
| Antoine Pitrou | 8a0eede | 2011-01-20 21:20:18 +0000 | [diff] [blame] | 355 |     def test_length_0_large_offset(self): | 
 | 356 |         # Issue #10959: test mapping of a file by passing 0 for | 
 | 357 |         # map length with a large offset doesn't cause a segfault. | 
| Antoine Pitrou | 8a0eede | 2011-01-20 21:20:18 +0000 | [diff] [blame] | 358 |         with open(TESTFN, "wb") as f: | 
 | 359 |             f.write(115699 * b'm') # Arbitrary character | 
 | 360 |  | 
 | 361 |         with open(TESTFN, "w+b") as f: | 
 | 362 |             self.assertRaises(ValueError, mmap.mmap, f.fileno(), 0, | 
 | 363 |                               offset=2147418112) | 
 | 364 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 365 |     def test_move(self): | 
 | 366 |         # make move works everywhere (64-bit format problem earlier) | 
 | 367 |         f = open(TESTFN, 'w+') | 
| Tim Peters | eba28be | 2005-03-28 01:08:02 +0000 | [diff] [blame] | 368 |  | 
| Neal Norwitz | 8856fb7 | 2005-12-18 03:34:22 +0000 | [diff] [blame] | 369 |         f.write("ABCDEabcde") # Arbitrary character | 
 | 370 |         f.flush() | 
 | 371 |  | 
 | 372 |         mf = mmap.mmap(f.fileno(), 10) | 
 | 373 |         mf.move(5, 0, 5) | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 374 |         self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5") | 
| Neal Norwitz | 8856fb7 | 2005-12-18 03:34:22 +0000 | [diff] [blame] | 375 |         mf.close() | 
 | 376 |         f.close() | 
 | 377 |  | 
| Hirokazu Yamamoto | 9d2ee5d | 2009-03-31 13:13:05 +0000 | [diff] [blame] | 378 |         # more excessive test | 
 | 379 |         data = "0123456789" | 
 | 380 |         for dest in range(len(data)): | 
 | 381 |             for src in range(len(data)): | 
 | 382 |                 for count in range(len(data) - max(dest, src)): | 
 | 383 |                     expected = data[:dest] + data[src:src+count] + data[dest+count:] | 
 | 384 |                     m = mmap.mmap(-1, len(data)) | 
 | 385 |                     m[:] = data | 
 | 386 |                     m.move(dest, src, count) | 
 | 387 |                     self.assertEqual(m[:], expected) | 
 | 388 |                     m.close() | 
 | 389 |  | 
| Hirokazu Yamamoto | 1d7d532 | 2009-03-31 20:14:04 +0000 | [diff] [blame] | 390 |         # segfault test (Issue 5387) | 
 | 391 |         m = mmap.mmap(-1, 100) | 
 | 392 |         offsets = [-100, -1, 0, 1, 100] | 
 | 393 |         for source, dest, size in itertools.product(offsets, offsets, offsets): | 
 | 394 |             try: | 
 | 395 |                 m.move(source, dest, size) | 
 | 396 |             except ValueError: | 
 | 397 |                 pass | 
| Jack Diederich | 2ecd3c3 | 2009-04-01 20:26:13 +0000 | [diff] [blame] | 398 |  | 
 | 399 |         offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), | 
 | 400 |                    (-1, 0, 0), (0, -1, 0), (0, 0, -1)] | 
 | 401 |         for source, dest, size in offsets: | 
 | 402 |             self.assertRaises(ValueError, m.move, source, dest, size) | 
 | 403 |  | 
| Hirokazu Yamamoto | 9d2ee5d | 2009-03-31 13:13:05 +0000 | [diff] [blame] | 404 |         m.close() | 
 | 405 |  | 
| Jack Diederich | 2ecd3c3 | 2009-04-01 20:26:13 +0000 | [diff] [blame] | 406 |         m = mmap.mmap(-1, 1) # single byte | 
 | 407 |         self.assertRaises(ValueError, m.move, 0, 0, 2) | 
 | 408 |         self.assertRaises(ValueError, m.move, 1, 0, 1) | 
 | 409 |         self.assertRaises(ValueError, m.move, 0, 1, 1) | 
 | 410 |         m.move(0, 0, 1) | 
 | 411 |         m.move(0, 0, 0) | 
 | 412 |  | 
 | 413 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 414 |     def test_anonymous(self): | 
 | 415 |         # anonymous mmap.mmap(-1, PAGE) | 
 | 416 |         m = mmap.mmap(-1, PAGESIZE) | 
 | 417 |         for x in xrange(PAGESIZE): | 
 | 418 |             self.assertEqual(m[x], '\0', "anonymously mmap'ed contents should be zero") | 
| Neal Norwitz | 8856fb7 | 2005-12-18 03:34:22 +0000 | [diff] [blame] | 419 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 420 |         for x in xrange(PAGESIZE): | 
 | 421 |             m[x] = ch = chr(x & 255) | 
 | 422 |             self.assertEqual(m[x], ch) | 
| Neal Norwitz | 0e6bc8c | 2006-02-05 05:45:43 +0000 | [diff] [blame] | 423 |  | 
| Thomas Wouters | 3ccec68 | 2007-08-28 15:28:19 +0000 | [diff] [blame] | 424 |     def test_extended_getslice(self): | 
 | 425 |         # Test extended slicing by comparing with list slicing. | 
 | 426 |         s = "".join(chr(c) for c in reversed(range(256))) | 
 | 427 |         m = mmap.mmap(-1, len(s)) | 
 | 428 |         m[:] = s | 
 | 429 |         self.assertEqual(m[:], s) | 
 | 430 |         indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) | 
 | 431 |         for start in indices: | 
 | 432 |             for stop in indices: | 
 | 433 |                 # Skip step 0 (invalid) | 
 | 434 |                 for step in indices[1:]: | 
 | 435 |                     self.assertEqual(m[start:stop:step], | 
 | 436 |                                      s[start:stop:step]) | 
 | 437 |  | 
 | 438 |     def test_extended_set_del_slice(self): | 
 | 439 |         # Test extended slicing by comparing with list slicing. | 
 | 440 |         s = "".join(chr(c) for c in reversed(range(256))) | 
 | 441 |         m = mmap.mmap(-1, len(s)) | 
 | 442 |         indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) | 
 | 443 |         for start in indices: | 
 | 444 |             for stop in indices: | 
 | 445 |                 # Skip invalid step 0 | 
 | 446 |                 for step in indices[1:]: | 
 | 447 |                     m[:] = s | 
 | 448 |                     self.assertEqual(m[:], s) | 
 | 449 |                     L = list(s) | 
 | 450 |                     # Make sure we have a slice of exactly the right length, | 
 | 451 |                     # but with different data. | 
 | 452 |                     data = L[start:stop:step] | 
 | 453 |                     data = "".join(reversed(data)) | 
 | 454 |                     L[start:stop:step] = data | 
 | 455 |                     m[start:stop:step] = data | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 456 |                     self.assertEqual(m[:], "".join(L)) | 
| Thomas Wouters | 3ccec68 | 2007-08-28 15:28:19 +0000 | [diff] [blame] | 457 |  | 
| Travis E. Oliphant | 8feafab | 2007-10-23 02:40:56 +0000 | [diff] [blame] | 458 |     def make_mmap_file (self, f, halfsize): | 
 | 459 |         # Write 2 pages worth of data to the file | 
 | 460 |         f.write ('\0' * halfsize) | 
 | 461 |         f.write ('foo') | 
 | 462 |         f.write ('\0' * (halfsize - 3)) | 
 | 463 |         f.flush () | 
 | 464 |         return mmap.mmap (f.fileno(), 0) | 
 | 465 |  | 
| Jesus Cea | 8b54d6d | 2012-09-10 00:22:39 +0200 | [diff] [blame] | 466 |     def test_empty_file (self): | 
 | 467 |         f = open (TESTFN, 'w+b') | 
 | 468 |         f.close() | 
| Jesus Cea | 20f0ea1 | 2012-09-10 22:45:47 +0200 | [diff] [blame] | 469 |         with open(TESTFN, "rb") as f : | 
| Terry Jan Reedy | 71b2ded | 2013-08-31 21:14:00 -0400 | [diff] [blame] | 470 |             self.assertRaisesRegexp(ValueError, | 
 | 471 |                                    "cannot mmap an empty file", | 
 | 472 |                                    mmap.mmap, f.fileno(), 0, | 
 | 473 |                                    access=mmap.ACCESS_READ) | 
| Jesus Cea | 8b54d6d | 2012-09-10 00:22:39 +0200 | [diff] [blame] | 474 |  | 
| Travis E. Oliphant | 8feafab | 2007-10-23 02:40:56 +0000 | [diff] [blame] | 475 |     def test_offset (self): | 
 | 476 |         f = open (TESTFN, 'w+b') | 
 | 477 |  | 
 | 478 |         try: # unlink TESTFN no matter what | 
 | 479 |             halfsize = mmap.ALLOCATIONGRANULARITY | 
 | 480 |             m = self.make_mmap_file (f, halfsize) | 
 | 481 |             m.close () | 
 | 482 |             f.close () | 
 | 483 |  | 
 | 484 |             mapsize = halfsize * 2 | 
 | 485 |             # Try invalid offset | 
 | 486 |             f = open(TESTFN, "r+b") | 
 | 487 |             for offset in [-2, -1, None]: | 
 | 488 |                 try: | 
 | 489 |                     m = mmap.mmap(f.fileno(), mapsize, offset=offset) | 
 | 490 |                     self.assertEqual(0, 1) | 
 | 491 |                 except (ValueError, TypeError, OverflowError): | 
 | 492 |                     pass | 
 | 493 |                 else: | 
 | 494 |                     self.assertEqual(0, 0) | 
 | 495 |             f.close() | 
 | 496 |  | 
 | 497 |             # Try valid offset, hopefully 8192 works on all OSes | 
 | 498 |             f = open(TESTFN, "r+b") | 
 | 499 |             m = mmap.mmap(f.fileno(), mapsize - halfsize, offset=halfsize) | 
 | 500 |             self.assertEqual(m[0:3], 'foo') | 
 | 501 |             f.close() | 
| Hirokazu Yamamoto | 17a837e | 2009-02-17 13:17:26 +0000 | [diff] [blame] | 502 |  | 
 | 503 |             # Try resizing map | 
 | 504 |             try: | 
 | 505 |                 m.resize(512) | 
 | 506 |             except SystemError: | 
 | 507 |                 pass | 
 | 508 |             else: | 
 | 509 |                 # resize() is supported | 
 | 510 |                 self.assertEqual(len(m), 512) | 
 | 511 |                 # Check that we can no longer seek beyond the new size. | 
 | 512 |                 self.assertRaises(ValueError, m.seek, 513, 0) | 
 | 513 |                 # Check that the content is not changed | 
 | 514 |                 self.assertEqual(m[0:3], 'foo') | 
 | 515 |  | 
 | 516 |                 # Check that the underlying file is truncated too | 
 | 517 |                 f = open(TESTFN) | 
 | 518 |                 f.seek(0, 2) | 
 | 519 |                 self.assertEqual(f.tell(), halfsize + 512) | 
 | 520 |                 f.close() | 
 | 521 |                 self.assertEqual(m.size(), halfsize + 512) | 
 | 522 |  | 
| Travis E. Oliphant | 8feafab | 2007-10-23 02:40:56 +0000 | [diff] [blame] | 523 |             m.close() | 
 | 524 |  | 
 | 525 |         finally: | 
 | 526 |             f.close() | 
 | 527 |             try: | 
 | 528 |                 os.unlink(TESTFN) | 
 | 529 |             except OSError: | 
 | 530 |                 pass | 
 | 531 |  | 
| Georg Brandl | d02fc48 | 2008-01-22 19:56:03 +0000 | [diff] [blame] | 532 |     def test_subclass(self): | 
 | 533 |         class anon_mmap(mmap.mmap): | 
 | 534 |             def __new__(klass, *args, **kwargs): | 
 | 535 |                 return mmap.mmap.__new__(klass, -1, *args, **kwargs) | 
 | 536 |         anon_mmap(PAGESIZE) | 
 | 537 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 538 |     @unittest.skipUnless(hasattr(mmap, 'PROT_READ'), "needs mmap.PROT_READ") | 
| Christian Heimes | 7adfad8 | 2008-02-15 08:20:11 +0000 | [diff] [blame] | 539 |     def test_prot_readonly(self): | 
 | 540 |         mapsize = 10 | 
 | 541 |         open(TESTFN, "wb").write("a"*mapsize) | 
 | 542 |         f = open(TESTFN, "rb") | 
 | 543 |         m = mmap.mmap(f.fileno(), mapsize, prot=mmap.PROT_READ) | 
 | 544 |         self.assertRaises(TypeError, m.write, "foo") | 
| Neal Norwitz | d48a2f7 | 2008-04-01 05:40:43 +0000 | [diff] [blame] | 545 |         f.close() | 
| Georg Brandl | d02fc48 | 2008-01-22 19:56:03 +0000 | [diff] [blame] | 546 |  | 
| Facundo Batista | e139688 | 2008-02-17 18:59:29 +0000 | [diff] [blame] | 547 |     def test_error(self): | 
| Benjamin Peterson | 5c8da86 | 2009-06-30 22:57:08 +0000 | [diff] [blame] | 548 |         self.assertTrue(issubclass(mmap.error, EnvironmentError)) | 
| Ezio Melotti | aa98058 | 2010-01-23 23:04:36 +0000 | [diff] [blame] | 549 |         self.assertIn("mmap.error", str(mmap.error)) | 
| Facundo Batista | e139688 | 2008-02-17 18:59:29 +0000 | [diff] [blame] | 550 |  | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 551 |     def test_io_methods(self): | 
 | 552 |         data = "0123456789" | 
 | 553 |         open(TESTFN, "wb").write("x"*len(data)) | 
 | 554 |         f = open(TESTFN, "r+b") | 
 | 555 |         m = mmap.mmap(f.fileno(), len(data)) | 
 | 556 |         f.close() | 
 | 557 |         # Test write_byte() | 
 | 558 |         for i in xrange(len(data)): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 559 |             self.assertEqual(m.tell(), i) | 
| Hirokazu Yamamoto | 772033f | 2009-04-04 17:20:05 +0000 | [diff] [blame] | 560 |             m.write_byte(data[i]) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 561 |             self.assertEqual(m.tell(), i+1) | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 562 |         self.assertRaises(ValueError, m.write_byte, "x") | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 563 |         self.assertEqual(m[:], data) | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 564 |         # Test read_byte() | 
 | 565 |         m.seek(0) | 
 | 566 |         for i in xrange(len(data)): | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 567 |             self.assertEqual(m.tell(), i) | 
 | 568 |             self.assertEqual(m.read_byte(), data[i]) | 
 | 569 |             self.assertEqual(m.tell(), i+1) | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 570 |         self.assertRaises(ValueError, m.read_byte) | 
 | 571 |         # Test read() | 
 | 572 |         m.seek(3) | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 573 |         self.assertEqual(m.read(3), "345") | 
 | 574 |         self.assertEqual(m.tell(), 6) | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 575 |         # Test write() | 
 | 576 |         m.seek(3) | 
 | 577 |         m.write("bar") | 
| Ezio Melotti | 2623a37 | 2010-11-21 13:34:58 +0000 | [diff] [blame] | 578 |         self.assertEqual(m.tell(), 6) | 
 | 579 |         self.assertEqual(m[:], "012bar6789") | 
| Hirokazu Yamamoto | f2dc885 | 2009-02-28 10:31:54 +0000 | [diff] [blame] | 580 |         m.seek(8) | 
 | 581 |         self.assertRaises(ValueError, m.write, "bar") | 
 | 582 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 583 |     @unittest.skipUnless(os.name == 'nt', 'requires Windows') | 
 | 584 |     def test_tagname(self): | 
 | 585 |         data1 = "0123456789" | 
 | 586 |         data2 = "abcdefghij" | 
 | 587 |         assert len(data1) == len(data2) | 
| Hirokazu Yamamoto | 264fc12 | 2009-03-05 14:21:12 +0000 | [diff] [blame] | 588 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 589 |         # Test same tag | 
 | 590 |         m1 = mmap.mmap(-1, len(data1), tagname="foo") | 
 | 591 |         m1[:] = data1 | 
 | 592 |         m2 = mmap.mmap(-1, len(data2), tagname="foo") | 
 | 593 |         m2[:] = data2 | 
 | 594 |         self.assertEqual(m1[:], data2) | 
 | 595 |         self.assertEqual(m2[:], data2) | 
 | 596 |         m2.close() | 
 | 597 |         m1.close() | 
| Hirokazu Yamamoto | 264fc12 | 2009-03-05 14:21:12 +0000 | [diff] [blame] | 598 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 599 |         # Test different tag | 
 | 600 |         m1 = mmap.mmap(-1, len(data1), tagname="foo") | 
 | 601 |         m1[:] = data1 | 
 | 602 |         m2 = mmap.mmap(-1, len(data2), tagname="boo") | 
 | 603 |         m2[:] = data2 | 
 | 604 |         self.assertEqual(m1[:], data1) | 
 | 605 |         self.assertEqual(m2[:], data2) | 
 | 606 |         m2.close() | 
 | 607 |         m1.close() | 
| Hirokazu Yamamoto | b0e10c7 | 2009-02-28 12:13:07 +0000 | [diff] [blame] | 608 |  | 
| Serhiy Storchaka | cbee972 | 2014-08-19 17:03:42 +0300 | [diff] [blame] | 609 |     @cpython_only | 
 | 610 |     @unittest.skipUnless(os.name == 'nt', 'requires Windows') | 
 | 611 |     def test_sizeof(self): | 
 | 612 |         m1 = mmap.mmap(-1, 100) | 
 | 613 |         tagname = "foo" | 
 | 614 |         m2 = mmap.mmap(-1, 100, tagname=tagname) | 
| Serhiy Storchaka | 2426da8 | 2014-08-19 18:20:07 +0300 | [diff] [blame] | 615 |         self.assertEqual(sys.getsizeof(m2), | 
 | 616 |                          sys.getsizeof(m1) + len(tagname) + 1) | 
| Serhiy Storchaka | cbee972 | 2014-08-19 17:03:42 +0300 | [diff] [blame] | 617 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 618 |     @unittest.skipUnless(os.name == 'nt', 'requires Windows') | 
 | 619 |     def test_crasher_on_windows(self): | 
 | 620 |         # Should not crash (Issue 1733986) | 
 | 621 |         m = mmap.mmap(-1, 1000, tagname="foo") | 
 | 622 |         try: | 
 | 623 |             mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size | 
 | 624 |         except: | 
 | 625 |             pass | 
 | 626 |         m.close() | 
| Hirokazu Yamamoto | 264fc12 | 2009-03-05 14:21:12 +0000 | [diff] [blame] | 627 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 628 |         # Should not crash (Issue 5385) | 
 | 629 |         open(TESTFN, "wb").write("x"*10) | 
 | 630 |         f = open(TESTFN, "r+b") | 
 | 631 |         m = mmap.mmap(f.fileno(), 0) | 
 | 632 |         f.close() | 
 | 633 |         try: | 
 | 634 |             m.resize(0) # will raise WindowsError | 
 | 635 |         except: | 
 | 636 |             pass | 
 | 637 |         try: | 
 | 638 |             m[:] | 
 | 639 |         except: | 
 | 640 |             pass | 
 | 641 |         m.close() | 
| Hirokazu Yamamoto | 264fc12 | 2009-03-05 14:21:12 +0000 | [diff] [blame] | 642 |  | 
| Serhiy Storchaka | 32e23e7 | 2013-11-03 23:15:46 +0200 | [diff] [blame] | 643 |     @unittest.skipUnless(os.name == 'nt', 'requires Windows') | 
 | 644 |     def test_invalid_descriptor(self): | 
 | 645 |         # socket file descriptors are valid, but out of range | 
 | 646 |         # for _get_osfhandle, causing a crash when validating the | 
 | 647 |         # parameters to _get_osfhandle. | 
 | 648 |         s = socket.socket() | 
 | 649 |         try: | 
 | 650 |             with self.assertRaises(mmap.error): | 
 | 651 |                 m = mmap.mmap(s.fileno(), 10) | 
 | 652 |         finally: | 
 | 653 |             s.close() | 
| Facundo Batista | e139688 | 2008-02-17 18:59:29 +0000 | [diff] [blame] | 654 |  | 
| Benjamin Peterson | 46550ff | 2016-10-05 22:09:31 -0700 | [diff] [blame] | 655 |     @unittest.skipIf(os.name == 'nt', 'cannot resize anonymous mmaps on Windows') | 
| Benjamin Peterson | 1df2cbe | 2016-10-05 21:45:48 -0700 | [diff] [blame] | 656 |     def test_resize_past_pos(self): | 
 | 657 |         m = mmap.mmap(-1, 8192) | 
 | 658 |         self.addCleanup(m.close) | 
 | 659 |         m.read(5000) | 
| Benjamin Peterson | 38297d7 | 2016-10-05 22:00:05 -0700 | [diff] [blame] | 660 |         try: | 
 | 661 |             m.resize(4096) | 
 | 662 |         except SystemError: | 
 | 663 |             self.skipTest("resizing not supported") | 
| Benjamin Peterson | 1df2cbe | 2016-10-05 21:45:48 -0700 | [diff] [blame] | 664 |         self.assertEqual(m.read(14), '') | 
| Benjamin Peterson | d7cfae9 | 2016-10-05 22:00:24 -0700 | [diff] [blame] | 665 |         self.assertRaises(ValueError, m.read_byte) | 
| Benjamin Peterson | 1df2cbe | 2016-10-05 21:45:48 -0700 | [diff] [blame] | 666 |         self.assertRaises(ValueError, m.write_byte, 'b') | 
 | 667 |         self.assertRaises(ValueError, m.write, 'abc') | 
 | 668 |  | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 669 |  | 
 | 670 | class LargeMmapTests(unittest.TestCase): | 
 | 671 |  | 
 | 672 |     def setUp(self): | 
 | 673 |         unlink(TESTFN) | 
 | 674 |  | 
 | 675 |     def tearDown(self): | 
 | 676 |         unlink(TESTFN) | 
 | 677 |  | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 678 |     def _make_test_file(self, num_zeroes, tail): | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 679 |         if sys.platform[:3] == 'win' or sys.platform == 'darwin': | 
 | 680 |             requires('largefile', | 
 | 681 |                 'test requires %s bytes and a long time to run' % str(0x180000000)) | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 682 |         f = open(TESTFN, 'w+b') | 
 | 683 |         try: | 
 | 684 |             f.seek(num_zeroes) | 
 | 685 |             f.write(tail) | 
 | 686 |             f.flush() | 
 | 687 |         except (IOError, OverflowError): | 
| Nadeem Vawda | 5ae6c42 | 2011-05-07 14:34:22 +0200 | [diff] [blame] | 688 |             f.close() | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 689 |             raise unittest.SkipTest("filesystem does not have largefile support") | 
 | 690 |         return f | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 691 |  | 
| Nadeem Vawda | 0d837ef | 2011-05-07 13:17:16 +0200 | [diff] [blame] | 692 |     def test_large_offset(self): | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 693 |         with self._make_test_file(0x14FFFFFFF, b" ") as f: | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 694 |             m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ) | 
 | 695 |             try: | 
 | 696 |                 self.assertEqual(m[0xFFFFFFF], b" ") | 
 | 697 |             finally: | 
 | 698 |                 m.close() | 
 | 699 |  | 
 | 700 |     def test_large_filesize(self): | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 701 |         with self._make_test_file(0x17FFFFFFF, b" ") as f: | 
| Richard Oudkerk | 36b9d41 | 2013-02-13 12:05:14 +0000 | [diff] [blame] | 702 |             if sys.maxsize < 0x180000000: | 
 | 703 |                 # On 32 bit platforms the file is larger than sys.maxsize so | 
 | 704 |                 # mapping the whole file should fail -- Issue #16743 | 
 | 705 |                 with self.assertRaises(OverflowError): | 
 | 706 |                     mmap.mmap(f.fileno(), 0x180000000, access=mmap.ACCESS_READ) | 
 | 707 |                 with self.assertRaises(ValueError): | 
 | 708 |                     mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 709 |             m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ) | 
 | 710 |             try: | 
 | 711 |                 self.assertEqual(m.size(), 0x180000000) | 
 | 712 |             finally: | 
 | 713 |                 m.close() | 
 | 714 |  | 
| Nadeem Vawda | 0d837ef | 2011-05-07 13:17:16 +0200 | [diff] [blame] | 715 |     # Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X. | 
 | 716 |  | 
 | 717 |     def _test_around_boundary(self, boundary): | 
 | 718 |         tail = b'  DEARdear  ' | 
 | 719 |         start = boundary - len(tail) // 2 | 
 | 720 |         end = start + len(tail) | 
| Nadeem Vawda | d0a8f16 | 2011-05-07 14:12:12 +0200 | [diff] [blame] | 721 |         with self._make_test_file(start, tail) as f: | 
| Nadeem Vawda | 0d837ef | 2011-05-07 13:17:16 +0200 | [diff] [blame] | 722 |             m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) | 
 | 723 |             try: | 
 | 724 |                 self.assertEqual(m[start:end], tail) | 
 | 725 |             finally: | 
 | 726 |                 m.close() | 
 | 727 |  | 
 | 728 |     @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems") | 
 | 729 |     def test_around_2GB(self): | 
 | 730 |         self._test_around_boundary(_2G) | 
 | 731 |  | 
 | 732 |     @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems") | 
 | 733 |     def test_around_4GB(self): | 
 | 734 |         self._test_around_boundary(_4G) | 
 | 735 |  | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 736 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 737 | def test_main(): | 
| Antoine Pitrou | f4d2b3d | 2011-02-21 23:59:20 +0000 | [diff] [blame] | 738 |     run_unittest(MmapTests, LargeMmapTests) | 
| Andrew M. Kuchling | e81b9cf | 2000-03-30 21:15:29 +0000 | [diff] [blame] | 739 |  | 
| Georg Brandl | 3163179 | 2006-10-29 19:13:40 +0000 | [diff] [blame] | 740 | if __name__ == '__main__': | 
 | 741 |     test_main() |