From c4189f2ffc5f0fbb7b077dc75612495b2a04117e Mon Sep 17 00:00:00 2001 From: Jonas Tarnstrom Date: Mon, 24 Sep 2012 12:21:23 +0200 Subject: [PATCH] Merged --- python/umemcache.cpp | 118 +++++++++++++++++++++++-------------------- tests/tests.py | 55 ++++++++++++++++---- 2 files changed, 106 insertions(+), 67 deletions(-) diff --git a/python/umemcache.cpp b/python/umemcache.cpp index ec378ee..afd9376 100644 --- a/python/umemcache.cpp +++ b/python/umemcache.cpp @@ -292,7 +292,7 @@ int Client_init(PyClient *self, PyObject *args, PyObject *kwargs) void Client_Destructor(PyClient *self) { PRINTMARK(); - if (self->client) delete self->client; + if (self->client) delete self->client; PRINTMARK(); Py_XDECREF(self->host); PRINTMARK(); @@ -989,78 +989,84 @@ PyObject *Client_flush_all(PyClient *self, PyObject *args) static PyMethodDef Client_methods[] = { - {"connect", (PyCFunction) Client_connect, METH_NOARGS, ""}, - {"is_connected", (PyCFunction) Client_is_connected, METH_NOARGS, ""}, - {"disconnect", (PyCFunction) Client_disconnect, METH_NOARGS, ""}, - {"close", (PyCFunction) Client_disconnect, METH_NOARGS, ""}, - {"set", (PyCFunction) Client_set, METH_VARARGS, "def set(self, key, data, expiration = 0, flags = 0, async = False)"}, - {"get", (PyCFunction) Client_get, METH_VARARGS, "def get(self, key, default = None)"}, - {"gets", (PyCFunction) Client_gets, METH_VARARGS, "def gets(self, key, default = None)"}, - {"get_multi", (PyCFunction) Client_get_multi, METH_O, "def get_multi(self, keys)"}, - {"gets_multi", (PyCFunction) Client_gets_multi, METH_O, "def gets_multi(self, keys)"}, - {"add", (PyCFunction) Client_add, METH_VARARGS, "def add(self, key, data, expiration = 0, flags = 0, async = False)"}, - {"replace", (PyCFunction) Client_replace, METH_VARARGS, "def replace(self, key, data, expiration = 0, flags = 0, async = False)"}, - {"append", (PyCFunction) Client_append, METH_VARARGS, "def append(self, key, data, expiration = 0, flags = 0, async = False)"}, - {"prepend", (PyCFunction) Client_prepend, METH_VARARGS, "def prepend(self, key, data, expiration = 0, flags = 0, async = False)"}, - {"delete", (PyCFunction) Client_delete, METH_VARARGS, "def delete(self, key, expiration = 0, async = False)"}, - {"cas", (PyCFunction) Client_cas, METH_VARARGS, "def cas(self, key, data, cas_unique, expiration = 0, flags = 0, async = False)"}, - {"incr", (PyCFunction) Client_incr, METH_VARARGS, "def incr(self, key, increment, async = False)"}, - {"decr", (PyCFunction) Client_decr, METH_VARARGS, "def decr(self, key, decrement, async = False)"}, - {"version", (PyCFunction) Client_version, METH_NOARGS, "def version(self)"}, - {"stats", (PyCFunction) Client_stats, METH_NOARGS, "def stats(self)"}, - {"flush_all", (PyCFunction) Client_flush_all, METH_VARARGS, "def flush_all(self, expiration = 0, async = False)"}, + {"connect", (PyCFunction) Client_connect, METH_NOARGS, ""}, + {"is_connected", (PyCFunction) Client_is_connected, METH_NOARGS, ""}, + {"disconnect", (PyCFunction) Client_disconnect, METH_NOARGS, ""}, + {"close", (PyCFunction) Client_disconnect, METH_NOARGS, ""}, + {"set", (PyCFunction) Client_set, METH_VARARGS, "def set(self, key, data, expiration = 0, flags = 0, async = False)"}, + {"get", (PyCFunction) Client_get, METH_VARARGS, "def get(self, key, default = None)"}, + {"gets", (PyCFunction) Client_gets, METH_VARARGS, "def gets(self, key, default = None)"}, + {"get_multi", (PyCFunction) Client_get_multi, METH_O, "def get_multi(self, keys)"}, + {"gets_multi", (PyCFunction) Client_gets_multi, METH_O, "def gets_multi(self, keys)"}, + {"add", (PyCFunction) Client_add, METH_VARARGS, "def add(self, key, data, expiration = 0, flags = 0, async = False)"}, + {"replace", (PyCFunction) Client_replace, METH_VARARGS, "def replace(self, key, data, expiration = 0, flags = 0, async = False)"}, + {"append", (PyCFunction) Client_append, METH_VARARGS, "def append(self, key, data, expiration = 0, flags = 0, async = False)"}, + {"prepend", (PyCFunction) Client_prepend, METH_VARARGS, "def prepend(self, key, data, expiration = 0, flags = 0, async = False)"}, + {"delete", (PyCFunction) Client_delete, METH_VARARGS, "def delete(self, key, expiration = 0, async = False)"}, + {"cas", (PyCFunction) Client_cas, METH_VARARGS, "def cas(self, key, data, cas_unique, expiration = 0, flags = 0, async = False)"}, + {"incr", (PyCFunction) Client_incr, METH_VARARGS, "def incr(self, key, increment, async = False)"}, + {"decr", (PyCFunction) Client_decr, METH_VARARGS, "def decr(self, key, decrement, async = False)"}, + {"version", (PyCFunction) Client_version, METH_NOARGS, "def version(self)"}, + {"stats", (PyCFunction) Client_stats, METH_NOARGS, "def stats(self)"}, + {"flush_all", (PyCFunction) Client_flush_all, METH_VARARGS, "def flush_all(self, expiration = 0, async = False)"}, {NULL} }; static PyMemberDef Client_members[] = { {"max_item_size", T_INT, offsetof(PyClient, maxSize), READONLY, "Max item size"}, + {"sock", T_OBJECT_EX, offsetof(PyClient, sock), READONLY, + "Socket instance"}, + {"host", T_OBJECT_EX, offsetof(PyClient, host), READONLY, + "Host"}, + {"port", T_INT, offsetof(PyClient, port), READONLY, + "Port"}, {NULL} /* Sentinel */ }; static PyTypeObject ClientType = { PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "umemcache.Client", /* tp_name */ - sizeof(PyClient), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) Client_Destructor, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* ob_size */ + "umemcache.Client", /* tp_name */ + sizeof(PyClient), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) Client_Destructor, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "Memcache client.\n\n" "Options:\n" "- address: memcache server address.\n" "- max_item_size: maximum size for an item in memcached.\n" " Defaults to 100,000 bytes", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Client_methods, /* tp_methods */ - Client_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Client_init, /* tp_init */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Client_methods, /* tp_methods */ + Client_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Client_init, /* tp_init */ }; static PyMethodDef methods[] = { diff --git a/tests/tests.py b/tests/tests.py index e337204..4335ddd 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -38,9 +38,14 @@ import logging import unittest import random +import socket +import sys from umemcache import Client -MEMCACHED_ADDRESS = "127.0.0.1:11211" + +MEMCACHED_HOST = "127.0.0.1" +MEMCACHED_PORT = 11211 +MEMCACHED_ADDRESS = "%s:%d" % (MEMCACHED_HOST, MEMCACHED_PORT) class Testumemcache(unittest.TestCase): log = logging.getLogger('umemcache') @@ -353,18 +358,46 @@ def testMaxSize(self): c.set("key1", "3") self.assertEquals(c.get("key1")[0], "3") + def testSockAccess(self): + # accessing the members before connect() is called + c = Client(MEMCACHED_ADDRESS) + self.assertEquals(c.host, MEMCACHED_HOST) + self.assertEquals(c.port, MEMCACHED_PORT) + self.assertTrue(isinstance(c.sock, socket.socket)) + c.sock.settimeout(2) + c.connect() + c.set("key1", "31337") + self.assertEquals(c.get("key1")[0], "31337") -if __name__ == '__main__': - unittest.main() + def testReadOnly(self): + # make sure once a Client class is created + # host, port and sock are readonly + c = Client(MEMCACHED_ADDRESS) + self.assertEquals(c.host, MEMCACHED_HOST) + self.assertEquals(c.port, MEMCACHED_PORT) + self.assertTrue(isinstance(c.sock, socket.socket)) + + for attr in ('sock', 'host', 'port'): + self.assertRaises(TypeError, setattr, c, attr, 'booo') -""" if __name__ == '__main__': - from guppy import hpy - hp = hpy() - hp.setrelheap() - while True: + leak = len(sys.argv) > 1 and sys.argv[-1] == '--leak' + if not leak: unittest.main() - heap = hp.heapu() - print heap -""" + else: + sys.argv = sys.argv[:-1] + try: + from guppy import hpy + except ImportError: + print('You need to install guppy') + sys.exit(0) + hp = hpy() + hp.setrelheap() + + while True: + try: + unittest.main() + finally: + heap = hp.heapu() + print heap