test_util: get almost full test coverage of dictutil, starting with the original pyutil tests as a base. The remaining three uncovered lines involve funny cases of ValueOrderedDict that I can't figure out how to get at

This commit is contained in:
Brian Warner 2009-02-15 20:32:10 -07:00
parent cc27b218f5
commit 3235b9630b
2 changed files with 357 additions and 16 deletions

View File

@ -19,7 +19,7 @@ from foolscap.logging import log
import sha
from allmydata.mutable.filenode import MutableFileNode, BackoffAgent
from allmydata.mutable.common import DictOfSets, ResponseCache, \
from allmydata.mutable.common import ResponseCache, \
MODE_CHECK, MODE_ANYTHING, MODE_WRITE, MODE_READ, \
NeedMoreDataError, UnrecoverableFileError, UncoordinatedWriteError, \
NotEnoughServersError, CorruptShareError
@ -1696,20 +1696,6 @@ class MultipleVersions(unittest.TestCase, PublishMixin, CheckerMixin):
class Utils(unittest.TestCase):
def test_dict_of_sets(self):
ds = DictOfSets()
ds.add(1, "a")
ds.add(2, "b")
ds.add(2, "b")
ds.add(2, "c")
self.failUnlessEqual(ds[1], set(["a"]))
self.failUnlessEqual(ds[2], set(["b", "c"]))
ds.discard(3, "d") # should not raise an exception
ds.discard(2, "b")
self.failUnlessEqual(ds[2], set(["c"]))
ds.discard(2, "c")
self.failIf(2 in ds)
def _do_inside(self, c, x_start, x_length, y_start, y_length):
# we compare this against sets of integers
x = set(range(x_start, x_start+x_length))

View File

