Include module for desktop build
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import decimal
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class TestDecode(TestCase):
|
||||
def test_decimal(self):
|
||||
rval = json.loads('1.1', parse_float=decimal.Decimal)
|
||||
self.assert_(isinstance(rval, decimal.Decimal))
|
||||
self.assertEquals(rval, decimal.Decimal('1.1'))
|
||||
|
||||
def test_float(self):
|
||||
rval = json.loads('1', parse_int=float)
|
||||
self.assert_(isinstance(rval, float))
|
||||
self.assertEquals(rval, 1.0)
|
||||
@@ -0,0 +1,9 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class TestDefault(TestCase):
|
||||
def test_default(self):
|
||||
self.assertEquals(
|
||||
json.dumps(type, default=repr),
|
||||
json.dumps(repr(type)))
|
||||
@@ -0,0 +1,13 @@
|
||||
from unittest import TestCase
|
||||
from cStringIO import StringIO
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class TestDump(TestCase):
|
||||
def test_dump(self):
|
||||
sio = StringIO()
|
||||
json.dump({}, sio)
|
||||
self.assertEquals(sio.getvalue(), '{}')
|
||||
|
||||
def test_dumps(self):
|
||||
self.assertEquals(json.dumps({}), '{}')
|
||||
@@ -0,0 +1,36 @@
|
||||
from twisted.trial.unittest import SkipTest, TestCase
|
||||
|
||||
from pyutil.jsonutil import encoder
|
||||
|
||||
CASES = [
|
||||
(u'/\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\x08\x0c\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?', '"/\\\\\\"\\ucafe\\ubabe\\uab98\\ufcde\\ubcda\\uef4a\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?"'),
|
||||
(u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
|
||||
(u'controls', '"controls"'),
|
||||
(u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
|
||||
(u'{"object with 1 member":["array with 1 element"]}', '"{\\"object with 1 member\\":[\\"array with 1 element\\"]}"'),
|
||||
(u' s p a c e d ', '" s p a c e d "'),
|
||||
(u'\U0001d120', '"\\ud834\\udd20"'),
|
||||
(u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
|
||||
('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
|
||||
(u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
|
||||
('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
|
||||
(u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
|
||||
(u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
|
||||
(u"`1~!@#$%^&*()_+-={':[,]}|;.</>?", '"`1~!@#$%^&*()_+-={\':[,]}|;.</>?"'),
|
||||
(u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
|
||||
(u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
|
||||
]
|
||||
|
||||
class TestEncodeBaseStringAscii(TestCase):
|
||||
def test_py_encode_basestring_ascii(self):
|
||||
self._test_encode_basestring_ascii(encoder.py_encode_basestring_ascii)
|
||||
|
||||
def test_c_encode_basestring_ascii(self):
|
||||
if not encoder.c_encode_basestring_ascii:
|
||||
raise SkipTest("no C extension speedups available to test")
|
||||
self._test_encode_basestring_ascii(encoder.c_encode_basestring_ascii)
|
||||
|
||||
def _test_encode_basestring_ascii(self, encode_basestring_ascii):
|
||||
for input_string, expect in CASES:
|
||||
result = encode_basestring_ascii(input_string)
|
||||
self.assertEquals(result, expect)
|
||||
@@ -0,0 +1,76 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
# Fri Dec 30 18:57:26 2005
|
||||
JSONDOCS = [
|
||||
# http://json.org/JSON_checker/test/fail1.json
|
||||
'"A JSON payload should be an object or array, not a string."',
|
||||
# http://json.org/JSON_checker/test/fail2.json
|
||||
'["Unclosed array"',
|
||||
# http://json.org/JSON_checker/test/fail3.json
|
||||
'{unquoted_key: "keys must be quoted}',
|
||||
# http://json.org/JSON_checker/test/fail4.json
|
||||
'["extra comma",]',
|
||||
# http://json.org/JSON_checker/test/fail5.json
|
||||
'["double extra comma",,]',
|
||||
# http://json.org/JSON_checker/test/fail6.json
|
||||
'[ , "<-- missing value"]',
|
||||
# http://json.org/JSON_checker/test/fail7.json
|
||||
'["Comma after the close"],',
|
||||
# http://json.org/JSON_checker/test/fail8.json
|
||||
'["Extra close"]]',
|
||||
# http://json.org/JSON_checker/test/fail9.json
|
||||
'{"Extra comma": true,}',
|
||||
# http://json.org/JSON_checker/test/fail10.json
|
||||
'{"Extra value after close": true} "misplaced quoted value"',
|
||||
# http://json.org/JSON_checker/test/fail11.json
|
||||
'{"Illegal expression": 1 + 2}',
|
||||
# http://json.org/JSON_checker/test/fail12.json
|
||||
'{"Illegal invocation": alert()}',
|
||||
# http://json.org/JSON_checker/test/fail13.json
|
||||
'{"Numbers cannot have leading zeroes": 013}',
|
||||
# http://json.org/JSON_checker/test/fail14.json
|
||||
'{"Numbers cannot be hex": 0x14}',
|
||||
# http://json.org/JSON_checker/test/fail15.json
|
||||
'["Illegal backslash escape: \\x15"]',
|
||||
# http://json.org/JSON_checker/test/fail16.json
|
||||
'["Illegal backslash escape: \\\'"]',
|
||||
# http://json.org/JSON_checker/test/fail17.json
|
||||
'["Illegal backslash escape: \\017"]',
|
||||
# http://json.org/JSON_checker/test/fail18.json
|
||||
'[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
|
||||
# http://json.org/JSON_checker/test/fail19.json
|
||||
'{"Missing colon" null}',
|
||||
# http://json.org/JSON_checker/test/fail20.json
|
||||
'{"Double colon":: null}',
|
||||
# http://json.org/JSON_checker/test/fail21.json
|
||||
'{"Comma instead of colon", null}',
|
||||
# http://json.org/JSON_checker/test/fail22.json
|
||||
'["Colon instead of comma": false]',
|
||||
# http://json.org/JSON_checker/test/fail23.json
|
||||
'["Bad value", truth]',
|
||||
# http://json.org/JSON_checker/test/fail24.json
|
||||
"['single quote']",
|
||||
# http://code.google.com/p/simplejson/issues/detail?id=3
|
||||
u'["A\u001FZ control characters in string"]',
|
||||
]
|
||||
|
||||
SKIPS = {
|
||||
1: "why not have a string payload?",
|
||||
18: "spec doesn't specify any nesting limitations",
|
||||
}
|
||||
|
||||
class TestFail(TestCase):
|
||||
def test_failures(self):
|
||||
for idx, doc in enumerate(JSONDOCS):
|
||||
idx = idx + 1
|
||||
if idx in SKIPS:
|
||||
json.loads(doc)
|
||||
continue
|
||||
try:
|
||||
json.loads(doc)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("Expected failure for fail%d.json: %r" % (idx, doc))
|
||||
@@ -0,0 +1,9 @@
|
||||
import math
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class TestFloat(TestCase):
|
||||
def test_floats(self):
|
||||
for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100]:
|
||||
self.assertEquals(float(json.dumps(num)), num)
|
||||
@@ -0,0 +1,41 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
import textwrap
|
||||
|
||||
class TestIndent(TestCase):
|
||||
def test_indent(self):
|
||||
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
|
||||
{'nifty': 87}, {'field': 'yes', 'morefield': False} ]
|
||||
|
||||
expect = textwrap.dedent("""\
|
||||
[
|
||||
[
|
||||
"blorpie"
|
||||
],
|
||||
[
|
||||
"whoops"
|
||||
],
|
||||
[],
|
||||
"d-shtaeou",
|
||||
"d-nthiouh",
|
||||
"i-vhbjkhnth",
|
||||
{
|
||||
"nifty": 87
|
||||
},
|
||||
{
|
||||
"field": "yes",
|
||||
"morefield": false
|
||||
}
|
||||
]""")
|
||||
|
||||
|
||||
d1 = json.dumps(h)
|
||||
d2 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
|
||||
|
||||
h1 = json.loads(d1)
|
||||
h2 = json.loads(d2)
|
||||
|
||||
self.assertEquals(h1, h)
|
||||
self.assertEquals(h2, h)
|
||||
self.assertEquals(d2, expect)
|
||||
@@ -0,0 +1,71 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass1.json
|
||||
JSON = r'''
|
||||
[
|
||||
"JSON Test Pattern pass1",
|
||||
{"object with 1 member":["array with 1 element"]},
|
||||
{},
|
||||
[],
|
||||
-42,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
{
|
||||
"integer": 1234567890,
|
||||
"real": -9876.543210,
|
||||
"e": 0.123456789e-12,
|
||||
"E": 1.234567890E+34,
|
||||
"": 23456789012E666,
|
||||
"zero": 0,
|
||||
"one": 1,
|
||||
"space": " ",
|
||||
"quote": "\"",
|
||||
"backslash": "\\",
|
||||
"controls": "\b\f\n\r\t",
|
||||
"slash": "/ & \/",
|
||||
"alpha": "abcdefghijklmnopqrstuvwyz",
|
||||
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
||||
"digit": "0123456789",
|
||||
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
|
||||
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
||||
"true": true,
|
||||
"false": false,
|
||||
"null": null,
|
||||
"array":[ ],
|
||||
"object":{ },
|
||||
"address": "50 St. James Street",
|
||||
"url": "http://www.JSON.org/",
|
||||
"comment": "// /* <!-- --",
|
||||
"# -- --> */": " ",
|
||||
" s p a c e d " :[1,2 , 3
|
||||
|
||||
,
|
||||
|
||||
4 , 5 , 6 ,7 ],
|
||||
"compact": [1,2,3,4,5,6,7],
|
||||
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
|
||||
"quotes": "" \u0022 %22 0x22 034 "",
|
||||
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
|
||||
: "A key can be any string"
|
||||
},
|
||||
0.5 ,98.6
|
||||
,
|
||||
99.44
|
||||
,
|
||||
|
||||
1066
|
||||
|
||||
|
||||
,"rosebud"]
|
||||
'''
|
||||
|
||||
class TestPass1(TestCase):
|
||||
def test_parse(self):
|
||||
# test in/out equivalence and parsing
|
||||
res = json.loads(JSON)
|
||||
out = json.dumps(res)
|
||||
self.assertEquals(res, json.loads(out))
|
||||
self.failUnless("2.3456789012E+676" in json.dumps(res, allow_nan=False))
|
||||
@@ -0,0 +1,14 @@
|
||||
from unittest import TestCase
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass2.json
|
||||
JSON = r'''
|
||||
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
|
||||
'''
|
||||
|
||||
class TestPass2(TestCase):
|
||||
def test_parse(self):
|
||||
# test in/out equivalence and parsing
|
||||
res = json.loads(JSON)
|
||||
out = json.dumps(res)
|
||||
self.assertEquals(res, json.loads(out))
|
||||
@@ -0,0 +1,20 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass3.json
|
||||
JSON = r'''
|
||||
{
|
||||
"JSON Test Pattern pass3": {
|
||||
"The outermost value": "must be an object or array.",
|
||||
"In this test": "It is an object."
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
class TestPass3(TestCase):
|
||||
def test_parse(self):
|
||||
# test in/out equivalence and parsing
|
||||
res = json.loads(JSON)
|
||||
out = json.dumps(res)
|
||||
self.assertEquals(res, json.loads(out))
|
||||
@@ -0,0 +1,67 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class JSONTestObject:
|
||||
pass
|
||||
|
||||
|
||||
class RecursiveJSONEncoder(json.JSONEncoder):
|
||||
recurse = False
|
||||
def default(self, o):
|
||||
if o is JSONTestObject:
|
||||
if self.recurse:
|
||||
return [JSONTestObject]
|
||||
else:
|
||||
return 'JSONTestObject'
|
||||
return json.JSONEncoder.default(o)
|
||||
|
||||
|
||||
class TestRecursion(TestCase):
|
||||
def test_listrecursion(self):
|
||||
x = []
|
||||
x.append(x)
|
||||
try:
|
||||
json.dumps(x)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("didn't raise ValueError on list recursion")
|
||||
x = []
|
||||
y = [x]
|
||||
x.append(y)
|
||||
try:
|
||||
json.dumps(x)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("didn't raise ValueError on alternating list recursion")
|
||||
y = []
|
||||
x = [y, y]
|
||||
# ensure that the marker is cleared
|
||||
json.dumps(x)
|
||||
|
||||
def test_dictrecursion(self):
|
||||
x = {}
|
||||
x["test"] = x
|
||||
try:
|
||||
json.dumps(x)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("didn't raise ValueError on dict recursion")
|
||||
x = {}
|
||||
{"a": x, "b": x}
|
||||
# ensure that the marker is cleared
|
||||
json.dumps(x)
|
||||
|
||||
def test_defaultrecursion(self):
|
||||
enc = RecursiveJSONEncoder()
|
||||
self.assertEquals(enc.encode(JSONTestObject), '"JSONTestObject"')
|
||||
enc.recurse = True
|
||||
try:
|
||||
enc.encode(JSONTestObject)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("didn't raise ValueError on default recursion")
|
||||
@@ -0,0 +1,42 @@
|
||||
import textwrap
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
|
||||
class TestSeparators(TestCase):
|
||||
def test_separators(self):
|
||||
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
|
||||
{'nifty': 87}, {'field': 'yes', 'morefield': False} ]
|
||||
|
||||
expect = textwrap.dedent("""\
|
||||
[
|
||||
[
|
||||
"blorpie"
|
||||
] ,
|
||||
[
|
||||
"whoops"
|
||||
] ,
|
||||
[] ,
|
||||
"d-shtaeou" ,
|
||||
"d-nthiouh" ,
|
||||
"i-vhbjkhnth" ,
|
||||
{
|
||||
"nifty" : 87
|
||||
} ,
|
||||
{
|
||||
"field" : "yes" ,
|
||||
"morefield" : false
|
||||
}
|
||||
]""")
|
||||
|
||||
|
||||
d1 = json.dumps(h)
|
||||
d2 = json.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : '))
|
||||
|
||||
h1 = json.loads(d1)
|
||||
h2 = json.loads(d2)
|
||||
|
||||
self.assertEquals(h1, h)
|
||||
self.assertEquals(h2, h)
|
||||
self.assertEquals(d2, expect)
|
||||
@@ -0,0 +1,18 @@
|
||||
from twisted.trial.unittest import SkipTest, TestCase
|
||||
|
||||
from pyutil.jsonutil import decoder
|
||||
from pyutil.jsonutil import encoder
|
||||
|
||||
class TestSpeedups(TestCase):
|
||||
def test_scanstring(self):
|
||||
if not encoder.c_encode_basestring_ascii:
|
||||
raise SkipTest("no C extension speedups available to test")
|
||||
self.assertEquals(decoder.scanstring.__module__, "simplejson._speedups")
|
||||
self.assert_(decoder.scanstring is decoder.c_scanstring)
|
||||
|
||||
def test_encode_basestring_ascii(self):
|
||||
if not encoder.c_encode_basestring_ascii:
|
||||
raise SkipTest("no C extension speedups available to test")
|
||||
self.assertEquals(encoder.encode_basestring_ascii.__module__, "simplejson._speedups")
|
||||
self.assert_(encoder.encode_basestring_ascii is
|
||||
encoder.c_encode_basestring_ascii)
|
||||
@@ -0,0 +1,55 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from pyutil import jsonutil as json
|
||||
|
||||
class TestUnicode(TestCase):
|
||||
def test_encoding1(self):
|
||||
encoder = json.JSONEncoder(encoding='utf-8')
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
s = u.encode('utf-8')
|
||||
ju = encoder.encode(u)
|
||||
js = encoder.encode(s)
|
||||
self.assertEquals(ju, js)
|
||||
|
||||
def test_encoding2(self):
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
s = u.encode('utf-8')
|
||||
ju = json.dumps(u, encoding='utf-8')
|
||||
js = json.dumps(s, encoding='utf-8')
|
||||
self.assertEquals(ju, js)
|
||||
|
||||
def test_encoding3(self):
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = json.dumps(u)
|
||||
self.assertEquals(j, '"\\u03b1\\u03a9"')
|
||||
|
||||
def test_encoding4(self):
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = json.dumps([u])
|
||||
self.assertEquals(j, '["\\u03b1\\u03a9"]')
|
||||
|
||||
def test_encoding5(self):
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = json.dumps(u, ensure_ascii=False)
|
||||
self.assertEquals(j, u'"%s"' % (u,))
|
||||
|
||||
def test_encoding6(self):
|
||||
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = json.dumps([u], ensure_ascii=False)
|
||||
self.assertEquals(j, u'["%s"]' % (u,))
|
||||
|
||||
def test_big_unicode_encode(self):
|
||||
u = u'\U0001d120'
|
||||
self.assertEquals(json.dumps(u), '"\\ud834\\udd20"')
|
||||
self.assertEquals(json.dumps(u, ensure_ascii=False), u'"\U0001d120"')
|
||||
|
||||
def test_big_unicode_decode(self):
|
||||
u = u'z\U0001d120x'
|
||||
self.assertEquals(json.loads('"' + u + '"'), u)
|
||||
self.assertEquals(json.loads('"z\\ud834\\udd20x"'), u)
|
||||
|
||||
def test_unicode_decode(self):
|
||||
for i in range(0, 0xd7ff):
|
||||
u = unichr(i)
|
||||
js = '"\\u%04x"' % (i,)
|
||||
self.assertEquals(json.loads(js), u)
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002-2009 Zooko Wilcox-O'Hearn
|
||||
# portions Copyright (c) 2001 Autonomous Zone Industries
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
# Python Standard Library modules
|
||||
import unittest
|
||||
|
||||
from pyutil import assertutil
|
||||
|
||||
class Testy(unittest.TestCase):
|
||||
def test_bad_precond(self):
|
||||
adict=23
|
||||
try:
|
||||
assertutil.precondition(isinstance(adict, dict), "adict is required to be a dict.", 23, adict=adict, foo=None)
|
||||
except AssertionError, le:
|
||||
self.failUnless(le.args[0] == "precondition: 'adict is required to be a dict.' <type 'str'>, 23 <type 'int'>, foo: None <type 'NoneType'>, 'adict': 23 <type 'int'>")
|
||||
@@ -0,0 +1,33 @@
|
||||
import unittest
|
||||
|
||||
import os
|
||||
|
||||
from pyutil import fileutil
|
||||
|
||||
class FileUtil(unittest.TestCase):
|
||||
def mkdir(self, basedir, path, mode=0777):
|
||||
fn = os.path.join(basedir, path)
|
||||
fileutil.make_dirs(fn, mode)
|
||||
|
||||
def touch(self, basedir, path, mode=None, data="touch\n"):
|
||||
fn = os.path.join(basedir, path)
|
||||
f = open(fn, "w")
|
||||
f.write(data)
|
||||
f.close()
|
||||
if mode is not None:
|
||||
os.chmod(fn, mode)
|
||||
|
||||
def test_du(self):
|
||||
basedir = "util/FileUtil/test_du"
|
||||
fileutil.make_dirs(basedir)
|
||||
d = os.path.join(basedir, "space-consuming")
|
||||
self.mkdir(d, "a/b")
|
||||
self.touch(d, "a/b/1.txt", data="a"*10)
|
||||
self.touch(d, "a/b/2.txt", data="b"*11)
|
||||
self.mkdir(d, "a/c")
|
||||
self.touch(d, "a/c/1.txt", data="c"*12)
|
||||
self.touch(d, "a/c/2.txt", data="d"*13)
|
||||
|
||||
used = fileutil.du(basedir)
|
||||
self.failUnlessEqual(10+11+12+13, used)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
try:
|
||||
from twisted.trial import unittest
|
||||
unittest # http://divmod.org/trac/ticket/1499
|
||||
except ImportError, le:
|
||||
print "Skipping test_iputil since it requires Twisted and Twisted could not be imported: %s" % (le,)
|
||||
else:
|
||||
from pyutil import iputil, testutil
|
||||
import re
|
||||
|
||||
DOTTED_QUAD_RE=re.compile("^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$")
|
||||
|
||||
class ListAddresses(testutil.SignalMixin):
|
||||
def test_get_local_ip_for(self):
|
||||
addr = iputil.get_local_ip_for('127.0.0.1')
|
||||
self.failUnless(DOTTED_QUAD_RE.match(addr))
|
||||
|
||||
def test_list_async(self):
|
||||
try:
|
||||
from twisted.trial import unittest
|
||||
unittest # http://divmod.org/trac/ticket/1499
|
||||
from pyutil import iputil
|
||||
except ImportError, le:
|
||||
raise unittest.SkipTest("iputil could not be imported (probably because its dependency, Twisted, is not installed). %s" % (le,))
|
||||
|
||||
d = iputil.get_local_addresses_async()
|
||||
def _check(addresses):
|
||||
self.failUnless(len(addresses) >= 1) # always have localhost
|
||||
self.failUnless("127.0.0.1" in addresses, addresses)
|
||||
d.addCallbacks(_check)
|
||||
return d
|
||||
test_list_async.timeout=2
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import unittest
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from pyutil import jsonutil
|
||||
|
||||
zero_point_one = Decimal("0.1")
|
||||
class TestDecimal(unittest.TestCase):
|
||||
def test_encode(self):
|
||||
self.failUnlessEqual(jsonutil.dumps(zero_point_one), "0.1")
|
||||
|
||||
def test_decode(self):
|
||||
self.failUnlessEqual(jsonutil.loads("0.1"), zero_point_one)
|
||||
|
||||
def test_no_exception_on_convergent_parse_float(self):
|
||||
self.failUnlessEqual(jsonutil.loads("0.1", parse_float=Decimal), zero_point_one)
|
||||
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import unittest
|
||||
|
||||
from pyutil import mathutil
|
||||
from pyutil.assertutil import _assert
|
||||
|
||||
class MathUtilTestCase(unittest.TestCase):
|
||||
def _help_test_is_power_of_k(self, k):
|
||||
for i in range(2, 40):
|
||||
_assert(mathutil.is_power_of_k(k**i, k), k, i)
|
||||
|
||||
def test_is_power_of_k(self):
|
||||
for i in range(2, 5):
|
||||
self._help_test_is_power_of_k(i)
|
||||
|
||||
def test_log_ceil(self):
|
||||
f = mathutil.log_ceil
|
||||
self.failUnlessEqual(f(1, 2), 0)
|
||||
self.failUnlessEqual(f(1, 3), 0)
|
||||
self.failUnlessEqual(f(2, 2), 1)
|
||||
self.failUnlessEqual(f(2, 3), 1)
|
||||
self.failUnlessEqual(f(3, 2), 2)
|
||||
|
||||
def test_log_floor(self):
|
||||
f = mathutil.log_floor
|
||||
self.failUnlessEqual(f(1, 2), 0)
|
||||
self.failUnlessEqual(f(1, 3), 0)
|
||||
self.failUnlessEqual(f(2, 2), 1)
|
||||
self.failUnlessEqual(f(2, 3), 0)
|
||||
self.failUnlessEqual(f(3, 2), 1)
|
||||
|
||||
def test_div_ceil(self):
|
||||
f = mathutil.div_ceil
|
||||
self.failUnlessEqual(f(0, 1), 0)
|
||||
self.failUnlessEqual(f(0, 2), 0)
|
||||
self.failUnlessEqual(f(0, 3), 0)
|
||||
self.failUnlessEqual(f(1, 3), 1)
|
||||
self.failUnlessEqual(f(2, 3), 1)
|
||||
self.failUnlessEqual(f(3, 3), 1)
|
||||
self.failUnlessEqual(f(4, 3), 2)
|
||||
self.failUnlessEqual(f(5, 3), 2)
|
||||
self.failUnlessEqual(f(6, 3), 2)
|
||||
self.failUnlessEqual(f(7, 3), 3)
|
||||
|
||||
def test_next_multiple(self):
|
||||
f = mathutil.next_multiple
|
||||
self.failUnlessEqual(f(5, 1), 5)
|
||||
self.failUnlessEqual(f(5, 2), 6)
|
||||
self.failUnlessEqual(f(5, 3), 6)
|
||||
self.failUnlessEqual(f(5, 4), 8)
|
||||
self.failUnlessEqual(f(5, 5), 5)
|
||||
self.failUnlessEqual(f(5, 6), 6)
|
||||
self.failUnlessEqual(f(32, 1), 32)
|
||||
self.failUnlessEqual(f(32, 2), 32)
|
||||
self.failUnlessEqual(f(32, 3), 33)
|
||||
self.failUnlessEqual(f(32, 4), 32)
|
||||
self.failUnlessEqual(f(32, 5), 35)
|
||||
self.failUnlessEqual(f(32, 6), 36)
|
||||
self.failUnlessEqual(f(32, 7), 35)
|
||||
self.failUnlessEqual(f(32, 8), 32)
|
||||
self.failUnlessEqual(f(32, 9), 36)
|
||||
self.failUnlessEqual(f(32, 10), 40)
|
||||
self.failUnlessEqual(f(32, 11), 33)
|
||||
self.failUnlessEqual(f(32, 12), 36)
|
||||
self.failUnlessEqual(f(32, 13), 39)
|
||||
self.failUnlessEqual(f(32, 14), 42)
|
||||
self.failUnlessEqual(f(32, 15), 45)
|
||||
self.failUnlessEqual(f(32, 16), 32)
|
||||
self.failUnlessEqual(f(32, 17), 34)
|
||||
self.failUnlessEqual(f(32, 18), 36)
|
||||
self.failUnlessEqual(f(32, 589), 589)
|
||||
|
||||
def test_pad_size(self):
|
||||
f = mathutil.pad_size
|
||||
self.failUnlessEqual(f(0, 4), 0)
|
||||
self.failUnlessEqual(f(1, 4), 3)
|
||||
self.failUnlessEqual(f(2, 4), 2)
|
||||
self.failUnlessEqual(f(3, 4), 1)
|
||||
self.failUnlessEqual(f(4, 4), 0)
|
||||
self.failUnlessEqual(f(5, 4), 3)
|
||||
|
||||
def test_is_power_of_k_part_2(self):
|
||||
f = mathutil.is_power_of_k
|
||||
for i in range(1, 100):
|
||||
if i in (1, 2, 4, 8, 16, 32, 64):
|
||||
self.failUnless(f(i, 2), "but %d *is* a power of 2" % i)
|
||||
else:
|
||||
self.failIf(f(i, 2), "but %d is *not* a power of 2" % i)
|
||||
for i in range(1, 100):
|
||||
if i in (1, 3, 9, 27, 81):
|
||||
self.failUnless(f(i, 3), "but %d *is* a power of 3" % i)
|
||||
else:
|
||||
self.failIf(f(i, 3), "but %d is *not* a power of 3" % i)
|
||||
|
||||
def test_next_power_of_k(self):
|
||||
f = mathutil.next_power_of_k
|
||||
self.failUnlessEqual(f(0,2), 1)
|
||||
self.failUnlessEqual(f(1,2), 1)
|
||||
self.failUnlessEqual(f(2,2), 2)
|
||||
self.failUnlessEqual(f(3,2), 4)
|
||||
self.failUnlessEqual(f(4,2), 4)
|
||||
for i in range(5, 8): self.failUnlessEqual(f(i,2), 8, "%d" % i)
|
||||
for i in range(9, 16): self.failUnlessEqual(f(i,2), 16, "%d" % i)
|
||||
for i in range(17, 32): self.failUnlessEqual(f(i,2), 32, "%d" % i)
|
||||
for i in range(33, 64): self.failUnlessEqual(f(i,2), 64, "%d" % i)
|
||||
for i in range(65, 100): self.failUnlessEqual(f(i,2), 128, "%d" % i)
|
||||
|
||||
self.failUnlessEqual(f(0,3), 1)
|
||||
self.failUnlessEqual(f(1,3), 1)
|
||||
self.failUnlessEqual(f(2,3), 3)
|
||||
self.failUnlessEqual(f(3,3), 3)
|
||||
for i in range(4, 9): self.failUnlessEqual(f(i,3), 9, "%d" % i)
|
||||
for i in range(10, 27): self.failUnlessEqual(f(i,3), 27, "%d" % i)
|
||||
for i in range(28, 81): self.failUnlessEqual(f(i,3), 81, "%d" % i)
|
||||
for i in range(82, 200): self.failUnlessEqual(f(i,3), 243, "%d" % i)
|
||||
|
||||
def test_ave(self):
|
||||
f = mathutil.ave
|
||||
self.failUnlessEqual(f([1,2,3]), 2)
|
||||
self.failUnlessEqual(f([0,0,0,4]), 1)
|
||||
self.failUnlessAlmostEqual(f([0.0, 1.0, 1.0]), .666666666666)
|
||||
|
||||
def failUnlessEqualContents(self, a, b):
|
||||
self.failUnlessEqual(sorted(a), sorted(b))
|
||||
|
||||
def test_permute(self):
|
||||
f = mathutil.permute
|
||||
self.failUnlessEqualContents(f([]), [])
|
||||
self.failUnlessEqualContents(f([1]), [[1]])
|
||||
self.failUnlessEqualContents(f([1,2]), [[1,2], [2,1]])
|
||||
self.failUnlessEqualContents(f([1,2,3]),
|
||||
[[1,2,3], [1,3,2],
|
||||
[2,1,3], [2,3,1],
|
||||
[3,1,2], [3,2,1]])
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python
|
||||
"""\
|
||||
Test time_format.py
|
||||
"""
|
||||
|
||||
import os, time, unittest
|
||||
|
||||
from pyutil import time_format, increasing_timer
|
||||
|
||||
class TimeUtilTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_iso8601_utc_time(self, timer=increasing_timer.timer):
|
||||
ts1 = time_format.iso_utc(timer.time() - 20)
|
||||
ts2 = time_format.iso_utc()
|
||||
assert ts1 < ts2, "failed: %s < %s" % (ts1, ts2)
|
||||
ts3 = time_format.iso_utc(timer.time() + 20)
|
||||
assert ts2 < ts3, "failed: %s < %s" % (ts2, ts3)
|
||||
|
||||
def test_iso_utc_time_to_localseconds(self, timer=increasing_timer.timer):
|
||||
# test three times of the year so that a DST problem would hopefully be triggered
|
||||
t1 = int(timer.time() - 365*3600/3)
|
||||
iso_utc_t1 = time_format.iso_utc(t1)
|
||||
t1_2 = time_format.iso_utc_time_to_seconds(iso_utc_t1)
|
||||
assert t1 == t1_2, (t1, t1_2)
|
||||
t1 = int(timer.time() - (365*3600*2/3))
|
||||
iso_utc_t1 = time_format.iso_utc(t1)
|
||||
t1_2 = time_format.iso_utc_time_to_seconds(iso_utc_t1)
|
||||
self.failUnlessEqual(t1, t1_2)
|
||||
t1 = int(timer.time())
|
||||
iso_utc_t1 = time_format.iso_utc(t1)
|
||||
t1_2 = time_format.iso_utc_time_to_seconds(iso_utc_t1)
|
||||
self.failUnlessEqual(t1, t1_2)
|
||||
|
||||
def test_epoch(self):
|
||||
return self._help_test_epoch()
|
||||
|
||||
def test_epoch_in_London(self):
|
||||
# Europe/London is a particularly troublesome timezone. Nowadays, its
|
||||
# offset from GMT is 0. But in 1970, its offset from GMT was 1.
|
||||
# (Apparently in 1970 Britain had redefined standard time to be GMT+1
|
||||
# and stayed in standard time all year round, whereas today
|
||||
# Europe/London standard time is GMT and Europe/London Daylight
|
||||
# Savings Time is GMT+1.) The current implementation of
|
||||
# time_format.iso_utc_time_to_seconds() breaks if the timezone is
|
||||
# Europe/London. (As soon as this unit test is done then I'll change
|
||||
# that implementation to something that works even in this case...)
|
||||
origtz = os.environ.get('TZ')
|
||||
os.environ['TZ'] = "Europe/London"
|
||||
if hasattr(time, 'tzset'):
|
||||
time.tzset()
|
||||
try:
|
||||
return self._help_test_epoch()
|
||||
finally:
|
||||
if origtz is None:
|
||||
del os.environ['TZ']
|
||||
else:
|
||||
os.environ['TZ'] = origtz
|
||||
if hasattr(time, 'tzset'):
|
||||
time.tzset()
|
||||
|
||||
def _help_test_epoch(self):
|
||||
origtzname = time.tzname
|
||||
s = time_format.iso_utc_time_to_seconds("1970-01-01T00:00:01Z")
|
||||
self.failUnlessEqual(s, 1.0)
|
||||
s = time_format.iso_utc_time_to_seconds("1970-01-01_00:00:01Z")
|
||||
self.failUnlessEqual(s, 1.0)
|
||||
s = time_format.iso_utc_time_to_seconds("1970-01-01 00:00:01Z")
|
||||
self.failUnlessEqual(s, 1.0)
|
||||
|
||||
self.failUnlessEqual(time_format.iso_utc(1.0), "1970-01-01 00:00:01Z")
|
||||
self.failUnlessEqual(time_format.iso_utc(1.0, sep="_"),
|
||||
"1970-01-01_00:00:01Z")
|
||||
|
||||
now = time.time()
|
||||
isostr = time_format.iso_utc(now)
|
||||
timestamp = time_format.iso_utc_time_to_seconds(isostr)
|
||||
self.failUnlessEqual(int(timestamp), int(now))
|
||||
|
||||
def my_time():
|
||||
return 1.0
|
||||
self.failUnlessEqual(time_format.iso_utc(t=my_time),
|
||||
"1970-01-01 00:00:01Z")
|
||||
self.failUnlessRaises(ValueError,
|
||||
time_format.iso_utc_time_to_seconds,
|
||||
"invalid timestring")
|
||||
s = time_format.iso_utc_time_to_seconds("1970-01-01 00:00:01.500Z")
|
||||
self.failUnlessEqual(s, 1.5)
|
||||
|
||||
# Look for daylight-savings-related errors.
|
||||
thatmomentinmarch = time_format.iso_utc_time_to_seconds("2009-03-20 21:49:02.226536Z")
|
||||
self.failUnlessEqual(thatmomentinmarch, 1237585742.226536)
|
||||
self.failUnlessEqual(origtzname, time.tzname)
|
||||
@@ -0,0 +1,124 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Tests for distutils.version."""
|
||||
import unittest
|
||||
import doctest
|
||||
|
||||
from pyutil.verlib import NormalizedVersion as V
|
||||
from pyutil.verlib import IrrationalVersionError
|
||||
from pyutil.verlib import suggest_normalized_version as suggest
|
||||
|
||||
class VersionTestCase(unittest.TestCase):
|
||||
|
||||
versions = ((V('1.0'), '1.0'),
|
||||
(V('1.1'), '1.1'),
|
||||
(V('1.2.3'), '1.2.3'),
|
||||
(V('1.2'), '1.2'),
|
||||
(V('1.2.3a4'), '1.2.3a4'),
|
||||
(V('1.2c4'), '1.2c4'),
|
||||
(V('1.2.3.4'), '1.2.3.4'),
|
||||
(V('1.2.3.4.0b3'), '1.2.3.4b3'),
|
||||
(V('1.2.0.0.0'), '1.2'),
|
||||
(V('1.0.dev345'), '1.0.dev345'),
|
||||
(V('1.0.post456.dev623'), '1.0.post456.dev623'))
|
||||
|
||||
def test_basic_versions(self):
|
||||
|
||||
for v, s in self.versions:
|
||||
self.assertEquals(str(v), s)
|
||||
|
||||
def test_from_parts(self):
|
||||
|
||||
for v, s in self.versions:
|
||||
v2 = V.from_parts(*v.parts)
|
||||
self.assertEquals(v, v2)
|
||||
self.assertEquals(str(v), str(v2))
|
||||
|
||||
def test_irrational_versions(self):
|
||||
|
||||
irrational = ('1', '1.2a', '1.2.3b', '1.02', '1.2a03',
|
||||
'1.2a3.04', '1.2.dev.2', '1.2dev', '1.2.dev',
|
||||
'1.2.dev2.post2', '1.2.post2.dev3.post4')
|
||||
|
||||
for s in irrational:
|
||||
self.assertRaises(IrrationalVersionError, V, s)
|
||||
|
||||
def test_comparison(self):
|
||||
r"""
|
||||
>>> V('1.2.0') == '1.2'
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: cannot compare NormalizedVersion and str
|
||||
|
||||
>>> V('1.2.0') == V('1.2')
|
||||
True
|
||||
>>> V('1.2.0') == V('1.2.3')
|
||||
False
|
||||
>>> V('1.2.0') < V('1.2.3')
|
||||
True
|
||||
>>> (V('1.0') > V('1.0b2'))
|
||||
True
|
||||
>>> (V('1.0') > V('1.0c2') > V('1.0c1') > V('1.0b2') > V('1.0b1')
|
||||
... > V('1.0a2') > V('1.0a1'))
|
||||
True
|
||||
>>> (V('1.0.0') > V('1.0.0c2') > V('1.0.0c1') > V('1.0.0b2') > V('1.0.0b1')
|
||||
... > V('1.0.0a2') > V('1.0.0a1'))
|
||||
True
|
||||
|
||||
>>> V('1.0') < V('1.0.post456.dev623')
|
||||
True
|
||||
|
||||
>>> V('1.0.post456.dev623') < V('1.0.post456') < V('1.0.post1234')
|
||||
True
|
||||
|
||||
>>> (V('1.0a1')
|
||||
... < V('1.0a2.dev456')
|
||||
... < V('1.0a2')
|
||||
... < V('1.0a2.1.dev456') # e.g. need to do a quick post release on 1.0a2
|
||||
... < V('1.0a2.1')
|
||||
... < V('1.0b1.dev456')
|
||||
... < V('1.0b2')
|
||||
... < V('1.0c1.dev456')
|
||||
... < V('1.0c1')
|
||||
... < V('1.0.dev7')
|
||||
... < V('1.0.dev18')
|
||||
... < V('1.0.dev456')
|
||||
... < V('1.0.dev1234')
|
||||
... < V('1.0')
|
||||
... < V('1.0.post456.dev623') # development version of a post release
|
||||
... < V('1.0.post456'))
|
||||
True
|
||||
"""
|
||||
# must be a simpler way to call the docstrings
|
||||
doctest.run_docstring_examples(self.test_comparison, globals(),
|
||||
name='test_comparison')
|
||||
|
||||
def test_suggest_normalized_version(self):
|
||||
|
||||
self.assertEquals(suggest('1.0'), '1.0')
|
||||
self.assertEquals(suggest('1.0-alpha1'), '1.0a1')
|
||||
self.assertEquals(suggest('1.0c2'), '1.0c2')
|
||||
self.assertEquals(suggest('walla walla washington'), None)
|
||||
self.assertEquals(suggest('2.4c1'), '2.4c1')
|
||||
|
||||
# from setuptools
|
||||
self.assertEquals(suggest('0.4a1.r10'), '0.4a1.post10')
|
||||
self.assertEquals(suggest('0.7a1dev-r66608'), '0.7a1.dev66608')
|
||||
self.assertEquals(suggest('0.6a9.dev-r41475'), '0.6a9.dev41475')
|
||||
self.assertEquals(suggest('2.4preview1'), '2.4c1')
|
||||
self.assertEquals(suggest('2.4pre1') , '2.4c1')
|
||||
self.assertEquals(suggest('2.1-rc2'), '2.1c2')
|
||||
|
||||
# from pypi
|
||||
self.assertEquals(suggest('0.1dev'), '0.1.dev0')
|
||||
self.assertEquals(suggest('0.1.dev'), '0.1.dev0')
|
||||
|
||||
# we want to be able to parse Twisted
|
||||
# development versions are like post releases in Twisted
|
||||
self.assertEquals(suggest('9.0.0+r2363'), '9.0.0.post2363')
|
||||
|
||||
# pre-releases are using markers like "pre1"
|
||||
self.assertEquals(suggest('9.0.0pre1'), '9.0.0c1')
|
||||
|
||||
# we want to be able to parse Tcl-TK
|
||||
# they us "p1" "p2" for post releases
|
||||
self.assertEquals(suggest('1.4p1'), '1.4.post1')
|
||||
@@ -0,0 +1,23 @@
|
||||
import unittest
|
||||
|
||||
from pyutil import version_class
|
||||
|
||||
V = version_class.Version
|
||||
|
||||
class T(unittest.TestCase):
|
||||
def test_rc_regex_rejects_rc_suffix(self):
|
||||
self.failUnlessRaises(ValueError, V, '9.9.9rc9')
|
||||
|
||||
def test_rc_regex_rejects_trailing_garbage(self):
|
||||
self.failUnlessRaises(ValueError, V, '9.9.9c9HEYTHISISNTRIGHT')
|
||||
|
||||
def test_comparisons(self):
|
||||
self.failUnless(V('1.0') < V('1.1'))
|
||||
self.failUnless(V('1.0a1') < V('1.0'))
|
||||
self.failUnless(V('1.0a1') < V('1.0b1'))
|
||||
self.failUnless(V('1.0b1') < V('1.0c1'))
|
||||
self.failUnless(V('1.0a1') < V('1.0a1-r99'))
|
||||
self.failUnlessEqual(V('1.0a1.post987'), V('1.0a1-r987'))
|
||||
self.failUnlessEqual(str(V('1.0a1.post999')), '1.0.0a1-r999')
|
||||
self.failUnlessEqual(str(V('1.0a1-r999')), '1.0.0a1-r999')
|
||||
self.failIfEqual(V('1.0a1'), V('1.0a1-r987'))
|
||||
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002-2009 Zooko "Zooko" Wilcox-O'Hearn
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
import random, sys, traceback, unittest
|
||||
|
||||
from pyutil.assertutil import _assert
|
||||
|
||||
from pyutil import dictutil
|
||||
|
||||
class EqButNotIs:
|
||||
def __init__(self, x):
|
||||
self.x = x
|
||||
self.hash = int(random.randrange(0, 2**31))
|
||||
def __repr__(self):
|
||||
return "<%s %s>" % (self.__class__.__name__, self.x,)
|
||||
def __hash__(self):
|
||||
return self.hash
|
||||
def __le__(self, other):
|
||||
return self.x <= other
|
||||
def __lt__(self, other):
|
||||
return self.x < other
|
||||
def __ge__(self, other):
|
||||
return self.x >= other
|
||||
def __gt__(self, other):
|
||||
return self.x > other
|
||||
def __ne__(self, other):
|
||||
return self.x != other
|
||||
def __eq__(self, other):
|
||||
return self.x == other
|
||||
|
||||
class Testy(unittest.TestCase):
|
||||
def _help_test_empty_dict(self, klass):
|
||||
d1 = klass()
|
||||
d2 = klass({})
|
||||
|
||||
self.failUnless(d1 == d2, "d1: %r, d2: %r" % (d1, d2,))
|
||||
self.failUnless(len(d1) == 0)
|
||||
self.failUnless(len(d2) == 0)
|
||||
|
||||
def _help_test_nonempty_dict(self, klass):
|
||||
d1 = klass({'a': 1, 'b': "eggs", 3: "spam",})
|
||||
d2 = klass({'a': 1, 'b': "eggs", 3: "spam",})
|
||||
|
||||
self.failUnless(d1 == d2)
|
||||
self.failUnless(len(d1) == 3, "%s, %s" % (len(d1), d1,))
|
||||
self.failUnless(len(d2) == 3)
|
||||
|
||||
def _help_test_eq_but_notis(self, klass):
|
||||
d = klass({'a': 3, 'b': EqButNotIs(3), 'c': 3})
|
||||
d.pop('b')
|
||||
|
||||
d.clear()
|
||||
d['a'] = 3
|
||||
d['b'] = EqButNotIs(3)
|
||||
d['c'] = 3
|
||||
d.pop('b')
|
||||
|
||||
d.clear()
|
||||
d['b'] = EqButNotIs(3)
|
||||
d['a'] = 3
|
||||
d['c'] = 3
|
||||
d.pop('b')
|
||||
|
||||
d.clear()
|
||||
d['a'] = EqButNotIs(3)
|
||||
d['c'] = 3
|
||||
d['a'] = 3
|
||||
|
||||
d.clear()
|
||||
fake3 = EqButNotIs(3)
|
||||
fake7 = EqButNotIs(7)
|
||||
d[fake3] = fake7
|
||||
d[3] = 7
|
||||
d[3] = 8
|
||||
_assert(filter(lambda x: x is 8, d.itervalues()))
|
||||
_assert(filter(lambda x: x is fake7, d.itervalues()))
|
||||
_assert(not filter(lambda x: x is 7, d.itervalues())) # The real 7 should have been ejected by the d[3] = 8.
|
||||
_assert(filter(lambda x: x is fake3, d.iterkeys()))
|
||||
_assert(filter(lambda x: x is 3, d.iterkeys()))
|
||||
d[fake3] = 8
|
||||
|
||||
d.clear()
|
||||
d[3] = 7
|
||||
fake3 = EqButNotIs(3)
|
||||
fake7 = EqButNotIs(7)
|
||||
d[fake3] = fake7
|
||||
d[3] = 8
|
||||
_assert(filter(lambda x: x is 8, d.itervalues()))
|
||||
_assert(filter(lambda x: x is fake7, d.itervalues()))
|
||||
_assert(not filter(lambda x: x is 7, d.itervalues())) # The real 7 should have been ejected by the d[3] = 8.
|
||||
_assert(filter(lambda x: x is fake3, d.iterkeys()))
|
||||
_assert(filter(lambda x: x is 3, d.iterkeys()))
|
||||
d[fake3] = 8
|
||||
|
||||
def test_em(self):
|
||||
for klass in (dictutil.UtilDict, dictutil.NumDict, dictutil.ValueOrderedDict,):
|
||||
# print "name of class: ", klass
|
||||
for helper in (self._help_test_empty_dict, self._help_test_nonempty_dict, self._help_test_eq_but_notis,):
|
||||
# print "name of test func: ", helper
|
||||
try:
|
||||
helper(klass)
|
||||
except:
|
||||
(etype, evalue, realtb) = sys.exc_info()
|
||||
traceback.print_exception(etype, evalue, realtb)
|
||||
self.fail(evalue)
|
||||
del realtb
|
||||
|
||||
def suite():
|
||||
suite = unittest.makeSuite(Testy, 'test')
|
||||
return suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002 Luke 'Artimage' Nelson
|
||||
# Copyright (c) 2005-2010 Zooko Wilcox-O'Hearn
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
from twisted.trial import unittest
|
||||
except ImportError, le:
|
||||
print "Skipping %s since it requires Twisted and Twisted could not be imported: %s" % (__name__, le,)
|
||||
else:
|
||||
from pyutil import PickleSaver, fileutil
|
||||
|
||||
class Thingie(PickleSaver.PickleSaver):
|
||||
def __init__(self, fname, delay=30):
|
||||
PickleSaver.PickleSaver.__init__(self, fname=fname, attrs={'tmp_store':'False'}, DELAY=delay)
|
||||
|
||||
class PickleSaverTest(unittest.TestCase):
|
||||
def _test_save_now(self, fname):
|
||||
thingie = Thingie(fname, delay=0)
|
||||
thingie.tmp_store = 'True'
|
||||
thingie.lazy_save() # Note: it was constructed with default save delay of 0.
|
||||
|
||||
def test_save_now(self):
|
||||
"""
|
||||
This test should create a lazy save object, save it with no delay and check if the file exists.
|
||||
"""
|
||||
tempdir = fileutil.NamedTemporaryDirectory()
|
||||
|
||||
fname = os.path.join(tempdir.name, "picklesavertest")
|
||||
self._test_save_now(fname)
|
||||
self.failUnless(os.path.isfile(fname), "The file [%s] does not exist." %(fname,))
|
||||
|
||||
tempdir.shutdown()
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002-2009 Zooko Wilcox-O'Hearn
|
||||
# portions Copyright (c) 2001 Autonomous Zone Industries
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from pyutil.xor import xor
|
||||
|
||||
# unit tests
|
||||
def _help_test(xf):
|
||||
assert xf('\000', '\000') == '\000'
|
||||
assert xf('\001', '\000') == '\001'
|
||||
assert xf('\001', '\001') == '\000'
|
||||
assert xf('\000\001', '\000\001') == '\000\000'
|
||||
assert xf('\100\101', '\000\101') == '\100\000'
|
||||
|
||||
class Testy(unittest.TestCase):
|
||||
def test_em(self):
|
||||
for xorfunc in (xor.py_xor, xor.py_xor_simple, xor.xor,):
|
||||
if callable(xorfunc):
|
||||
# print "testing xorfunc ", xorfunc
|
||||
_help_test(xorfunc)
|
||||
@@ -0,0 +1,454 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002-2010 Zooko "Zooko" Wilcox-O'Hearn
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
import random, unittest
|
||||
|
||||
from pyutil.assertutil import _assert
|
||||
|
||||
from pyutil.humanreadable import hr
|
||||
from pyutil import memutil
|
||||
from pyutil import cache
|
||||
|
||||
class Bencher:
|
||||
def __init__(self, klass, MAXREPS=2**8, MAXTIME=5):
|
||||
print klass
|
||||
self.klass = klass
|
||||
self.MAXREPS = MAXREPS
|
||||
self.MAXTIME = MAXTIME
|
||||
self.d = {}
|
||||
self.lrun = None
|
||||
|
||||
def _generic_benchmarking_init(self, n):
|
||||
self.d.clear()
|
||||
global lrun
|
||||
self.lrun = self.klass(maxsize=n)
|
||||
for i in range(n):
|
||||
self.d[i] = i
|
||||
self.lrun[n+i] = n+i
|
||||
|
||||
def _benchmark_init(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(initialdata=self.d, maxsize=MAXSIZE)
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
return True
|
||||
|
||||
def _benchmark_update(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(maxsize=MAXSIZE)
|
||||
assert len(d2) == 0
|
||||
d2.update(self.d)
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
return True
|
||||
|
||||
def _benchmark_insert(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(maxsize=MAXSIZE)
|
||||
assert len(d2) == 0
|
||||
for k, v, in self.d.iteritems():
|
||||
d2[k] = v
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_popitem(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(initialdata=self.d, maxsize=MAXSIZE)
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
for i in range(len(d2), 0, -1):
|
||||
assert len(d2) == i
|
||||
d2.popitem()
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_has_key_and_del(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(initialdata=self.d, maxsize=MAXSIZE)
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
for k in self.d.iterkeys():
|
||||
if d2.has_key(k):
|
||||
del d2[k]
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_remove(self, n):
|
||||
MAXSIZE=n/2
|
||||
d2 = self.klass(initialdata=self.d, maxsize=MAXSIZE)
|
||||
assert len(d2) == min(len(self.d), MAXSIZE)
|
||||
for k in self.d.iterkeys():
|
||||
d2.remove(k, strictkey=False)
|
||||
return True
|
||||
|
||||
def bench(self, BSIZES=(128, 250, 2048, 5000, 2**13, 2**20,)):
|
||||
from pyutil import benchutil
|
||||
funcs = ("_benchmark_insert", "_benchmark_init_and_has_key_and_del", "_benchmark_init_and_remove", "_benchmark_init_and_popitem", "_benchmark_update", "_benchmark_init",)
|
||||
max = 0
|
||||
for func in funcs:
|
||||
if len(func) > max:
|
||||
max = len(func)
|
||||
for func in funcs:
|
||||
print func + " " * (max + 1 - len(func))
|
||||
for BSIZE in BSIZES:
|
||||
f = getattr(self, func)
|
||||
benchutil.rep_bench(f, BSIZE, self._generic_benchmarking_init, MAXREPS=self.MAXREPS, MAXTIME=self.MAXTIME)
|
||||
|
||||
def quick_bench():
|
||||
Bencher(cache.LRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15, 2**16,))
|
||||
Bencher(cache.LinkedListLRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15,))
|
||||
Bencher(cache.SmallLRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15,))
|
||||
|
||||
def slow_bench():
|
||||
Bencher(cache.LRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 21)])
|
||||
Bencher(cache.LinkedListLRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 21)])
|
||||
Bencher(cache.SmallLRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 17)])
|
||||
|
||||
MUCHADDINGSIZE=2**4
|
||||
MUCHADDINGNUM = 2**4
|
||||
|
||||
# The following parameters are for testing for memory leakage.
|
||||
MIN_SLOPE = 512.0 # If it leaks less than 512.0 bytes per iteration, then it's probably just some kind of noise from the interpreter or something...
|
||||
SAMPLES = 2**5
|
||||
# MIN_SLOPE is high because samples is low, which is because taking a statistically useful numbers of samples takes too long.
|
||||
# For a *good* test, turn samples up as high as you can stand (maybe 2**10) and set MIN_SLOPE to about 1.0.
|
||||
# For a *really* good test, add a variance measure to memutil.measure_mem_leakage(), and only consider it to be leaking if the slope is > 0.1 *and* is a "pretty good" fit for the data.
|
||||
# MIN_SLOPE = 1.0
|
||||
# SAMPLES = 2**10
|
||||
|
||||
class Testy(unittest.TestCase):
|
||||
def _test_empty_lookup(self, d) :
|
||||
self.failUnless(d.get('spam') is None)
|
||||
|
||||
def _test_key_error(self, C) :
|
||||
d = C()
|
||||
try:
|
||||
d['spam']
|
||||
self.fail(d)
|
||||
except KeyError :
|
||||
pass
|
||||
|
||||
def _test_insert_and_get(self, d) :
|
||||
d.insert("spam", "eggs")
|
||||
d["spam2"] = "eggs2"
|
||||
self.failUnless(d.get("spam") == "eggs", str(d))
|
||||
self.failUnless(d.get("spam2") == "eggs2")
|
||||
self.failUnless(d["spam"] == "eggs")
|
||||
self.failUnless(d["spam2"] == "eggs2")
|
||||
|
||||
def _test_insert_and_remove(self, d):
|
||||
d.insert('spam', "eggs")
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggs")
|
||||
self.failUnless(d['spam'] == "eggs")
|
||||
x = d.remove('spam')
|
||||
self.failUnless(x == "eggs", "x: %s" % `x`)
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
d['spam'] = "eggs"
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggs")
|
||||
self.failUnless(d['spam'] == "eggs")
|
||||
del d['spam']
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
|
||||
def _test_setdefault(self, d):
|
||||
d.setdefault('spam', "eggs")
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggs")
|
||||
self.failUnless(d['spam'] == "eggs")
|
||||
x = d.remove('spam')
|
||||
self.failUnless(x == "eggs", "x: %s" % `x`)
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
|
||||
def _test_extracted_bound_method(self, d):
|
||||
insmeth = d.insert
|
||||
insmeth('spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_extracted_unbound_method(self, d):
|
||||
insumeth = d.__class__.insert
|
||||
insumeth(d, 'spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_unbound_method(self, C, d):
|
||||
umeth = C.insert
|
||||
umeth(d, 'spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_clear(self, d):
|
||||
d[11] = 11
|
||||
d._assert_invariants()
|
||||
self.failUnless(len(d) == 1)
|
||||
d.clear()
|
||||
d._assert_invariants()
|
||||
self.failUnless(len(d) == 0)
|
||||
|
||||
def _test_update(self, d):
|
||||
self.failUnless(d._assert_invariants())
|
||||
d['b'] = 99
|
||||
self.failUnless(d._assert_invariants())
|
||||
d2={ 'a': 0, 'b': 1, 'c': 2,}
|
||||
d.update(d2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('a') == 0, "d.get('a'): %s" % d.get('a'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('b') == 1, "d.get('b'): %s" % d.get('b'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('c') == 2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
|
||||
def _test_popitem(self, C):
|
||||
c = C({"a": 1})
|
||||
res = c.popitem()
|
||||
_assert(res == ("a", 1,), C, c, res)
|
||||
self.failUnless(res == ("a", 1,))
|
||||
|
||||
def _test_iterate_items(self, C):
|
||||
c = C({"a": 1})
|
||||
i = c.iteritems()
|
||||
x = i.next()
|
||||
self.failUnless(x == ("a", 1,))
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_iterate_keys(self, C):
|
||||
c = C({"a": 1})
|
||||
i = c.iterkeys()
|
||||
x = i.next()
|
||||
self.failUnless(x == "a")
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_iterate_values(self, C):
|
||||
c = C({"a": 1})
|
||||
i = c.itervalues()
|
||||
x = i.next()
|
||||
self.failUnless(x == 1)
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_LRU_much_adding_some_removing(self, C):
|
||||
c = C(maxsize=MUCHADDINGSIZE)
|
||||
for i in range(MUCHADDINGNUM):
|
||||
c[i] = i
|
||||
if (i % 400) == 0:
|
||||
k = random.choice(c.keys())
|
||||
del c[k]
|
||||
for i in range(MUCHADDINGSIZE):
|
||||
c[i] = i
|
||||
self.failUnless(len(c) == MUCHADDINGSIZE)
|
||||
|
||||
def _test_LRU_1(self, C):
|
||||
c = C(maxsize=10)
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_LRU_2(self, C):
|
||||
c = C(maxsize=10)
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
del c[11]
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_LRU_3(self, C):
|
||||
c = C(maxsize=10)
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 12
|
||||
c._assert_invariants()
|
||||
c[11] = 13
|
||||
c._assert_invariants()
|
||||
del c[11]
|
||||
c._assert_invariants()
|
||||
c[11] = 14
|
||||
c._assert_invariants()
|
||||
c[11] = 15
|
||||
c._assert_invariants()
|
||||
c[11] = 16
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_LRU_full(self, C):
|
||||
c = C(maxsize=10)
|
||||
c._assert_invariants()
|
||||
for i in xrange(11):
|
||||
c._assert_invariants()
|
||||
c[i] = i
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(10 in c.values(), c.values())
|
||||
self.failUnless(0 not in c.values())
|
||||
|
||||
del c[1]
|
||||
c._assert_invariants()
|
||||
self.failUnless(1 not in c.values())
|
||||
self.failUnless(len(c) == 9)
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(1 not in c.values())
|
||||
self.failUnless(11 in c.values())
|
||||
del c[11]
|
||||
c._assert_invariants()
|
||||
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(1 not in c.values())
|
||||
self.failUnless(11 in c.values())
|
||||
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(1 not in c.values())
|
||||
self.failUnless(11 in c.values())
|
||||
|
||||
for i in xrange(200):
|
||||
c[i] = i
|
||||
c._assert_invariants()
|
||||
self.failUnless(199 in c.values())
|
||||
self.failUnless(190 in c.values())
|
||||
|
||||
def _test_LRU_has_key(self, C):
|
||||
c = C(maxsize=10)
|
||||
c._assert_invariants()
|
||||
for i in xrange(11):
|
||||
c._assert_invariants()
|
||||
c[i] = i
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(10 in c.values())
|
||||
self.failUnless(0 not in c.values())
|
||||
|
||||
# c.has_key(1) # this touches `1' and makes it fresher so that it will live and `2' will die next time we overfill.
|
||||
c[1] = 1 # this touches `1' and makes it fresher so that it will live and `2' will die next time we overfill.
|
||||
c._assert_invariants()
|
||||
|
||||
c[99] = 99
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(1 in c.values(), "C: %s, c.values(): %s" % (hr(C), hr(c.values(),),))
|
||||
self.failUnless(not 2 in c.values())
|
||||
self.failUnless(99 in c.values())
|
||||
|
||||
def _test_LRU_not_overfull_on_idempotent_add(self, C):
|
||||
c = C(maxsize=10)
|
||||
for i in xrange(11):
|
||||
c[i] = i
|
||||
c[1] = "spam"
|
||||
# Now 1 is the freshest, so 2 is the next one that would be removed *if* we went over limit.
|
||||
c[3] = "eggs"
|
||||
self.failUnless(c.has_key(2))
|
||||
self.failUnless(len(c) == 10)
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_LRU_overflow_on_update(self, C):
|
||||
d = C(maxsize=10)
|
||||
self.failUnless(d._assert_invariants())
|
||||
d2 = {}
|
||||
for i in range(12):
|
||||
d2[i] = i
|
||||
d.update(d2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(len(d) == 10)
|
||||
|
||||
def _test_LRU_overflow_on_init(self, C):
|
||||
d2 = {}
|
||||
for i in range(12):
|
||||
d2[i] = i
|
||||
d = C(d2, maxsize=10)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(len(d) == 10)
|
||||
|
||||
def _test_em(self):
|
||||
for klass in (cache.LRUCache, cache.SmallLRUCache,):
|
||||
for testfunc in (self._test_empty_lookup, self._test_insert_and_get, self._test_insert_and_remove, self._test_extracted_bound_method, self._test_extracted_unbound_method, self._test_clear, self._test_update, self._test_setdefault,):
|
||||
testfunc(klass())
|
||||
|
||||
for testfunc in (self._test_popitem, self._test_iterate_items, self._test_iterate_keys, self._test_iterate_values, self._test_key_error, ):
|
||||
testfunc(klass)
|
||||
|
||||
self._test_unbound_method(klass, klass())
|
||||
|
||||
for klass in (cache.LRUCache, cache.SmallLRUCache,):
|
||||
for testfunc in (self._test_LRU_1, self._test_LRU_2, self._test_LRU_3, self._test_LRU_full, self._test_LRU_has_key, self._test_LRU_not_overfull_on_idempotent_add, self._test_LRU_overflow_on_update, self._test_LRU_overflow_on_init,):
|
||||
testfunc(klass)
|
||||
|
||||
def test_em(self):
|
||||
self._test_em()
|
||||
|
||||
def _mem_test_LRU_much_adding_some_removing(self):
|
||||
for klass in (cache.LRUCache, cache.SmallLRUCache,):
|
||||
return self._test_LRU_much_adding_some_removing(klass)
|
||||
|
||||
def test_mem_leakage(self):
|
||||
try:
|
||||
self._test_mem_leakage()
|
||||
except memutil.NotSupportedException:
|
||||
print "Skipping memory leak test since measurement of current mem usage isn't implemented on this platform."
|
||||
pass
|
||||
del test_mem_leakage # This test takes too long.
|
||||
|
||||
def _test_mem_leakage(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of memory state.
|
||||
memutil.measure_mem_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
slope = memutil.measure_mem_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks memory at a rate of approximately %s system bytes per invocation" % (self.test_em, "%0.3f" % slope,))
|
||||
|
||||
def test_mem_leakage_much_adding_some_removing(self):
|
||||
try:
|
||||
self._test_mem_leakage_much_adding_some_removing()
|
||||
except memutil.NotSupportedException:
|
||||
print "Skipping memory leak test since measurement of current mem usage isn't implemented on this platform."
|
||||
pass
|
||||
del test_mem_leakage_much_adding_some_removing # This test takes too long.
|
||||
|
||||
def _test_mem_leakage_much_adding_some_removing(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of memory state.
|
||||
memutil.measure_mem_leakage(self._mem_test_LRU_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
slope = memutil.measure_mem_leakage(self._mem_test_LRU_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks memory at a rate of approximately %s system bytes per invocation" % (self._mem_test_LRU_much_adding_some_removing, "%0.3f" % slope,))
|
||||
|
||||
def test_obj_leakage(self):
|
||||
self._test_obj_leakage()
|
||||
del test_obj_leakage # This test takes too long.
|
||||
|
||||
def _test_obj_leakage(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of objects state.
|
||||
memutil.measure_obj_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
slope = memutil.measure_obj_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks objects at a rate of approximately %s system bytes per invocation" % (self.test_em, "%0.3f" % slope,))
|
||||
|
||||
def test_obj_leakage_much_adding_some_removing(self):
|
||||
self._test_obj_leakage_much_adding_some_removing()
|
||||
del test_obj_leakage_much_adding_some_removing # This test takes too long.
|
||||
|
||||
def _test_obj_leakage_much_adding_some_removing(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of objects state.
|
||||
memutil.measure_obj_leakage(self._mem_test_LRU_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
slope = memutil.measure_obj_leakage(self._mem_test_LRU_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks objects at a rate of approximately %s system bytes per invocation" % (self._mem_test_LRU_much_adding_some_removing, "%0.3f" % slope,))
|
||||
@@ -0,0 +1,441 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2002-2010 Zooko Wilcox-O'Hearn
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
import random, unittest
|
||||
|
||||
from pyutil.humanreadable import hr
|
||||
from pyutil import memutil
|
||||
from pyutil import odict
|
||||
|
||||
class Bencher:
|
||||
def __init__(self, klass, MAXREPS=2**8, MAXTIME=5):
|
||||
print klass
|
||||
self.klass = klass
|
||||
self.MAXREPS = MAXREPS
|
||||
self.MAXTIME = MAXTIME
|
||||
self.d = {}
|
||||
self.lrun = None
|
||||
|
||||
def _generic_benchmarking_init(self, n):
|
||||
self.d.clear()
|
||||
self.lrun = self.klass()
|
||||
for i in range(n):
|
||||
self.d[i] = i
|
||||
self.lrun[n+i] = n+i
|
||||
|
||||
def _benchmark_init(self, n):
|
||||
d2 = self.klass(initialdata=self.d)
|
||||
assert len(d2) == len(self.d)
|
||||
return True
|
||||
|
||||
def _benchmark_update(self, n):
|
||||
d2 = self.klass()
|
||||
assert len(d2) == 0
|
||||
d2.update(self.d)
|
||||
assert len(d2) == len(self.d)
|
||||
return True
|
||||
|
||||
def _benchmark_insert(self, n):
|
||||
d2 = self.klass()
|
||||
assert len(d2) == 0
|
||||
for k, v, in self.d.iteritems():
|
||||
d2[k] = v
|
||||
assert len(d2) == len(self.d)
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_popitem(self, n):
|
||||
d2 = self.klass(initialdata=self.d)
|
||||
assert len(d2) == len(self.d)
|
||||
for i in range(len(d2), 0, -1):
|
||||
assert len(d2) == i
|
||||
d2.popitem()
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_has_key_and_del(self, n):
|
||||
d2 = self.klass(initialdata=self.d)
|
||||
assert len(d2) == len(self.d)
|
||||
for k in self.d.iterkeys():
|
||||
if d2.has_key(k):
|
||||
del d2[k]
|
||||
return True
|
||||
|
||||
def _benchmark_init_and_remove(self, n):
|
||||
d2 = self.klass(initialdata=self.d)
|
||||
assert len(d2) == len(self.d)
|
||||
for k in self.d.iterkeys():
|
||||
d2.remove(k, strictkey=False)
|
||||
return True
|
||||
|
||||
def bench(self, BSIZES=(128, 250, 2048, 5000, 2**13, 2**20,)):
|
||||
from pyutil import benchutil
|
||||
funcs = ("_benchmark_insert", "_benchmark_init_and_has_key_and_del", "_benchmark_init_and_remove", "_benchmark_init_and_popitem", "_benchmark_update", "_benchmark_init",)
|
||||
max = 0
|
||||
for func in funcs:
|
||||
if len(func) > max:
|
||||
max = len(func)
|
||||
for func in funcs:
|
||||
print func + " " * (max + 1 - len(func))
|
||||
for BSIZE in BSIZES:
|
||||
f = getattr(self, func)
|
||||
benchutil.rep_bench(f, BSIZE, self._generic_benchmarking_init, MAXREPS=self.MAXREPS, MAXTIME=self.MAXTIME)
|
||||
|
||||
def quick_bench():
|
||||
Bencher(odict.LRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15, 2**16,))
|
||||
Bencher(odict.LinkedListLRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15,))
|
||||
Bencher(odict.SmallLRUCache, MAXTIME=2).bench(BSIZES=(2**7, 2**12, 2**14, 2**15,))
|
||||
|
||||
def slow_bench():
|
||||
Bencher(odict.LRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 21)])
|
||||
Bencher(odict.LinkedListLRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 21)])
|
||||
Bencher(odict.SmallLRUCache, MAXTIME=5).bench(BSIZES=[2**x for x in range(7, 17)])
|
||||
|
||||
MUCHADDINGSIZE=2**4
|
||||
|
||||
# The following parameters are for testing for memory leakage.
|
||||
MIN_SLOPE = 512.0 # If it leaks less than 512.0 bytes per iteration, then it's probably just some kind of noise from the interpreter or something...
|
||||
SAMPLES = 2**5
|
||||
# MIN_SLOPE is high because samples is low, which is because taking a statistically useful numbers of samples takes too long.
|
||||
# For a *good* test, turn samples up as high as you can stand (maybe 2**10) and set MIN_SLOPE to about 1.0.
|
||||
# For a *really* good test, add a variance measure to memutil.measure_mem_leakage(), and only consider it to be leaking if the slope is > 0.1 *and* is a "pretty good" fit for the data.
|
||||
# MIN_SLOPE = 1.0
|
||||
# SAMPLES = 2**10
|
||||
|
||||
class Testy(unittest.TestCase):
|
||||
def _test_empty_lookup(self, d) :
|
||||
self.failUnless(d.get('spam') is None)
|
||||
|
||||
def _test_key_error(self, C) :
|
||||
d = C()
|
||||
try:
|
||||
d['spam']
|
||||
self.fail(d)
|
||||
except KeyError :
|
||||
pass
|
||||
|
||||
def _test_insert_and_get_and_items(self, d) :
|
||||
d.insert("spam", "eggs")
|
||||
d["spam2"] = "eggs2"
|
||||
self.failUnless(d.get("spam") == "eggs", str(d))
|
||||
self.failUnless(d.get("spam2") == "eggs2")
|
||||
self.failUnless(d["spam"] == "eggs")
|
||||
self.failUnless(d["spam2"] == "eggs2")
|
||||
self.failUnlessEqual(d.items(), [("spam", "eggs"), ("spam2", "eggs2")], d)
|
||||
|
||||
def _test_move_to_most_recent(self, d) :
|
||||
d.insert("spam", "eggs")
|
||||
d["spam2"] = "eggs2"
|
||||
self.failUnless(d.get("spam") == "eggs", str(d))
|
||||
self.failUnless(d.get("spam2") == "eggs2")
|
||||
self.failUnless(d["spam"] == "eggs")
|
||||
self.failUnless(d["spam2"] == "eggs2")
|
||||
self.failUnlessEqual(d.items(), [("spam", "eggs"), ("spam2", "eggs2")])
|
||||
d.move_to_most_recent("spam")
|
||||
self.failUnlessEqual(d.items(), [("spam2", "eggs2"), ("spam", "eggs")])
|
||||
|
||||
def _test_insert_and_remove(self, d):
|
||||
d.insert('spam', "eggs")
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggs")
|
||||
self.failUnless(d['spam'] == "eggs")
|
||||
self.failUnlessEqual(d.items(), [("spam", "eggs")])
|
||||
x = d.remove('spam')
|
||||
self.failUnless(x == "eggs", "x: %s" % `x`)
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
self.failUnlessEqual(d.items(), [])
|
||||
d['spam'] = "eggsy"
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggsy")
|
||||
self.failUnless(d['spam'] == "eggsy")
|
||||
self.failUnlessEqual(d.items(), [("spam", "eggsy")])
|
||||
del d['spam']
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
self.failUnlessEqual(d.items(), [])
|
||||
|
||||
def _test_setdefault(self, d):
|
||||
d.setdefault('spam', "eggs")
|
||||
self.failUnless(d.has_key('spam'))
|
||||
self.failUnless(d.get('spam') == "eggs")
|
||||
self.failUnless(d['spam'] == "eggs")
|
||||
self.failUnlessEqual(d.items(), [("spam", "eggs")])
|
||||
x = d.remove('spam')
|
||||
self.failUnless(x == "eggs", "x: %s" % `x`)
|
||||
self.failUnless(not d.has_key('spam'))
|
||||
self.failUnlessEqual(d.items(), [])
|
||||
|
||||
def _test_extracted_bound_method(self, d):
|
||||
insmeth = d.insert
|
||||
insmeth('spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_extracted_unbound_method(self, d):
|
||||
insumeth = d.__class__.insert
|
||||
insumeth(d, 'spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_unbound_method(self, C, d):
|
||||
umeth = C.insert
|
||||
umeth(d, 'spammy', "eggsy")
|
||||
self.failUnless(d.get('spammy') == "eggsy")
|
||||
|
||||
def _test_clear(self, d):
|
||||
d[11] = 11
|
||||
d._assert_invariants()
|
||||
self.failUnless(len(d) == 1)
|
||||
d.clear()
|
||||
d._assert_invariants()
|
||||
self.failUnless(len(d) == 0)
|
||||
self.failUnlessEqual(d.items(), [])
|
||||
|
||||
def _test_update_from_dict(self, d):
|
||||
self.failUnless(d._assert_invariants())
|
||||
d['b'] = 99
|
||||
self.failUnless(d._assert_invariants())
|
||||
d2={ 'a': 0, 'b': 1, 'c': 2,}
|
||||
d.update(d2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('a') == 0, "d.get('a'): %s" % d.get('a'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('b') == 1, "d.get('b'): %s" % d.get('b'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('c') == 2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
|
||||
def _test_update_from_odict(self, d):
|
||||
self.failUnless(d._assert_invariants())
|
||||
d['b'] = 99
|
||||
self.failUnless(d._assert_invariants())
|
||||
d2 = odict.OrderedDict()
|
||||
d2['a'] = 0
|
||||
d2['b'] = 1
|
||||
d2['c'] = 2
|
||||
d.update(d2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('a') == 0, "d.get('a'): %s" % d.get('a'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('b') == 1, "d.get('b'): %s" % d.get('b'))
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnless(d.get('c') == 2)
|
||||
self.failUnless(d._assert_invariants())
|
||||
self.failUnlessEqual(d.items(), [("b", 1), ("a", 0), ("c", 2)])
|
||||
|
||||
def _test_popitem(self, C):
|
||||
c = C({"a": 1})
|
||||
res = c.popitem()
|
||||
self.failUnlessEqual(res, ("a", 1,))
|
||||
|
||||
c["a"] = 1
|
||||
c["b"] = 2
|
||||
|
||||
res = c.popitem()
|
||||
self.failUnlessEqual(res, ("b", 2,))
|
||||
|
||||
def _test_pop(self, C):
|
||||
c = C({"a": 1})
|
||||
res = c.pop()
|
||||
self.failUnlessEqual(res, "a")
|
||||
|
||||
c["a"] = 1
|
||||
c["b"] = 2
|
||||
|
||||
res = c.pop()
|
||||
self.failUnlessEqual(res, "b")
|
||||
|
||||
def _test_iterate_items(self, C):
|
||||
c = C({"a": 1})
|
||||
c["b"] = 2
|
||||
i = c.iteritems()
|
||||
x = i.next()
|
||||
self.failUnlessEqual(x, ("a", 1,))
|
||||
x = i.next()
|
||||
self.failUnlessEqual(x, ("b", 2,))
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_iterate_keys(self, C):
|
||||
c = C({"a": 1})
|
||||
c["b"] = 2
|
||||
i = c.iterkeys()
|
||||
x = i.next()
|
||||
self.failUnlessEqual(x, "a")
|
||||
x = i.next()
|
||||
self.failUnlessEqual(x, "b")
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_iterate_values(self, C):
|
||||
c = C({"a": 1})
|
||||
c["b"] = 2
|
||||
i = c.itervalues()
|
||||
x = i.next()
|
||||
self.failUnless(x == 1)
|
||||
x = i.next()
|
||||
self.failUnless(x == 2)
|
||||
try:
|
||||
i.next()
|
||||
self.fail() # Should have gotten StopIteration exception
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
def _test_much_adding_some_removing(self, C):
|
||||
c = C()
|
||||
for i in range(MUCHADDINGSIZE):
|
||||
c[i] = i
|
||||
if (i % 4) == 0:
|
||||
k = random.choice(c.keys())
|
||||
del c[k]
|
||||
for i in range(MUCHADDINGSIZE):
|
||||
c[i] = i
|
||||
self.failUnlessEqual(len(c), MUCHADDINGSIZE)
|
||||
|
||||
def _test_1(self, C):
|
||||
c = C()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
c[11] = 1001
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_2(self, C):
|
||||
c = C()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
del c[11]
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_3(self, C):
|
||||
c = C()
|
||||
c[11] = 11
|
||||
c._assert_invariants()
|
||||
c[11] = 12
|
||||
c._assert_invariants()
|
||||
c[11] = 13
|
||||
c._assert_invariants()
|
||||
del c[11]
|
||||
c._assert_invariants()
|
||||
c[11] = 14
|
||||
c._assert_invariants()
|
||||
c[11] = 15
|
||||
c._assert_invariants()
|
||||
c[11] = 16
|
||||
c._assert_invariants()
|
||||
|
||||
def _test_has_key(self, C):
|
||||
c = C()
|
||||
c._assert_invariants()
|
||||
for i in xrange(11):
|
||||
c._assert_invariants()
|
||||
c[i] = i
|
||||
c._assert_invariants()
|
||||
del c[0]
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(10 in c.values())
|
||||
self.failUnless(0 not in c.values())
|
||||
|
||||
c.has_key(1) # this touches `1' but does not make it fresher so that it will get popped next time we pop.
|
||||
c[1] = 1 # this touches `1' but does not make it fresher so that it will get popped.
|
||||
c._assert_invariants()
|
||||
|
||||
x = c.pop()
|
||||
self.failUnlessEqual(x, 10)
|
||||
|
||||
c[99] = 99
|
||||
c._assert_invariants()
|
||||
self.failUnless(len(c) == 10)
|
||||
self.failUnless(1 in c.values(), "C: %s, c.values(): %s" % (hr(C), hr(c.values(),),))
|
||||
self.failUnless(2 in c.values(), "C: %s, c.values(): %s" % (hr(C), hr(c.values(),),))
|
||||
self.failIf(10 in c.values(), "C: %s, c.values(): %s" % (hr(C), hr(c.values(),),))
|
||||
self.failUnless(99 in c.values())
|
||||
|
||||
def _test_em(self):
|
||||
for klass in (odict.OrderedDict,):
|
||||
for testfunc in (self._test_empty_lookup, self._test_insert_and_get_and_items, self._test_insert_and_remove, self._test_extracted_bound_method, self._test_extracted_unbound_method, self._test_clear, self._test_update_from_dict, self._test_update_from_odict, self._test_setdefault,):
|
||||
testfunc(klass())
|
||||
|
||||
for testfunc in (self._test_pop, self._test_popitem, self._test_iterate_items, self._test_iterate_keys, self._test_iterate_values, self._test_key_error, ):
|
||||
testfunc(klass)
|
||||
|
||||
self._test_unbound_method(klass, klass())
|
||||
|
||||
for klass in (odict.OrderedDict,):
|
||||
for testfunc in (self._test_1, self._test_2, self._test_3, self._test_has_key,):
|
||||
testfunc(klass)
|
||||
|
||||
def test_em(self):
|
||||
self._test_em()
|
||||
|
||||
def _mem_test_much_adding_some_removing(self):
|
||||
for klass in (odict.LRUCache, odict.SmallLRUCache,):
|
||||
return self._test_much_adding_some_removing(klass)
|
||||
|
||||
def test_mem_leakage(self):
|
||||
try:
|
||||
self._test_mem_leakage()
|
||||
except memutil.NotSupportedException:
|
||||
print "Skipping memory leak test since measurement of current mem usage isn't implemented on this platform."
|
||||
pass
|
||||
del test_mem_leakage # This test takes too long.
|
||||
|
||||
def _test_mem_leakage(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of memory state.
|
||||
memutil.measure_mem_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
slope = memutil.measure_mem_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks memory at a rate of approximately %s system bytes per invocation" % (self.test_em, "%0.3f" % slope,))
|
||||
|
||||
def test_mem_leakage_much_adding_some_removing(self):
|
||||
try:
|
||||
self._test_mem_leakage_much_adding_some_removing()
|
||||
except memutil.NotSupportedException:
|
||||
print "Skipping memory leak test since measurement of current mem usage isn't implemented on this platform."
|
||||
pass
|
||||
del test_mem_leakage_much_adding_some_removing # This test takes too long.
|
||||
|
||||
def _test_mem_leakage_much_adding_some_removing(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of memory state.
|
||||
memutil.measure_mem_leakage(self._mem_test_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
slope = memutil.measure_mem_leakage(self._mem_test_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks memory at a rate of approximately %s system bytes per invocation" % (self._mem_test_much_adding_some_removing, "%0.3f" % slope,))
|
||||
|
||||
def test_obj_leakage(self):
|
||||
self._test_obj_leakage()
|
||||
del test_obj_leakage # This test takes too long.
|
||||
|
||||
def _test_obj_leakage(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of objects state.
|
||||
memutil.measure_obj_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
slope = memutil.measure_obj_leakage(self.test_em, max(2**3, SAMPLES/2**3), iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks objects at a rate of approximately %s system bytes per invocation" % (self.test_em, "%0.3f" % slope,))
|
||||
|
||||
def test_obj_leakage_much_adding_some_removing(self):
|
||||
self._test_obj_leakage_much_adding_some_removing()
|
||||
del test_obj_leakage_much_adding_some_removing # This test takes too long.
|
||||
|
||||
def _test_obj_leakage_much_adding_some_removing(self):
|
||||
# measure one and throw it away, in order to reach a "steady state" in terms of initialization of objects state.
|
||||
memutil.measure_obj_leakage(self._mem_test_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
slope = memutil.measure_obj_leakage(self._mem_test_much_adding_some_removing, SAMPLES, iterspersample=2**0)
|
||||
|
||||
self.failUnless(slope <= MIN_SLOPE, "%s leaks objects at a rate of approximately %s system bytes per invocation" % (self._mem_test_much_adding_some_removing, "%0.3f" % slope,))
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2004-2009 Zooko "Zooko" Wilcox-O'Hearn
|
||||
# This file is part of pyutil; see README.rst for licensing terms.
|
||||
|
||||
import unittest
|
||||
|
||||
from pyutil.assertutil import _assert
|
||||
from pyutil import strutil
|
||||
|
||||
class Teststrutil(unittest.TestCase):
|
||||
def test_short_input(self):
|
||||
self.failUnless(strutil.pop_trailing_newlines("\r\n") == "")
|
||||
self.failUnless(strutil.pop_trailing_newlines("\r") == "")
|
||||
self.failUnless(strutil.pop_trailing_newlines("x\r\n") == "x")
|
||||
self.failUnless(strutil.pop_trailing_newlines("x\r") == "x")
|
||||
|
||||
def test_split(self):
|
||||
_assert(strutil.split_on_newlines("x\r\ny") == ["x", "y",], strutil.split_on_newlines("x\r\ny"))
|
||||
_assert(strutil.split_on_newlines("x\r\ny\r\n") == ["x", "y", '',], strutil.split_on_newlines("x\r\ny\r\n"))
|
||||
_assert(strutil.split_on_newlines("x\n\ny\n\n") == ["x", '', "y", '', '',], strutil.split_on_newlines("x\n\ny\n\n"))
|
||||
|
||||
def test_commonprefix(self):
|
||||
_assert(strutil.commonprefix(["foo","foobarooo", "foosplat",]) == 'foo', strutil.commonprefix(["foo","foobarooo", "foosplat",]))
|
||||
_assert(strutil.commonprefix(["foo","afoobarooo", "foosplat",]) == '', strutil.commonprefix(["foo","afoobarooo", "foosplat",]))
|
||||
|
||||
def test_commonsuffix(self):
|
||||
_assert(strutil.commonsuffix(["foo","foobarooo", "foosplat",]) == '', strutil.commonsuffix(["foo","foobarooo", "foosplat",]))
|
||||
_assert(strutil.commonsuffix(["foo","foobarooo", "foosplato",]) == 'o', strutil.commonsuffix(["foo","foobarooo", "foosplato",]))
|
||||
_assert(strutil.commonsuffix(["foo","foobarooofoo", "foosplatofoo",]) == 'foo', strutil.commonsuffix(["foo","foobarooofoo", "foosplatofoo",]))
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import unittest
|
||||
|
||||
from pyutil import randutil
|
||||
|
||||
from pyutil import zlibutil
|
||||
|
||||
class Accumulator:
|
||||
def __init__(self):
|
||||
self.buf = ''
|
||||
|
||||
def write(self, str):
|
||||
self.buf += str
|
||||
|
||||
def make_decomp(realdecomp):
|
||||
def decomp(str, maxlen, maxmem):
|
||||
d = Accumulator()
|
||||
realdecomp(str, d, maxlen, maxmem)
|
||||
return d.buf
|
||||
return decomp
|
||||
|
||||
def genrandstr(strlen):
|
||||
return randutil.insecurerandstr(strlen)
|
||||
|
||||
def genbombstr(strlen):
|
||||
return '0' * strlen
|
||||
|
||||
MAXMEM=65*2**20
|
||||
|
||||
class ZlibTestCase(unittest.TestCase):
|
||||
def _help_test(self, genstring, decomp, strlen):
|
||||
s = genstring(strlen)
|
||||
cs = zlibutil.zlib.compress(s)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=strlen*2**3 + zlibutil.MINMAXMEM)
|
||||
self.failUnless(s == s2)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=strlen*2**6 + zlibutil.MINMAXMEM)
|
||||
self.failUnless(s == s2)
|
||||
self.failUnlessRaises(zlibutil.TooBigError, decomp, cs, maxlen=strlen-1, maxmem=strlen*2**3 + zlibutil.MINMAXMEM)
|
||||
|
||||
def _help_test_inplace_minmaxmem(self, genstring, decomp, strlen):
|
||||
s = genstring(strlen)
|
||||
cs = zlibutil.zlib.compress(s)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=zlibutil.MINMAXMEM)
|
||||
self.failUnless(s == s2)
|
||||
self.failUnlessRaises(zlibutil.TooBigError, decomp, cs, maxlen=strlen-1, maxmem=zlibutil.MINMAXMEM)
|
||||
|
||||
def _help_test_inplace(self, genstring, decomp, strlen):
|
||||
# ### XXX self.failUnlessRaises(UnsafeDecompressError, decomp, zlib.compress(genstring(strlen)), maxlen=strlen, maxmem=strlen-1)
|
||||
s = genstring(strlen)
|
||||
cs = zlibutil.zlib.compress(s)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=max(strlen*2**3, zlibutil.MINMAXMEM))
|
||||
self.failUnless(s == s2)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=max(strlen*2**6, zlibutil.MINMAXMEM))
|
||||
self.failUnless(s == s2)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=max(strlen-1, zlibutil.MINMAXMEM))
|
||||
self.failUnless(s == s2)
|
||||
s2 = decomp(cs, maxlen=strlen, maxmem=max(strlen/2, zlibutil.MINMAXMEM))
|
||||
self.failUnless(s == s2)
|
||||
self.failUnlessRaises(zlibutil.TooBigError, decomp, cs, maxlen=strlen-1, maxmem=max(strlen*2**3, zlibutil.MINMAXMEM))
|
||||
|
||||
def testem(self):
|
||||
# for strlen in [2**1, 2**2, 2**10, 2**14, 2**21]: # a *real* test ought to include 2**21, which exercises different cases re: maxmem. But it takes too long.
|
||||
for strlen in [2, 3, 4, 99,]:
|
||||
# print "strlen: %s\n" % (strlen,)
|
||||
for decomp in [zlibutil.decompress, make_decomp(zlibutil.decompress_to_fileobj), make_decomp(zlibutil.decompress_to_spool),]:
|
||||
# print "decomp: %s\n" % (decomp,)
|
||||
for genstring in [genrandstr, genbombstr,]:
|
||||
# print "genstring: %s\n" % (genstring,)
|
||||
self._help_test(genstring, decomp, strlen)
|
||||
|
||||
for decomp in [make_decomp(zlibutil.decompress_to_spool),]:
|
||||
# print "decomp: %s\n" % (decomp,)
|
||||
for genstring in [genrandstr, genbombstr,]:
|
||||
# print "genstring: %s\n" % (genstring,)
|
||||
self._help_test_inplace(genstring, decomp, strlen)
|
||||
self._help_test_inplace_minmaxmem(genstring, decomp, strlen)
|
||||
Reference in New Issue
Block a user