def test_refcounts(self): SENTINEL = object() DUMMY = b"dummy" KEY = b"fwLiDZKV7IlVByM5bVDNkg" VALUE = "PVILgNVNkCfMkQup5vkGSQ" class MyClient(_pylibmc.client): """Always serialize and deserialize to the same constants.""" def serialize(self, value): return DUMMY, 1 def deserialize(self, bytes_, flags): return SENTINEL refcountables = [1, long_(1), SENTINEL, DUMMY, KEY, VALUE] c = make_test_client(MyClient) initial_refcounts = get_refcounts(refcountables) c.set(KEY, VALUE) eq_(get_refcounts(refcountables), initial_refcounts) assert c.get(KEY) is SENTINEL eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.get_multi([KEY]), {KEY: SENTINEL}) eq_(get_refcounts(refcountables), initial_refcounts) c.set_multi({KEY: True}) eq_(get_refcounts(refcountables), initial_refcounts)
def _test_get(self, key, val): bc = make_test_client(binary=True) refcountables = [key, val] initial_refcounts = get_refcounts(refcountables) bc.set(key, val) eq_(get_refcounts(refcountables), initial_refcounts) eq_(bc.get(key), val) eq_(get_refcounts(refcountables), initial_refcounts)
def test_get_multi(self): bc = make_test_client(binary=True) keys = ["first", "second", "", b""] value = "first_value" refcountables = keys + [value] initial_refcounts = get_refcounts(refcountables) bc.set(keys[0], value) eq_(get_refcounts(refcountables), initial_refcounts) eq_(bc.get_multi(keys), {keys[0]: value}) eq_(get_refcounts(refcountables), initial_refcounts)
def test_get_multi_bytes_and_unicode(self): bc = make_test_client(binary=True) keys = ["third", b"fourth"] value = "another_value" kv = dict((k, value) for k in keys) refcountables = [keys] + [value] initial_refcounts = get_refcounts(refcountables) bc.set_multi(kv) eq_(get_refcounts(refcountables), initial_refcounts) eq_(bc.get_multi(keys)[keys[0]], value) eq_(get_refcounts(refcountables), initial_refcounts)
def test_get_invalid_key(self): bc = make_test_client(binary=True) key = object() initial_refcount = get_refcounts([key]) raised = False try: bc.get(key) except TypeError: raised = True assert raised eq_(get_refcounts([key]), initial_refcount)
def test_incr(self): bc = make_test_client(binary=True) keys = [b"increment_key", "increment_key_again"] refcountables = keys initial_refcounts = get_refcounts(refcountables) bc.set(keys[0], 1) eq_(get_refcounts(refcountables), initial_refcounts) bc.incr(keys[0]) eq_(get_refcounts(refcountables), initial_refcounts) bc.set(keys[1], 5) eq_(get_refcounts(refcountables), initial_refcounts) bc.incr(keys[1]) eq_(get_refcounts(refcountables), initial_refcounts)
def test_cas(self): k = "testkey" val = 1138478589238 mc = make_test_client(binary=False, behaviors={'cas': True}) refcountables = [k, val] initial_refcounts = get_refcounts(refcountables) ok_(mc.set(k, 0)) eq_(get_refcounts(refcountables), initial_refcounts) while True: rv, cas = mc.gets(k) eq_(get_refcounts(refcountables), initial_refcounts) ok_(mc.cas(k, rv + 1, cas)) eq_(get_refcounts(refcountables), initial_refcounts) if rv == 10: break
def test_invalid_flags_returned(self): # test that nothing bad (memory leaks, segfaults) happens # when subclasses implement `deserialize` incorrectly DUMMY = b"dummy" BAD_FLAGS = object() KEY = 'foo' VALUE = object() refcountables = [KEY, DUMMY, VALUE, BAD_FLAGS] class MyClient(pylibmc.Client): def serialize(self, value): return DUMMY, BAD_FLAGS c = make_test_client(MyClient) initial_refcounts = get_refcounts(refcountables) self._assert_set_raises(c, KEY, VALUE) eq_(get_refcounts(refcountables), initial_refcounts)
def test_override_deserialize(self): class MyClient(pylibmc.Client): ignored = [] def deserialize(self, bytes_, flags): try: return super(MyClient, self).deserialize(bytes_, flags) except Exception as error: self.ignored.append(error) raise pylibmc.CacheMiss global MyObject # Needed by the pickling system. class MyObject(object): def __getstate__(self): return dict(a=1) def __eq__(self, other): return type(other) is type(self) def __setstate__(self, d): assert d['a'] == 1 c = make_test_client(MyClient, behaviors={'cas': True}) eq_(c.get('notathing'), None) refcountables = ['foo', 'myobj', 'noneobj', 'myobj2', 'cachemiss'] initial_refcounts = get_refcounts(refcountables) c['foo'] = 'foo' c['myobj'] = MyObject() c['noneobj'] = None c['myobj2'] = MyObject() # Show that everything is initially regular. eq_(c.get('myobj'), MyObject()) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.get_multi(['foo', 'myobj', 'noneobj', 'cachemiss']), dict(foo='foo', myobj=MyObject(), noneobj=None)) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.gets('myobj2')[0], MyObject()) eq_(get_refcounts(refcountables), initial_refcounts) # Show that the subclass can transform unpickling issues into a cache miss. del MyObject # Break unpickling eq_(c.get('myobj'), None) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.get_multi(['foo', 'myobj', 'noneobj', 'cachemiss']), dict(foo='foo', noneobj=None)) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.gets('myobj2'), (None, None)) eq_(get_refcounts(refcountables), initial_refcounts) # The ignored errors are "AttributeError: test.test_client has no MyObject" eq_(len(MyClient.ignored), 3) assert all( isinstance(error, AttributeError) for error in MyClient.ignored)
def test_override_deserialize(self): class MyClient(pylibmc.Client): ignored = [] def deserialize(self, bytes_, flags): try: return super(MyClient, self).deserialize(bytes_, flags) except Exception as error: self.ignored.append(error) raise pylibmc.CacheMiss global MyObject # Needed by the pickling system. class MyObject(object): def __getstate__(self): return dict(a=1) def __eq__(self, other): return type(other) is type(self) def __setstate__(self, d): assert d["a"] == 1 c = make_test_client(MyClient, behaviors={"cas": True}) eq_(c.get("notathing"), None) refcountables = ["foo", "myobj", "noneobj", "myobj2", "cachemiss"] initial_refcounts = get_refcounts(refcountables) c["foo"] = "foo" c["myobj"] = MyObject() c["noneobj"] = None c["myobj2"] = MyObject() # Show that everything is initially regular. eq_(c.get("myobj"), MyObject()) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.get_multi(["foo", "myobj", "noneobj", "cachemiss"]), dict(foo="foo", myobj=MyObject(), noneobj=None)) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.gets("myobj2")[0], MyObject()) eq_(get_refcounts(refcountables), initial_refcounts) # Show that the subclass can transform unpickling issues into a cache miss. del MyObject # Break unpickling eq_(c.get("myobj"), None) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.get_multi(["foo", "myobj", "noneobj", "cachemiss"]), dict(foo="foo", noneobj=None)) eq_(get_refcounts(refcountables), initial_refcounts) eq_(c.gets("myobj2"), (None, None)) eq_(get_refcounts(refcountables), initial_refcounts) # The ignored errors are "AttributeError: test.test_client has no MyObject" eq_(len(MyClient.ignored), 3) assert all(isinstance(error, AttributeError) for error in MyClient.ignored)
def test_invalid_flags_returned_2(self): DUMMY = "ab" KEY = "key" VALUE = 123456 refcountables = [DUMMY, KEY, VALUE] class MyClient(pylibmc.Client): def serialize(self, value): return DUMMY c = make_test_client(MyClient) initial_refcounts = get_refcounts(refcountables) self._assert_set_raises(c, KEY, VALUE) eq_(get_refcounts(refcountables), initial_refcounts) try: c.set_multi({KEY: DUMMY}) except ValueError: raised = True assert raised eq_(get_refcounts(refcountables), initial_refcounts)
def test_prefixes(self): bc = make_test_client(binary=True) keys = ["prefixone", b"prefixtwo"] prefix = "testprefix-" values = [b"valone", "valtwo"] refcountables = keys + values + [prefix] initial_refcounts = get_refcounts(refcountables) bc.set_multi(dict(zip(keys, values)), key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.get_multi(keys, key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi([keys[0]], key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi([keys[1]], key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.set_multi(dict(zip(keys, values)), key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi(keys, key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi(keys, key_prefix=prefix) eq_(get_refcounts(refcountables), initial_refcounts)
def test_set_and_delete_multi(self): bc = make_test_client(binary=True) keys = ["delone", b"deltwo", "delthree", "delfour"] values = [b"valone", "valtwo", object(), 2] refcountables = keys + values initial_refcounts = get_refcounts(refcountables) bc.set_multi(dict(zip(keys, values))) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi([keys[0]]) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi([keys[1]]) eq_(get_refcounts(refcountables), initial_refcounts) bc.set_multi(dict(zip(keys, values))) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi(keys) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete_multi(keys) eq_(get_refcounts(refcountables), initial_refcounts)
def test_delete(self): bc = make_test_client(binary=True) keys = ["delone", b"deltwo"] values = [b"valone", "valtwo"] refcountables = keys + values initial_refcounts = get_refcounts(refcountables) bc.set(keys[0], values[0]) eq_(get_refcounts(refcountables), initial_refcounts) bc.set(keys[1], values[1]) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete(keys[0]) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete(keys[1]) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete(keys[0]) eq_(get_refcounts(refcountables), initial_refcounts) bc.delete(keys[1]) eq_(get_refcounts(refcountables), initial_refcounts)
def test_get_with_default(self): bc = make_test_client(binary=True) key = b'refcountest4' val = 'some_value' default = object() refcountables = [key, val, default] initial_refcounts = get_refcounts(refcountables) bc.set(key, val) eq_(get_refcounts(refcountables), initial_refcounts) assert bc.get(key) == val eq_(get_refcounts(refcountables), initial_refcounts) assert bc.get(key, default) == val eq_(get_refcounts(refcountables), initial_refcounts) bc.delete(key) assert bc.get(key) is None eq_(get_refcounts(refcountables), initial_refcounts) assert bc.get(key, default) is default eq_(get_refcounts(refcountables), initial_refcounts)