diff options
author | Andrew Bartlett <abartlet@samba.org> | 2017-06-26 13:16:01 +1200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2017-07-02 17:35:20 +0200 |
commit | b3db6558d324c23ad8011175d9cb0b70ad233121 (patch) | |
tree | f3313bbc4c14e7e78beadef0e49d6cbd80dee8e3 /python/samba/tests/dsdb.py | |
parent | 4b5ff4a3092aa7700e0193a00882261ee990aa10 (diff) | |
download | samba-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.py | 71 |
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() |