2 # Simple tests for the ldb python bindings.
3 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
6 from unittest
import TestCase
11 PY3
= sys
.version_info
> (3, 0)
17 dir_prefix
= os
.path
.join(os
.environ
["SELFTEST_PREFIX"], "tmp")
20 return tempfile
.mktemp(dir=dir_prefix
)
23 class NoContextTests(TestCase
):
25 def test_valid_attr_name(self
):
26 self
.assertTrue(ldb
.valid_attr_name("foo"))
27 self
.assertFalse(ldb
.valid_attr_name("24foo"))
29 def test_timestring(self
):
30 self
.assertEqual("19700101000000.0Z", ldb
.timestring(0))
31 self
.assertEqual("20071119191012.0Z", ldb
.timestring(1195499412))
33 def test_string_to_time(self
):
34 self
.assertEqual(0, ldb
.string_to_time("19700101000000.0Z"))
35 self
.assertEqual(1195499412, ldb
.string_to_time("20071119191012.0Z"))
37 def test_binary_encode(self
):
38 encoded
= ldb
.binary_encode(b
'test\\x')
39 decoded
= ldb
.binary_decode(encoded
)
40 self
.assertEqual(decoded
, b
'test\\x')
42 encoded2
= ldb
.binary_encode('test\\x')
43 self
.assertEqual(encoded2
, encoded
)
45 class SimpleLdb(TestCase
):
47 def test_connect(self
):
50 def test_connect_none(self
):
53 def test_connect_later(self
):
59 self
.assertTrue(repr(x
).startswith("<ldb connection"))
61 def test_set_create_perms(self
):
63 x
.set_create_perms(0o600)
65 def test_modules_none(self
):
67 self
.assertEqual([], x
.modules())
69 def test_modules_tdb(self
):
70 x
= ldb
.Ldb(filename())
71 self
.assertEqual("[<ldb module 'tdb'>]", repr(x
.modules()))
73 def test_search(self
):
74 l
= ldb
.Ldb(filename())
75 self
.assertEqual(len(l
.search()), 0)
77 def test_search_controls(self
):
78 l
= ldb
.Ldb(filename())
79 self
.assertEqual(len(l
.search(controls
=["paged_results:0:5"])), 0)
81 def test_search_attrs(self
):
82 l
= ldb
.Ldb(filename())
83 self
.assertEqual(len(l
.search(ldb
.Dn(l
, ""), ldb
.SCOPE_SUBTREE
, "(dc=*)", ["dc"])), 0)
85 def test_search_string_dn(self
):
86 l
= ldb
.Ldb(filename())
87 self
.assertEqual(len(l
.search("", ldb
.SCOPE_SUBTREE
, "(dc=*)", ["dc"])), 0)
89 def test_search_attr_string(self
):
90 l
= ldb
.Ldb(filename())
91 self
.assertRaises(TypeError, l
.search
, attrs
="dc")
92 self
.assertRaises(TypeError, l
.search
, attrs
=b
"dc")
94 def test_opaque(self
):
95 l
= ldb
.Ldb(filename())
96 l
.set_opaque("my_opaque", l
)
97 self
.assertTrue(l
.get_opaque("my_opaque") is not None)
98 self
.assertEqual(None, l
.get_opaque("unknown"))
100 def test_search_scope_base(self
):
101 l
= ldb
.Ldb(filename())
102 self
.assertEqual(len(l
.search(ldb
.Dn(l
, "dc=foo1"),
103 ldb
.SCOPE_ONELEVEL
)), 0)
105 def test_delete(self
):
106 l
= ldb
.Ldb(filename())
107 self
.assertRaises(ldb
.LdbError
, lambda: l
.delete(ldb
.Dn(l
, "dc=foo2")))
109 def test_delete_w_unhandled_ctrl(self
):
110 l
= ldb
.Ldb(filename())
112 m
.dn
= ldb
.Dn(l
, "dc=foo1")
115 self
.assertRaises(ldb
.LdbError
, lambda: l
.delete(m
.dn
, ["search_options:1:2"]))
118 def test_contains(self
):
121 self
.assertFalse(ldb
.Dn(l
, "dc=foo3") in l
)
124 m
.dn
= ldb
.Dn(l
, "dc=foo3")
128 self
.assertTrue(ldb
.Dn(l
, "dc=foo3") in l
)
132 def test_get_config_basedn(self
):
133 l
= ldb
.Ldb(filename())
134 self
.assertEqual(None, l
.get_config_basedn())
136 def test_get_root_basedn(self
):
137 l
= ldb
.Ldb(filename())
138 self
.assertEqual(None, l
.get_root_basedn())
140 def test_get_schema_basedn(self
):
141 l
= ldb
.Ldb(filename())
142 self
.assertEqual(None, l
.get_schema_basedn())
144 def test_get_default_basedn(self
):
145 l
= ldb
.Ldb(filename())
146 self
.assertEqual(None, l
.get_default_basedn())
149 l
= ldb
.Ldb(filename())
151 m
.dn
= ldb
.Dn(l
, "dc=foo4")
153 self
.assertEqual(len(l
.search()), 0)
156 self
.assertEqual(len(l
.search()), 1)
158 l
.delete(ldb
.Dn(l
, "dc=foo4"))
160 def test_add_text(self
):
161 l
= ldb
.Ldb(filename())
163 m
.dn
= ldb
.Dn(l
, "dc=foo4")
165 self
.assertEqual(len(l
.search()), 0)
168 self
.assertEqual(len(l
.search()), 1)
170 l
.delete(ldb
.Dn(l
, "dc=foo4"))
172 def test_add_w_unhandled_ctrl(self
):
173 l
= ldb
.Ldb(filename())
175 m
.dn
= ldb
.Dn(l
, "dc=foo4")
177 self
.assertEqual(len(l
.search()), 0)
178 self
.assertRaises(ldb
.LdbError
, lambda: l
.add(m
,["search_options:1:2"]))
180 def test_add_dict(self
):
181 l
= ldb
.Ldb(filename())
182 m
= {"dn": ldb
.Dn(l
, "dc=foo5"),
184 self
.assertEqual(len(l
.search()), 0)
187 self
.assertEqual(len(l
.search()), 1)
189 l
.delete(ldb
.Dn(l
, "dc=foo5"))
191 def test_add_dict_text(self
):
192 l
= ldb
.Ldb(filename())
193 m
= {"dn": ldb
.Dn(l
, "dc=foo5"),
195 self
.assertEqual(len(l
.search()), 0)
198 self
.assertEqual(len(l
.search()), 1)
200 l
.delete(ldb
.Dn(l
, "dc=foo5"))
202 def test_add_dict_string_dn(self
):
203 l
= ldb
.Ldb(filename())
204 m
= {"dn": "dc=foo6", "bla": b
"bla"}
205 self
.assertEqual(len(l
.search()), 0)
208 self
.assertEqual(len(l
.search()), 1)
210 l
.delete(ldb
.Dn(l
, "dc=foo6"))
212 def test_add_dict_bytes_dn(self
):
213 l
= ldb
.Ldb(filename())
214 m
= {"dn": b
"dc=foo6", "bla": b
"bla"}
215 self
.assertEqual(len(l
.search()), 0)
218 self
.assertEqual(len(l
.search()), 1)
220 l
.delete(ldb
.Dn(l
, "dc=foo6"))
222 def test_rename(self
):
223 l
= ldb
.Ldb(filename())
225 m
.dn
= ldb
.Dn(l
, "dc=foo7")
227 self
.assertEqual(len(l
.search()), 0)
230 l
.rename(ldb
.Dn(l
, "dc=foo7"), ldb
.Dn(l
, "dc=bar"))
231 self
.assertEqual(len(l
.search()), 1)
233 l
.delete(ldb
.Dn(l
, "dc=bar"))
235 def test_rename_string_dns(self
):
236 l
= ldb
.Ldb(filename())
238 m
.dn
= ldb
.Dn(l
, "dc=foo8")
240 self
.assertEqual(len(l
.search()), 0)
242 self
.assertEqual(len(l
.search()), 1)
244 l
.rename("dc=foo8", "dc=bar")
245 self
.assertEqual(len(l
.search()), 1)
247 l
.delete(ldb
.Dn(l
, "dc=bar"))
249 def test_modify_delete(self
):
250 l
= ldb
.Ldb(filename())
252 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
255 rm
= l
.search(m
.dn
)[0]
256 self
.assertEqual([b
"1234"], list(rm
["bla"]))
259 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
260 m
["bla"] = ldb
.MessageElement([], ldb
.FLAG_MOD_DELETE
, "bla")
261 self
.assertEqual(ldb
.FLAG_MOD_DELETE
, m
["bla"].flags())
263 rm
= l
.search(m
.dn
)[0]
264 self
.assertEqual(1, len(rm
))
265 rm
= l
.search(m
.dn
, attrs
=["bla"])
266 self
.assertEqual(0, len(rm
))
268 l
.delete(ldb
.Dn(l
, "dc=modifydelete"))
270 def test_modify_delete_text(self
):
271 l
= ldb
.Ldb(filename())
273 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
274 m
.text
["bla"] = ["1234"]
276 rm
= l
.search(m
.dn
)[0]
277 self
.assertEqual(["1234"], list(rm
.text
["bla"]))
280 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
281 m
["bla"] = ldb
.MessageElement([], ldb
.FLAG_MOD_DELETE
, "bla")
282 self
.assertEqual(ldb
.FLAG_MOD_DELETE
, m
["bla"].flags())
284 rm
= l
.search(m
.dn
)[0]
285 self
.assertEqual(1, len(rm
))
286 rm
= l
.search(m
.dn
, attrs
=["bla"])
287 self
.assertEqual(0, len(rm
))
289 l
.delete(ldb
.Dn(l
, "dc=modifydelete"))
291 def test_modify_add(self
):
292 l
= ldb
.Ldb(filename())
294 m
.dn
= ldb
.Dn(l
, "dc=add")
299 m
.dn
= ldb
.Dn(l
, "dc=add")
300 m
["bla"] = ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla")
301 self
.assertEqual(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
303 rm
= l
.search(m
.dn
)[0]
304 self
.assertEqual(2, len(rm
))
305 self
.assertEqual([b
"1234", b
"456"], list(rm
["bla"]))
307 l
.delete(ldb
.Dn(l
, "dc=add"))
309 def test_modify_add_text(self
):
310 l
= ldb
.Ldb(filename())
312 m
.dn
= ldb
.Dn(l
, "dc=add")
313 m
.text
["bla"] = ["1234"]
317 m
.dn
= ldb
.Dn(l
, "dc=add")
318 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
319 self
.assertEqual(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
321 rm
= l
.search(m
.dn
)[0]
322 self
.assertEqual(2, len(rm
))
323 self
.assertEqual(["1234", "456"], list(rm
.text
["bla"]))
325 l
.delete(ldb
.Dn(l
, "dc=add"))
327 def test_modify_replace(self
):
328 l
= ldb
.Ldb(filename())
330 m
.dn
= ldb
.Dn(l
, "dc=modify2")
331 m
["bla"] = [b
"1234", b
"456"]
335 m
.dn
= ldb
.Dn(l
, "dc=modify2")
336 m
["bla"] = ldb
.MessageElement([b
"789"], ldb
.FLAG_MOD_REPLACE
, "bla")
337 self
.assertEqual(ldb
.FLAG_MOD_REPLACE
, m
["bla"].flags())
339 rm
= l
.search(m
.dn
)[0]
340 self
.assertEqual(2, len(rm
))
341 self
.assertEqual([b
"789"], list(rm
["bla"]))
342 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
343 self
.assertEqual(1, len(rm
))
345 l
.delete(ldb
.Dn(l
, "dc=modify2"))
347 def test_modify_replace_text(self
):
348 l
= ldb
.Ldb(filename())
350 m
.dn
= ldb
.Dn(l
, "dc=modify2")
351 m
.text
["bla"] = ["1234", "456"]
355 m
.dn
= ldb
.Dn(l
, "dc=modify2")
356 m
["bla"] = ldb
.MessageElement(["789"], ldb
.FLAG_MOD_REPLACE
, "bla")
357 self
.assertEqual(ldb
.FLAG_MOD_REPLACE
, m
["bla"].flags())
359 rm
= l
.search(m
.dn
)[0]
360 self
.assertEqual(2, len(rm
))
361 self
.assertEqual(["789"], list(rm
.text
["bla"]))
362 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
363 self
.assertEqual(1, len(rm
))
365 l
.delete(ldb
.Dn(l
, "dc=modify2"))
367 def test_modify_flags_change(self
):
368 l
= ldb
.Ldb(filename())
370 m
.dn
= ldb
.Dn(l
, "dc=add")
375 m
.dn
= ldb
.Dn(l
, "dc=add")
376 m
["bla"] = ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla")
377 self
.assertEqual(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
379 rm
= l
.search(m
.dn
)[0]
380 self
.assertEqual(2, len(rm
))
381 self
.assertEqual([b
"1234", b
"456"], list(rm
["bla"]))
383 # Now create another modify, but switch the flags before we do it
384 m
["bla"] = ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla")
385 m
["bla"].set_flags(ldb
.FLAG_MOD_DELETE
)
387 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
388 self
.assertEqual(1, len(rm
))
389 self
.assertEqual([b
"1234"], list(rm
["bla"]))
391 l
.delete(ldb
.Dn(l
, "dc=add"))
393 def test_modify_flags_change_text(self
):
394 l
= ldb
.Ldb(filename())
396 m
.dn
= ldb
.Dn(l
, "dc=add")
397 m
.text
["bla"] = ["1234"]
401 m
.dn
= ldb
.Dn(l
, "dc=add")
402 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
403 self
.assertEqual(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
405 rm
= l
.search(m
.dn
)[0]
406 self
.assertEqual(2, len(rm
))
407 self
.assertEqual(["1234", "456"], list(rm
.text
["bla"]))
409 # Now create another modify, but switch the flags before we do it
410 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
411 m
["bla"].set_flags(ldb
.FLAG_MOD_DELETE
)
413 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
414 self
.assertEqual(1, len(rm
))
415 self
.assertEqual(["1234"], list(rm
.text
["bla"]))
417 l
.delete(ldb
.Dn(l
, "dc=add"))
419 def test_transaction_commit(self
):
420 l
= ldb
.Ldb(filename())
421 l
.transaction_start()
422 m
= ldb
.Message(ldb
.Dn(l
, "dc=foo9"))
425 l
.transaction_commit()
428 def test_transaction_cancel(self
):
429 l
= ldb
.Ldb(filename())
430 l
.transaction_start()
431 m
= ldb
.Message(ldb
.Dn(l
, "dc=foo10"))
434 l
.transaction_cancel()
435 self
.assertEqual(0, len(l
.search(ldb
.Dn(l
, "dc=foo10"))))
437 def test_set_debug(self
):
438 def my_report_fn(level
, text
):
440 l
= ldb
.Ldb(filename())
441 l
.set_debug(my_report_fn
)
443 def test_zero_byte_string(self
):
444 """Testing we do not get trapped in the \0 byte in a property string."""
445 l
= ldb
.Ldb(filename())
448 "objectclass" : b
"user",
449 "cN" : b
"LDAPtestUSER",
450 "givenname" : b
"ldap",
451 "displayname" : b
"foo\0bar",
453 res
= l
.search(expression
="(dn=dc=somedn)")
454 self
.assertEqual(b
"foo\0bar", res
[0]["displayname"][0])
456 def test_no_crash_broken_expr(self
):
457 l
= ldb
.Ldb(filename())
458 self
.assertRaises(ldb
.LdbError
,lambda: l
.search("", ldb
.SCOPE_SUBTREE
, "&(dc=*)(dn=*)", ["dc"]))
461 class DnTests(TestCase
):
464 super(DnTests
, self
).setUp()
465 self
.ldb
= ldb
.Ldb(filename())
467 def test_set_dn_invalid(self
):
471 self
.assertRaises(TypeError, assign
)
474 x
= ldb
.Dn(self
.ldb
, "dc=foo11,bar=bloe")
475 y
= ldb
.Dn(self
.ldb
, "dc=foo11,bar=bloe")
476 self
.assertEqual(x
, y
)
477 y
= ldb
.Dn(self
.ldb
, "dc=foo11,bar=blie")
478 self
.assertNotEqual(x
, y
)
481 x
= ldb
.Dn(self
.ldb
, "dc=foo12,bar=bloe")
482 self
.assertEqual(x
.__str
__(), "dc=foo12,bar=bloe")
485 x
= ldb
.Dn(self
.ldb
, "dc=foo13,bla=blie")
486 self
.assertEqual(x
.__repr
__(), "Dn('dc=foo13,bla=blie')")
488 def test_get_casefold(self
):
489 x
= ldb
.Dn(self
.ldb
, "dc=foo14,bar=bloe")
490 self
.assertEqual(x
.get_casefold(), "DC=FOO14,BAR=bloe")
492 def test_validate(self
):
493 x
= ldb
.Dn(self
.ldb
, "dc=foo15,bar=bloe")
494 self
.assertTrue(x
.validate())
496 def test_parent(self
):
497 x
= ldb
.Dn(self
.ldb
, "dc=foo16,bar=bloe")
498 self
.assertEqual("bar=bloe", x
.parent().__str
__())
500 def test_parent_nonexistent(self
):
501 x
= ldb
.Dn(self
.ldb
, "@BLA")
502 self
.assertEqual(None, x
.parent())
504 def test_is_valid(self
):
505 x
= ldb
.Dn(self
.ldb
, "dc=foo18,dc=bloe")
506 self
.assertTrue(x
.is_valid())
507 x
= ldb
.Dn(self
.ldb
, "")
508 self
.assertTrue(x
.is_valid())
510 def test_is_special(self
):
511 x
= ldb
.Dn(self
.ldb
, "dc=foo19,bar=bloe")
512 self
.assertFalse(x
.is_special())
513 x
= ldb
.Dn(self
.ldb
, "@FOOBAR")
514 self
.assertTrue(x
.is_special())
516 def test_check_special(self
):
517 x
= ldb
.Dn(self
.ldb
, "dc=foo20,bar=bloe")
518 self
.assertFalse(x
.check_special("FOOBAR"))
519 x
= ldb
.Dn(self
.ldb
, "@FOOBAR")
520 self
.assertTrue(x
.check_special("@FOOBAR"))
523 x
= ldb
.Dn(self
.ldb
, "dc=foo21,bar=bloe")
524 self
.assertEqual(2, len(x
))
525 x
= ldb
.Dn(self
.ldb
, "dc=foo21")
526 self
.assertEqual(1, len(x
))
528 def test_add_child(self
):
529 x
= ldb
.Dn(self
.ldb
, "dc=foo22,bar=bloe")
530 self
.assertTrue(x
.add_child(ldb
.Dn(self
.ldb
, "bla=bloe")))
531 self
.assertEqual("bla=bloe,dc=foo22,bar=bloe", x
.__str
__())
533 def test_add_base(self
):
534 x
= ldb
.Dn(self
.ldb
, "dc=foo23,bar=bloe")
535 base
= ldb
.Dn(self
.ldb
, "bla=bloe")
536 self
.assertTrue(x
.add_base(base
))
537 self
.assertEqual("dc=foo23,bar=bloe,bla=bloe", x
.__str
__())
539 def test_add_child_str(self
):
540 x
= ldb
.Dn(self
.ldb
, "dc=foo22,bar=bloe")
541 self
.assertTrue(x
.add_child("bla=bloe"))
542 self
.assertEquals("bla=bloe,dc=foo22,bar=bloe", x
.__str
__())
544 def test_add_base_str(self
):
545 x
= ldb
.Dn(self
.ldb
, "dc=foo23,bar=bloe")
547 self
.assertTrue(x
.add_base(base
))
548 self
.assertEquals("dc=foo23,bar=bloe,bla=bloe", x
.__str
__())
551 x
= ldb
.Dn(self
.ldb
, "dc=foo24")
552 y
= ldb
.Dn(self
.ldb
, "bar=bla")
553 self
.assertEqual("dc=foo24,bar=bla", str(x
+ y
))
555 def test_remove_base_components(self
):
556 x
= ldb
.Dn(self
.ldb
, "dc=foo24,dc=samba,dc=org")
557 x
.remove_base_components(len(x
)-1)
558 self
.assertEqual("dc=foo24", str(x
))
560 def test_parse_ldif(self
):
561 msgs
= self
.ldb
.parse_ldif("dn: foo=bar\n")
563 self
.assertEqual("foo=bar", str(msg
[1].dn
))
564 self
.assertTrue(isinstance(msg
[1], ldb
.Message
))
565 ldif
= self
.ldb
.write_ldif(msg
[1], ldb
.CHANGETYPE_NONE
)
566 self
.assertEqual("dn: foo=bar\n\n", ldif
)
568 def test_parse_ldif_more(self
):
569 msgs
= self
.ldb
.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar")
571 self
.assertEqual("foo=bar", str(msg
[1].dn
))
573 self
.assertEqual("bar=bar", str(msg
[1].dn
))
575 def test_canonical_string(self
):
576 x
= ldb
.Dn(self
.ldb
, "dc=foo25,bar=bloe")
577 self
.assertEqual("/bloe/foo25", x
.canonical_str())
579 def test_canonical_ex_string(self
):
580 x
= ldb
.Dn(self
.ldb
, "dc=foo26,bar=bloe")
581 self
.assertEqual("/bloe\nfoo26", x
.canonical_ex_str())
583 def test_ldb_is_child_of(self
):
584 """Testing ldb_dn_compare_dn"""
585 dn1
= ldb
.Dn(self
.ldb
, "dc=base")
586 dn2
= ldb
.Dn(self
.ldb
, "cn=foo,dc=base")
587 dn3
= ldb
.Dn(self
.ldb
, "cn=bar,dc=base")
588 dn4
= ldb
.Dn(self
.ldb
, "cn=baz,cn=bar,dc=base")
590 self
.assertTrue(dn2
.is_child_of(dn1
))
591 self
.assertTrue(dn4
.is_child_of(dn1
))
592 self
.assertTrue(dn4
.is_child_of(dn3
))
593 self
.assertFalse(dn3
.is_child_of(dn2
))
594 self
.assertFalse(dn1
.is_child_of(dn4
))
596 def test_ldb_is_child_of_str(self
):
597 """Testing ldb_dn_compare_dn"""
599 dn2_str
= "cn=foo,dc=base"
600 dn3_str
= "cn=bar,dc=base"
601 dn4_str
= "cn=baz,cn=bar,dc=base"
603 dn1
= ldb
.Dn(self
.ldb
, dn1_str
)
604 dn2
= ldb
.Dn(self
.ldb
, dn2_str
)
605 dn3
= ldb
.Dn(self
.ldb
, dn3_str
)
606 dn4
= ldb
.Dn(self
.ldb
, dn4_str
)
608 self
.assertTrue(dn2
.is_child_of(dn1_str
))
609 self
.assertTrue(dn4
.is_child_of(dn1_str
))
610 self
.assertTrue(dn4
.is_child_of(dn3_str
))
611 self
.assertFalse(dn3
.is_child_of(dn2_str
))
612 self
.assertFalse(dn1
.is_child_of(dn4_str
))
614 class LdbMsgTests(TestCase
):
617 super(LdbMsgTests
, self
).setUp()
618 self
.msg
= ldb
.Message()
620 def test_init_dn(self
):
621 self
.msg
= ldb
.Message(ldb
.Dn(ldb
.Ldb(), "dc=foo27"))
622 self
.assertEqual("dc=foo27", str(self
.msg
.dn
))
624 def test_iter_items(self
):
625 self
.assertEqual(0, len(self
.msg
.items()))
626 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "dc=foo28")
627 self
.assertEqual(1, len(self
.msg
.items()))
630 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "dc=foo29")
631 self
.msg
["dc"] = b
"foo"
633 self
.assertIn(repr(self
.msg
), [
634 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})",
635 "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})",
637 self
.assertIn(repr(self
.msg
.text
), [
638 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text",
639 "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text",
644 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})")
647 "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text")
650 self
.assertEqual(0, len(self
.msg
))
652 def test_notpresent(self
):
653 self
.assertRaises(KeyError, lambda: self
.msg
["foo"])
659 self
.msg
.add(ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla"))
661 def test_add_text(self
):
662 self
.msg
.add(ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla"))
664 def test_elements_empty(self
):
665 self
.assertEqual([], self
.msg
.elements())
667 def test_elements(self
):
668 el
= ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla")
670 self
.assertEqual([el
], self
.msg
.elements())
671 self
.assertEqual([el
.text
], self
.msg
.text
.elements())
673 def test_add_value(self
):
674 self
.assertEqual(0, len(self
.msg
))
675 self
.msg
["foo"] = [b
"foo"]
676 self
.assertEqual(1, len(self
.msg
))
678 def test_add_value_text(self
):
679 self
.assertEqual(0, len(self
.msg
))
680 self
.msg
["foo"] = ["foo"]
681 self
.assertEqual(1, len(self
.msg
))
683 def test_add_value_multiple(self
):
684 self
.assertEqual(0, len(self
.msg
))
685 self
.msg
["foo"] = [b
"foo", b
"bla"]
686 self
.assertEqual(1, len(self
.msg
))
687 self
.assertEqual([b
"foo", b
"bla"], list(self
.msg
["foo"]))
689 def test_add_value_multiple_text(self
):
690 self
.assertEqual(0, len(self
.msg
))
691 self
.msg
["foo"] = ["foo", "bla"]
692 self
.assertEqual(1, len(self
.msg
))
693 self
.assertEqual(["foo", "bla"], list(self
.msg
.text
["foo"]))
695 def test_set_value(self
):
696 self
.msg
["foo"] = [b
"fool"]
697 self
.assertEqual([b
"fool"], list(self
.msg
["foo"]))
698 self
.msg
["foo"] = [b
"bar"]
699 self
.assertEqual([b
"bar"], list(self
.msg
["foo"]))
701 def test_set_value_text(self
):
702 self
.msg
["foo"] = ["fool"]
703 self
.assertEqual(["fool"], list(self
.msg
.text
["foo"]))
704 self
.msg
["foo"] = ["bar"]
705 self
.assertEqual(["bar"], list(self
.msg
.text
["foo"]))
708 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
709 self
.msg
["foo"] = [b
"bla"]
710 self
.msg
["bar"] = [b
"bla"]
711 self
.assertEqual(["dn", "foo", "bar"], self
.msg
.keys())
713 def test_keys_text(self
):
714 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
715 self
.msg
["foo"] = ["bla"]
716 self
.msg
["bar"] = ["bla"]
717 self
.assertEqual(["dn", "foo", "bar"], self
.msg
.text
.keys())
720 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
721 self
.assertEqual("@BASEINFO", self
.msg
.dn
.__str
__())
723 def test_get_dn(self
):
724 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
725 self
.assertEqual("@BASEINFO", self
.msg
.get("dn").__str
__())
727 def test_dn_text(self
):
728 self
.msg
.text
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
729 self
.assertEqual("@BASEINFO", str(self
.msg
.dn
))
730 self
.assertEqual("@BASEINFO", str(self
.msg
.text
.dn
))
732 def test_get_dn_text(self
):
733 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
734 self
.assertEqual("@BASEINFO", str(self
.msg
.get("dn")))
735 self
.assertEqual("@BASEINFO", str(self
.msg
.text
.get("dn")))
737 def test_get_invalid(self
):
738 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
739 self
.assertRaises(TypeError, self
.msg
.get
, 42)
741 def test_get_other(self
):
742 self
.msg
["foo"] = [b
"bar"]
743 self
.assertEqual(b
"bar", self
.msg
.get("foo")[0])
744 self
.assertEqual(b
"bar", self
.msg
.get("foo", idx
=0))
745 self
.assertEqual(None, self
.msg
.get("foo", idx
=1))
746 self
.assertEqual("", self
.msg
.get("foo", default
='', idx
=1))
748 def test_get_other_text(self
):
749 self
.msg
["foo"] = ["bar"]
750 self
.assertEqual(["bar"], list(self
.msg
.text
.get("foo")))
751 self
.assertEqual("bar", self
.msg
.text
.get("foo")[0])
752 self
.assertEqual("bar", self
.msg
.text
.get("foo", idx
=0))
753 self
.assertEqual(None, self
.msg
.get("foo", idx
=1))
754 self
.assertEqual("", self
.msg
.get("foo", default
='', idx
=1))
756 def test_get_default(self
):
757 self
.assertEqual(None, self
.msg
.get("tatayoyo", idx
=0))
758 self
.assertEqual("anniecordie", self
.msg
.get("tatayoyo", "anniecordie"))
760 def test_get_default_text(self
):
761 self
.assertEqual(None, self
.msg
.text
.get("tatayoyo", idx
=0))
762 self
.assertEqual("anniecordie", self
.msg
.text
.get("tatayoyo", "anniecordie"))
764 def test_get_unknown(self
):
765 self
.assertEqual(None, self
.msg
.get("lalalala"))
767 def test_get_unknown_text(self
):
768 self
.assertEqual(None, self
.msg
.text
.get("lalalala"))
770 def test_msg_diff(self
):
772 msgs
= l
.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n")
775 msgdiff
= l
.msg_diff(msg1
, msg2
)
776 self
.assertEqual("foo=bar", msgdiff
.get("dn").__str
__())
777 self
.assertRaises(KeyError, lambda: msgdiff
["foo"])
778 self
.assertEqual(1, len(msgdiff
))
780 def test_equal_empty(self
):
783 self
.assertEqual(msg1
, msg2
)
785 def test_equal_simplel(self
):
786 db
= ldb
.Ldb(filename())
788 msg1
.dn
= ldb
.Dn(db
, "foo=bar")
790 msg2
.dn
= ldb
.Dn(db
, "foo=bar")
791 self
.assertEqual(msg1
, msg2
)
794 self
.assertEqual(msg1
, msg2
)
795 msg2
['foo'] = b
'blie'
796 self
.assertNotEqual(msg1
, msg2
)
797 msg2
['foo'] = b
'blie'
799 def test_from_dict(self
):
800 rec
= {"dn": "dc=fromdict",
801 "a1": [b
"a1-val1", b
"a1-val1"]}
803 # check different types of input Flags
804 for flags
in [ldb
.FLAG_MOD_ADD
, ldb
.FLAG_MOD_REPLACE
, ldb
.FLAG_MOD_DELETE
]:
805 m
= ldb
.Message
.from_dict(l
, rec
, flags
)
806 self
.assertEqual(rec
["a1"], list(m
["a1"]))
807 self
.assertEqual(flags
, m
["a1"].flags())
809 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, dict(), rec
, ldb
.FLAG_MOD_REPLACE
)
810 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, l
, list(), ldb
.FLAG_MOD_REPLACE
)
811 self
.assertRaises(ValueError, ldb
.Message
.from_dict
, l
, rec
, 0)
812 # Message.from_dict expects dictionary with 'dn'
813 err_rec
= {"a1": [b
"a1-val1", b
"a1-val1"]}
814 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, l
, err_rec
, ldb
.FLAG_MOD_REPLACE
)
816 def test_from_dict_text(self
):
817 rec
= {"dn": "dc=fromdict",
818 "a1": ["a1-val1", "a1-val1"]}
820 # check different types of input Flags
821 for flags
in [ldb
.FLAG_MOD_ADD
, ldb
.FLAG_MOD_REPLACE
, ldb
.FLAG_MOD_DELETE
]:
822 m
= ldb
.Message
.from_dict(l
, rec
, flags
)
823 self
.assertEqual(rec
["a1"], list(m
.text
["a1"]))
824 self
.assertEqual(flags
, m
.text
["a1"].flags())
826 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, dict(), rec
, ldb
.FLAG_MOD_REPLACE
)
827 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, l
, list(), ldb
.FLAG_MOD_REPLACE
)
828 self
.assertRaises(ValueError, ldb
.Message
.from_dict
, l
, rec
, 0)
829 # Message.from_dict expects dictionary with 'dn'
830 err_rec
= {"a1": ["a1-val1", "a1-val1"]}
831 self
.assertRaises(TypeError, ldb
.Message
.from_dict
, l
, err_rec
, ldb
.FLAG_MOD_REPLACE
)
833 def test_copy_add_message_element(self
):
835 m
["1"] = ldb
.MessageElement([b
"val 111"], ldb
.FLAG_MOD_ADD
, "1")
836 m
["2"] = ldb
.MessageElement([b
"val 222"], ldb
.FLAG_MOD_ADD
, "2")
840 self
.assertEqual(mto
["1"], m
["1"])
841 self
.assertEqual(mto
["2"], m
["2"])
845 self
.assertEqual(mto
["1"], m
["1"])
846 self
.assertEqual(mto
["2"], m
["2"])
848 def test_copy_add_message_element_text(self
):
850 m
["1"] = ldb
.MessageElement(["val 111"], ldb
.FLAG_MOD_ADD
, "1")
851 m
["2"] = ldb
.MessageElement(["val 222"], ldb
.FLAG_MOD_ADD
, "2")
855 self
.assertEqual(mto
["1"], m
.text
["1"])
856 self
.assertEqual(mto
["2"], m
.text
["2"])
860 self
.assertEqual(mto
.text
["1"], m
.text
["1"])
861 self
.assertEqual(mto
.text
["2"], m
.text
["2"])
862 self
.assertEqual(mto
["1"], m
["1"])
863 self
.assertEqual(mto
["2"], m
["2"])
866 class MessageElementTests(TestCase
):
868 def test_cmp_element(self
):
869 x
= ldb
.MessageElement([b
"foo"])
870 y
= ldb
.MessageElement([b
"foo"])
871 z
= ldb
.MessageElement([b
"bzr"])
872 self
.assertEqual(x
, y
)
873 self
.assertNotEqual(x
, z
)
875 def test_cmp_element_text(self
):
876 x
= ldb
.MessageElement([b
"foo"])
877 y
= ldb
.MessageElement(["foo"])
878 self
.assertEqual(x
, y
)
880 def test_create_iterable(self
):
881 x
= ldb
.MessageElement([b
"foo"])
882 self
.assertEqual([b
"foo"], list(x
))
883 self
.assertEqual(["foo"], list(x
.text
))
886 x
= ldb
.MessageElement([b
"foo"])
888 self
.assertEqual("MessageElement([b'foo'])", repr(x
))
889 self
.assertEqual("MessageElement([b'foo']).text", repr(x
.text
))
891 self
.assertEqual("MessageElement(['foo'])", repr(x
))
892 self
.assertEqual("MessageElement(['foo']).text", repr(x
.text
))
893 x
= ldb
.MessageElement([b
"foo", b
"bla"])
894 self
.assertEqual(2, len(x
))
896 self
.assertEqual("MessageElement([b'foo',b'bla'])", repr(x
))
897 self
.assertEqual("MessageElement([b'foo',b'bla']).text", repr(x
.text
))
899 self
.assertEqual("MessageElement(['foo','bla'])", repr(x
))
900 self
.assertEqual("MessageElement(['foo','bla']).text", repr(x
.text
))
902 def test_get_item(self
):
903 x
= ldb
.MessageElement([b
"foo", b
"bar"])
904 self
.assertEqual(b
"foo", x
[0])
905 self
.assertEqual(b
"bar", x
[1])
906 self
.assertEqual(b
"bar", x
[-1])
907 self
.assertRaises(IndexError, lambda: x
[45])
909 def test_get_item_text(self
):
910 x
= ldb
.MessageElement(["foo", "bar"])
911 self
.assertEqual("foo", x
.text
[0])
912 self
.assertEqual("bar", x
.text
[1])
913 self
.assertEqual("bar", x
.text
[-1])
914 self
.assertRaises(IndexError, lambda: x
[45])
917 x
= ldb
.MessageElement([b
"foo", b
"bar"])
918 self
.assertEqual(2, len(x
))
921 x
= ldb
.MessageElement([b
"foo", b
"bar"])
922 y
= ldb
.MessageElement([b
"foo", b
"bar"])
923 self
.assertEqual(y
, x
)
924 x
= ldb
.MessageElement([b
"foo"])
925 self
.assertNotEqual(y
, x
)
926 y
= ldb
.MessageElement([b
"foo"])
927 self
.assertEqual(y
, x
)
929 def test_extended(self
):
930 el
= ldb
.MessageElement([b
"456"], ldb
.FLAG_MOD_ADD
, "bla")
932 self
.assertEqual("MessageElement([b'456'])", repr(el
))
933 self
.assertEqual("MessageElement([b'456']).text", repr(el
.text
))
935 self
.assertEqual("MessageElement(['456'])", repr(el
))
936 self
.assertEqual("MessageElement(['456']).text", repr(el
.text
))
938 def test_bad_text(self
):
939 el
= ldb
.MessageElement(b
'\xba\xdd')
940 self
.assertRaises(UnicodeDecodeError, el
.text
.__getitem
__, 0)
943 class ModuleTests(TestCase
):
945 def test_register_module(self
):
948 ldb
.register_module(ExampleModule
)
950 def test_use_module(self
):
955 def __init__(self
, ldb
, next
):
959 def search(self
, *args
, **kwargs
):
960 return self
.next
.search(*args
, **kwargs
)
962 def request(self
, *args
, **kwargs
):
966 ldb
.register_module(ExampleModule
)
967 if os
.path
.exists(name
):
970 l
.add({"dn": "@MODULES", "@LIST": "bla"})
971 self
.assertEqual([], ops
)
973 self
.assertEqual(["init"], ops
)
975 class LdbResultTests(TestCase
):
978 super(LdbResultTests
, self
).setUp()
981 if os
.path
.exists(name
):
983 self
.l
= ldb
.Ldb(name
)
984 self
.l
.add({"dn": "DC=SAMBA,DC=ORG", "name": b
"samba.org"})
985 self
.l
.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b
"Admins"})
986 self
.l
.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b
"Users"})
987 self
.l
.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b
"OU #1"})
988 self
.l
.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b
"OU #2"})
989 self
.l
.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b
"OU #3"})
990 self
.l
.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b
"OU #4"})
991 self
.l
.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b
"OU #5"})
992 self
.l
.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b
"OU #6"})
993 self
.l
.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b
"OU #7"})
994 self
.l
.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b
"OU #8"})
995 self
.l
.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b
"OU #9"})
996 self
.l
.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b
"OU #10"})
999 super(LdbResultTests
, self
).tearDown()
1000 if os
.path
.exists(self
.name
):
1001 os
.unlink(self
.name
)
1003 def test_return_type(self
):
1004 res
= self
.l
.search()
1005 self
.assertEqual(str(res
), "<ldb result>")
1007 def test_get_msgs(self
):
1008 res
= self
.l
.search()
1011 def test_get_controls(self
):
1012 res
= self
.l
.search()
1015 def test_get_referals(self
):
1016 res
= self
.l
.search()
1019 def test_iter_msgs(self
):
1021 for l
in self
.l
.search().msgs
:
1022 if str(l
.dn
) == "OU=OU10,DC=SAMBA,DC=ORG":
1024 self
.assertTrue(found
)
1026 def test_iter_msgs_count(self
):
1027 self
.assertTrue(self
.l
.search().count
> 0)
1028 # 13 objects has been added to the DC=SAMBA, DC=ORG
1029 self
.assertEqual(self
.l
.search(base
="DC=SAMBA,DC=ORG").count
, 13)
1031 def test_iter_controls(self
):
1032 res
= self
.l
.search().controls
1035 def test_create_control(self
):
1036 self
.assertRaises(ValueError, ldb
.Control
, self
.l
, "tatayoyo:0")
1037 c
= ldb
.Control(self
.l
, "relax:1")
1038 self
.assertEqual(c
.critical
, True)
1039 self
.assertEqual(c
.oid
, "1.3.6.1.4.1.4203.666.5.12")
1041 def test_iter_refs(self
):
1042 res
= self
.l
.search().referals
1045 def test_iter_as_sequence_msgs(self
):
1047 res
= self
.l
.search().msgs
1049 for i
in range(0, len(res
)):
1051 if str(l
.dn
) == "OU=OU10,DC=SAMBA,DC=ORG":
1053 self
.assertTrue(found
)
1055 def test_iter_as_sequence(self
):
1057 res
= self
.l
.search()
1059 for i
in range(0, len(res
)):
1061 if str(l
.dn
) == "OU=OU10,DC=SAMBA,DC=ORG":
1063 self
.assertTrue(found
)
1066 class BadTypeTests(TestCase
):
1067 def test_control(self
):
1069 self
.assertRaises(TypeError, ldb
.Control
, '<bad type>', 'relax:1')
1070 self
.assertRaises(TypeError, ldb
.Control
, ldb
, 1234)
1072 def test_modify(self
):
1074 dn
= ldb
.Dn(l
, 'a=b')
1076 self
.assertRaises(TypeError, l
.modify
, '<bad type>')
1077 self
.assertRaises(TypeError, l
.modify
, m
, '<bad type>')
1081 dn
= ldb
.Dn(l
, 'a=b')
1083 self
.assertRaises(TypeError, l
.add
, '<bad type>')
1084 self
.assertRaises(TypeError, l
.add
, m
, '<bad type>')
1086 def test_delete(self
):
1088 dn
= ldb
.Dn(l
, 'a=b')
1089 self
.assertRaises(TypeError, l
.add
, '<bad type>')
1090 self
.assertRaises(TypeError, l
.add
, dn
, '<bad type>')
1092 def test_rename(self
):
1094 dn
= ldb
.Dn(l
, 'a=b')
1095 self
.assertRaises(TypeError, l
.add
, '<bad type>', dn
)
1096 self
.assertRaises(TypeError, l
.add
, dn
, '<bad type>')
1097 self
.assertRaises(TypeError, l
.add
, dn
, dn
, '<bad type>')
1099 def test_search(self
):
1101 self
.assertRaises(TypeError, l
.search
, base
=1234)
1102 self
.assertRaises(TypeError, l
.search
, scope
='<bad type>')
1103 self
.assertRaises(TypeError, l
.search
, expression
=1234)
1104 self
.assertRaises(TypeError, l
.search
, attrs
='<bad type>')
1105 self
.assertRaises(TypeError, l
.search
, controls
='<bad type>')
1108 class VersionTests(TestCase
):
1110 def test_version(self
):
1111 self
.assertTrue(isinstance(ldb
.__version
__, str))
1114 if __name__
== '__main__':
1116 unittest
.TestProgram()