summaryrefslogtreecommitdiff
path: root/python/samba/tests/dsdb.py
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2017-06-26 13:16:01 +1200
committerStefan Metzmacher <metze@samba.org>2017-07-02 17:35:20 +0200
commitb3db6558d324c23ad8011175d9cb0b70ad233121 (patch)
treef3313bbc4c14e7e78beadef0e49d6cbd80dee8e3 /python/samba/tests/dsdb.py
parent4b5ff4a3092aa7700e0193a00882261ee990aa10 (diff)
downloadsamba-b3db6558d324c23ad8011175d9cb0b70ad233121.tar.gz
dsdb: Add new test adding a record to the top level sam.ldb file
This shows that locks are made on this file as well Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'python/samba/tests/dsdb.py')
-rw-r--r--python/samba/tests/dsdb.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/python/samba/tests/dsdb.py b/python/samba/tests/dsdb.py
index 36da7225de8..cfe19093b9c 100644
--- a/python/samba/tests/dsdb.py
+++ b/python/samba/tests/dsdb.py
@@ -278,6 +278,77 @@ class DsdbTests(TestCase):
self.assertTrue(os.WIFEXITED(status))
self.assertEqual(os.WEXITSTATUS(status), 0)
+ def test_db_lock3(self):
+ basedn = self.samdb.get_default_basedn()
+ (r1, w1) = os.pipe()
+ (r2, w2) = os.pipe()
+
+ pid = os.fork()
+ if pid == 0:
+ # In the child, close the main DB, re-open
+ del(self.samdb)
+ gc.collect()
+ self.samdb = SamDB(session_info=self.session,
+ credentials=self.creds,
+ lp=self.lp)
+
+ # We need to hold this iterator open to hold the all-record lock.
+ res = self.samdb.search_iterator()
+
+ os.write(w2, b"start")
+ if (os.read(r1, 7) != b"started"):
+ os._exit(1)
+
+ os.write(w2, b"add")
+ if (os.read(r1, 5) != b"added"):
+ os._exit(2)
+
+ # Wait 2 seconds to block prepare_commit() in the child.
+ os.write(w2, b"prepare")
+ time.sleep(2)
+
+ # Release the locks
+ for l in res:
+ pass
+
+ if (os.read(r1, 8) != b"prepared"):
+ os._exit(3)
+
+ os._exit(0)
+
+ # We can start the transaction during the search
+ # because both just grab the all-record read lock.
+ self.assertEqual(os.read(r2, 5), b"start")
+ self.samdb.transaction_start()
+ os.write(w1, b"started")
+
+ self.assertEqual(os.read(r2, 3), b"add")
+
+ # This will end up in the top level db
+ dn = "@DSDB_LOCK_TEST"
+ self.samdb.add({
+ "dn": dn})
+ self.samdb.delete(dn)
+ os.write(w1, b"added")
+
+ # Obtain a write lock, this will block until
+ # the child releases the read lock.
+ self.assertEqual(os.read(r2, 7), b"prepare")
+ start = time.time()
+ self.samdb.transaction_prepare_commit()
+ end = time.time()
+ self.assertGreater(end - start, 1.9)
+ os.write(w1, b"prepared")
+
+ # Drop the write lock
+ self.samdb.transaction_cancel()
+
+ (got_pid, status) = os.waitpid(pid, 0)
+ self.assertTrue(os.WIFEXITED(status))
+ self.assertEqual(os.WEXITSTATUS(status), 0)
+ self.assertEqual(got_pid, pid)
+
+
def test_full_db_lock1(self):
basedn = self.samdb.get_default_basedn()
backend_filename = "%s.ldb" % basedn.get_casefold()