[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Dec 5 23:14:04 MST 2013


The branch, master has been updated
       via  df9df74 cldap: quieten error when abandon packet is sent
       via  43c0215 pyntdb: Add tests for Python API.
       via  9a67bfa pyntdb: Don't segfault when passing in None as filename (for memory db)
       via  4111f31 pyntdb: Don't allow access after a database is closed.
       via  28b5b7e tdb tests: Remove custom code for "tdb2", which has been split out into ntdb.
      from  8c3bf7b selftest: Remove samba3.smb2.lock.*.rw-exclusive from flapping file

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit df9df7419500c42aae3cb7ccf43159d69b80b471
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Dec 5 11:53:14 2013 +1300

    cldap: quieten error when abandon packet is sent
    
    The specification indicates that no response needs to be sent when receiving
    an abandon request packet.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jelmer Vernooij <jelmer at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri Dec  6 07:13:29 CET 2013 on sn-devel-104

commit 43c021512cab2469b5ef6bb5074ee3f3b9da42a0
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Dec 1 23:20:36 2013 +0000

    pyntdb: Add tests for Python API.
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 9a67bfa834856cce0f2ce974e0189123c55095ed
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Dec 1 23:20:35 2013 +0000

    pyntdb: Don't segfault when passing in None as filename (for memory db)
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4111f31eac942fb243b3baa41a95914a4c8587c2
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Dec 1 23:20:34 2013 +0000

    pyntdb: Don't allow access after a database is closed.
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 28b5b7e28ed5a1b564851e56e8b6b3202d9f1ea9
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Dec 1 23:20:33 2013 +0000

    tdb tests: Remove custom code for "tdb2", which has been split out into ntdb.
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>
    
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/ntdb/pyntdb.c                   |   70 +++++++++++++++--
 lib/ntdb/test/python-api.py         |  154 +++++++++++++++++++++++++++++++++++
 lib/ntdb/wscript                    |   13 +++
 lib/tdb/python/tests/simple.py      |   65 +++++----------
 source4/cldap_server/cldap_server.c |    7 ++
 5 files changed, 260 insertions(+), 49 deletions(-)
 create mode 100644 lib/ntdb/test/python-api.py


Changeset truncated at 500 lines:

diff --git a/lib/ntdb/pyntdb.c b/lib/ntdb/pyntdb.c
index e4965fb..cbe7ae8 100644
--- a/lib/ntdb/pyntdb.c
+++ b/lib/ntdb/pyntdb.c
@@ -72,6 +72,13 @@ static PyObject *PyString_FromNtdb_Data(NTDB_DATA data)
 		return NULL; \
 	}
 
