Revert the Lib/test/test_bigmem.py changes from commit 17891566a478 (and a

few other assertEqual tests that snuck in), and expand the docstrings and
comments explaining why and how these tests are supposed to work.
This commit is contained in:
Thomas Wouters 2011-03-25 11:42:37 +01:00
parent 07b29a07ad
commit 518b5aea1a
2 changed files with 58 additions and 28 deletions

View File

@ -1029,6 +1029,11 @@ def bigmemtest(minsize, memuse):
return decorator
def precisionbigmemtest(size, memuse):
"""Decorator for bigmem tests that need exact sizes.
Like bigmemtest, but without the size scaling upward to fill available
memory.
"""
def decorator(f):
def wrapper(self):
size = wrapper.size

View File

@ -1,3 +1,13 @@
"""Bigmem tests - tests for the 32-bit boundary in containers.
These tests try to exercise the 32-bit boundary that is sometimes, if
rarely, exceeded in practice, but almost never tested. They are really only
meaningful on 64-bit builds on machines with a *lot* of memory, but the
tests are always run, usually with very low memory limits to make sure the
tests themselves don't suffer from bitrot. To run them for real, pass a
high memory limit to regrtest, with the -M option.
"""
from test import support
from test.support import bigmemtest, _1G, _2G, _4G, precisionbigmemtest
@ -6,30 +16,45 @@ import operator
import sys
import functools
# These tests all use one of the bigmemtest decorators to indicate how much
# memory they use and how much memory they need to be even meaningful. The
# decorators take two arguments: a 'memuse' indicator declaring
# (approximate) bytes per size-unit the test will use (at peak usage), and a
# 'minsize' indicator declaring a minimum *useful* size. A test that
# allocates a bytestring to test various operations near the end will have a
# minsize of at least 2Gb (or it wouldn't reach the 32-bit limit, so the
# test wouldn't be very useful) and a memuse of 1 (one byte per size-unit,
# if it allocates only one big string at a time.)
#
# When run with a memory limit set, both decorators skip tests that need
# more memory than available to be meaningful. The precisionbigmemtest will
# always pass minsize as size, even if there is much more memory available.
# The bigmemtest decorator will scale size upward to fill available memory.
#
# Bigmem testing houserules:
#
# - Try not to allocate too many large objects. It's okay to rely on
# refcounting semantics, but don't forget that 's = create_largestring()'
# refcounting semantics, and don't forget that 's = create_largestring()'
# doesn't release the old 's' (if it exists) until well after its new
# value has been created. Use 'del s' before the create_largestring call.
#
# - Do *not* compare large objects using assertEqual or similar. It's a
# lengthy operation and the errormessage will be utterly useless due to
# its size. To make sure whether a result has the right contents, better
# to use the strip or count methods, or compare meaningful slices.
# - Do *not* compare large objects using assertEqual, assertIn or similar.
# It's a lengthy operation and the errormessage will be utterly useless
# due to its size. To make sure whether a result has the right contents,
# better to use the strip or count methods, or compare meaningful slices.
#
# - Don't forget to test for large indices, offsets and results and such,
# in addition to large sizes.
# in addition to large sizes. Anything that probes the 32-bit boundary.
#
# - When repeating an object (say, a substring, or a small list) to create
# a large object, make the subobject of a length that is not a power of
# 2. That way, int-wrapping problems are more easily detected.
#
# - While the bigmemtest decorator speaks of 'minsize', all tests will
# actually be called with a much smaller number too, in the normal
# test run (5Kb currently.) This is so the tests themselves get frequent
# testing. Consequently, always make all large allocations based on the
# passed-in 'size', and don't rely on the size being very large. Also,
# - While the bigmem decorators speak of 'minsize', all tests will actually
# be called with a much smaller number too, in the normal test run (5Kb
# currently.) This is so the tests themselves get frequent testing.
# Consequently, always make all large allocations based on the passed-in
# 'size', and don't rely on the size being very large. Also,
# memuse-per-size should remain sane (less than a few thousand); if your
# test uses more, adjust 'size' upward, instead.
@ -92,7 +117,7 @@ class BaseStrTest:
_ = self.from_latin1
s = _('-') * size
tabsize = 8
self.assertEqual(s.expandtabs(), s)
self.assertTrue(s.expandtabs() == s)
del s
slen, remainder = divmod(size, tabsize)
s = _(' \t') * slen
@ -519,19 +544,19 @@ class BaseStrTest:
edge = _('-') * (size // 2)
s = _('').join([edge, SUBSTR, edge])
del edge
self.assertIn(SUBSTR, s)
self.assertNotIn(SUBSTR * 2, s)
self.assertIn(_('-'), s)
self.assertNotIn(_('a'), s)
self.assertTrue(SUBSTR in s)
self.assertFalse(SUBSTR * 2 in s)
self.assertTrue(_('-') in s)
self.assertFalse(_('a') in s)
s += _('a')
self.assertIn(_('a'), s)
self.assertTrue(_('a') in s)
@bigmemtest(minsize=_2G + 10, memuse=2)
def test_compare(self, size):
_ = self.from_latin1
s1 = _('-') * size
s2 = _('-') * size
self.assertEqual(s1, s2)
self.assertTrue(s1 == s2)
del s2
s2 = s1 + _('a')
self.assertFalse(s1 == s2)
@ -552,7 +577,7 @@ class BaseStrTest:
h1 = hash(s)
del s
s = _('\x00') * (size + 1)
self.assertFalse(h1 == hash(s))
self.assertNotEqual(h1, hash(s))
class StrTest(unittest.TestCase, BaseStrTest):
@ -633,7 +658,7 @@ class StrTest(unittest.TestCase, BaseStrTest):
def test_format(self, size):
s = '-' * size
sf = '%s' % (s,)
self.assertEqual(s, sf)
self.assertTrue(s == sf)
del sf
sf = '..%s..' % (s,)
self.assertEqual(len(sf), len(s) + 4)
@ -743,7 +768,7 @@ class TupleTest(unittest.TestCase):
def test_compare(self, size):
t1 = ('',) * size
t2 = ('',) * size
self.assertEqual(t1, t2)
self.assertTrue(t1 == t2)
del t2
t2 = ('',) * (size + 1)
self.assertFalse(t1 == t2)
@ -774,9 +799,9 @@ class TupleTest(unittest.TestCase):
def test_contains(self, size):
t = (1, 2, 3, 4, 5) * size
self.assertEqual(len(t), size * 5)
self.assertIn(5, t)
self.assertNotIn((1, 2, 3, 4, 5), t)
self.assertNotIn(0, t)
self.assertTrue(5 in t)
self.assertFalse((1, 2, 3, 4, 5) in t)
self.assertFalse(0 in t)
@bigmemtest(minsize=_2G + 10, memuse=8)
def test_hash(self, size):
@ -879,7 +904,7 @@ class ListTest(unittest.TestCase):
def test_compare(self, size):
l1 = [''] * size
l2 = [''] * size
self.assertEqual(l1, l2)
self.assertTrue(l1 == l2)
del l2
l2 = [''] * (size + 1)
self.assertFalse(l1 == l2)
@ -925,9 +950,9 @@ class ListTest(unittest.TestCase):
def test_contains(self, size):
l = [1, 2, 3, 4, 5] * size
self.assertEqual(len(l), size * 5)
self.assertIn(5, l)
self.assertNotIn([1, 2, 3, 4, 5], l)
self.assertNotIn(0, l)
self.assertTrue(5 in l)
self.assertFalse([1, 2, 3, 4, 5] in l)
self.assertFalse(0 in l)
@bigmemtest(minsize=_2G + 10, memuse=8)
def test_hash(self, size):