1
from pypy.conftest import gettestobjspace
2
from pypy.tool.udir import udir
7
space = gettestobjspace(usemodules=('mmap',))
9
cls.w_tmpname = space.wrap(str(udir.join('mmap-')))
11
def test_page_size(self):
13
assert mmap.PAGESIZE > 0
14
assert isinstance(mmap.PAGESIZE, int)
16
def test_attributes(self):
19
assert isinstance(mmap.ACCESS_READ, int)
20
assert isinstance(mmap.ACCESS_WRITE, int)
21
assert isinstance(mmap.ACCESS_COPY, int)
22
if os.name == "posix":
23
assert isinstance(mmap.MAP_ANON, int)
24
assert isinstance(mmap.MAP_ANONYMOUS, int)
25
assert isinstance(mmap.MAP_PRIVATE, int)
26
assert isinstance(mmap.MAP_SHARED, int)
27
assert isinstance(mmap.PROT_EXEC, int)
28
assert isinstance(mmap.PROT_READ, int)
29
assert isinstance(mmap.PROT_WRITE, int)
31
assert mmap.error is EnvironmentError
38
raises(TypeError, mmap, "foo")
39
raises(TypeError, mmap, 0, "foo")
41
if os.name == "posix":
42
raises(TypeError, mmap, 0, 1, 2, 3, 4, 5)
43
raises(TypeError, mmap, 0, 1, 2, 3, "foo", 5)
44
raises(TypeError, mmap, 0, 1, foo="foo")
45
raises(TypeError, mmap, 0, -1)
46
raises(OverflowError, mmap, 0, sys.maxint ** 3)
47
raises(ValueError, mmap, 0, 1, flags=2, access=3)
48
raises(ValueError, mmap, 0, 1, access=123)
50
raises(TypeError, mmap, 0, 1, 2, 3, 4)
51
raises(TypeError, mmap, 0, 1, tagname=123)
52
raises(TypeError, mmap, 0, 1, access="foo")
53
raises(ValueError, mmap, 0, 1, access=-1)
55
def test_file_size(self):
58
skip("Only Unix checks file size")
61
f = open(self.tmpname + "a", "w+")
65
raises(ValueError, mmap, f.fileno(), 123)
68
def test_create(self):
70
f = open(self.tmpname + "b", "w+")
74
m = mmap(f.fileno(), 1)
75
assert m.read(99) == "c"
81
f = open(self.tmpname + "c", "w+")
85
m = mmap(f.fileno(), 1)
87
raises(ValueError, m.read, 1)
89
def test_read_byte(self):
91
f = open(self.tmpname + "d", "w+")
95
m = mmap(f.fileno(), 1)
96
assert m.read_byte() == "c"
97
raises(ValueError, m.read_byte)
101
def test_readline(self):
102
from mmap import mmap
104
f = open(self.tmpname + "e", "w+")
108
m = mmap(f.fileno(), 4)
110
# windows replaces \n with \r. it's time to change to \n only MS!
111
assert m.readline() == "foo\r"
112
elif os.name == "posix":
113
assert m.readline() == "foo\n"
114
assert m.readline() == ""
119
from mmap import mmap
120
f = open(self.tmpname + "f", "w+")
124
m = mmap(f.fileno(), 6)
125
raises(TypeError, m.read, "foo")
126
assert m.read(1) == "f"
127
assert m.read(6) == "oobar"
128
assert m.read(1) == ""
133
from mmap import mmap
134
f = open(self.tmpname + "g", "w+")
138
m = mmap(f.fileno(), 7)
139
raises(TypeError, m.find, 123)
140
raises(TypeError, m.find, "foo", "baz")
141
assert m.find("b") == 3
142
assert m.find("z") == -1
143
assert m.find("o", 5) == -1
144
assert m.find("ob") == 2
145
assert m.find("\0") == 6
149
def test_is_modifiable(self):
151
f = open(self.tmpname + "h", "w+")
155
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
156
raises(TypeError, m.write, 'x')
157
raises(TypeError, m.resize, 7)
162
from mmap import mmap
163
f = open(self.tmpname + "i", "w+")
167
m = mmap(f.fileno(), 6)
168
raises(TypeError, m.seek, "foo")
169
raises(TypeError, m.seek, 0, "foo")
170
raises(ValueError, m.seek, -1, 0)
171
raises(ValueError, m.seek, -1, 1)
172
raises(ValueError, m.seek, -7, 2)
173
raises(ValueError, m.seek, 1, 3)
174
raises(ValueError, m.seek, 10)
186
def test_write(self):
188
f = open(self.tmpname + "j", "w+")
192
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
193
raises(TypeError, m.write, "foo")
194
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
195
raises(TypeError, m.write, 123)
196
raises(ValueError, m.write, "c"*10)
199
assert m.read(6) == "ciao\nr"
202
def test_write_byte(self):
204
f = open(self.tmpname + "k", "w+")
208
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
209
raises(TypeError, m.write_byte, "f")
210
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
211
raises(TypeError, m.write_byte, 123)
212
raises(TypeError, m.write_byte, "ab")
215
assert m.read(6) == "xoobar"
219
from mmap import mmap
220
f = open(self.tmpname + "l", "w+")
224
m = mmap(f.fileno(), 5)
225
assert m.size() == 6 # size of the underline file, not the mmap
230
from mmap import mmap
231
f = open(self.tmpname + "m", "w+")
235
m = mmap(f.fileno(), 1)
240
def test_flush(self):
241
from mmap import mmap
242
f = open(self.tmpname + "n", "w+")
246
m = mmap(f.fileno(), 6)
247
raises(TypeError, m.flush, 1, 2, 3)
248
raises(TypeError, m.flush, 1, "a")
249
raises(ValueError, m.flush, 0, 99)
250
m.flush() # return value is a bit meaningless, platform-dependent
256
f = open(self.tmpname + "o", "w+")
260
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
261
raises(TypeError, m.move, 1)
262
raises(TypeError, m.move, 1, "foo", 2)
263
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
264
raises(ValueError, m.move, 7, 1, 2)
265
raises(ValueError, m.move, 1, 7, 2)
267
assert m.read(6) == "fbarar"
275
def test_resize(self):
277
if ("darwin" in sys.platform) or ("freebsd" in sys.platform):
278
skip("resize does not work under OSX or FreeBSD")
283
f = open(self.tmpname + "p", "w+")
286
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
287
raises(TypeError, m.resize, 1)
288
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_COPY)
289
raises(TypeError, m.resize, 1)
290
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
291
f_size = os.fstat(f.fileno()).st_size
292
assert m.size() == f_size == 6
294
f_size = os.fstat(f.fileno()).st_size
295
assert m.size() == f_size == 10
300
from mmap import mmap
302
f = open(self.tmpname + "q", "w+")
306
m = mmap(f.fileno(), 6)
311
def test_get_item(self):
312
from mmap import mmap
314
f = open(self.tmpname + "r", "w+")
318
m = mmap(f.fileno(), 6)
319
fn = lambda: m["foo"]
320
raises(TypeError, fn)
322
raises(IndexError, fn)
326
# assert m.get_item(sl) == 'o'
330
def test_set_item(self):
333
f = open(self.tmpname + "s", "w+")
337
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)
339
raises(TypeError, fn)
340
m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_WRITE)
341
def fn(): m["foo"] = 'a'
342
raises(TypeError, fn)
343
def fn(): m[-7] = 'a'
344
raises(IndexError, fn)
345
def fn(): m[0] = 'ab'
346
raises((IndexError, ValueError), fn) # IndexError is in CPython,
347
# but doesn't make much sense
348
# def f(m): m[1:3] = u'xx'
349
# py.test.raises(IndexError, f, m)
350
# def f(m): m[1:4] = "zz"
351
# py.test.raises(IndexError, f, m)
352
# def f(m): m[1:6] = "z" * 6
353
# py.test.raises(IndexError, f, m)
354
# def f(m): m[:2] = "z" * 5
356
# assert m.read(6) == "fxxbar"
362
assert data == "yoobar" # yxxbar with slice's stuff
366
def test_del_item(self):
367
from mmap import mmap
369
f = open(self.tmpname + "t", "w+")
373
m = mmap(f.fileno(), 6)
374
def fn(): del m["foo"]
375
raises(TypeError, fn)
376
# def f(m): del m[1:3]
377
# py.test.raises(TypeError, f, m)
379
raises(TypeError, fn)
383
def test_concatenation(self):
384
from mmap import mmap
386
f = open(self.tmpname + "u", "w+")
390
m = mmap(f.fileno(), 6)
392
raises((SystemError, TypeError), fn) # SystemError is in CPython,
393
def fn(m): m += 1 # but it doesn't make much
394
raises((SystemError, TypeError), fn, m) # sense
396
raises(TypeError, fn)
400
def test_repeatition(self):
401
from mmap import mmap
403
f = open(self.tmpname + "v", "w+")
407
m = mmap(f.fileno(), 6)
409
raises((SystemError, TypeError), fn) # SystemError is in CPython,
410
def fn(m): m *= 1 # but it
411
raises((SystemError, TypeError), fn, m) # doesn't
412
def fn(): 1 * m # make much sense
413
raises(TypeError, fn)
417
# def test_slicing(self):
419
# m = mmap(self.f.fileno(), 6)
420
# assert m[-3:7] == "bar"
423
def test_sequence_type(self):
424
from mmap import mmap
425
f = open(self.tmpname + "x", "w+")
428
m = mmap(f.fileno(), 6)
430
assert operator.isSequenceType(m)
431
assert not operator.isMappingType(m)
434
# this is a global test, ported from test_mmap.py
436
from mmap import PAGESIZE
440
filename = self.tmpname + "w"
442
f = open(filename, "w+")
444
# write 2 pages worth of data to the file
445
f.write('\0' * PAGESIZE)
447
f.write('\0' * (PAGESIZE - 3))
449
m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
453
assert m.find("foo") == PAGESIZE
454
assert len(m) == 2 * PAGESIZE
456
# assert m[0:3] == '\0\0\0'
458
# modify the file's content
460
# m[PAGESIZE+3:PAGESIZE+3+3] = 'bar'
462
# check that the modification worked
464
# assert m[0:3] == '3\0\0'
465
# assert m[PAGESIZE-1:PAGESIZE+7] == '\0foobar\0'
469
# test seeking around
473
assert m.tell() == 42
475
assert m.tell() == len(m)
477
raises(ValueError, m.seek, -1)
478
raises(ValueError, m.seek, 1, 2)
479
raises(ValueError, m.seek, -len(m) - 1, 2)
482
if not (("darwin" in sys.platform) or ("freebsd" in sys.platform)):
486
raises(ValueError, m.seek, 513, 0)
488
# check that the underlying file is truncated too
491
assert f.tell() == 512
493
assert m.size() == 512
498
# test access=ACCESS_READ
500
f = open(filename, "wb")
501
f.write("a" * mapsize)
503
f = open(filename, "rb")
504
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
505
# assert m[:] == 'a' * mapsize
506
# def f(m): m[:] = 'b' * mapsize
507
# py.test.raises(TypeError, f, m)
509
raises(TypeError, fn)
510
def fn(m): m.seek(0, 0); m.write("abc")
511
raises(TypeError, fn, m)
512
def fn(m): m.seek(0, 0); m.write_byte("d")
513
raises(TypeError, fn, m)
514
if not (("darwin" in sys.platform) or ("freebsd" in sys.platform)):
515
raises(TypeError, m.resize, 2 * mapsize)
516
assert open(filename, "rb").read() == 'a' * mapsize
518
# opening with size too big
519
f = open(filename, "r+b")
520
if not os.name == "nt":
521
# this should work under windows
522
raises(ValueError, mmap.mmap, f.fileno(), mapsize + 1)
526
# # repair damage from the resizing test.
527
# f = open(filename, 'r+b')
528
# f.truncate(mapsize)
532
# test access=ACCESS_WRITE"
533
f = open(filename, "r+b")
534
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
535
m.write('c' * mapsize)
537
data = m.read(mapsize)
538
assert data == 'c' * mapsize
542
f = open(filename, 'rb')
545
assert stuff == 'c' * mapsize
547
# test access=ACCESS_COPY
548
f = open(filename, "r+b")
549
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
550
m.write('d' * mapsize)
552
data = m.read(mapsize)
553
assert data == 'd' * mapsize
555
assert open(filename, "rb").read() == 'c' * mapsize
556
if not (("darwin" in sys.platform) or ("freebsd" in sys.platform)):
557
raises(TypeError, m.resize, 2 * mapsize)
561
# test invalid access
562
f = open(filename, "r+b")
563
raises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
566
# test incompatible parameters
567
if os.name == "posix":
568
f = open(filename, "r+b")
569
raises(ValueError, mmap.mmap, f.fileno(), mapsize, flags=mmap.MAP_PRIVATE,
570
prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
574
# bad file descriptor
575
raises(EnvironmentError, mmap.mmap, -2, 4096)
577
# do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
578
# searching for data with embedded \0 bytes didn't work.
579
f = open(filename, 'w+')
580
data = 'aabaac\x00deef\x00\x00aa\x00'
584
m = mmap.mmap(f.fileno(), n)
587
for start in range(n + 1):
588
for finish in range(start, n + 1):
589
sl = data[start:finish]
590
assert m.find(sl) == data.find(sl)
591
assert m.find(sl + 'x') == -1
594
# test mapping of entire file by passing 0 for map length
595
f = open(filename, "w+")
598
f = open(filename, "rb+")
599
m = mmap.mmap(f.fileno(), 0)
600
assert len(m) == 2**16
601
assert m.read(2**16) == 2**16 * "m"
605
# make move works everywhere (64-bit format problem earlier)
606
f = open(filename, 'w+')
607
f.write("ABCDEabcde")
609
m = mmap.mmap(f.fileno(), 10)
611
assert m.read(10) == "ABCDEABCDE"