+#define PyNtdb_CHECK_CLOSED(pyobj) \
+	if (pyobj->closed) {\
+		PyErr_SetObject(PyExc_RuntimeError, \
+			Py_BuildValue("(i,s)", NTDB_ERR_EINVAL, "database is closed")); \
+		return NULL; \
+	}
+
 static void stderr_log(struct ntdb_context *ntdb,
 		       enum ntdb_log_level level,
 		       enum NTDB_ERROR ecode,
@@ -96,6 +103,7 @@ static PyObject *py_ntdb_open(PyTypeObject *type, PyObject *args, PyObject *kwar
 
 	if (name == NULL) {
 		ntdb_flags |= NTDB_INTERNAL;
+		name = "<internal>";
 	}
 
 	logattr.log.base.attr = NTDB_ATTRIBUTE_LOG;
@@ -120,53 +128,66 @@ static PyObject *py_ntdb_open(PyTypeObject *type, PyObject *args, PyObject *kwar
 
 static PyObject *obj_transaction_cancel(PyNtdbObject *self)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	ntdb_transaction_cancel(self->ctx);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_transaction_commit(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_transaction_commit(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_transaction_commit(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_transaction_prepare_commit(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_transaction_prepare_commit(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_transaction_prepare_commit(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_transaction_start(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_transaction_start(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_transaction_start(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_lockall(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_lockall(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_lockall(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_unlockall(PyNtdbObject *self)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	ntdb_unlockall(self->ctx);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_lockall_read(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_lockall_read(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_lockall_read(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_unlockall_read(PyNtdbObject *self)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	ntdb_unlockall_read(self->ctx);
 	Py_RETURN_NONE;
 }
@@ -190,6 +211,9 @@ static PyObject *obj_get(PyNtdbObject *self, PyObject *args)
 	NTDB_DATA key, data;
 	PyObject *py_key;
 	enum NTDB_ERROR ret;
+
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "O", &py_key))
 		return NULL;
 
@@ -206,6 +230,9 @@ static PyObject *obj_append(PyNtdbObject *self, PyObject *args)
 	NTDB_DATA key, data;
 	PyObject *py_key, *py_data;
 	enum NTDB_ERROR ret;
+
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data))
 		return NULL;
 
@@ -222,6 +249,8 @@ static PyObject *obj_firstkey(PyNtdbObject *self)
 	enum NTDB_ERROR ret;
 	NTDB_DATA key;
 
+	PyNtdb_CHECK_CLOSED(self);
+
 	ret = ntdb_firstkey(self->ctx, &key);
 	if (ret == NTDB_ERR_NOEXIST)
 		Py_RETURN_NONE;
@@ -235,6 +264,9 @@ static PyObject *obj_nextkey(PyNtdbObject *self, PyObject *args)
 	NTDB_DATA key;
 	PyObject *py_key;
 	enum NTDB_ERROR ret;
+
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "O", &py_key))
 		return NULL;
 
@@ -256,6 +288,9 @@ static PyObject *obj_delete(PyNtdbObject *self, PyObject *args)
 	NTDB_DATA key;
 	PyObject *py_key;
 	enum NTDB_ERROR ret;
+
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "O", &py_key))
 		return NULL;
 
@@ -269,6 +304,9 @@ static PyObject *obj_has_key(PyNtdbObject *self, PyObject *args)
 {
 	NTDB_DATA key;
 	PyObject *py_key;
+
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "O", &py_key))
 		return NULL;
 
@@ -284,6 +322,7 @@ static PyObject *obj_store(PyNtdbObject *self, PyObject *args)
 	enum NTDB_ERROR ret;
 	int flag = NTDB_REPLACE;
 	PyObject *py_key, *py_value;
+	PyNtdb_CHECK_CLOSED(self);
 
 	if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag))
 		return NULL;
@@ -299,6 +338,7 @@ static PyObject *obj_store(PyNtdbObject *self, PyObject *args)
 static PyObject *obj_add_flag(PyNtdbObject *self, PyObject *args)
 {
 	unsigned flag;
+	PyNtdb_CHECK_CLOSED(self);
 
 	if (!PyArg_ParseTuple(args, "I", &flag))
 		return NULL;
@@ -311,6 +351,8 @@ static PyObject *obj_remove_flag(PyNtdbObject *self, PyObject *args)
 {
 	unsigned flag;
 
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyArg_ParseTuple(args, "I", &flag))
 		return NULL;
 
@@ -360,6 +402,7 @@ static PyObject *ntdb_object_iter(PyNtdbObject *self)
 {
 	PyNtdbIteratorObject *ret;
 	enum NTDB_ERROR e;
+	PyNtdb_CHECK_CLOSED(self);
 
 	ret = PyObject_New(PyNtdbIteratorObject, &PyNtdbIterator);
 	if (!ret)
@@ -378,13 +421,16 @@ static PyObject *ntdb_object_iter(PyNtdbObject *self)
 
 static PyObject *obj_clear(PyNtdbObject *self)
 {
-	enum NTDB_ERROR ret = ntdb_wipe_all(self->ctx);
+	enum NTDB_ERROR ret;
+	PyNtdb_CHECK_CLOSED(self);
+	ret = ntdb_wipe_all(self->ctx);
 	PyErr_NTDB_ERROR_IS_ERR_RAISE(ret);
 	Py_RETURN_NONE;
 }
 
 static PyObject *obj_enable_seqnum(PyNtdbObject *self)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	ntdb_add_flag(self->ctx, NTDB_SEQNUM);
 	Py_RETURN_NONE;
 }
@@ -433,16 +479,19 @@ static PyMethodDef ntdb_object_methods[] = {
 
 static PyObject *obj_get_flags(PyNtdbObject *self, void *closure)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	return PyInt_FromLong(ntdb_get_flags(self->ctx));
 }
 
 static PyObject *obj_get_filename(PyNtdbObject *self, void *closure)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	return PyString_FromString(ntdb_name(self->ctx));
 }
 
 static PyObject *obj_get_seqnum(PyNtdbObject *self, void *closure)
 {
+	PyNtdb_CHECK_CLOSED(self);
 	return PyInt_FromLong(ntdb_get_seqnum(self->ctx));
 }
 
@@ -476,6 +525,8 @@ static PyObject *obj_getitem(PyNtdbObject *self, PyObject *key)
 	NTDB_DATA tkey, val;
 	enum NTDB_ERROR ret;
 
+	PyNtdb_CHECK_CLOSED(self);
+
 	if (!PyString_Check(key)) {
 		PyErr_SetString(PyExc_TypeError, "Expected string as key");
 		return NULL;
@@ -498,6 +549,12 @@ static int obj_setitem(PyNtdbObject *self, PyObject *key, PyObject *value)
 {
 	NTDB_DATA tkey, tval;
 	enum NTDB_ERROR ret;
+	if (self->closed) {
+		PyErr_SetObject(PyExc_RuntimeError,
+			Py_BuildValue("(i,s)", NTDB_ERR_EINVAL, "database is closed"));
+		return -1;
+	}
+
 	if (!PyString_Check(key)) {
 		PyErr_SetString(PyExc_TypeError, "Expected string as key");
 		return -1;
@@ -530,6 +587,7 @@ static PyMappingMethods ntdb_object_mapping = {
 	.mp_subscript = (binaryfunc)obj_getitem,
 	.mp_ass_subscript = (objobjargproc)obj_setitem,
 };
+
 static PyTypeObject PyNtdb = {
 	.tp_name = "ntdb.Ntdb",
 	.tp_basicsize = sizeof(PyNtdbObject),
diff --git a/lib/ntdb/test/python-api.py b/lib/ntdb/test/python-api.py
new file mode 100644
index 0000000..b728ad0
--- /dev/null
+++ b/lib/ntdb/test/python-api.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# Some simple tests for the Python bindings for TDB
+# Note that this tests the interface of the Python bindings
+# It does not test tdb itself.
+#
+# Copyright (C) 2007-2013 Jelmer Vernooij <jelmer at samba.org>
+# Published under the GNU LGPLv3 or later
+
+import ntdb
+from unittest import TestCase
+import os, tempfile
+
+
+class OpenTdbTests(TestCase):
+
+    def test_nonexistent_read(self):
+        self.assertRaises(IOError, ntdb.Ntdb, "/some/nonexistent/file", 0,
+                ntdb.DEFAULT, os.O_RDWR)
+
+class CloseTdbTests(TestCase):
+
+    def test_double_close(self):
+        self.ntdb = ntdb.Ntdb(tempfile.mkstemp()[1], ntdb.DEFAULT,
+                           os.O_CREAT|os.O_RDWR)
+        self.assertNotEqual(None, self.ntdb)
+
+        # ensure that double close does not crash python
+        self.ntdb.close()
+        self.ntdb.close()
+
+        # Check that further operations do not crash python
+        self.assertRaises(RuntimeError, lambda: self.ntdb.transaction_start())
+
+        self.assertRaises(RuntimeError, lambda: self.ntdb["bar"])
+
+
+class InternalTdbTests(TestCase):
+
+    def test_repr(self):
+        self.ntdb = ntdb.Ntdb()
+
+        # repr used to crash on internal db
+        self.assertEquals(repr(self.ntdb), "Ntdb(<internal>)")
+
+
+class SimpleTdbTests(TestCase):
+
+    def setUp(self):
+        super(SimpleTdbTests, self).setUp()
+        self.ntdb = ntdb.Ntdb(tempfile.mkstemp()[1], ntdb.DEFAULT,
+                           os.O_CREAT|os.O_RDWR)
+        self.assertNotEqual(None, self.ntdb)
+
+    def tearDown(self):
+        del self.ntdb
+
+    def test_repr(self):
+        self.assertTrue(repr(self.ntdb).startswith("Ntdb('"))
+
+    def test_lockall(self):
+        self.ntdb.lock_all()
+
+    def test_unlockall(self):
+        self.ntdb.lock_all()
+        self.ntdb.unlock_all()
+
+    def test_lockall_read(self):
+        self.ntdb.read_lock_all()
+        self.ntdb.read_unlock_all()
+
+    def test_store(self):
+        self.ntdb.store("bar", "bla")
+        self.assertEquals("bla", self.ntdb.get("bar"))
+
+    def test_getitem(self):
+        self.ntdb["bar"] = "foo"
+        self.assertEquals("foo", self.ntdb["bar"])
+
+    def test_delete(self):
+        self.ntdb["bar"] = "foo"
+        del self.ntdb["bar"]
+        self.assertRaises(KeyError, lambda: self.ntdb["bar"])
+
+    def test_contains(self):
+        self.ntdb["bla"] = "bloe"
+        self.assertTrue("bla" in self.ntdb)
+
+    def test_keyerror(self):
+        self.assertRaises(KeyError, lambda: self.ntdb["bla"])
+
+    def test_name(self):
+        self.ntdb.filename
+
+    def test_iterator(self):
+        self.ntdb["bla"] = "1"
+        self.ntdb["brainslug"] = "2"
+        l = list(self.ntdb)
+        l.sort()
+        self.assertEquals(["bla", "brainslug"], l)
+
+    def test_transaction_cancel(self):
+        self.ntdb["bloe"] = "2"
+        self.ntdb.transaction_start()
+        self.ntdb["bloe"] = "1"
+        self.ntdb.transaction_cancel()
+        self.assertEquals("2", self.ntdb["bloe"])
+
+    def test_transaction_commit(self):
+        self.ntdb["bloe"] = "2"
+        self.ntdb.transaction_start()
+        self.ntdb["bloe"] = "1"
+        self.ntdb.transaction_commit()
+        self.assertEquals("1", self.ntdb["bloe"])
+
+    def test_transaction_prepare_commit(self):
+        self.ntdb["bloe"] = "2"
+        self.ntdb.transaction_start()
+        self.ntdb["bloe"] = "1"
+        self.ntdb.transaction_prepare_commit()
+        self.ntdb.transaction_commit()
+        self.assertEquals("1", self.ntdb["bloe"])
+
+    def test_iterkeys(self):
+        self.ntdb["bloe"] = "2"
+        self.ntdb["bla"] = "25"
+        i = self.ntdb.iterkeys()
+        self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()]))
+
+    def test_clear(self):
+        self.ntdb["bloe"] = "2"
+        self.ntdb["bla"] = "25"
+        self.assertEquals(2, len(list(self.ntdb)))
+        self.ntdb.clear()
+        self.assertEquals(0, len(list(self.ntdb)))
+
+    def test_len(self):
+        self.assertEquals(0, len(list(self.ntdb)))
+        self.ntdb["entry"] = "value"
+        self.assertEquals(1, len(list(self.ntdb)))
+
+    def test_add_flags(self):
+        self.ntdb.add_flag(ntdb.NOMMAP)
+        self.ntdb.remove_flag(ntdb.NOMMAP)
+
+
+class VersionTests(TestCase):
+
+    def test_present(self):
+        self.assertTrue(isinstance(ntdb.__version__, str))
+
+
+if __name__ == '__main__':
+    import unittest
+    unittest.TestProgram()
diff --git a/lib/ntdb/wscript b/lib/ntdb/wscript
index de67615..2513e5c 100644
--- a/lib/ntdb/wscript
+++ b/lib/ntdb/wscript
@@ -92,6 +92,7 @@ def configure(conf):
                                 'test/api-record-expand.c',
                                 'test/api-simple-delete.c',
                                 'test/api-summary.c']
+    conf.env.NTDB_TEST_API_PY=['test/python-api.py']
     conf.env.NTDB_TEST_API_HELPER_SRC=['test/helpapi-external-agent.c']
     conf.env.NTDB_TEST_RUN_HELPER_SRC=['test/helprun-external-agent.c',
                                        'test/helprun-layout.c']
@@ -253,6 +254,18 @@ def testonly(ctx):
                 samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output'))
                 ecode = ret;
                 break;
+        if not env.disable_python:
+            for f in env.NTDB_TEST_API_PY:
+                print("..." + f)
+                cmd = "cd " + testdir + " && PYTHONPATH=%s %s %s > test-output 2>&1" % (
+                    os.path.abspath(os.path.join(Utils.g_module.blddir, "python")),
+                        env["PYTHON"], os.path.abspath(f))
+                ret = samba_utils.RUN_COMMAND(cmd)
+                if ret != 0:
+                    print("%s (%s) failed:" % (name, f))
+                    samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output'))
+                    ecode = ret
+                    break
 
     sys.exit(ecode)
 
diff --git a/lib/tdb/python/tests/simple.py b/lib/tdb/python/tests/simple.py
index 7e295a8..4751f9b 100644
--- a/lib/tdb/python/tests/simple.py
+++ b/lib/tdb/python/tests/simple.py
@@ -20,13 +20,8 @@ class OpenTdbTests(TestCase):
 class CloseTdbTests(TestCase):
 
     def test_double_close(self):
-        # No hash size in tdb2.
-        if tdb.__version__.startswith("2"):
-            self.tdb = tdb.Tdb(tempfile.mkstemp()[1], tdb.DEFAULT,
-                               os.O_CREAT|os.O_RDWR)
-        else:
-            self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT,
-                               os.O_CREAT|os.O_RDWR)
+        self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT,
+                           os.O_CREAT|os.O_RDWR)
         self.assertNotEqual(None, self.tdb)
 
         # ensure that double close does not crash python
@@ -52,12 +47,8 @@ class SimpleTdbTests(TestCase):
 
     def setUp(self):
         super(SimpleTdbTests, self).setUp()
-        if tdb.__version__.startswith("2"):
-            self.tdb = tdb.Tdb(tempfile.mkstemp()[1], tdb.DEFAULT,
-                               os.O_CREAT|os.O_RDWR)
-        else:
-            self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT,
-                               os.O_CREAT|os.O_RDWR)
+        self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT,
+                           os.O_CREAT|os.O_RDWR)
         self.assertNotEqual(None, self.tdb)
 
     def tearDown(self):
@@ -70,8 +61,7 @@ class SimpleTdbTests(TestCase):
         self.tdb.lock_all()
 
     def test_max_dead(self):
-        if not tdb.__version__.startswith("2"):
-            self.tdb.max_dead = 20
+        self.tdb.max_dead = 20
 
     def test_unlockall(self):
         self.tdb.lock_all()
@@ -82,8 +72,7 @@ class SimpleTdbTests(TestCase):
         self.tdb.read_unlock_all()
 
     def test_reopen(self):
-        if not tdb.__version__.startswith("2"):
-            self.tdb.reopen()


-- 
Samba Shared Repository


More information about the samba-cvs mailing list