@ -10,7 +10,7 @@ from twisted.python import failure
from allmydata.util import base32, idlib, humanreadable, mathutil, hashutil
from allmydata.util import assertutil, fileutil, deferredutil, abbreviate
from allmydata.util import limiter, time_format, pollmixin, cachedir
from allmydata.util import statistics
from allmydata.util import statistics, dictutil
class Base32(unittest.TestCase):
def test_b2a_matches_Pythons(self):
@ -840,3 +840,358 @@ class CacheDir(unittest.TestCase):
_failIfExists("a")
_failUnlessExists("b")
_failUnlessExists("c")
ctr = [0]
class EqButNotIs:
def __init__(self, x):
self.x = x
self.hash = ctr[0]
ctr[0] += 1
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 DictUtil(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
self.failUnless(filter(lambda x: x is 8, d.itervalues()))
self.failUnless(filter(lambda x: x is fake7, d.itervalues()))
# The real 7 should have been ejected by the d[3] = 8.
self.failUnless(not filter(lambda x: x is 7, d.itervalues()))
self.failUnless(filter(lambda x: x is fake3, d.iterkeys()))
self.failUnless(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
self.failUnless(filter(lambda x: x is 8, d.itervalues()))
self.failUnless(filter(lambda x: x is fake7, d.itervalues()))
# The real 7 should have been ejected by the d[3] = 8.
self.failUnless(not filter(lambda x: x is 7, d.itervalues()))
self.failUnless(filter(lambda x: x is fake3, d.iterkeys()))
self.failUnless(filter(lambda x: x is 3, d.iterkeys()))
d[fake3] = 8
def test_all(self):
self._help_test_eq_but_notis(dictutil.UtilDict)
self._help_test_eq_but_notis(dictutil.NumDict)
self._help_test_eq_but_notis(dictutil.ValueOrderedDict)
self._help_test_nonempty_dict(dictutil.UtilDict)
self._help_test_nonempty_dict(dictutil.NumDict)
self._help_test_nonempty_dict(dictutil.ValueOrderedDict)
self._help_test_eq_but_notis(dictutil.UtilDict)
self._help_test_eq_but_notis(dictutil.NumDict)
self._help_test_eq_but_notis(dictutil.ValueOrderedDict)
def test_dict_of_sets(self):
ds = dictutil.DictOfSets()
ds.add(1, "a")
ds.add(2, "b")
ds.add(2, "b")
ds.add(2, "c")
self.failUnlessEqual(ds[1], set(["a"]))
self.failUnlessEqual(ds[2], set(["b", "c"]))
ds.discard(3, "d") # should not raise an exception
ds.discard(2, "b")
self.failUnlessEqual(ds[2], set(["c"]))
ds.discard(2, "c")
self.failIf(2 in ds)
ds.union(1, ["a", "e"])
ds.union(3, ["f"])
self.failUnlessEqual(ds[1], set(["a","e"]))
self.failUnlessEqual(ds[3], set(["f"]))
ds2 = dictutil.DictOfSets()
ds2.add(3, "f")
ds2.add(3, "g")
ds2.add(4, "h")
ds.update(ds2)
self.failUnlessEqual(ds[1], set(["a","e"]))
self.failUnlessEqual(ds[3], set(["f", "g"]))
self.failUnlessEqual(ds[4], set(["h"]))
def test_move(self):
d1 = {1: "a", 2: "b"}
d2 = {2: "c", 3: "d"}
dictutil.move(1, d1, d2)
self.failUnlessEqual(d1, {2: "b"})
self.failUnlessEqual(d2, {1: "a", 2: "c", 3: "d"})
d1 = {1: "a", 2: "b"}
d2 = {2: "c", 3: "d"}
dictutil.move(2, d1, d2)
self.failUnlessEqual(d1, {1: "a"})
self.failUnlessEqual(d2, {2: "b", 3: "d"})
d1 = {1: "a", 2: "b"}
d2 = {2: "c", 3: "d"}
self.failUnlessRaises(KeyError, dictutil.move, 5, d1, d2, strict=True)
def test_subtract(self):
d1 = {1: "a", 2: "b"}
d2 = {2: "c", 3: "d"}
d3 = dictutil.subtract(d1, d2)
self.failUnlessEqual(d3, {1: "a"})
d1 = {1: "a", 2: "b"}
d2 = {2: "c"}
d3 = dictutil.subtract(d1, d2)
self.failUnlessEqual(d3, {1: "a"})
def test_utildict(self):
d = dictutil.UtilDict({1: "a", 2: "b"})
d.del_if_present(1)
d.del_if_present(3)
self.failUnlessEqual(d, {2: "b"})
def eq(a, b):
return a == b
self.failUnlessRaises(TypeError, eq, d, "not a dict")
d = dictutil.UtilDict({1: "b", 2: "a"})
self.failUnlessEqual(d.items_sorted_by_value(),
[(2, "a"), (1, "b")])
self.failUnlessEqual(d.items_sorted_by_key(),
[(1, "b"), (2, "a")])
self.failUnlessEqual(repr(d), "{1: 'b', 2: 'a'}")
self.failUnless(1 in d)
d2 = dictutil.UtilDict({3: "c", 4: "d"})
self.failUnless(d != d2)
self.failUnless(d2 > d)
self.failUnless(d2 >= d)
self.failUnless(d <= d2)
self.failUnless(d < d2)
self.failUnlessEqual(d[1], "b")
self.failUnlessEqual(sorted(list([k for k in d])), [1,2])
d3 = d.copy()
self.failUnlessEqual(d, d3)
self.failUnless(isinstance(d3, dictutil.UtilDict))
d4 = d.fromkeys([3,4], "e")
self.failUnlessEqual(d4, {3: "e", 4: "e"})
self.failUnlessEqual(d.get(1), "b")
self.failUnlessEqual(d.get(3), None)
self.failUnlessEqual(d.get(3, "default"), "default")
self.failUnlessEqual(sorted(list(d.items())),
[(1, "b"), (2, "a")])
self.failUnlessEqual(sorted(list(d.iteritems())),
[(1, "b"), (2, "a")])
self.failUnlessEqual(sorted(d.keys()), [1, 2])
self.failUnlessEqual(sorted(d.values()), ["a", "b"])
x = d.setdefault(1, "new")
self.failUnlessEqual(x, "b")
self.failUnlessEqual(d[1], "b")
x = d.setdefault(3, "new")
self.failUnlessEqual(x, "new")
self.failUnlessEqual(d[3], "new")
del d[3]
x = d.popitem()
self.failUnless(x in [(1, "b"), (2, "a")])
x = d.popitem()
self.failUnless(x in [(1, "b"), (2, "a")])
self.failUnlessRaises(KeyError, d.popitem)
def test_numdict(self):
d = dictutil.NumDict({"a": 1, "b": 2})
d.add_num("a", 10, 5)
d.add_num("c", 20, 5)
d.add_num("d", 30)
self.failUnlessEqual(d, {"a": 11, "b": 2, "c": 25, "d": 30})
d.subtract_num("a", 10)
d.subtract_num("e", 10)
d.subtract_num("f", 10, 15)
self.failUnlessEqual(d, {"a": 1, "b": 2, "c": 25, "d": 30,
"e": -10, "f": 5})
self.failUnlessEqual(d.sum(), sum([1, 2, 25, 30, -10, 5]))
d = dictutil.NumDict()
d.inc("a")
d.inc("a")
d.inc("b", 5)
self.failUnlessEqual(d, {"a": 2, "b": 6})
d.dec("a")
d.dec("c")
d.dec("d", 5)
self.failUnlessEqual(d, {"a": 1, "b": 6, "c": -1, "d": 4})
self.failUnlessEqual(d.items_sorted_by_key(),
[("a", 1), ("b", 6), ("c", -1), ("d", 4)])
self.failUnlessEqual(d.items_sorted_by_value(),
[("c", -1), ("a", 1), ("d", 4), ("b", 6)])
self.failUnlessEqual(d.item_with_largest_value(), ("b", 6))
d = dictutil.NumDict({"a": 1, "b": 2})
self.failUnlessEqual(repr(d), "{'a': 1, 'b': 2}")
self.failUnless("a" in d)
d2 = dictutil.NumDict({"c": 3, "d": 4})
self.failUnless(d != d2)
self.failUnless(d2 > d)
self.failUnless(d2 >= d)
self.failUnless(d <= d2)
self.failUnless(d < d2)
self.failUnlessEqual(d["a"], 1)
self.failUnlessEqual(sorted(list([k for k in d])), ["a","b"])
def eq(a, b):
return a == b
self.failUnlessRaises(TypeError, eq, d, "not a dict")
d3 = d.copy()
self.failUnlessEqual(d, d3)
self.failUnless(isinstance(d3, dictutil.NumDict))
d4 = d.fromkeys(["a","b"], 5)
self.failUnlessEqual(d4, {"a": 5, "b": 5})
self.failUnlessEqual(d.get("a"), 1)
self.failUnlessEqual(d.get("c"), 0)
self.failUnlessEqual(d.get("c", 5), 5)
self.failUnlessEqual(sorted(list(d.items())),
[("a", 1), ("b", 2)])
self.failUnlessEqual(sorted(list(d.iteritems())),
[("a", 1), ("b", 2)])
self.failUnlessEqual(sorted(d.keys()), ["a", "b"])
self.failUnlessEqual(sorted(d.values()), [1, 2])
self.failUnless(d.has_key("a"))
self.failIf(d.has_key("c"))
x = d.setdefault("c", 3)
self.failUnlessEqual(x, 3)
self.failUnlessEqual(d["c"], 3)
x = d.setdefault("c", 5)
self.failUnlessEqual(x, 3)
self.failUnlessEqual(d["c"], 3)
del d["c"]
x = d.popitem()
self.failUnless(x in [("a", 1), ("b", 2)])
x = d.popitem()
self.failUnless(x in [("a", 1), ("b", 2)])
self.failUnlessRaises(KeyError, d.popitem)
d.update({"c": 3})
d.update({"c": 4, "d": 5})
self.failUnlessEqual(d, {"c": 4, "d": 5})
def test_del_if_present(self):
d = {1: "a", 2: "b"}
dictutil.del_if_present(d, 1)
dictutil.del_if_present(d, 3)
self.failUnlessEqual(d, {2: "b"})
def test_valueordereddict(self):
d = dictutil.ValueOrderedDict()
d["a"] = 3
d["b"] = 2
d["c"] = 1
self.failUnlessEqual(d, {"a": 3, "b": 2, "c": 1})
self.failUnlessEqual(d.items(), [("c", 1), ("b", 2), ("a", 3)])
self.failUnlessEqual(d.values(), [1, 2, 3])
self.failUnlessEqual(d.keys(), ["c", "b", "a"])
self.failUnlessEqual(repr(d), "<ValueOrderedDict {c: 1, b: 2, a: 3}>")
def eq(a, b):
return a == b
self.failIf(d == {"a": 4})
self.failUnless(d != {"a": 4})
x = d.setdefault("d", 0)
self.failUnlessEqual(x, 0)
self.failUnlessEqual(d["d"], 0)
x = d.setdefault("d", -1)
self.failUnlessEqual(x, 0)
self.failUnlessEqual(d["d"], 0)
x = d.remove("e", "default", False)
self.failUnlessEqual(x, "default")
self.failUnlessRaises(KeyError, d.remove, "e", "default", True)
x = d.remove("d", 5)
self.failUnlessEqual(x, 0)
x = d.__getitem__("c")
self.failUnlessEqual(x, 1)
x = d.__getitem__("e", "default", False)
self.failUnlessEqual(x, "default")
self.failUnlessRaises(KeyError, d.__getitem__, "e", "default", True)
self.failUnlessEqual(d.popitem(), ("c", 1))
self.failUnlessEqual(d.popitem(), ("b", 2))
self.failUnlessEqual(d.popitem(), ("a", 3))
self.failUnlessRaises(KeyError, d.popitem)
d = dictutil.ValueOrderedDict({"a": 3, "b": 2, "c": 1})
x = d.pop("d", "default", False)
self.failUnlessEqual(x, "default")
self.failUnlessRaises(KeyError, d.pop, "d", "default", True)
x = d.pop("b")
self.failUnlessEqual(x, 2)
self.failUnlessEqual(d.items(), [("c", 1), ("a", 3)])
d = dictutil.ValueOrderedDict({"a": 3, "b": 2, "c": 1})
x = d.pop_from_list(1) # pop the second item, b/2
self.failUnlessEqual(x, "b")
self.failUnlessEqual(d.items(), [("c", 1), ("a", 3)])