X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=python%2Fsamba%2Ftests%2Fdsdb.py;fp=python%2Fsamba%2Ftests%2Fdsdb.py;h=cfe19093b9c7086a8c1878d2bb5bb5bab495121c;hp=36da7225de8773b24058013d260f3194b7203938;hb=b3db6558d324c23ad8011175d9cb0b70ad233121;hpb=4b5ff4a3092aa7700e0193a00882261ee990aa10 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()