mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
ldb: Add tests for when we should expect a full scan
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13448 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
parent
88ae60ed18
commit
e99c199d81
@ -806,7 +806,7 @@ int ltdb_search(struct ltdb_context *ctx)
|
||||
* callback error */
|
||||
if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
|
||||
/* Not indexed, so we need to do a full scan */
|
||||
if (ltdb->warn_unindexed) {
|
||||
if (ltdb->warn_unindexed || ltdb->disable_full_db_scan) {
|
||||
/* useful for debugging when slow performance
|
||||
* is caused by unindexed searches */
|
||||
char *expression = ldb_filter_from_tree(ctx, ctx->tree);
|
||||
@ -819,6 +819,7 @@ int ltdb_search(struct ltdb_context *ctx)
|
||||
|
||||
talloc_free(expression);
|
||||
}
|
||||
|
||||
if (match_count != 0) {
|
||||
/* the indexing code gave an error
|
||||
* after having returned at least one
|
||||
@ -831,6 +832,14 @@ int ltdb_search(struct ltdb_context *ctx)
|
||||
ltdb->kv_ops->unlock_read(module);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
if (ltdb->disable_full_db_scan) {
|
||||
ldb_set_errstring(ldb,
|
||||
"ldb FULL SEARCH disabled");
|
||||
ltdb->kv_ops->unlock_read(module);
|
||||
return LDB_ERR_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
|
||||
ret = ltdb_search_full(ctx);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
|
||||
|
@ -2279,6 +2279,22 @@ int init_store(struct ltdb_private *ltdb,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override full DB scans
|
||||
*
|
||||
* A full DB scan is expensive on a large database. This
|
||||
* option is for testing to show that the full DB scan is not
|
||||
* triggered.
|
||||
*/
|
||||
{
|
||||
const char *len_str =
|
||||
ldb_options_find(ldb, options,
|
||||
"disable_full_db_scan_for_self_test");
|
||||
if (len_str != NULL) {
|
||||
ltdb->disable_full_db_scan = true;
|
||||
}
|
||||
}
|
||||
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,12 @@ struct ltdb_private {
|
||||
*/
|
||||
unsigned max_key_length;
|
||||
|
||||
/*
|
||||
* To allow testing that ensures the DB does not fall back
|
||||
* to a full scan
|
||||
*/
|
||||
bool disable_full_db_scan;
|
||||
|
||||
/*
|
||||
* The PID that opened this database so we don't work in a
|
||||
* fork()ed child.
|
||||
|
@ -695,9 +695,12 @@ class SearchTests(LdbBaseTest):
|
||||
super(SearchTests, self).setUp()
|
||||
self.testdir = tempdir()
|
||||
self.filename = os.path.join(self.testdir, "search_test.ldb")
|
||||
options = ["modules:rdn_name"]
|
||||
if hasattr(self, 'IDXCHECK'):
|
||||
options.append("disable_full_db_scan_for_self_test:1")
|
||||
self.l = ldb.Ldb(self.url(),
|
||||
flags=self.flags(),
|
||||
options=["modules:rdn_name"])
|
||||
options=options)
|
||||
try:
|
||||
self.l.add(self.index)
|
||||
except AttributeError:
|
||||
@ -982,6 +985,47 @@ class SearchTests(LdbBaseTest):
|
||||
expression="(|(x=y)(y=b))")
|
||||
self.assertEqual(len(res11), 20)
|
||||
|
||||
def test_one_unindexable(self):
|
||||
"""Testing a search"""
|
||||
|
||||
try:
|
||||
res11 = self.l.search(base="DC=samba,DC=org",
|
||||
scope=ldb.SCOPE_ONELEVEL,
|
||||
expression="(y=b*)")
|
||||
if hasattr(self, 'IDX') and \
|
||||
not hasattr(self, 'IDXONE') and \
|
||||
hasattr(self, 'IDXCHECK'):
|
||||
self.fail("Should have failed as un-indexed search")
|
||||
|
||||
self.assertEqual(len(res11), 9)
|
||||
|
||||
except ldb.LdbError as err:
|
||||
enum = err.args[0]
|
||||
estr = err.args[1]
|
||||
self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
|
||||
self.assertIn(estr, "ldb FULL SEARCH disabled")
|
||||
|
||||
def test_one_unindexable_presence(self):
|
||||
"""Testing a search"""
|
||||
|
||||
try:
|
||||
res11 = self.l.search(base="DC=samba,DC=org",
|
||||
scope=ldb.SCOPE_ONELEVEL,
|
||||
expression="(y=*)")
|
||||
if hasattr(self, 'IDX') and \
|
||||
not hasattr(self, 'IDXONE') and \
|
||||
hasattr(self, 'IDXCHECK'):
|
||||
self.fail("Should have failed as un-indexed search")
|
||||
|
||||
self.assertEqual(len(res11), 24)
|
||||
|
||||
except ldb.LdbError as err:
|
||||
enum = err.args[0]
|
||||
estr = err.args[1]
|
||||
self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
|
||||
self.assertIn(estr, "ldb FULL SEARCH disabled")
|
||||
|
||||
|
||||
def test_subtree_and_or(self):
|
||||
"""Testing a search"""
|
||||
|
||||
@ -1062,6 +1106,45 @@ class SearchTests(LdbBaseTest):
|
||||
expression="(@IDXONE=DC=SAMBA,DC=ORG)")
|
||||
self.assertEqual(len(res11), 0)
|
||||
|
||||
def test_subtree_unindexable(self):
|
||||
"""Testing a search"""
|
||||
|
||||
try:
|
||||
res11 = self.l.search(base="DC=samba,DC=org",
|
||||
scope=ldb.SCOPE_SUBTREE,
|
||||
expression="(y=b*)")
|
||||
if hasattr(self, 'IDX') and \
|
||||
hasattr(self, 'IDXCHECK'):
|
||||
self.fail("Should have failed as un-indexed search")
|
||||
|
||||
self.assertEqual(len(res11), 9)
|
||||
|
||||
except ldb.LdbError as err:
|
||||
enum = err.args[0]
|
||||
estr = err.args[1]
|
||||
self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
|
||||
self.assertIn(estr, "ldb FULL SEARCH disabled")
|
||||
|
||||
def test_subtree_unindexable_presence(self):
|
||||
"""Testing a search"""
|
||||
|
||||
try:
|
||||
res11 = self.l.search(base="DC=samba,DC=org",
|
||||
scope=ldb.SCOPE_SUBTREE,
|
||||
expression="(y=*)")
|
||||
if hasattr(self, 'IDX') and \
|
||||
hasattr(self, 'IDXCHECK'):
|
||||
self.fail("Should have failed as un-indexed search")
|
||||
|
||||
self.assertEqual(len(res11), 24)
|
||||
|
||||
except ldb.LdbError as err:
|
||||
enum = err.args[0]
|
||||
estr = err.args[1]
|
||||
self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
|
||||
self.assertIn(estr, "ldb FULL SEARCH disabled")
|
||||
|
||||
|
||||
def test_dn_filter_one(self):
|
||||
"""Testing that a dn= filter succeeds
|
||||
(or fails with disallowDNFilter
|
||||
@ -1131,6 +1214,13 @@ class IndexedSearchTests(SearchTests):
|
||||
"@IDXATTR": [b"x", b"y", b"ou"]})
|
||||
self.IDX = True
|
||||
|
||||
class IndexedCheckSearchTests(IndexedSearchTests):
|
||||
"""Test searches using the index, to ensure the index doesn't
|
||||
break things (full scan disabled)"""
|
||||
def setUp(self):
|
||||
self.IDXCHECK = True
|
||||
super(IndexedCheckSearchTests, self).setUp()
|
||||
|
||||
class IndexedSearchDnFilterTests(SearchTests):
|
||||
"""Test searches using the index, to ensure the index doesn't
|
||||
break things"""
|
||||
@ -1153,6 +1243,14 @@ class IndexedAndOneLevelSearchTests(SearchTests):
|
||||
"@IDXATTR": [b"x", b"y", b"ou"],
|
||||
"@IDXONE": [b"1"]})
|
||||
self.IDX = True
|
||||
self.IDXONE = True
|
||||
|
||||
class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests):
|
||||
"""Test searches using the index including @IDXONE, to ensure
|
||||
the index doesn't break things (full scan disabled)"""
|
||||
def setUp(self):
|
||||
self.IDXCHECK = True
|
||||
super(IndexedCheckedAndOneLevelSearchTests, self).setUp()
|
||||
|
||||
class IndexedAndOneLevelDNFilterSearchTests(SearchTests):
|
||||
"""Test searches using the index including @IDXONE, to ensure
|
||||
|
Loading…
Reference in New Issue
Block a user