From c9b750d3993176a4eff243a9d73983eec64c5e7b Mon Sep 17 00:00:00 2001 From: Justin Salmon Date: Fri, 22 Feb 2013 18:29:40 +0100 Subject: [PATCH] Add some more tests --- examples/stat.py | 12 +++-- src/ClientType.hh | 51 ++++++++++++------- src/URLType.hh | 20 ++++---- src/XRootDStatusType.hh | 73 +++++++++++++++++++--------- test/test_client.py | 5 -- test/types/test_client_type.py | 12 +++++ test/types/test_url_type.py | 12 +++++ test/types/test_xrootdstatus_type.py | 12 +++++ 8 files changed, 138 insertions(+), 59 deletions(-) delete mode 100644 test/test_client.py create mode 100644 test/types/test_client_type.py create mode 100644 test/types/test_url_type.py create mode 100644 test/types/test_xrootdstatus_type.py diff --git a/examples/stat.py b/examples/stat.py index b1ab7acebe7..f3367cb9fd1 100644 --- a/examples/stat.py +++ b/examples/stat.py @@ -1,10 +1,12 @@ from XRootD import client -myclient = client.Client("root://localhost") -print myclient.url.url +myclient = client.Client("root://localhoost") +print 'URL:', myclient.url status = myclient.stat("/tmp") +print status -print "status: ", status.status -print 'code: ', status.code -print 'errNo: ', status.errNo \ No newline at end of file +print "status:", status.status +print 'code:', status.code +print 'errNo:', status.errNo +print 'message:', status.GetErrorMessage() \ No newline at end of file diff --git a/src/ClientType.hh b/src/ClientType.hh index c857ebb7ae6..8668970ba6f 100644 --- a/src/ClientType.hh +++ b/src/ClientType.hh @@ -34,7 +34,7 @@ namespace XrdClBind typedef struct { PyObject_HEAD - /* Type-specific fields go here. */ + /* Type-specific fields */ URL* url; } Client; @@ -48,7 +48,6 @@ namespace XrdClBind static int Client_init(Client *self, PyObject *args, PyObject *kwds) { - std::cout << "Client_init" << std::endl; const char *urlstr; static char *kwlist[] = {"url", NULL}; @@ -60,7 +59,8 @@ namespace XrdClBind return NULL; } - self->url = (URL *) PyObject_CallObject((PyObject *) &URLType, bind_args); + self->url = (URL *) PyObject_CallObject((PyObject *) + &URLType, bind_args); Py_DECREF(bind_args); if (!self->url) { @@ -73,32 +73,49 @@ namespace XrdClBind static PyObject* Stat(Client* self, PyObject* args) { - std::cout << "Stat()" << std::endl; const char* path; if (!PyArg_ParseTuple(args, "s", &path)) return NULL; - std::cout << self->url->url << std::endl; - std::cout << path << std::endl; - - XrdCl::URL *url = new XrdCl::URL(std::string(self->url->url)); - XrdCl::FileSystem fs(*url); + XrdCl::FileSystem fs(*self->url->url); XrdCl::XRootDStatus status; XrdCl::StatInfo *statinfo = 0; status = fs.Stat(path, statinfo, 5); - PyObject* bind_args = Py_BuildValue("(iii)", status.status, status.code, - status.errNo); - if (!bind_args) { + + //std::cout << "modtime: " << statinfo->GetModTime() << std::endl; + + // Build XRootDStatus mapping object + std::cout << "errmsg: " << status.GetErrorMessage() << std::endl; + + PyObject* status_args = Py_BuildValue("(iiis)", status.status, + status.code, status.errNo, status.GetErrorMessage().c_str()); + if (!status_args) { return NULL; } - PyObject* status_bind = PyObject_CallObject((PyObject *) &XRootDStatusType, bind_args); - PyObject_Print(status_bind, stdout, 0); std::cout << std::endl; - - Py_DECREF(bind_args); + PyObject* status_bind = PyObject_CallObject((PyObject *) + &XRootDStatusType, status_args); + if (!status_bind) { + return NULL; + } + Py_DECREF(status_args); + + // Build StatInfo mapping object +// PyObject* statinfo_args = Py_BuildValue("(iii)", status.status, status.code, +// status.errNo); +// if (!statinfo_args) { +// return NULL; +// } +// +// PyObject* statinfo_bind = PyObject_CallObject((PyObject *) +// &XRootDStatusType, statinfo_args); +// if (!statinfo_bind) { +// return NULL; +// } +// Py_DECREF(statinfo_args); return Py_BuildValue("O", status_bind); } @@ -121,7 +138,7 @@ namespace XrdClBind "client.Client", /* tp_name */ sizeof(Client), /* tp_basicsize */ 0, /* tp_itemsize */ - (destructor) Client_dealloc, /* tp_dealloc */ + (destructor) Client_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/src/URLType.hh b/src/URLType.hh index eed16089752..835e53159b8 100644 --- a/src/URLType.hh +++ b/src/URLType.hh @@ -6,23 +6,21 @@ namespace XrdClBind { - typedef struct { PyObject_HEAD - /* Type-specific fields go here. */ - const char *url; + /* Type-specific fields */ + XrdCl::URL *url; } URL; static void URL_dealloc(URL* self) { - //Py_XDECREF(self->url); + delete self->url; self->ob_type->tp_free((PyObject*) self); } static int URL_init(URL *self, PyObject *args, PyObject *kwds) { - std::cout << "URL_init" << std::endl; const char *url; static char *kwlist[] = {"url", NULL}; @@ -31,12 +29,18 @@ namespace XrdClBind return -1; if (url) { - self->url = url; + self->url = new XrdCl::URL(url); } return 0; } + static PyObject * + URL_str(URL *url) + { + return PyString_FromString(url->url->GetURL().c_str()); + } + static PyObject* IsValid(URL* self) { @@ -48,8 +52,6 @@ namespace XrdClBind } static PyMemberDef URLMembers[] = { - {"url", T_STRING, offsetof(URL, url), 0, - "The actual URL"}, {NULL} /* Sentinel */ }; @@ -76,7 +78,7 @@ namespace XrdClBind 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + (reprfunc) URL_str, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/src/XRootDStatusType.hh b/src/XRootDStatusType.hh index 9ab9888d0bd..3df4a727a29 100644 --- a/src/XRootDStatusType.hh +++ b/src/XRootDStatusType.hh @@ -18,9 +18,7 @@ namespace XrdClBind typedef struct { PyObject_HEAD /* Type-specific fields */ - uint16_t status; - uint16_t code; - uint32_t errNo; + XrdCl::XRootDStatus *status; } XRootDStatus; static void @@ -31,40 +29,69 @@ namespace XrdClBind static int XRootDStatus_init(XRootDStatus *self, PyObject *args, PyObject *kwds) { - std::cout << "XRootDStatus_init" << std::endl; - static char *kwlist[] = {"status", "code", "errNo", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwlist, - &self->status, &self->code, &self->errNo)) + static char *kwlist[] = {"status", "code", "errNo", "message", NULL}; + + uint16_t status, code; + uint32_t errNo; + const char *message; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiis", kwlist, + &status, &code, &errNo, &message)) return -1; + self->status = new XrdCl::XRootDStatus(status, code, errNo, std::string(message)); + return 0; } + static PyObject * + XRootDStatus_str(XRootDStatus *status) + { + return PyString_FromString(status->status->ToStr().c_str()); + } + static PyObject* - IsError(XRootDStatus* self) + GetErrorMessage(XRootDStatus* self) { - PyObject *status = Py_BuildValue("i", self->status); - if (status == NULL) - return NULL; + return Py_BuildValue("s", self->status->GetErrorMessage()); + } - Py_DECREF(status); - return status; + static PyObject * + XRootDStatus_GetStatus(XRootDStatus *self, void *closure) + { + return Py_BuildValue("i", self->status->status); } + static PyObject * + XRootDStatus_GetCode(XRootDStatus *self, void *closure) + { + return Py_BuildValue("i", self->status->code); + } + + static PyObject * + XRootDStatus_GetErrNo(XRootDStatus *self, void *closure) + { + return Py_BuildValue("i", self->status->errNo); + } + + static PyGetSetDef XRootDStatusGetSet[] = { + {"status", (getter) XRootDStatus_GetStatus, NULL, + "Status of the execution", NULL}, + {"code", (getter) XRootDStatus_GetCode, NULL, + "Error type, or additional hints on what to do", NULL}, + {"errNo", (getter) XRootDStatus_GetErrNo, NULL, + "Errno, if any", NULL}, + {NULL} /* Sentinel */ + }; + static PyMemberDef XRootDStatusMembers[] = { - {"status", T_INT, offsetof(XRootDStatus, status), 0, - "Status of the execution"}, - {"code", T_INT, offsetof(XRootDStatus, code), 0, - "Error type, or additional hints on what to do"}, - {"errNo", T_INT, offsetof(XRootDStatus, errNo), 0, - "Errno, if any"}, {NULL} /* Sentinel */ }; static PyMethodDef XRootDStatusMethods[] = { - {"IsError", (PyCFunction) IsError, METH_NOARGS, - "Return the error status"}, + {"GetErrorMessage", (PyCFunction) GetErrorMessage, METH_NOARGS, + "Return the error message"}, {NULL} /* Sentinel */ }; @@ -85,7 +112,7 @@ namespace XrdClBind 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + (reprfunc) XRootDStatus_str, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ @@ -99,7 +126,7 @@ namespace XrdClBind 0, /* tp_iternext */ XRootDStatusMethods, /* tp_methods */ XRootDStatusMembers, /* tp_members */ - 0, /* tp_getset */ + XRootDStatusGetSet, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ diff --git a/test/test_client.py b/test/test_client.py deleted file mode 100644 index ca0add40717..00000000000 --- a/test/test_client.py +++ /dev/null @@ -1,5 +0,0 @@ -from XRootD import client - -def test_creation(): - assert client.Client("root://localhost") is not None - diff --git a/test/types/test_client_type.py b/test/types/test_client_type.py new file mode 100644 index 00000000000..becf3aa43d0 --- /dev/null +++ b/test/types/test_client_type.py @@ -0,0 +1,12 @@ +import pytest +from XRootD import client + +def test_creation(): + c = client.Client("root://localhost") + assert c.url is not None + +def test_deletion(): + c = client.Client("root://localhost") + del c + with pytest.raises(UnboundLocalError): + assert c \ No newline at end of file diff --git a/test/types/test_url_type.py b/test/types/test_url_type.py new file mode 100644 index 00000000000..55a9629117a --- /dev/null +++ b/test/types/test_url_type.py @@ -0,0 +1,12 @@ +import pytest +from XRootD import client + +def test_creation(): + u = client.URL("root://localhost") + assert u is not None + +def test_deletion(): + u = client.URL("root://localhost") + del u + with pytest.raises(UnboundLocalError): + assert u \ No newline at end of file diff --git a/test/types/test_xrootdstatus_type.py b/test/types/test_xrootdstatus_type.py new file mode 100644 index 00000000000..e9af418b98e --- /dev/null +++ b/test/types/test_xrootdstatus_type.py @@ -0,0 +1,12 @@ +import pytest +from XRootD import client + +def test_creation(): + x = client.XRootDStatus(0, 0, 0) + assert x is not None + +def test_deletion(): + x = client.XRootDStatus(0, 0, 0) + del x + with pytest.raises(UnboundLocalError): + assert x \ No newline at end of file