2 # Simple tests for the ldb python bindings.
3 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
6 from unittest import TestCase
13 PY3 = sys.version_info > (3, 0)
21 "@IDXGUID": [b"objectUUID"],
22 "@IDX_DN_GUID": [b"GUID"]
28 dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp")
31 return tempfile.mkdtemp(dir=dir_prefix)
34 class NoContextTests(TestCase):
36 def test_valid_attr_name(self):
37 self.assertTrue(ldb.valid_attr_name("foo"))
38 self.assertFalse(ldb.valid_attr_name("24foo"))
40 def test_timestring(self):
41 self.assertEqual("19700101000000.0Z", ldb.timestring(0))
42 self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412))
44 def test_string_to_time(self):
45 self.assertEqual(0, ldb.string_to_time("19700101000000.0Z"))
46 self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z"))
48 def test_binary_encode(self):
49 encoded = ldb.binary_encode(b'test\\x')
50 decoded = ldb.binary_decode(encoded)
51 self.assertEqual(decoded, b'test\\x')
53 encoded2 = ldb.binary_encode('test\\x')
54 self.assertEqual(encoded2, encoded)
57 class LdbBaseTest(TestCase):
59 super(LdbBaseTest, self).setUp()
61 if self.prefix is None:
62 self.prefix = TDB_PREFIX
63 except AttributeError:
64 self.prefix = TDB_PREFIX
67 super(LdbBaseTest, self).tearDown()
70 return self.prefix + self.filename
73 if self.prefix == MDB_PREFIX:
79 class SimpleLdb(LdbBaseTest):
82 super(SimpleLdb, self).setUp()
83 self.testdir = tempdir()
84 self.filename = os.path.join(self.testdir, "test.ldb")
85 self.ldb = ldb.Ldb(self.url(), flags=self.flags())
87 self.ldb.add(self.index)
88 except AttributeError:
92 shutil.rmtree(self.testdir)
93 super(SimpleLdb, self).tearDown()
94 # Ensure the LDB is closed now, so we close the FD
97 def test_connect(self):
98 ldb.Ldb(self.url(), flags=self.flags())
100 def test_connect_none(self):
103 def test_connect_later(self):
105 x.connect(self.url(), flags=self.flags())
109 self.assertTrue(repr(x).startswith("<ldb connection"))
111 def test_set_create_perms(self):
113 x.set_create_perms(0o600)
115 def test_modules_none(self):
117 self.assertEqual([], x.modules())
119 def test_modules_tdb(self):
120 x = ldb.Ldb(self.url(), flags=self.flags())
121 self.assertEqual("[<ldb module 'tdb'>]", repr(x.modules()))
123 def test_firstmodule_none(self):
125 self.assertEqual(x.firstmodule, None)
127 def test_firstmodule_tdb(self):
128 x = ldb.Ldb(self.url(), flags=self.flags())
130 self.assertEqual(repr(mod), "<ldb module 'tdb'>")
132 def test_search(self):
133 l = ldb.Ldb(self.url(), flags=self.flags())
134 self.assertEqual(len(l.search()), 0)
136 def test_search_controls(self):
137 l = ldb.Ldb(self.url(), flags=self.flags())
138 self.assertEqual(len(l.search(controls=["paged_results:0:5"])), 0)
140 def test_search_attrs(self):
141 l = ldb.Ldb(self.url(), flags=self.flags())
142 self.assertEqual(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
144 def test_search_string_dn(self):
145 l = ldb.Ldb(self.url(), flags=self.flags())
146 self.assertEqual(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
148 def test_search_attr_string(self):
149 l = ldb.Ldb(self.url(), flags=self.flags())
150 self.assertRaises(TypeError, l.search, attrs="dc")
151 self.assertRaises(TypeError, l.search, attrs=b"dc")
153 def test_opaque(self):
154 l = ldb.Ldb(self.url(), flags=self.flags())
155 l.set_opaque("my_opaque", l)
156 self.assertTrue(l.get_opaque("my_opaque") is not None)
157 self.assertEqual(None, l.get_opaque("unknown"))
159 def test_search_scope_base_empty_db(self):
160 l = ldb.Ldb(self.url(), flags=self.flags())
161 self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"),
164 def test_search_scope_onelevel_empty_db(self):
165 l = ldb.Ldb(self.url(), flags=self.flags())
166 self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"),
167 ldb.SCOPE_ONELEVEL)), 0)
169 def test_delete(self):
170 l = ldb.Ldb(self.url(), flags=self.flags())
171 self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2")))
173 def test_delete_w_unhandled_ctrl(self):
174 l = ldb.Ldb(self.url(), flags=self.flags())
176 m.dn = ldb.Dn(l, "dc=foo1")
178 m["objectUUID"] = b"0123456789abcdef"
180 self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"]))
183 def test_contains(self):
185 l = ldb.Ldb(name, flags=self.flags())
186 self.assertFalse(ldb.Dn(l, "dc=foo3") in l)
187 l = ldb.Ldb(name, flags=self.flags())
189 m.dn = ldb.Dn(l, "dc=foo3")
191 m["objectUUID"] = b"0123456789abcdef"
194 self.assertTrue(ldb.Dn(l, "dc=foo3") in l)
195 self.assertFalse(ldb.Dn(l, "dc=foo4") in l)
199 def test_get_config_basedn(self):
200 l = ldb.Ldb(self.url(), flags=self.flags())
201 self.assertEqual(None, l.get_config_basedn())
203 def test_get_root_basedn(self):
204 l = ldb.Ldb(self.url(), flags=self.flags())
205 self.assertEqual(None, l.get_root_basedn())
207 def test_get_schema_basedn(self):
208 l = ldb.Ldb(self.url(), flags=self.flags())
209 self.assertEqual(None, l.get_schema_basedn())
211 def test_get_default_basedn(self):
212 l = ldb.Ldb(self.url(), flags=self.flags())
213 self.assertEqual(None, l.get_default_basedn())
216 l = ldb.Ldb(self.url(), flags=self.flags())
218 m.dn = ldb.Dn(l, "dc=foo4")
220 m["objectUUID"] = b"0123456789abcdef"
221 self.assertEqual(len(l.search()), 0)
224 self.assertEqual(len(l.search()), 1)
226 l.delete(ldb.Dn(l, "dc=foo4"))
228 def test_search_iterator(self):
229 l = ldb.Ldb(self.url(), flags=self.flags())
230 s = l.search_iterator()
236 except RuntimeError as re:
241 except RuntimeError as re:
246 except RuntimeError as re:
249 s = l.search_iterator()
252 self.assertTrue(isinstance(me, ldb.Message))
255 self.assertEqual(len(r), 0)
256 self.assertEqual(count, 0)
259 m1.dn = ldb.Dn(l, "dc=foo4")
261 m1["objectUUID"] = b"0123456789abcdef"
264 s = l.search_iterator()
267 self.assertTrue(isinstance(me, ldb.Message))
271 self.assertEqual(len(r), 0)
272 self.assertEqual(len(msgs), 1)
273 self.assertEqual(msgs[0].dn, m1.dn)
276 m2.dn = ldb.Dn(l, "dc=foo5")
278 m2["objectUUID"] = b"0123456789abcdee"
281 s = l.search_iterator()
284 self.assertTrue(isinstance(me, ldb.Message))
288 self.assertEqual(len(r), 0)
289 self.assertEqual(len(msgs), 2)
290 if msgs[0].dn == m1.dn:
291 self.assertEqual(msgs[0].dn, m1.dn)
292 self.assertEqual(msgs[1].dn, m2.dn)
294 self.assertEqual(msgs[0].dn, m2.dn)
295 self.assertEqual(msgs[1].dn, m1.dn)
297 s = l.search_iterator()
300 self.assertTrue(isinstance(me, ldb.Message))
307 except RuntimeError as re:
310 self.assertTrue(isinstance(me, ldb.Message))
318 self.assertEqual(len(r), 0)
319 self.assertEqual(len(msgs), 2)
320 if msgs[0].dn == m1.dn:
321 self.assertEqual(msgs[0].dn, m1.dn)
322 self.assertEqual(msgs[1].dn, m2.dn)
324 self.assertEqual(msgs[0].dn, m2.dn)
325 self.assertEqual(msgs[1].dn, m1.dn)
327 l.delete(ldb.Dn(l, "dc=foo4"))
328 l.delete(ldb.Dn(l, "dc=foo5"))
330 def test_add_text(self):
331 l = ldb.Ldb(self.url(), flags=self.flags())
333 m.dn = ldb.Dn(l, "dc=foo4")
335 m["objectUUID"] = b"0123456789abcdef"
336 self.assertEqual(len(l.search()), 0)
339 self.assertEqual(len(l.search()), 1)
341 l.delete(ldb.Dn(l, "dc=foo4"))
343 def test_add_w_unhandled_ctrl(self):
344 l = ldb.Ldb(self.url(), flags=self.flags())
346 m.dn = ldb.Dn(l, "dc=foo4")
348 self.assertEqual(len(l.search()), 0)
349 self.assertRaises(ldb.LdbError, lambda: l.add(m,["search_options:1:2"]))
351 def test_add_dict(self):
352 l = ldb.Ldb(self.url(), flags=self.flags())
353 m = {"dn": ldb.Dn(l, "dc=foo5"),
355 "objectUUID": b"0123456789abcdef"}
356 self.assertEqual(len(l.search()), 0)
359 self.assertEqual(len(l.search()), 1)
361 l.delete(ldb.Dn(l, "dc=foo5"))
363 def test_add_dict_text(self):
364 l = ldb.Ldb(self.url(), flags=self.flags())
365 m = {"dn": ldb.Dn(l, "dc=foo5"),
367 "objectUUID": b"0123456789abcdef"}
368 self.assertEqual(len(l.search()), 0)
371 self.assertEqual(len(l.search()), 1)
373 l.delete(ldb.Dn(l, "dc=foo5"))
375 def test_add_dict_string_dn(self):
376 l = ldb.Ldb(self.url(), flags=self.flags())
377 m = {"dn": "dc=foo6", "bla": b"bla",
378 "objectUUID": b"0123456789abcdef"}
379 self.assertEqual(len(l.search()), 0)
382 self.assertEqual(len(l.search()), 1)
384 l.delete(ldb.Dn(l, "dc=foo6"))
386 def test_add_dict_bytes_dn(self):
387 l = ldb.Ldb(self.url(), flags=self.flags())
388 m = {"dn": b"dc=foo6", "bla": b"bla",
389 "objectUUID": b"0123456789abcdef"}
390 self.assertEqual(len(l.search()), 0)
393 self.assertEqual(len(l.search()), 1)
395 l.delete(ldb.Dn(l, "dc=foo6"))
397 def test_rename(self):
398 l = ldb.Ldb(self.url(), flags=self.flags())
400 m.dn = ldb.Dn(l, "dc=foo7")
402 m["objectUUID"] = b"0123456789abcdef"
403 self.assertEqual(len(l.search()), 0)
406 l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar"))
407 self.assertEqual(len(l.search()), 1)
409 l.delete(ldb.Dn(l, "dc=bar"))
411 def test_rename_string_dns(self):
412 l = ldb.Ldb(self.url(), flags=self.flags())
414 m.dn = ldb.Dn(l, "dc=foo8")
416 m["objectUUID"] = b"0123456789abcdef"
417 self.assertEqual(len(l.search()), 0)
419 self.assertEqual(len(l.search()), 1)
421 l.rename("dc=foo8", "dc=bar")
422 self.assertEqual(len(l.search()), 1)
424 l.delete(ldb.Dn(l, "dc=bar"))
426 def test_empty_dn(self):
427 l = ldb.Ldb(self.url(), flags=self.flags())
428 self.assertEqual(0, len(l.search()))
430 m.dn = ldb.Dn(l, "dc=empty")
431 m["objectUUID"] = b"0123456789abcdef"
434 self.assertEqual(1, len(rm))
435 self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
439 self.assertEqual(1, len(rm))
440 self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
442 rm = l.search(m.dn, attrs=["blah"])
443 self.assertEqual(1, len(rm))
444 self.assertEqual(0, len(rm[0]))
446 def test_modify_delete(self):
447 l = ldb.Ldb(self.url(), flags=self.flags())
449 m.dn = ldb.Dn(l, "dc=modifydelete")
451 m["objectUUID"] = b"0123456789abcdef"
453 rm = l.search(m.dn)[0]
454 self.assertEqual([b"1234"], list(rm["bla"]))
457 m.dn = ldb.Dn(l, "dc=modifydelete")
458 m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla")
459 self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags())
462 self.assertEqual(1, len(rm))
463 self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
465 rm = l.search(m.dn, attrs=["bla"])
466 self.assertEqual(1, len(rm))
467 self.assertEqual(0, len(rm[0]))
469 l.delete(ldb.Dn(l, "dc=modifydelete"))
471 def test_modify_delete_text(self):
472 l = ldb.Ldb(self.url(), flags=self.flags())
474 m.dn = ldb.Dn(l, "dc=modifydelete")
475 m.text["bla"] = ["1234"]
476 m["objectUUID"] = b"0123456789abcdef"
478 rm = l.search(m.dn)[0]
479 self.assertEqual(["1234"], list(rm.text["bla"]))
482 m.dn = ldb.Dn(l, "dc=modifydelete")
483 m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla")
484 self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags())
487 self.assertEqual(1, len(rm))
488 self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]),
490 rm = l.search(m.dn, attrs=["bla"])
491 self.assertEqual(1, len(rm))
492 self.assertEqual(0, len(rm[0]))
494 l.delete(ldb.Dn(l, "dc=modifydelete"))
496 def test_modify_add(self):
497 l = ldb.Ldb(self.url(), flags=self.flags())
499 m.dn = ldb.Dn(l, "dc=add")
501 m["objectUUID"] = b"0123456789abcdef"
505 m.dn = ldb.Dn(l, "dc=add")
506 m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")
507 self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
509 rm = l.search(m.dn)[0]
510 self.assertEqual(3, len(rm))
511 self.assertEqual([b"1234", b"456"], list(rm["bla"]))
513 l.delete(ldb.Dn(l, "dc=add"))
515 def test_modify_add_text(self):
516 l = ldb.Ldb(self.url(), flags=self.flags())
518 m.dn = ldb.Dn(l, "dc=add")
519 m.text["bla"] = ["1234"]
520 m["objectUUID"] = b"0123456789abcdef"
524 m.dn = ldb.Dn(l, "dc=add")
525 m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
526 self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
528 rm = l.search(m.dn)[0]
529 self.assertEqual(3, len(rm))
530 self.assertEqual(["1234", "456"], list(rm.text["bla"]))
532 l.delete(ldb.Dn(l, "dc=add"))
534 def test_modify_replace(self):
535 l = ldb.Ldb(self.url(), flags=self.flags())
537 m.dn = ldb.Dn(l, "dc=modify2")
538 m["bla"] = [b"1234", b"456"]
539 m["objectUUID"] = b"0123456789abcdef"
543 m.dn = ldb.Dn(l, "dc=modify2")
544 m["bla"] = ldb.MessageElement([b"789"], ldb.FLAG_MOD_REPLACE, "bla")
545 self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags())
547 rm = l.search(m.dn)[0]
548 self.assertEqual(3, len(rm))
549 self.assertEqual([b"789"], list(rm["bla"]))
550 rm = l.search(m.dn, attrs=["bla"])[0]
551 self.assertEqual(1, len(rm))
553 l.delete(ldb.Dn(l, "dc=modify2"))
555 def test_modify_replace_text(self):
556 l = ldb.Ldb(self.url(), flags=self.flags())
558 m.dn = ldb.Dn(l, "dc=modify2")
559 m.text["bla"] = ["1234", "456"]
560 m["objectUUID"] = b"0123456789abcdef"
564 m.dn = ldb.Dn(l, "dc=modify2")
565 m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla")
566 self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags())
568 rm = l.search(m.dn)[0]
569 self.assertEqual(3, len(rm))
570 self.assertEqual(["789"], list(rm.text["bla"]))
571 rm = l.search(m.dn, attrs=["bla"])[0]
572 self.assertEqual(1, len(rm))
574 l.delete(ldb.Dn(l, "dc=modify2"))
576 def test_modify_flags_change(self):
577 l = ldb.Ldb(self.url(), flags=self.flags())
579 m.dn = ldb.Dn(l, "dc=add")
581 m["objectUUID"] = b"0123456789abcdef"
585 m.dn = ldb.Dn(l, "dc=add")
586 m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")
587 self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
589 rm = l.search(m.dn)[0]
590 self.assertEqual(3, len(rm))
591 self.assertEqual([b"1234", b"456"], list(rm["bla"]))
593 # Now create another modify, but switch the flags before we do it
594 m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")
595 m["bla"].set_flags(ldb.FLAG_MOD_DELETE)
597 rm = l.search(m.dn, attrs=["bla"])[0]
598 self.assertEqual(1, len(rm))
599 self.assertEqual([b"1234"], list(rm["bla"]))
601 l.delete(ldb.Dn(l, "dc=add"))
603 def test_modify_flags_change_text(self):
604 l = ldb.Ldb(self.url(), flags=self.flags())
606 m.dn = ldb.Dn(l, "dc=add")
607 m.text["bla"] = ["1234"]
608 m["objectUUID"] = b"0123456789abcdef"
612 m.dn = ldb.Dn(l, "dc=add")
613 m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
614 self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags())
616 rm = l.search(m.dn)[0]
617 self.assertEqual(3, len(rm))
618 self.assertEqual(["1234", "456"], list(rm.text["bla"]))
620 # Now create another modify, but switch the flags before we do it
621 m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
622 m["bla"].set_flags(ldb.FLAG_MOD_DELETE)
624 rm = l.search(m.dn, attrs=["bla"])[0]
625 self.assertEqual(1, len(rm))
626 self.assertEqual(["1234"], list(rm.text["bla"]))
628 l.delete(ldb.Dn(l, "dc=add"))
630 def test_transaction_commit(self):
631 l = ldb.Ldb(self.url(), flags=self.flags())
632 l.transaction_start()
633 m = ldb.Message(ldb.Dn(l, "dc=foo9"))
635 m["objectUUID"] = b"0123456789abcdef"
637 l.transaction_commit()
640 def test_transaction_cancel(self):
641 l = ldb.Ldb(self.url(), flags=self.flags())
642 l.transaction_start()
643 m = ldb.Message(ldb.Dn(l, "dc=foo10"))
645 m["objectUUID"] = b"0123456789abcdee"
647 l.transaction_cancel()
648 self.assertEqual(0, len(l.search(ldb.Dn(l, "dc=foo10"))))
650 def test_set_debug(self):
651 def my_report_fn(level, text):
653 l = ldb.Ldb(self.url(), flags=self.flags())
654 l.set_debug(my_report_fn)
656 def test_zero_byte_string(self):
657 """Testing we do not get trapped in the \0 byte in a property string."""
658 l = ldb.Ldb(self.url(), flags=self.flags())
661 "objectclass" : b"user",
662 "cN" : b"LDAPtestUSER",
663 "givenname" : b"ldap",
664 "displayname" : b"foo\0bar",
665 "objectUUID" : b"0123456789abcdef"
667 res = l.search(expression="(dn=dc=somedn)")
668 self.assertEqual(b"foo\0bar", res[0]["displayname"][0])
670 def test_no_crash_broken_expr(self):
671 l = ldb.Ldb(self.url(), flags=self.flags())
672 self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"]))
674 # Run the SimpleLdb tests against an lmdb backend
675 class SimpleLdbLmdb(SimpleLdb):
678 self.prefix = MDB_PREFIX
679 self.index = MDB_INDEX_OBJ
680 super(SimpleLdbLmdb, self).setUp()
683 super(SimpleLdbLmdb, self).tearDown()
685 class SearchTests(LdbBaseTest):
687 shutil.rmtree(self.testdir)
688 super(SearchTests, self).tearDown()
690 # Ensure the LDB is closed now, so we close the FD
695 super(SearchTests, self).setUp()
696 self.testdir = tempdir()
697 self.filename = os.path.join(self.testdir, "search_test.ldb")
698 options = ["modules:rdn_name"]
699 if hasattr(self, 'IDXCHECK'):
700 options.append("disable_full_db_scan_for_self_test:1")
701 self.l = ldb.Ldb(self.url(),
705 self.l.add(self.index)
706 except AttributeError:
709 self.l.add({"dn": "@ATTRIBUTES",
710 "DC": "CASE_INSENSITIVE"})
712 # Note that we can't use the name objectGUID here, as we
713 # want to stay clear of the objectGUID handler in LDB and
714 # instead use just the 16 bytes raw, which we just keep
715 # to printable chars here for ease of handling.
717 self.l.add({"dn": "DC=SAMBA,DC=ORG",
718 "name": b"samba.org",
719 "objectUUID": b"0123456789abcdef"})
720 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
723 "objectUUID": b"0123456789abcde1"})
724 self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG",
727 "objectUUID": b"0123456789abcde2"})
728 self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG",
731 "objectUUID": b"0123456789abcde3"})
732 self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG",
735 "objectUUID": b"0123456789abcde4"})
736 self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG",
739 "objectUUID": b"0123456789abcde5"})
740 self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG",
743 "objectUUID": b"0123456789abcde6"})
744 self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG",
747 "objectUUID": b"0123456789abcde7"})
748 self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG",
751 "objectUUID": b"0123456789abcde8"})
752 self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG",
755 "objectUUID": b"0123456789abcde9"})
756 self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG",
759 "objectUUID": b"0123456789abcde0"})
760 self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG",
763 "objectUUID": b"0123456789abcdea"})
764 self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG",
767 "objectUUID": b"0123456789abcdeb"})
768 self.l.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG",
771 "objectUUID": b"0123456789abcdec"})
772 self.l.add({"dn": "OU=OU12,DC=SAMBA,DC=ORG",
775 "objectUUID": b"0123456789abcded"})
776 self.l.add({"dn": "OU=OU13,DC=SAMBA,DC=ORG",
779 "objectUUID": b"0123456789abcdee"})
780 self.l.add({"dn": "OU=OU14,DC=SAMBA,DC=ORG",
783 "objectUUID": b"0123456789abcd01"})
784 self.l.add({"dn": "OU=OU15,DC=SAMBA,DC=ORG",
787 "objectUUID": b"0123456789abcd02"})
788 self.l.add({"dn": "OU=OU16,DC=SAMBA,DC=ORG",
791 "objectUUID": b"0123456789abcd03"})
792 self.l.add({"dn": "OU=OU17,DC=SAMBA,DC=ORG",
795 "objectUUID": b"0123456789abcd04"})
796 self.l.add({"dn": "OU=OU18,DC=SAMBA,DC=ORG",
799 "objectUUID": b"0123456789abcd05"})
800 self.l.add({"dn": "OU=OU19,DC=SAMBA,DC=ORG",
803 "objectUUID": b"0123456789abcd06"})
804 self.l.add({"dn": "OU=OU20,DC=SAMBA,DC=ORG",
807 "objectUUID": b"0123456789abcd07"})
808 self.l.add({"dn": "OU=OU21,DC=SAMBA,DC=ORG",
811 "objectUUID": b"0123456789abcd08"})
812 self.l.add({"dn": "OU=OU22,DC=SAMBA,DC=ORG",
815 "objectUUID": b"0123456789abcd09"})
818 """Testing a search"""
820 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
821 scope=ldb.SCOPE_BASE)
822 self.assertEqual(len(res11), 1)
824 def test_base_lower(self):
825 """Testing a search"""
827 res11 = self.l.search(base="OU=OU11,DC=samba,DC=org",
828 scope=ldb.SCOPE_BASE)
829 self.assertEqual(len(res11), 1)
831 def test_base_or(self):
832 """Testing a search"""
834 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
835 scope=ldb.SCOPE_BASE,
836 expression="(|(ou=ou11)(ou=ou12))")
837 self.assertEqual(len(res11), 1)
839 def test_base_or2(self):
840 """Testing a search"""
842 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
843 scope=ldb.SCOPE_BASE,
844 expression="(|(x=y)(y=b))")
845 self.assertEqual(len(res11), 1)
847 def test_base_and(self):
848 """Testing a search"""
850 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
851 scope=ldb.SCOPE_BASE,
852 expression="(&(ou=ou11)(ou=ou12))")
853 self.assertEqual(len(res11), 0)
855 def test_base_and2(self):
856 """Testing a search"""
858 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
859 scope=ldb.SCOPE_BASE,
860 expression="(&(x=y)(y=a))")
861 self.assertEqual(len(res11), 1)
863 def test_base_false(self):
864 """Testing a search"""
866 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
867 scope=ldb.SCOPE_BASE,
868 expression="(|(ou=ou13)(ou=ou12))")
869 self.assertEqual(len(res11), 0)
871 def test_check_base_false(self):
872 """Testing a search"""
873 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
874 scope=ldb.SCOPE_BASE,
875 expression="(|(ou=ou13)(ou=ou12))")
876 self.assertEqual(len(res11), 0)
878 def test_check_base_error(self):
879 """Testing a search"""
880 checkbaseonsearch = {"dn": "@OPTIONS",
881 "checkBaseOnSearch": b"TRUE"}
883 self.l.add(checkbaseonsearch)
884 except ldb.LdbError as err:
886 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
887 m = ldb.Message.from_dict(self.l,
892 res11 = self.l.search(base="OU=OU11x,DC=SAMBA,DC=ORG",
893 scope=ldb.SCOPE_BASE,
894 expression="(|(ou=ou13)(ou=ou12))")
895 self.fail("Should have failed on missing base")
896 except ldb.LdbError as err:
898 self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT)
900 def test_subtree_and(self):
901 """Testing a search"""
903 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
904 scope=ldb.SCOPE_SUBTREE,
905 expression="(&(ou=ou11)(ou=ou12))")
906 self.assertEqual(len(res11), 0)
908 def test_subtree_and2(self):
909 """Testing a search"""
911 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
912 scope=ldb.SCOPE_SUBTREE,
913 expression="(&(x=y)(|(y=b)(y=c)))")
914 self.assertEqual(len(res11), 1)
916 def test_subtree_and2_lower(self):
917 """Testing a search"""
919 res11 = self.l.search(base="DC=samba,DC=org",
920 scope=ldb.SCOPE_SUBTREE,
921 expression="(&(x=y)(|(y=b)(y=c)))")
922 self.assertEqual(len(res11), 1)
924 def test_subtree_or(self):
925 """Testing a search"""
927 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
928 scope=ldb.SCOPE_SUBTREE,
929 expression="(|(ou=ou11)(ou=ou12))")
930 self.assertEqual(len(res11), 2)
932 def test_subtree_or2(self):
933 """Testing a search"""
935 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
936 scope=ldb.SCOPE_SUBTREE,
937 expression="(|(x=y)(y=b))")
938 self.assertEqual(len(res11), 20)
940 def test_subtree_or3(self):
941 """Testing a search"""
943 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
944 scope=ldb.SCOPE_SUBTREE,
945 expression="(|(x=y)(y=b)(y=c))")
946 self.assertEqual(len(res11), 22)
948 def test_one_and(self):
949 """Testing a search"""
951 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
952 scope=ldb.SCOPE_ONELEVEL,
953 expression="(&(ou=ou11)(ou=ou12))")
954 self.assertEqual(len(res11), 0)
956 def test_one_and2(self):
957 """Testing a search"""
959 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
960 scope=ldb.SCOPE_ONELEVEL,
961 expression="(&(x=y)(y=b))")
962 self.assertEqual(len(res11), 1)
964 def test_one_or(self):
965 """Testing a search"""
967 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
968 scope=ldb.SCOPE_ONELEVEL,
969 expression="(|(ou=ou11)(ou=ou12))")
970 self.assertEqual(len(res11), 2)
972 def test_one_or2(self):
973 """Testing a search"""
975 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
976 scope=ldb.SCOPE_ONELEVEL,
977 expression="(|(x=y)(y=b))")
978 self.assertEqual(len(res11), 20)
980 def test_one_or2_lower(self):
981 """Testing a search"""
983 res11 = self.l.search(base="DC=samba,DC=org",
984 scope=ldb.SCOPE_ONELEVEL,
985 expression="(|(x=y)(y=b))")
986 self.assertEqual(len(res11), 20)
988 def test_one_unindexable(self):
989 """Testing a search"""
992 res11 = self.l.search(base="DC=samba,DC=org",
993 scope=ldb.SCOPE_ONELEVEL,
995 if hasattr(self, 'IDX') and \
996 not hasattr(self, 'IDXONE') and \
997 hasattr(self, 'IDXCHECK'):
998 self.fail("Should have failed as un-indexed search")
1000 self.assertEqual(len(res11), 9)
1002 except ldb.LdbError as err:
1005 self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
1006 self.assertIn(estr, "ldb FULL SEARCH disabled")
1008 def test_one_unindexable_presence(self):
1009 """Testing a search"""
1012 res11 = self.l.search(base="DC=samba,DC=org",
1013 scope=ldb.SCOPE_ONELEVEL,
1015 if hasattr(self, 'IDX') and \
1016 not hasattr(self, 'IDXONE') and \
1017 hasattr(self, 'IDXCHECK'):
1018 self.fail("Should have failed as un-indexed search")
1020 self.assertEqual(len(res11), 24)
1022 except ldb.LdbError as err:
1025 self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
1026 self.assertIn(estr, "ldb FULL SEARCH disabled")
1029 def test_subtree_and_or(self):
1030 """Testing a search"""
1032 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1033 scope=ldb.SCOPE_SUBTREE,
1034 expression="(&(|(x=z)(y=b))(x=x)(y=c))")
1035 self.assertEqual(len(res11), 0)
1037 def test_subtree_and_or2(self):
1038 """Testing a search"""
1040 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1041 scope=ldb.SCOPE_SUBTREE,
1042 expression="(&(x=x)(y=c)(|(x=z)(y=b)))")
1043 self.assertEqual(len(res11), 0)
1045 def test_subtree_and_or3(self):
1046 """Testing a search"""
1048 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1049 scope=ldb.SCOPE_SUBTREE,
1050 expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))")
1051 self.assertEqual(len(res11), 2)
1053 def test_subtree_and_or4(self):
1054 """Testing a search"""
1056 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1057 scope=ldb.SCOPE_SUBTREE,
1058 expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))")
1059 self.assertEqual(len(res11), 2)
1061 def test_subtree_and_or5(self):
1062 """Testing a search"""
1064 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1065 scope=ldb.SCOPE_SUBTREE,
1066 expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))")
1067 self.assertEqual(len(res11), 1)
1069 def test_subtree_or_and(self):
1070 """Testing a search"""
1072 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1073 scope=ldb.SCOPE_SUBTREE,
1074 expression="(|(x=x)(y=c)(&(x=z)(y=b)))")
1075 self.assertEqual(len(res11), 10)
1077 def test_subtree_large_and_unique(self):
1078 """Testing a search"""
1080 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1081 scope=ldb.SCOPE_SUBTREE,
1082 expression="(&(ou=ou10)(y=a))")
1083 self.assertEqual(len(res11), 1)
1085 def test_subtree_and_none(self):
1086 """Testing a search"""
1088 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1089 scope=ldb.SCOPE_SUBTREE,
1090 expression="(&(ou=ouX)(y=a))")
1091 self.assertEqual(len(res11), 0)
1093 def test_subtree_and_idx_record(self):
1094 """Testing a search against the index record"""
1096 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1097 scope=ldb.SCOPE_SUBTREE,
1098 expression="(@IDXDN=DC=SAMBA,DC=ORG)")
1099 self.assertEqual(len(res11), 0)
1101 def test_subtree_and_idxone_record(self):
1102 """Testing a search against the index record"""
1104 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1105 scope=ldb.SCOPE_SUBTREE,
1106 expression="(@IDXONE=DC=SAMBA,DC=ORG)")
1107 self.assertEqual(len(res11), 0)
1109 def test_subtree_unindexable(self):
1110 """Testing a search"""
1113 res11 = self.l.search(base="DC=samba,DC=org",
1114 scope=ldb.SCOPE_SUBTREE,
1115 expression="(y=b*)")
1116 if hasattr(self, 'IDX') and \
1117 hasattr(self, 'IDXCHECK'):
1118 self.fail("Should have failed as un-indexed search")
1120 self.assertEqual(len(res11), 9)
1122 except ldb.LdbError as err:
1125 self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
1126 self.assertIn(estr, "ldb FULL SEARCH disabled")
1128 def test_subtree_unindexable_presence(self):
1129 """Testing a search"""
1132 res11 = self.l.search(base="DC=samba,DC=org",
1133 scope=ldb.SCOPE_SUBTREE,
1135 if hasattr(self, 'IDX') and \
1136 hasattr(self, 'IDXCHECK'):
1137 self.fail("Should have failed as un-indexed search")
1139 self.assertEqual(len(res11), 24)
1141 except ldb.LdbError as err:
1144 self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING)
1145 self.assertIn(estr, "ldb FULL SEARCH disabled")
1148 def test_dn_filter_one(self):
1149 """Testing that a dn= filter succeeds
1150 (or fails with disallowDNFilter
1151 set and IDXGUID or (IDX and not IDXONE) mode)
1152 when the scope is SCOPE_ONELEVEL.
1154 This should be made more consistent, but for now lock in
1159 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1160 scope=ldb.SCOPE_ONELEVEL,
1161 expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)")
1162 if hasattr(self, 'disallowDNFilter') and \
1163 hasattr(self, 'IDX') and \
1164 (hasattr(self, 'IDXGUID') or \
1165 ((hasattr(self, 'IDXONE') == False and hasattr(self, 'IDX')))):
1166 self.assertEqual(len(res11), 0)
1168 self.assertEqual(len(res11), 1)
1170 def test_dn_filter_subtree(self):
1171 """Testing that a dn= filter succeeds
1172 (or fails with disallowDNFilter set)
1173 when the scope is SCOPE_SUBTREE"""
1175 res11 = self.l.search(base="DC=SAMBA,DC=ORG",
1176 scope=ldb.SCOPE_SUBTREE,
1177 expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)")
1178 if hasattr(self, 'disallowDNFilter') \
1179 and hasattr(self, 'IDX'):
1180 self.assertEqual(len(res11), 0)
1182 self.assertEqual(len(res11), 1)
1184 def test_dn_filter_base(self):
1185 """Testing that (incorrectly) a dn= filter works
1186 when the scope is SCOPE_BASE"""
1188 res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG",
1189 scope=ldb.SCOPE_BASE,
1190 expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)")
1192 # At some point we should fix this, but it isn't trivial
1193 self.assertEqual(len(res11), 1)
1196 # Run the search tests against an lmdb backend
1197 class SearchTestsLmdb(SearchTests):
1200 self.prefix = MDB_PREFIX
1201 self.index = MDB_INDEX_OBJ
1202 super(SearchTestsLmdb, self).setUp()
1205 super(SearchTestsLmdb, self).tearDown()
1208 class IndexedSearchTests(SearchTests):
1209 """Test searches using the index, to ensure the index doesn't
1212 super(IndexedSearchTests, self).setUp()
1213 self.l.add({"dn": "@INDEXLIST",
1214 "@IDXATTR": [b"x", b"y", b"ou"]})
1217 class IndexedCheckSearchTests(IndexedSearchTests):
1218 """Test searches using the index, to ensure the index doesn't
1219 break things (full scan disabled)"""
1221 self.IDXCHECK = True
1222 super(IndexedCheckSearchTests, self).setUp()
1224 class IndexedSearchDnFilterTests(SearchTests):
1225 """Test searches using the index, to ensure the index doesn't
1228 super(IndexedSearchDnFilterTests, self).setUp()
1229 self.l.add({"dn": "@OPTIONS",
1230 "disallowDNFilter": "TRUE"})
1231 self.disallowDNFilter = True
1233 self.l.add({"dn": "@INDEXLIST",
1234 "@IDXATTR": [b"x", b"y", b"ou"]})
1237 class IndexedAndOneLevelSearchTests(SearchTests):
1238 """Test searches using the index including @IDXONE, to ensure
1239 the index doesn't break things"""
1241 super(IndexedAndOneLevelSearchTests, self).setUp()
1242 self.l.add({"dn": "@INDEXLIST",
1243 "@IDXATTR": [b"x", b"y", b"ou"],
1248 class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests):
1249 """Test searches using the index including @IDXONE, to ensure
1250 the index doesn't break things (full scan disabled)"""
1252 self.IDXCHECK = True
1253 super(IndexedCheckedAndOneLevelSearchTests, self).setUp()
1255 class IndexedAndOneLevelDNFilterSearchTests(SearchTests):
1256 """Test searches using the index including @IDXONE, to ensure
1257 the index doesn't break things"""
1259 super(IndexedAndOneLevelDNFilterSearchTests, self).setUp()
1260 self.l.add({"dn": "@OPTIONS",
1261 "disallowDNFilter": "TRUE"})
1262 self.disallowDNFilter = True
1264 self.l.add({"dn": "@INDEXLIST",
1265 "@IDXATTR": [b"x", b"y", b"ou"],
1270 class GUIDIndexedSearchTests(SearchTests):
1271 """Test searches using the index, to ensure the index doesn't
1274 self.index = {"dn": "@INDEXLIST",
1275 "@IDXATTR": [b"x", b"y", b"ou"],
1276 "@IDXGUID": [b"objectUUID"],
1277 "@IDX_DN_GUID": [b"GUID"]}
1278 super(GUIDIndexedSearchTests, self).setUp()
1284 class GUIDIndexedDNFilterSearchTests(SearchTests):
1285 """Test searches using the index, to ensure the index doesn't
1288 self.index = {"dn": "@INDEXLIST",
1289 "@IDXATTR": [b"x", b"y", b"ou"],
1290 "@IDXGUID": [b"objectUUID"],
1291 "@IDX_DN_GUID": [b"GUID"]}
1292 super(GUIDIndexedDNFilterSearchTests, self).setUp()
1293 self.l.add({"dn": "@OPTIONS",
1294 "disallowDNFilter": "TRUE"})
1295 self.disallowDNFilter = True
1299 class GUIDAndOneLevelIndexedSearchTests(SearchTests):
1300 """Test searches using the index including @IDXONE, to ensure
1301 the index doesn't break things"""
1303 self.index = {"dn": "@INDEXLIST",
1304 "@IDXATTR": [b"x", b"y", b"ou"],
1305 "@IDXGUID": [b"objectUUID"],
1306 "@IDX_DN_GUID": [b"GUID"]}
1307 super(GUIDAndOneLevelIndexedSearchTests, self).setUp()
1308 self.l.add({"dn": "@OPTIONS",
1309 "disallowDNFilter": "TRUE"})
1310 self.disallowDNFilter = True
1315 class GUIDIndexedSearchTestsLmdb(GUIDIndexedSearchTests):
1318 self.prefix = MDB_PREFIX
1319 super(GUIDIndexedSearchTestsLmdb, self).setUp()
1322 super(GUIDIndexedSearchTestsLmdb, self).tearDown()
1325 class GUIDIndexedDNFilterSearchTestsLmdb(GUIDIndexedDNFilterSearchTests):
1328 self.prefix = MDB_PREFIX
1329 super(GUIDIndexedDNFilterSearchTestsLmdb, self).setUp()
1332 super(GUIDIndexedDNFilterSearchTestsLmdb, self).tearDown()
1335 class GUIDAndOneLevelIndexedSearchTestsLmdb(GUIDAndOneLevelIndexedSearchTests):
1338 self.prefix = MDB_PREFIX
1339 super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).setUp()
1342 super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).tearDown()
1345 class AddModifyTests(LdbBaseTest):
1347 shutil.rmtree(self.testdir)
1348 super(AddModifyTests, self).tearDown()
1350 # Ensure the LDB is closed now, so we close the FD
1354 super(AddModifyTests, self).setUp()
1355 self.testdir = tempdir()
1356 self.filename = os.path.join(self.testdir, "add_test.ldb")
1357 self.l = ldb.Ldb(self.url(),
1359 options=["modules:rdn_name"])
1361 self.l.add(self.index)
1362 except AttributeError:
1365 self.l.add({"dn": "DC=SAMBA,DC=ORG",
1366 "name": b"samba.org",
1367 "objectUUID": b"0123456789abcdef"})
1368 self.l.add({"dn": "@ATTRIBUTES",
1369 "objectUUID": "UNIQUE_INDEX"})
1371 def test_add_dup(self):
1372 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1375 "objectUUID": b"0123456789abcde1"})
1377 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1380 "objectUUID": b"0123456789abcde2"})
1381 self.fail("Should have failed adding dupliate entry")
1382 except ldb.LdbError as err:
1384 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
1386 def test_add_del_add(self):
1387 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1390 "objectUUID": b"0123456789abcde1"})
1391 self.l.delete("OU=DUP,DC=SAMBA,DC=ORG")
1392 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1395 "objectUUID": b"0123456789abcde2"})
1397 def test_add_move_add(self):
1398 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1401 "objectUUID": b"0123456789abcde1"})
1402 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1403 "OU=DUP2,DC=SAMBA,DC=ORG")
1404 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1407 "objectUUID": b"0123456789abcde2"})
1409 def test_add_move_fail_move_move(self):
1410 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1413 "objectUUID": b"0123456789abcde1"})
1414 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1417 "objectUUID": b"0123456789abcde2"})
1419 res2 = self.l.search(base="DC=SAMBA,DC=ORG",
1420 scope=ldb.SCOPE_SUBTREE,
1421 expression="(objectUUID=0123456789abcde1)")
1422 self.assertEqual(len(res2), 1)
1423 self.assertEqual(str(res2[0].dn), "OU=DUP,DC=SAMBA,DC=ORG")
1425 res3 = self.l.search(base="DC=SAMBA,DC=ORG",
1426 scope=ldb.SCOPE_SUBTREE,
1427 expression="(objectUUID=0123456789abcde2)")
1428 self.assertEqual(len(res3), 1)
1429 self.assertEqual(str(res3[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG")
1432 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1433 "OU=DUP2,DC=SAMBA,DC=ORG")
1434 self.fail("Should have failed on duplicate DN")
1435 except ldb.LdbError as err:
1437 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
1439 self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG",
1440 "OU=DUP3,DC=SAMBA,DC=ORG")
1442 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1443 "OU=DUP2,DC=SAMBA,DC=ORG")
1445 res2 = self.l.search(base="DC=SAMBA,DC=ORG",
1446 scope=ldb.SCOPE_SUBTREE,
1447 expression="(objectUUID=0123456789abcde1)")
1448 self.assertEqual(len(res2), 1)
1449 self.assertEqual(str(res2[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG")
1451 res3 = self.l.search(base="DC=SAMBA,DC=ORG",
1452 scope=ldb.SCOPE_SUBTREE,
1453 expression="(objectUUID=0123456789abcde2)")
1454 self.assertEqual(len(res3), 1)
1455 self.assertEqual(str(res3[0].dn), "OU=DUP3,DC=SAMBA,DC=ORG")
1457 def test_move_missing(self):
1459 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1460 "OU=DUP2,DC=SAMBA,DC=ORG")
1461 self.fail("Should have failed on missing")
1462 except ldb.LdbError as err:
1464 self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT)
1466 def test_move_missing2(self):
1467 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1470 "objectUUID": b"0123456789abcde2"})
1473 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1474 "OU=DUP2,DC=SAMBA,DC=ORG")
1475 self.fail("Should have failed on missing")
1476 except ldb.LdbError as err:
1478 self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT)
1480 def test_move_fail_move_add(self):
1481 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1484 "objectUUID": b"0123456789abcde1"})
1485 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1488 "objectUUID": b"0123456789abcde2"})
1490 self.l.rename("OU=DUP,DC=SAMBA,DC=ORG",
1491 "OU=DUP2,DC=SAMBA,DC=ORG")
1492 self.fail("Should have failed on duplicate DN")
1493 except ldb.LdbError as err:
1495 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
1497 self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG",
1498 "OU=DUP3,DC=SAMBA,DC=ORG")
1500 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1503 "objectUUID": b"0123456789abcde3"})
1506 class AddModifyTestsLmdb(AddModifyTests):
1509 self.prefix = MDB_PREFIX
1510 self.index = MDB_INDEX_OBJ
1511 super(AddModifyTestsLmdb, self).setUp()
1514 super(AddModifyTestsLmdb, self).tearDown()
1516 class IndexedAddModifyTests(AddModifyTests):
1517 """Test searches using the index, to ensure the index doesn't
1520 if not hasattr(self, 'index'):
1521 self.index = {"dn": "@INDEXLIST",
1522 "@IDXATTR": [b"x", b"y", b"ou", b"objectUUID"],
1524 super(IndexedAddModifyTests, self).setUp()
1526 def test_duplicate_GUID(self):
1528 self.l.add({"dn": "OU=DUPGUID,DC=SAMBA,DC=ORG",
1531 "objectUUID": b"0123456789abcdef"})
1532 self.fail("Should have failed adding dupliate GUID")
1533 except ldb.LdbError as err:
1535 self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION)
1537 def test_duplicate_name_dup_GUID(self):
1538 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
1541 "objectUUID": b"a123456789abcdef"})
1543 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
1546 "objectUUID": b"a123456789abcdef"})
1547 self.fail("Should have failed adding dupliate GUID")
1548 except ldb.LdbError as err:
1550 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
1552 def test_duplicate_name_dup_GUID2(self):
1553 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
1556 "objectUUID": b"abc3456789abcdef"})
1558 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG",
1561 "objectUUID": b"aaa3456789abcdef"})
1562 self.fail("Should have failed adding dupliate DN")
1563 except ldb.LdbError as err:
1565 self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS)
1567 # Checking the GUID didn't stick in the index
1568 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1571 "objectUUID": b"aaa3456789abcdef"})
1573 def test_add_dup_guid_add(self):
1574 self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG",
1577 "objectUUID": b"0123456789abcde1"})
1579 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1582 "objectUUID": b"0123456789abcde1"})
1583 self.fail("Should have failed on duplicate GUID")
1585 except ldb.LdbError as err:
1587 self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION)
1589 self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG",
1592 "objectUUID": b"0123456789abcde2"})
1594 class GUIDIndexedAddModifyTests(IndexedAddModifyTests):
1595 """Test searches using the index, to ensure the index doesn't
1598 self.index = {"dn": "@INDEXLIST",
1599 "@IDXATTR": [b"x", b"y", b"ou"],
1601 "@IDXGUID": [b"objectUUID"],
1602 "@IDX_DN_GUID": [b"GUID"]}
1603 super(GUIDIndexedAddModifyTests, self).setUp()
1606 class GUIDTransIndexedAddModifyTests(GUIDIndexedAddModifyTests):
1607 """Test GUID index behaviour insdie the transaction"""
1609 super(GUIDTransIndexedAddModifyTests, self).setUp()
1610 self.l.transaction_start()
1613 self.l.transaction_commit()
1614 super(GUIDTransIndexedAddModifyTests, self).tearDown()
1616 class TransIndexedAddModifyTests(IndexedAddModifyTests):
1617 """Test index behaviour insdie the transaction"""
1619 super(TransIndexedAddModifyTests, self).setUp()
1620 self.l.transaction_start()
1623 self.l.transaction_commit()
1624 super(TransIndexedAddModifyTests, self).tearDown()
1626 class GuidIndexedAddModifyTestsLmdb(GUIDIndexedAddModifyTests):
1629 self.prefix = MDB_PREFIX
1630 super(GuidIndexedAddModifyTestsLmdb, self).setUp()
1633 super(GuidIndexedAddModifyTestsLmdb, self).tearDown()
1635 class GuidTransIndexedAddModifyTestsLmdb(GUIDTransIndexedAddModifyTests):
1638 self.prefix = MDB_PREFIX
1639 super(GuidTransIndexedAddModifyTestsLmdb, self).setUp()
1642 super(GuidTransIndexedAddModifyTestsLmdb, self).tearDown()
1644 class BadIndexTests(LdbBaseTest):
1646 super(BadIndexTests, self).setUp()
1647 self.testdir = tempdir()
1648 self.filename = os.path.join(self.testdir, "test.ldb")
1649 self.ldb = ldb.Ldb(self.url(), flags=self.flags())
1650 if hasattr(self, 'IDXGUID'):
1651 self.ldb.add({"dn": "@INDEXLIST",
1652 "@IDXATTR": [b"x", b"y", b"ou"],
1653 "@IDXGUID": [b"objectUUID"],
1654 "@IDX_DN_GUID": [b"GUID"]})
1656 self.ldb.add({"dn": "@INDEXLIST",
1657 "@IDXATTR": [b"x", b"y", b"ou"]})
1659 super(BadIndexTests, self).setUp()
1661 def test_unique(self):
1662 self.ldb.add({"dn": "x=x,dc=samba,dc=org",
1663 "objectUUID": b"0123456789abcde1",
1665 self.ldb.add({"dn": "x=y,dc=samba,dc=org",
1666 "objectUUID": b"0123456789abcde2",
1668 self.ldb.add({"dn": "x=z,dc=samba,dc=org",
1669 "objectUUID": b"0123456789abcde3",
1672 res = self.ldb.search(expression="(y=1)",
1673 base="dc=samba,dc=org")
1674 self.assertEquals(len(res), 3)
1676 # Now set this to unique index, but forget to check the result
1678 self.ldb.add({"dn": "@ATTRIBUTES",
1679 "y": "UNIQUE_INDEX"})
1681 except ldb.LdbError:
1684 # We must still have a working index
1685 res = self.ldb.search(expression="(y=1)",
1686 base="dc=samba,dc=org")
1687 self.assertEquals(len(res), 3)
1689 def test_unique_transaction(self):
1690 self.ldb.add({"dn": "x=x,dc=samba,dc=org",
1691 "objectUUID": b"0123456789abcde1",
1693 self.ldb.add({"dn": "x=y,dc=samba,dc=org",
1694 "objectUUID": b"0123456789abcde2",
1696 self.ldb.add({"dn": "x=z,dc=samba,dc=org",
1697 "objectUUID": b"0123456789abcde3",
1700 res = self.ldb.search(expression="(y=1)",
1701 base="dc=samba,dc=org")
1702 self.assertEquals(len(res), 3)
1704 self.ldb.transaction_start()
1706 # Now set this to unique index, but forget to check the result
1708 self.ldb.add({"dn": "@ATTRIBUTES",
1709 "y": "UNIQUE_INDEX"})
1710 except ldb.LdbError:
1714 self.ldb.transaction_commit()
1717 except ldb.LdbError as err:
1719 self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR)
1721 # We must still have a working index
1722 res = self.ldb.search(expression="(y=1)",
1723 base="dc=samba,dc=org")
1725 self.assertEquals(len(res), 3)
1727 def test_casefold(self):
1728 self.ldb.add({"dn": "x=x,dc=samba,dc=org",
1729 "objectUUID": b"0123456789abcde1",
1731 self.ldb.add({"dn": "x=y,dc=samba,dc=org",
1732 "objectUUID": b"0123456789abcde2",
1734 self.ldb.add({"dn": "x=z,dc=samba,dc=org",
1735 "objectUUID": b"0123456789abcde3",
1738 res = self.ldb.search(expression="(y=a)",
1739 base="dc=samba,dc=org")
1740 self.assertEquals(len(res), 2)
1742 self.ldb.add({"dn": "@ATTRIBUTES",
1743 "y": "CASE_INSENSITIVE"})
1745 # We must still have a working index
1746 res = self.ldb.search(expression="(y=a)",
1747 base="dc=samba,dc=org")
1749 if hasattr(self, 'IDXGUID'):
1750 self.assertEquals(len(res), 3)
1752 # We should not return this entry twice, but sadly
1753 # we have not yet fixed
1754 # https://bugzilla.samba.org/show_bug.cgi?id=13361
1755 self.assertEquals(len(res), 4)
1757 def test_casefold_transaction(self):
1758 self.ldb.add({"dn": "x=x,dc=samba,dc=org",
1759 "objectUUID": b"0123456789abcde1",
1761 self.ldb.add({"dn": "x=y,dc=samba,dc=org",
1762 "objectUUID": b"0123456789abcde2",
1764 self.ldb.add({"dn": "x=z,dc=samba,dc=org",
1765 "objectUUID": b"0123456789abcde3",
1768 res = self.ldb.search(expression="(y=a)",
1769 base="dc=samba,dc=org")
1770 self.assertEquals(len(res), 2)
1772 self.ldb.transaction_start()
1774 self.ldb.add({"dn": "@ATTRIBUTES",
1775 "y": "CASE_INSENSITIVE"})
1777 self.ldb.transaction_commit()
1779 # We must still have a working index
1780 res = self.ldb.search(expression="(y=a)",
1781 base="dc=samba,dc=org")
1783 if hasattr(self, 'IDXGUID'):
1784 self.assertEquals(len(res), 3)
1786 # We should not return this entry twice, but sadly
1787 # we have not yet fixed
1788 # https://bugzilla.samba.org/show_bug.cgi?id=13361
1789 self.assertEquals(len(res), 4)
1793 super(BadIndexTests, self).tearDown()
1796 class GUIDBadIndexTests(BadIndexTests):
1797 """Test Bad index things with GUID index mode"""
1801 super(GUIDBadIndexTests, self).setUp()
1803 class DnTests(TestCase):
1806 super(DnTests, self).setUp()
1807 self.ldb = ldb.Ldb()
1810 super(DnTests, self).tearDown()
1813 def test_set_dn_invalid(self):
1817 self.assertRaises(TypeError, assign)
1820 x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe")
1821 y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe")
1822 self.assertEqual(x, y)
1823 y = ldb.Dn(self.ldb, "dc=foo11,bar=blie")
1824 self.assertNotEqual(x, y)
1827 x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe")
1828 self.assertEqual(x.__str__(), "dc=foo12,bar=bloe")
1830 def test_repr(self):
1831 x = ldb.Dn(self.ldb, "dc=foo13,bla=blie")
1832 self.assertEqual(x.__repr__(), "Dn('dc=foo13,bla=blie')")
1834 def test_get_casefold(self):
1835 x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe")
1836 self.assertEqual(x.get_casefold(), "DC=FOO14,BAR=bloe")
1838 def test_validate(self):
1839 x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe")
1840 self.assertTrue(x.validate())
1842 def test_parent(self):
1843 x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe")
1844 self.assertEqual("bar=bloe", x.parent().__str__())
1846 def test_parent_nonexistent(self):
1847 x = ldb.Dn(self.ldb, "@BLA")
1848 self.assertEqual(None, x.parent())
1850 def test_is_valid(self):
1851 x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe")
1852 self.assertTrue(x.is_valid())
1853 x = ldb.Dn(self.ldb, "")
1854 self.assertTrue(x.is_valid())
1856 def test_is_special(self):
1857 x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe")
1858 self.assertFalse(x.is_special())
1859 x = ldb.Dn(self.ldb, "@FOOBAR")
1860 self.assertTrue(x.is_special())
1862 def test_check_special(self):
1863 x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe")
1864 self.assertFalse(x.check_special("FOOBAR"))
1865 x = ldb.Dn(self.ldb, "@FOOBAR")
1866 self.assertTrue(x.check_special("@FOOBAR"))
1869 x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe")
1870 self.assertEqual(2, len(x))
1871 x = ldb.Dn(self.ldb, "dc=foo21")
1872 self.assertEqual(1, len(x))
1874 def test_add_child(self):
1875 x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe")
1876 self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe")))
1877 self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__())
1879 def test_add_base(self):
1880 x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe")
1881 base = ldb.Dn(self.ldb, "bla=bloe")
1882 self.assertTrue(x.add_base(base))
1883 self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__())
1885 def test_add_child_str(self):
1886 x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe")
1887 self.assertTrue(x.add_child("bla=bloe"))
1888 self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__())
1890 def test_add_base_str(self):
1891 x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe")
1893 self.assertTrue(x.add_base(base))
1894 self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__())
1897 x = ldb.Dn(self.ldb, "dc=foo24")
1898 y = ldb.Dn(self.ldb, "bar=bla")
1899 self.assertEqual("dc=foo24,bar=bla", str(x + y))
1901 def test_remove_base_components(self):
1902 x = ldb.Dn(self.ldb, "dc=foo24,dc=samba,dc=org")
1903 x.remove_base_components(len(x)-1)
1904 self.assertEqual("dc=foo24", str(x))
1906 def test_parse_ldif(self):
1907 msgs = self.ldb.parse_ldif("dn: foo=bar\n")
1909 self.assertEqual("foo=bar", str(msg[1].dn))
1910 self.assertTrue(isinstance(msg[1], ldb.Message))
1911 ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE)
1912 self.assertEqual("dn: foo=bar\n\n", ldif)
1914 def test_parse_ldif_more(self):
1915 msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar")
1917 self.assertEqual("foo=bar", str(msg[1].dn))
1919 self.assertEqual("bar=bar", str(msg[1].dn))
1921 def test_canonical_string(self):
1922 x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe")
1923 self.assertEqual("/bloe/foo25", x.canonical_str())
1925 def test_canonical_ex_string(self):
1926 x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe")
1927 self.assertEqual("/bloe\nfoo26", x.canonical_ex_str())
1929 def test_ldb_is_child_of(self):
1930 """Testing ldb_dn_compare_dn"""
1931 dn1 = ldb.Dn(self.ldb, "dc=base")
1932 dn2 = ldb.Dn(self.ldb, "cn=foo,dc=base")
1933 dn3 = ldb.Dn(self.ldb, "cn=bar,dc=base")
1934 dn4 = ldb.Dn(self.ldb, "cn=baz,cn=bar,dc=base")
1936 self.assertTrue(dn1.is_child_of(dn1))
1937 self.assertTrue(dn2.is_child_of(dn1))
1938 self.assertTrue(dn4.is_child_of(dn1))
1939 self.assertTrue(dn4.is_child_of(dn3))
1940 self.assertTrue(dn4.is_child_of(dn4))
1941 self.assertFalse(dn3.is_child_of(dn2))
1942 self.assertFalse(dn1.is_child_of(dn4))
1944 def test_ldb_is_child_of_str(self):
1945 """Testing ldb_dn_compare_dn"""
1947 dn2_str = "cn=foo,dc=base"
1948 dn3_str = "cn=bar,dc=base"
1949 dn4_str = "cn=baz,cn=bar,dc=base"
1951 dn1 = ldb.Dn(self.ldb, dn1_str)
1952 dn2 = ldb.Dn(self.ldb, dn2_str)
1953 dn3 = ldb.Dn(self.ldb, dn3_str)
1954 dn4 = ldb.Dn(self.ldb, dn4_str)
1956 self.assertTrue(dn1.is_child_of(dn1_str))
1957 self.assertTrue(dn2.is_child_of(dn1_str))
1958 self.assertTrue(dn4.is_child_of(dn1_str))
1959 self.assertTrue(dn4.is_child_of(dn3_str))
1960 self.assertTrue(dn4.is_child_of(dn4_str))
1961 self.assertFalse(dn3.is_child_of(dn2_str))
1962 self.assertFalse(dn1.is_child_of(dn4_str))
1964 def test_get_component_name(self):
1965 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
1966 self.assertEqual(dn.get_component_name(0), 'cn')
1967 self.assertEqual(dn.get_component_name(1), 'dc')
1968 self.assertEqual(dn.get_component_name(2), None)
1969 self.assertEqual(dn.get_component_name(-1), None)
1971 def test_get_component_value(self):
1972 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
1973 self.assertEqual(dn.get_component_value(0), 'foo')
1974 self.assertEqual(dn.get_component_value(1), 'base')
1975 self.assertEqual(dn.get_component_name(2), None)
1976 self.assertEqual(dn.get_component_name(-1), None)
1978 def test_set_component(self):
1979 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
1980 dn.set_component(0, 'cn', 'bar')
1981 self.assertEqual(str(dn), "cn=bar,dc=base")
1982 dn.set_component(1, 'o', 'asep')
1983 self.assertEqual(str(dn), "cn=bar,o=asep")
1984 self.assertRaises(TypeError, dn.set_component, 2, 'dc', 'base')
1985 self.assertEqual(str(dn), "cn=bar,o=asep")
1986 dn.set_component(1, 'o', 'a,b+c')
1987 self.assertEqual(str(dn), r"cn=bar,o=a\,b\+c")
1989 def test_set_component_bytes(self):
1990 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
1991 dn.set_component(0, 'cn', b'bar')
1992 self.assertEqual(str(dn), "cn=bar,dc=base")
1993 dn.set_component(1, 'o', b'asep')
1994 self.assertEqual(str(dn), "cn=bar,o=asep")
1996 def test_set_component_none(self):
1997 dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base")
1998 self.assertRaises(TypeError, dn.set_component, 1, 'cn', None)
2000 def test_get_extended_component_null(self):
2001 dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base")
2002 self.assertEqual(dn.get_extended_component("TEST"), None)
2004 def test_get_extended_component(self):
2005 self.ldb._register_test_extensions()
2006 dn = ldb.Dn(self.ldb, "<TEST=foo>;cn=bar,dc=base")
2007 self.assertEqual(dn.get_extended_component("TEST"), b"foo")
2009 def test_set_extended_component(self):
2010 self.ldb._register_test_extensions()
2011 dn = ldb.Dn(self.ldb, "dc=base")
2012 dn.set_extended_component("TEST", "foo")
2013 self.assertEqual(dn.get_extended_component("TEST"), b"foo")
2014 dn.set_extended_component("TEST", b"bar")
2015 self.assertEqual(dn.get_extended_component("TEST"), b"bar")
2017 def test_extended_str(self):
2018 self.ldb._register_test_extensions()
2019 dn = ldb.Dn(self.ldb, "<TEST=foo>;cn=bar,dc=base")
2020 self.assertEqual(dn.extended_str(), "<TEST=foo>;cn=bar,dc=base")
2022 def test_get_rdn_name(self):
2023 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
2024 self.assertEqual(dn.get_rdn_name(), 'cn')
2026 def test_get_rdn_value(self):
2027 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
2028 self.assertEqual(dn.get_rdn_value(), 'foo')
2030 def test_get_casefold(self):
2031 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
2032 self.assertEqual(dn.get_casefold(), 'CN=FOO,DC=BASE')
2034 def test_get_linearized(self):
2035 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
2036 self.assertEqual(dn.get_linearized(), 'cn=foo,dc=base')
2038 def test_is_null(self):
2039 dn = ldb.Dn(self.ldb, "cn=foo,dc=base")
2040 self.assertFalse(dn.is_null())
2042 dn = ldb.Dn(self.ldb, '')
2043 self.assertTrue(dn.is_null())
2045 class LdbMsgTests(TestCase):
2048 super(LdbMsgTests, self).setUp()
2049 self.msg = ldb.Message()
2051 def test_init_dn(self):
2052 self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27"))
2053 self.assertEqual("dc=foo27", str(self.msg.dn))
2055 def test_iter_items(self):
2056 self.assertEqual(0, len(self.msg.items()))
2057 self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo28")
2058 self.assertEqual(1, len(self.msg.items()))
2060 def test_repr(self):
2061 self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo29")
2062 self.msg["dc"] = b"foo"
2064 self.assertIn(repr(self.msg), [
2065 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})",
2066 "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})",
2068 self.assertIn(repr(self.msg.text), [
2069 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text",
2070 "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text",
2075 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})")
2077 repr(self.msg.text),
2078 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text")
2081 self.assertEqual(0, len(self.msg))
2083 def test_notpresent(self):
2084 self.assertRaises(KeyError, lambda: self.msg["foo"])
2090 self.msg.add(ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla"))
2092 def test_add_text(self):
2093 self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla"))
2095 def test_elements_empty(self):
2096 self.assertEqual([], self.msg.elements())
2098 def test_elements(self):
2099 el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")
2101 self.assertEqual([el], self.msg.elements())
2102 self.assertEqual([el.text], self.msg.text.elements())
2104 def test_add_value(self):
2105 self.assertEqual(0, len(self.msg))
2106 self.msg["foo"] = [b"foo"]
2107 self.assertEqual(1, len(self.msg))
2109 def test_add_value_text(self):
2110 self.assertEqual(0, len(self.msg))
2111 self.msg["foo"] = ["foo"]
2112 self.assertEqual(1, len(self.msg))
2114 def test_add_value_multiple(self):
2115 self.assertEqual(0, len(self.msg))
2116 self.msg["foo"] = [b"foo", b"bla"]
2117 self.assertEqual(1, len(self.msg))
2118 self.assertEqual([b"foo", b"bla"], list(self.msg["foo"]))
2120 def test_add_value_multiple_text(self):
2121 self.assertEqual(0, len(self.msg))
2122 self.msg["foo"] = ["foo", "bla"]
2123 self.assertEqual(1, len(self.msg))
2124 self.assertEqual(["foo", "bla"], list(self.msg.text["foo"]))
2126 def test_set_value(self):
2127 self.msg["foo"] = [b"fool"]
2128 self.assertEqual([b"fool"], list(self.msg["foo"]))
2129 self.msg["foo"] = [b"bar"]
2130 self.assertEqual([b"bar"], list(self.msg["foo"]))
2132 def test_set_value_text(self):
2133 self.msg["foo"] = ["fool"]
2134 self.assertEqual(["fool"], list(self.msg.text["foo"]))
2135 self.msg["foo"] = ["bar"]
2136 self.assertEqual(["bar"], list(self.msg.text["foo"]))
2138 def test_keys(self):
2139 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2140 self.msg["foo"] = [b"bla"]
2141 self.msg["bar"] = [b"bla"]
2142 self.assertEqual(["dn", "foo", "bar"], list(self.msg.keys()))
2144 def test_keys_text(self):
2145 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2146 self.msg["foo"] = ["bla"]
2147 self.msg["bar"] = ["bla"]
2148 self.assertEqual(["dn", "foo", "bar"], list(self.msg.text.keys()))
2151 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2152 self.assertEqual("@BASEINFO", self.msg.dn.__str__())
2154 def test_get_dn(self):
2155 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2156 self.assertEqual("@BASEINFO", self.msg.get("dn").__str__())
2158 def test_dn_text(self):
2159 self.msg.text.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2160 self.assertEqual("@BASEINFO", str(self.msg.dn))
2161 self.assertEqual("@BASEINFO", str(self.msg.text.dn))
2163 def test_get_dn_text(self):
2164 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2165 self.assertEqual("@BASEINFO", str(self.msg.get("dn")))
2166 self.assertEqual("@BASEINFO", str(self.msg.text.get("dn")))
2168 def test_get_invalid(self):
2169 self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO")
2170 self.assertRaises(TypeError, self.msg.get, 42)
2172 def test_get_other(self):
2173 self.msg["foo"] = [b"bar"]
2174 self.assertEqual(b"bar", self.msg.get("foo")[0])
2175 self.assertEqual(b"bar", self.msg.get("foo", idx=0))
2176 self.assertEqual(None, self.msg.get("foo", idx=1))
2177 self.assertEqual("", self.msg.get("foo", default='', idx=1))
2179 def test_get_other_text(self):
2180 self.msg["foo"] = ["bar"]
2181 self.assertEqual(["bar"], list(self.msg.text.get("foo")))
2182 self.assertEqual("bar", self.msg.text.get("foo")[0])
2183 self.assertEqual("bar", self.msg.text.get("foo", idx=0))
2184 self.assertEqual(None, self.msg.get("foo", idx=1))
2185 self.assertEqual("", self.msg.get("foo", default='', idx=1))
2187 def test_get_default(self):
2188 self.assertEqual(None, self.msg.get("tatayoyo", idx=0))
2189 self.assertEqual("anniecordie", self.msg.get("tatayoyo", "anniecordie"))
2191 def test_get_default_text(self):
2192 self.assertEqual(None, self.msg.text.get("tatayoyo", idx=0))
2193 self.assertEqual("anniecordie", self.msg.text.get("tatayoyo", "anniecordie"))
2195 def test_get_unknown(self):
2196 self.assertEqual(None, self.msg.get("lalalala"))
2198 def test_get_unknown_text(self):
2199 self.assertEqual(None, self.msg.text.get("lalalala"))
2201 def test_msg_diff(self):
2203 msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n")
2204 msg1 = next(msgs)[1]
2205 msg2 = next(msgs)[1]
2206 msgdiff = l.msg_diff(msg1, msg2)
2207 self.assertEqual("foo=bar", msgdiff.get("dn").__str__())
2208 self.assertRaises(KeyError, lambda: msgdiff["foo"])
2209 self.assertEqual(1, len(msgdiff))
2211 def test_equal_empty(self):
2212 msg1 = ldb.Message()
2213 msg2 = ldb.Message()
2214 self.assertEqual(msg1, msg2)
2216 def test_equal_simplel(self):
2218 msg1 = ldb.Message()
2219 msg1.dn = ldb.Dn(db, "foo=bar")
2220 msg2 = ldb.Message()
2221 msg2.dn = ldb.Dn(db, "foo=bar")
2222 self.assertEqual(msg1, msg2)
2223 msg1['foo'] = b'bar'
2224 msg2['foo'] = b'bar'
2225 self.assertEqual(msg1, msg2)
2226 msg2['foo'] = b'blie'
2227 self.assertNotEqual(msg1, msg2)
2228 msg2['foo'] = b'blie'
2230 def test_from_dict(self):
2231 rec = {"dn": "dc=fromdict",
2232 "a1": [b"a1-val1", b"a1-val1"]}
2234 # check different types of input Flags
2235 for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]:
2236 m = ldb.Message.from_dict(l, rec, flags)
2237 self.assertEqual(rec["a1"], list(m["a1"]))
2238 self.assertEqual(flags, m["a1"].flags())
2239 # check input params
2240 self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE)
2241 self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE)
2242 self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0)
2243 # Message.from_dict expects dictionary with 'dn'
2244 err_rec = {"a1": [b"a1-val1", b"a1-val1"]}
2245 self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE)
2247 def test_from_dict_text(self):
2248 rec = {"dn": "dc=fromdict",
2249 "a1": ["a1-val1", "a1-val1"]}
2251 # check different types of input Flags
2252 for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]:
2253 m = ldb.Message.from_dict(l, rec, flags)
2254 self.assertEqual(rec["a1"], list(m.text["a1"]))
2255 self.assertEqual(flags, m.text["a1"].flags())
2256 # check input params
2257 self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE)
2258 self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE)
2259 self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0)
2260 # Message.from_dict expects dictionary with 'dn'
2261 err_rec = {"a1": ["a1-val1", "a1-val1"]}
2262 self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE)
2264 def test_copy_add_message_element(self):
2266 m["1"] = ldb.MessageElement([b"val 111"], ldb.FLAG_MOD_ADD, "1")
2267 m["2"] = ldb.MessageElement([b"val 222"], ldb.FLAG_MOD_ADD, "2")
2271 self.assertEqual(mto["1"], m["1"])
2272 self.assertEqual(mto["2"], m["2"])
2276 self.assertEqual(mto["1"], m["1"])
2277 self.assertEqual(mto["2"], m["2"])
2279 def test_copy_add_message_element_text(self):
2281 m["1"] = ldb.MessageElement(["val 111"], ldb.FLAG_MOD_ADD, "1")
2282 m["2"] = ldb.MessageElement(["val 222"], ldb.FLAG_MOD_ADD, "2")
2286 self.assertEqual(mto["1"], m.text["1"])
2287 self.assertEqual(mto["2"], m.text["2"])
2291 self.assertEqual(mto.text["1"], m.text["1"])
2292 self.assertEqual(mto.text["2"], m.text["2"])
2293 self.assertEqual(mto["1"], m["1"])
2294 self.assertEqual(mto["2"], m["2"])
2297 class MessageElementTests(TestCase):
2299 def test_cmp_element(self):
2300 x = ldb.MessageElement([b"foo"])
2301 y = ldb.MessageElement([b"foo"])
2302 z = ldb.MessageElement([b"bzr"])
2303 self.assertEqual(x, y)
2304 self.assertNotEqual(x, z)
2306 def test_cmp_element_text(self):
2307 x = ldb.MessageElement([b"foo"])
2308 y = ldb.MessageElement(["foo"])
2309 self.assertEqual(x, y)
2311 def test_create_iterable(self):
2312 x = ldb.MessageElement([b"foo"])
2313 self.assertEqual([b"foo"], list(x))
2314 self.assertEqual(["foo"], list(x.text))
2316 def test_repr(self):
2317 x = ldb.MessageElement([b"foo"])
2319 self.assertEqual("MessageElement([b'foo'])", repr(x))
2320 self.assertEqual("MessageElement([b'foo']).text", repr(x.text))
2322 self.assertEqual("MessageElement(['foo'])", repr(x))
2323 self.assertEqual("MessageElement(['foo']).text", repr(x.text))
2324 x = ldb.MessageElement([b"foo", b"bla"])
2325 self.assertEqual(2, len(x))
2327 self.assertEqual("MessageElement([b'foo',b'bla'])", repr(x))
2328 self.assertEqual("MessageElement([b'foo',b'bla']).text", repr(x.text))
2330 self.assertEqual("MessageElement(['foo','bla'])", repr(x))
2331 self.assertEqual("MessageElement(['foo','bla']).text", repr(x.text))
2333 def test_get_item(self):
2334 x = ldb.MessageElement([b"foo", b"bar"])
2335 self.assertEqual(b"foo", x[0])
2336 self.assertEqual(b"bar", x[1])
2337 self.assertEqual(b"bar", x[-1])
2338 self.assertRaises(IndexError, lambda: x[45])
2340 def test_get_item_text(self):
2341 x = ldb.MessageElement(["foo", "bar"])
2342 self.assertEqual("foo", x.text[0])
2343 self.assertEqual("bar", x.text[1])
2344 self.assertEqual("bar", x.text[-1])
2345 self.assertRaises(IndexError, lambda: x[45])
2348 x = ldb.MessageElement([b"foo", b"bar"])
2349 self.assertEqual(2, len(x))
2352 x = ldb.MessageElement([b"foo", b"bar"])
2353 y = ldb.MessageElement([b"foo", b"bar"])
2354 self.assertEqual(y, x)
2355 x = ldb.MessageElement([b"foo"])
2356 self.assertNotEqual(y, x)
2357 y = ldb.MessageElement([b"foo"])
2358 self.assertEqual(y, x)
2360 def test_extended(self):
2361 el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")
2363 self.assertEqual("MessageElement([b'456'])", repr(el))
2364 self.assertEqual("MessageElement([b'456']).text", repr(el.text))
2366 self.assertEqual("MessageElement(['456'])", repr(el))
2367 self.assertEqual("MessageElement(['456']).text", repr(el.text))
2369 def test_bad_text(self):
2370 el = ldb.MessageElement(b'\xba\xdd')
2371 self.assertRaises(UnicodeDecodeError, el.text.__getitem__, 0)
2374 class ModuleTests(TestCase):
2377 super(ModuleTests, self).setUp()
2378 self.testdir = tempdir()
2379 self.filename = os.path.join(self.testdir, "test.ldb")
2380 self.ldb = ldb.Ldb(self.filename)
2383 shutil.rmtree(self.testdir)
2384 super(ModuleTests, self).setUp()
2386 def test_register_module(self):
2387 class ExampleModule:
2389 ldb.register_module(ExampleModule)
2391 def test_use_module(self):
2393 class ExampleModule:
2396 def __init__(self, ldb, next):
2400 def search(self, *args, **kwargs):
2401 return self.next.search(*args, **kwargs)
2403 def request(self, *args, **kwargs):
2406 ldb.register_module(ExampleModule)
2407 l = ldb.Ldb(self.filename)
2408 l.add({"dn": "@MODULES", "@LIST": "bla"})
2409 self.assertEqual([], ops)
2410 l = ldb.Ldb(self.filename)
2411 self.assertEqual(["init"], ops)
2413 class LdbResultTests(LdbBaseTest):
2416 super(LdbResultTests, self).setUp()
2417 self.testdir = tempdir()
2418 self.filename = os.path.join(self.testdir, "test.ldb")
2419 self.l = ldb.Ldb(self.url(), flags=self.flags())
2421 self.l.add(self.index)
2422 except AttributeError:
2424 self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org",
2425 "objectUUID": b"0123456789abcde0"})
2426 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins",
2427 "objectUUID": b"0123456789abcde1"})
2428 self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users",
2429 "objectUUID": b"0123456789abcde2"})
2430 self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1",
2431 "objectUUID": b"0123456789abcde3"})
2432 self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2",
2433 "objectUUID": b"0123456789abcde4"})
2434 self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3",
2435 "objectUUID": b"0123456789abcde5"})
2436 self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4",
2437 "objectUUID": b"0123456789abcde6"})
2438 self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5",
2439 "objectUUID": b"0123456789abcde7"})
2440 self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6",
2441 "objectUUID": b"0123456789abcde8"})
2442 self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7",
2443 "objectUUID": b"0123456789abcde9"})
2444 self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8",
2445 "objectUUID": b"0123456789abcdea"})
2446 self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9",
2447 "objectUUID": b"0123456789abcdeb"})
2448 self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10",
2449 "objectUUID": b"0123456789abcdec"})
2452 shutil.rmtree(self.testdir)
2453 super(LdbResultTests, self).tearDown()
2454 # Ensure the LDB is closed now, so we close the FD
2457 def test_return_type(self):
2458 res = self.l.search()
2459 self.assertEqual(str(res), "<ldb result>")
2461 def test_get_msgs(self):
2462 res = self.l.search()
2465 def test_get_controls(self):
2466 res = self.l.search()
2469 def test_get_referals(self):
2470 res = self.l.search()
2473 def test_iter_msgs(self):
2475 for l in self.l.search().msgs:
2476 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
2478 self.assertTrue(found)
2480 def test_iter_msgs_count(self):
2481 self.assertTrue(self.l.search().count > 0)
2482 # 13 objects has been added to the DC=SAMBA, DC=ORG
2483 self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13)
2485 def test_iter_controls(self):
2486 res = self.l.search().controls
2489 def test_create_control(self):
2490 self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0")
2491 c = ldb.Control(self.l, "relax:1")
2492 self.assertEqual(c.critical, True)
2493 self.assertEqual(c.oid, "1.3.6.1.4.1.4203.666.5.12")
2495 def test_iter_refs(self):
2496 res = self.l.search().referals
2499 def test_search_sequence_msgs(self):
2501 res = self.l.search().msgs
2503 for i in range(0, len(res)):
2505 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
2507 self.assertTrue(found)
2509 def test_search_as_iter(self):
2511 res = self.l.search()
2514 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
2516 self.assertTrue(found)
2518 def test_search_iter(self):
2520 res = self.l.search_iterator()
2523 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
2525 self.assertTrue(found)
2528 # Show that search results can't see into a transaction
2529 def test_search_against_trans(self):
2532 (r1, w1) = os.pipe()
2534 (r2, w2) = os.pipe()
2536 # For the first element, fork a child that will
2540 # In the child, re-open
2544 child_ldb = ldb.Ldb(self.url(), flags=self.flags())
2545 # start a transaction
2546 child_ldb.transaction_start()
2549 child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG",
2550 "name": b"samba.org",
2551 "objectUUID": b"o123456789acbdef"})
2553 os.write(w1, b"added")
2555 # Now wait for the search to be done
2560 child_ldb.transaction_commit()
2561 except LdbError as err:
2562 # We print this here to see what went wrong in the child
2566 os.write(w1, b"transaction")
2569 self.assertEqual(os.read(r1, 5), b"added")
2571 # This should not turn up until the transaction is concluded
2572 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
2573 scope=ldb.SCOPE_BASE)
2574 self.assertEqual(len(res11), 0)
2576 os.write(w2, b"search")
2578 # Now wait for the transaction to be done. This should
2579 # deadlock, but the search doesn't hold a read lock for the
2580 # iterator lifetime currently.
2581 self.assertEqual(os.read(r1, 11), b"transaction")
2583 # This should now turn up, as the transaction is over
2584 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
2585 scope=ldb.SCOPE_BASE)
2586 self.assertEqual(len(res11), 1)
2588 self.assertFalse(found11)
2590 (got_pid, status) = os.waitpid(pid, 0)
2591 self.assertEqual(got_pid, pid)
2594 def test_search_iter_against_trans(self):
2598 # We need to hold this iterator open to hold the all-record
2600 res = self.l.search_iterator()
2602 (r1, w1) = os.pipe()
2604 (r2, w2) = os.pipe()
2606 # For the first element, with the sequence open (which
2607 # means with ldb locks held), fork a child that will
2611 # In the child, re-open
2616 child_ldb = ldb.Ldb(self.url(), flags=self.flags())
2617 # start a transaction
2618 child_ldb.transaction_start()
2621 child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG",
2622 "name": b"samba.org",
2623 "objectUUID": b"o123456789acbdef"})
2625 os.write(w1, b"added")
2627 # Now wait for the search to be done
2632 child_ldb.transaction_commit()
2633 except LdbError as err:
2634 # We print this here to see what went wrong in the child
2638 os.write(w1, b"transaction")
2641 self.assertEqual(os.read(r1, 5), b"added")
2643 # This should not turn up until the transaction is concluded
2644 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
2645 scope=ldb.SCOPE_BASE)
2646 self.assertEqual(len(res11), 0)
2648 os.write(w2, b"search")
2650 # allow the transaction to start
2653 # This should not turn up until the search finishes and
2654 # removed the read lock, but for ldb_tdb that happened as soon
2655 # as we called the first res.next()
2656 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
2657 scope=ldb.SCOPE_BASE)
2658 self.assertEqual(len(res11), 0)
2660 # These results are all collected at the first next(res) call
2662 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG":
2664 if str(l.dn) == "OU=OU11,DC=SAMBA,DC=ORG":
2667 # Now wait for the transaction to be done.
2668 self.assertEqual(os.read(r1, 11), b"transaction")
2670 # This should now turn up, as the transaction is over and all
2671 # read locks are gone
2672 res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG",
2673 scope=ldb.SCOPE_BASE)
2674 self.assertEqual(len(res11), 1)
2676 self.assertTrue(found)
2677 self.assertFalse(found11)
2679 (got_pid, status) = os.waitpid(pid, 0)
2680 self.assertEqual(got_pid, pid)
2683 class LdbResultTestsLmdb(LdbResultTests):
2686 self.prefix = MDB_PREFIX
2687 self.index = MDB_INDEX_OBJ
2688 super(LdbResultTestsLmdb, self).setUp()
2691 super(LdbResultTestsLmdb, self).tearDown()
2694 class BadTypeTests(TestCase):
2695 def test_control(self):
2697 self.assertRaises(TypeError, ldb.Control, '<bad type>', 'relax:1')
2698 self.assertRaises(TypeError, ldb.Control, ldb, 1234)
2700 def test_modify(self):
2702 dn = ldb.Dn(l, 'a=b')
2704 self.assertRaises(TypeError, l.modify, '<bad type>')
2705 self.assertRaises(TypeError, l.modify, m, '<bad type>')
2709 dn = ldb.Dn(l, 'a=b')
2711 self.assertRaises(TypeError, l.add, '<bad type>')
2712 self.assertRaises(TypeError, l.add, m, '<bad type>')
2714 def test_delete(self):
2716 dn = ldb.Dn(l, 'a=b')
2717 self.assertRaises(TypeError, l.add, '<bad type>')
2718 self.assertRaises(TypeError, l.add, dn, '<bad type>')
2720 def test_rename(self):
2722 dn = ldb.Dn(l, 'a=b')
2723 self.assertRaises(TypeError, l.add, '<bad type>', dn)
2724 self.assertRaises(TypeError, l.add, dn, '<bad type>')
2725 self.assertRaises(TypeError, l.add, dn, dn, '<bad type>')
2727 def test_search(self):
2729 self.assertRaises(TypeError, l.search, base=1234)
2730 self.assertRaises(TypeError, l.search, scope='<bad type>')
2731 self.assertRaises(TypeError, l.search, expression=1234)
2732 self.assertRaises(TypeError, l.search, attrs='<bad type>')
2733 self.assertRaises(TypeError, l.search, controls='<bad type>')
2736 class VersionTests(TestCase):
2738 def test_version(self):
2739 self.assertTrue(isinstance(ldb.__version__, str))
2742 if __name__ == '__main__':
2744 unittest.TestProgram()