test_bigaddrspace.py 2.92 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
"""
These tests are meant to exercise that requests to create objects bigger
than what the address space allows are properly met with an OverflowError
(rather than crash weirdly).

Primarily, this means 32-bit builds with at least 2 GB of available memory.
You need to pass the -M option to regrtest (e.g. "-M 2.1G") for tests to
be enabled.
"""

11 12
from test import support
from test.support import bigaddrspacetest, MAX_Py_ssize_t
13 14 15 16 17 18

import unittest
import operator
import sys


19 20 21 22 23 24 25
class BytesTest(unittest.TestCase):

    @bigaddrspacetest
    def test_concat(self):
        # Allocate a bytestring that's near the maximum size allowed by
        # the address space, and then try to build a new, larger one through
        # concatenation.
26 27 28 29 30
        try:
            x = b"x" * (MAX_Py_ssize_t - 128)
            self.assertRaises(OverflowError, operator.add, x, b"x" * 128)
        finally:
            x = None
31 32 33

    @bigaddrspacetest
    def test_optimized_concat(self):
34 35
        try:
            x = b"x" * (MAX_Py_ssize_t - 128)
36

37 38 39
            with self.assertRaises(OverflowError) as cm:
                # this statement used a fast path in ceval.c
                x = x + b"x" * 128
40

41 42 43 44 45
            with self.assertRaises(OverflowError) as cm:
                # this statement used a fast path in ceval.c
                x +=  b"x" * 128
        finally:
            x = None
46 47 48

    @bigaddrspacetest
    def test_repeat(self):
49 50 51 52 53
        try:
            x = b"x" * (MAX_Py_ssize_t - 128)
            self.assertRaises(OverflowError, operator.mul, x, 128)
        finally:
            x = None
54 55


56 57
class StrTest(unittest.TestCase):

58 59
    unicodesize = 2 if sys.maxunicode < 65536 else 4

60 61
    @bigaddrspacetest
    def test_concat(self):
62 63 64 65 66 67 68 69
        try:
            # Create a string that would fill almost the address space
            x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize))
            # Unicode objects trigger MemoryError in case an operation that's
            # going to cause a size overflow is executed
            self.assertRaises(MemoryError, operator.add, x, x)
        finally:
            x = None
70 71 72

    @bigaddrspacetest
    def test_optimized_concat(self):
73 74
        try:
            x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize))
75

76 77 78
            with self.assertRaises(MemoryError) as cm:
                # this statement uses a fast path in ceval.c
                x = x + x
79

80 81 82 83 84
            with self.assertRaises(MemoryError) as cm:
                # this statement uses a fast path in ceval.c
                x +=  x
        finally:
            x = None
85 86 87

    @bigaddrspacetest
    def test_repeat(self):
88 89 90 91 92
        try:
            x = "x" * int(MAX_Py_ssize_t // (1.1 * self.unicodesize))
            self.assertRaises(MemoryError, operator.mul, x, 2)
        finally:
            x = None
93 94 95


def test_main():
96
    support.run_unittest(BytesTest, StrTest)
97 98 99

if __name__ == '__main__':
    if len(sys.argv) > 1:
100
        support.set_memlimit(sys.argv[1])
101
    test_main()