2 # Simple tests for the ldb python bindings.
3 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
8 # Required for the standalone LDB build
9 sys
.path
.append("build/lib.linux-i686-2.4")
16 class NoContextTests(unittest
.TestCase
):
18 def test_valid_attr_name(self
):
19 self
.assertTrue(ldb
.valid_attr_name("foo"))
20 self
.assertFalse(ldb
.valid_attr_name("24foo"))
22 def test_timestring(self
):
23 self
.assertEquals("19700101000000.0Z", ldb
.timestring(0))
24 self
.assertEquals("20071119191012.0Z", ldb
.timestring(1195499412))
26 def test_string_to_time(self
):
27 self
.assertEquals(0, ldb
.string_to_time("19700101000000.0Z"))
28 self
.assertEquals(1195499412, ldb
.string_to_time("20071119191012.0Z"))
31 class SimpleLdb(unittest
.TestCase
):
33 def test_connect(self
):
36 def test_connect_none(self
):
39 def test_connect_later(self
):
45 self
.assertTrue(repr(x
).startswith("<ldb connection"))
47 def test_set_create_perms(self
):
49 x
.set_create_perms(0600)
51 def test_set_modules_dir(self
):
53 x
.set_modules_dir("/tmp")
55 def test_modules_none(self
):
57 self
.assertEquals([], x
.modules())
59 def test_modules_tdb(self
):
60 x
= ldb
.Ldb("bar.ldb")
61 self
.assertEquals("[<ldb module 'tdb'>]", repr(x
.modules()))
63 def test_search(self
):
64 l
= ldb
.Ldb(filename())
65 self
.assertEquals(len(l
.search()), 1)
67 def test_search_controls(self
):
68 l
= ldb
.Ldb(filename())
69 self
.assertEquals(len(l
.search(controls
=["paged_results:0:5"])), 1)
71 def test_search_attrs(self
):
72 l
= ldb
.Ldb(filename())
73 self
.assertEquals(len(l
.search(ldb
.Dn(l
, ""), ldb
.SCOPE_SUBTREE
, "(dc=*)", ["dc"])), 0)
75 def test_search_string_dn(self
):
76 l
= ldb
.Ldb(filename())
77 self
.assertEquals(len(l
.search("", ldb
.SCOPE_SUBTREE
, "(dc=*)", ["dc"])), 0)
79 def test_search_attr_string(self
):
80 l
= ldb
.Ldb("foo.tdb")
81 self
.assertRaises(TypeError, l
.search
, attrs
="dc")
83 def test_opaque(self
):
84 l
= ldb
.Ldb(filename())
85 l
.set_opaque("my_opaque", l
)
86 self
.assertTrue(l
.get_opaque("my_opaque") is not None)
87 self
.assertEquals(None, l
.get_opaque("unknown"))
89 def test_search_scope_base(self
):
90 l
= ldb
.Ldb(filename())
91 self
.assertEquals(len(l
.search(ldb
.Dn(l
, "dc=foo1"),
92 ldb
.SCOPE_ONELEVEL
)), 0)
94 def test_delete(self
):
95 l
= ldb
.Ldb(filename())
96 self
.assertRaises(ldb
.LdbError
, lambda: l
.delete(ldb
.Dn(l
, "dc=foo2")))
98 def test_contains(self
):
99 l
= ldb
.Ldb(filename())
100 self
.assertFalse(ldb
.Dn(l
, "dc=foo3") in l
)
101 l
= ldb
.Ldb(filename())
103 m
.dn
= ldb
.Dn(l
, "dc=foo3")
107 self
.assertTrue(ldb
.Dn(l
, "dc=foo3") in l
)
111 def test_get_config_basedn(self
):
112 l
= ldb
.Ldb(filename())
113 self
.assertEquals(None, l
.get_config_basedn())
115 def test_get_root_basedn(self
):
116 l
= ldb
.Ldb(filename())
117 self
.assertEquals(None, l
.get_root_basedn())
119 def test_get_schema_basedn(self
):
120 l
= ldb
.Ldb(filename())
121 self
.assertEquals(None, l
.get_schema_basedn())
123 def test_get_default_basedn(self
):
124 l
= ldb
.Ldb(filename())
125 self
.assertEquals(None, l
.get_default_basedn())
128 l
= ldb
.Ldb(filename())
130 m
.dn
= ldb
.Dn(l
, "dc=foo4")
132 self
.assertEquals(len(l
.search()), 1)
135 self
.assertEquals(len(l
.search()), 2)
137 l
.delete(ldb
.Dn(l
, "dc=foo4"))
139 def test_add_dict(self
):
140 l
= ldb
.Ldb(filename())
141 m
= {"dn": ldb
.Dn(l
, "dc=foo5"),
143 self
.assertEquals(len(l
.search()), 1)
146 self
.assertEquals(len(l
.search()), 2)
148 l
.delete(ldb
.Dn(l
, "dc=foo5"))
150 def test_add_dict_string_dn(self
):
151 l
= ldb
.Ldb(filename())
152 m
= {"dn": "dc=foo6", "bla": "bla"}
153 self
.assertEquals(len(l
.search()), 1)
156 self
.assertEquals(len(l
.search()), 2)
158 l
.delete(ldb
.Dn(l
, "dc=foo6"))
160 def test_rename(self
):
161 l
= ldb
.Ldb(filename())
163 m
.dn
= ldb
.Dn(l
, "dc=foo7")
165 self
.assertEquals(len(l
.search()), 1)
168 l
.rename(ldb
.Dn(l
, "dc=foo7"), ldb
.Dn(l
, "dc=bar"))
169 self
.assertEquals(len(l
.search()), 2)
171 l
.delete(ldb
.Dn(l
, "dc=bar"))
173 def test_rename_string_dns(self
):
174 l
= ldb
.Ldb(filename())
176 m
.dn
= ldb
.Dn(l
, "dc=foo8")
178 self
.assertEquals(len(l
.search()), 1)
180 self
.assertEquals(len(l
.search()), 2)
182 l
.rename("dc=foo8", "dc=bar")
183 self
.assertEquals(len(l
.search()), 2)
185 l
.delete(ldb
.Dn(l
, "dc=bar"))
187 def test_modify_delete(self
):
188 l
= ldb
.Ldb(filename())
190 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
193 rm
= l
.search(m
.dn
)[0]
194 self
.assertEquals(["1234"], list(rm
["bla"]))
197 m
.dn
= ldb
.Dn(l
, "dc=modifydelete")
198 m
["bla"] = ldb
.MessageElement([], ldb
.FLAG_MOD_DELETE
, "bla")
199 self
.assertEquals(ldb
.FLAG_MOD_DELETE
, m
["bla"].flags())
201 rm
= l
.search(m
.dn
)[0]
202 self
.assertEquals(1, len(rm
))
203 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
204 self
.assertEquals(0, len(rm
))
206 l
.delete(ldb
.Dn(l
, "dc=modifydelete"))
208 def test_modify_add(self
):
209 l
= ldb
.Ldb(filename())
211 m
.dn
= ldb
.Dn(l
, "dc=add")
216 m
.dn
= ldb
.Dn(l
, "dc=add")
217 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
218 self
.assertEquals(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
220 rm
= l
.search(m
.dn
)[0]
221 self
.assertEquals(2, len(rm
))
222 self
.assertEquals(["1234", "456"], list(rm
["bla"]))
224 l
.delete(ldb
.Dn(l
, "dc=add"))
226 def test_modify_replace(self
):
227 l
= ldb
.Ldb(filename())
229 m
.dn
= ldb
.Dn(l
, "dc=modify2")
230 m
["bla"] = ["1234", "456"]
234 m
.dn
= ldb
.Dn(l
, "dc=modify2")
235 m
["bla"] = ldb
.MessageElement(["789"], ldb
.FLAG_MOD_REPLACE
, "bla")
236 self
.assertEquals(ldb
.FLAG_MOD_REPLACE
, m
["bla"].flags())
238 rm
= l
.search(m
.dn
)[0]
239 self
.assertEquals(2, len(rm
))
240 self
.assertEquals(["789"], list(rm
["bla"]))
241 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
242 self
.assertEquals(1, len(rm
))
244 l
.delete(ldb
.Dn(l
, "dc=modify2"))
246 def test_modify_flags_change(self
):
247 l
= ldb
.Ldb(filename())
249 m
.dn
= ldb
.Dn(l
, "dc=add")
254 m
.dn
= ldb
.Dn(l
, "dc=add")
255 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
256 self
.assertEquals(ldb
.FLAG_MOD_ADD
, m
["bla"].flags())
258 rm
= l
.search(m
.dn
)[0]
259 self
.assertEquals(2, len(rm
))
260 self
.assertEquals(["1234", "456"], list(rm
["bla"]))
262 #Now create another modify, but switch the flags before we do it
263 m
["bla"] = ldb
.MessageElement(["456"], ldb
.FLAG_MOD_ADD
, "bla")
264 m
["bla"].set_flags(ldb
.FLAG_MOD_DELETE
)
266 rm
= l
.search(m
.dn
, attrs
=["bla"])[0]
267 self
.assertEquals(1, len(rm
))
268 self
.assertEquals(["1234"], list(rm
["bla"]))
271 l
.delete(ldb
.Dn(l
, "dc=add"))
273 def test_transaction_commit(self
):
274 l
= ldb
.Ldb(filename())
275 l
.transaction_start()
276 m
= ldb
.Message(ldb
.Dn(l
, "dc=foo9"))
279 l
.transaction_commit()
282 def test_transaction_cancel(self
):
283 l
= ldb
.Ldb(filename())
284 l
.transaction_start()
285 m
= ldb
.Message(ldb
.Dn(l
, "dc=foo10"))
288 l
.transaction_cancel()
289 self
.assertEquals(0, len(l
.search(ldb
.Dn(l
, "dc=foo10"))))
291 def test_set_debug(self
):
292 def my_report_fn(level
, text
):
294 l
= ldb
.Ldb(filename())
295 l
.set_debug(my_report_fn
)
297 def test_zero_byte_string(self
):
298 """Testing we do not get trapped in the \0 byte in a property string."""
299 l
= ldb
.Ldb(filename())
302 "objectclass" : "user",
303 "cN" : "LDAPtestUSER",
304 "givenname" : "ldap",
305 "displayname" : "foo\0bar",
307 res
= l
.search(expression
="(dn=dc=somedn)")
308 self
.assertEquals("foo\0bar", res
[0]["displayname"][0])
311 class DnTests(unittest
.TestCase
):
314 self
.ldb
= ldb
.Ldb(filename())
316 def test_set_dn_invalid(self
):
320 self
.assertRaises(TypeError, assign
)
323 x
= ldb
.Dn(self
.ldb
, "dc=foo11,bar=bloe")
324 y
= ldb
.Dn(self
.ldb
, "dc=foo11,bar=bloe")
325 self
.assertEquals(x
, y
)
328 x
= ldb
.Dn(self
.ldb
, "dc=foo12,bar=bloe")
329 self
.assertEquals(x
.__str
__(), "dc=foo12,bar=bloe")
332 x
= ldb
.Dn(self
.ldb
, "dc=foo13,bla=blie")
333 self
.assertEquals(x
.__repr
__(), "Dn('dc=foo13,bla=blie')")
335 def test_get_casefold(self
):
336 x
= ldb
.Dn(self
.ldb
, "dc=foo14,bar=bloe")
337 self
.assertEquals(x
.get_casefold(), "DC=FOO14,BAR=bloe")
339 def test_validate(self
):
340 x
= ldb
.Dn(self
.ldb
, "dc=foo15,bar=bloe")
341 self
.assertTrue(x
.validate())
343 def test_parent(self
):
344 x
= ldb
.Dn(self
.ldb
, "dc=foo16,bar=bloe")
345 self
.assertEquals("bar=bloe", x
.parent().__str
__())
347 def test_parent_nonexistant(self
):
348 x
= ldb
.Dn(self
.ldb
, "@BLA")
349 self
.assertEquals(None, x
.parent())
351 def test_compare(self
):
352 x
= ldb
.Dn(self
.ldb
, "dc=foo17,bar=bloe")
353 y
= ldb
.Dn(self
.ldb
, "dc=foo17,bar=bloe")
354 self
.assertEquals(x
, y
)
355 z
= ldb
.Dn(self
.ldb
, "dc=foo17,bar=blie")
356 self
.assertNotEquals(z
, y
)
358 def test_is_valid(self
):
359 x
= ldb
.Dn(self
.ldb
, "dc=foo18,dc=bloe")
360 self
.assertTrue(x
.is_valid())
361 x
= ldb
.Dn(self
.ldb
, "")
362 # is_valid()'s return values appears to be a side effect of
363 # some other ldb functions. yuck.
364 # self.assertFalse(x.is_valid())
366 def test_is_special(self
):
367 x
= ldb
.Dn(self
.ldb
, "dc=foo19,bar=bloe")
368 self
.assertFalse(x
.is_special())
369 x
= ldb
.Dn(self
.ldb
, "@FOOBAR")
370 self
.assertTrue(x
.is_special())
372 def test_check_special(self
):
373 x
= ldb
.Dn(self
.ldb
, "dc=foo20,bar=bloe")
374 self
.assertFalse(x
.check_special("FOOBAR"))
375 x
= ldb
.Dn(self
.ldb
, "@FOOBAR")
376 self
.assertTrue(x
.check_special("@FOOBAR"))
379 x
= ldb
.Dn(self
.ldb
, "dc=foo21,bar=bloe")
380 self
.assertEquals(2, len(x
))
381 x
= ldb
.Dn(self
.ldb
, "dc=foo21")
382 self
.assertEquals(1, len(x
))
384 def test_add_child(self
):
385 x
= ldb
.Dn(self
.ldb
, "dc=foo22,bar=bloe")
386 self
.assertTrue(x
.add_child(ldb
.Dn(self
.ldb
, "bla=bloe")))
387 self
.assertEquals("bla=bloe,dc=foo22,bar=bloe", x
.__str
__())
389 def test_add_base(self
):
390 x
= ldb
.Dn(self
.ldb
, "dc=foo23,bar=bloe")
391 base
= ldb
.Dn(self
.ldb
, "bla=bloe")
392 self
.assertTrue(x
.add_base(base
))
393 self
.assertEquals("dc=foo23,bar=bloe,bla=bloe", x
.__str
__())
396 x
= ldb
.Dn(self
.ldb
, "dc=foo24")
397 y
= ldb
.Dn(self
.ldb
, "bar=bla")
398 self
.assertEquals("dc=foo24,bar=bla", str(y
+ x
))
400 def test_parse_ldif(self
):
401 msgs
= self
.ldb
.parse_ldif("dn: foo=bar\n")
403 self
.assertEquals("foo=bar", str(msg
[1].dn
))
404 self
.assertTrue(isinstance(msg
[1], ldb
.Message
))
406 def test_parse_ldif_more(self
):
407 msgs
= self
.ldb
.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar")
409 self
.assertEquals("foo=bar", str(msg
[1].dn
))
411 self
.assertEquals("bar=bar", str(msg
[1].dn
))
413 def test_canonical_string(self
):
414 x
= ldb
.Dn(self
.ldb
, "dc=foo25,bar=bloe")
415 self
.assertEquals("/bloe/foo25", x
.canonical_str())
417 def test_canonical_ex_string(self
):
418 x
= ldb
.Dn(self
.ldb
, "dc=foo26,bar=bloe")
419 self
.assertEquals("/bloe\nfoo26", x
.canonical_ex_str())
422 class LdbMsgTests(unittest
.TestCase
):
425 self
.msg
= ldb
.Message()
427 def test_init_dn(self
):
428 self
.msg
= ldb
.Message(ldb
.Dn(ldb
.Ldb(), "dc=foo27"))
429 self
.assertEquals("dc=foo27", str(self
.msg
.dn
))
431 def test_iter_items(self
):
432 self
.assertEquals(0, len(self
.msg
.items()))
433 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb("foo.tdb"), "dc=foo28")
434 self
.assertEquals(1, len(self
.msg
.items()))
437 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb("foo.tdb"), "dc=foo29")
438 self
.msg
["dc"] = "foo"
439 self
.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self
.msg
))
442 self
.assertEquals(0, len(self
.msg
))
444 def test_notpresent(self
):
445 self
.assertRaises(KeyError, lambda: self
.msg
["foo"])
450 def test_add_value(self
):
451 self
.assertEquals(0, len(self
.msg
))
452 self
.msg
["foo"] = ["foo"]
453 self
.assertEquals(1, len(self
.msg
))
455 def test_add_value_multiple(self
):
456 self
.assertEquals(0, len(self
.msg
))
457 self
.msg
["foo"] = ["foo", "bla"]
458 self
.assertEquals(1, len(self
.msg
))
459 self
.assertEquals(["foo", "bla"], list(self
.msg
["foo"]))
461 def test_set_value(self
):
462 self
.msg
["foo"] = ["fool"]
463 self
.assertEquals(["fool"], list(self
.msg
["foo"]))
464 self
.msg
["foo"] = ["bar"]
465 self
.assertEquals(["bar"], list(self
.msg
["foo"]))
468 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb("foo.tdb"), "@BASEINFO")
469 self
.msg
["foo"] = ["bla"]
470 self
.msg
["bar"] = ["bla"]
471 self
.assertEquals(["dn", "foo", "bar"], self
.msg
.keys())
474 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb(filename()), "@BASEINFO")
475 self
.assertEquals("@BASEINFO", self
.msg
.dn
.__str
__())
477 def test_get_dn(self
):
478 self
.msg
.dn
= ldb
.Dn(ldb
.Ldb("foo.tdb"), "@BASEINFO")
479 self
.assertEquals("@BASEINFO", self
.msg
.get("dn").__str
__())
481 def test_get_other(self
):
482 self
.msg
["foo"] = ["bar"]
483 self
.assertEquals("bar", self
.msg
.get("foo")[0])
485 def test_get_unknown(self
):
486 self
.assertEquals(None, self
.msg
.get("lalalala"))
488 def test_msg_diff(self
):
490 msgs
= l
.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n")
491 msg1
= msgs
.next()[1]
492 msg2
= msgs
.next()[1]
493 msgdiff
= l
.msg_diff(msg1
, msg2
)
494 self
.assertEquals("foo=bar", msgdiff
.get("dn").__str
__())
495 self
.assertRaises(KeyError, lambda: msgdiff
["foo"])
496 self
.assertEquals(1, len(msgdiff
))
500 class MessageElementTests(unittest
.TestCase
):
502 def test_cmp_element(self
):
503 x
= ldb
.MessageElement(["foo"])
504 y
= ldb
.MessageElement(["foo"])
505 z
= ldb
.MessageElement(["bzr"])
506 self
.assertEquals(x
, y
)
507 self
.assertNotEquals(x
, z
)
509 def test_create_iterable(self
):
510 x
= ldb
.MessageElement(["foo"])
511 self
.assertEquals(["foo"], list(x
))
514 x
= ldb
.MessageElement(["foo"])
515 self
.assertEquals("MessageElement(['foo'])", repr(x
))
516 x
= ldb
.MessageElement(["foo", "bla"])
517 self
.assertEquals(2, len(x
))
518 self
.assertEquals("MessageElement(['foo','bla'])", repr(x
))
520 def test_get_item(self
):
521 x
= ldb
.MessageElement(["foo", "bar"])
522 self
.assertEquals("foo", x
[0])
523 self
.assertEquals("bar", x
[1])
524 self
.assertEquals("bar", x
[-1])
525 self
.assertRaises(IndexError, lambda: x
[45])
528 x
= ldb
.MessageElement(["foo", "bar"])
529 self
.assertEquals(2, len(x
))
532 x
= ldb
.MessageElement(["foo", "bar"])
533 y
= ldb
.MessageElement(["foo", "bar"])
534 self
.assertEquals(y
, x
)
535 x
= ldb
.MessageElement(["foo"])
536 self
.assertNotEquals(y
, x
)
537 y
= ldb
.MessageElement(["foo"])
538 self
.assertEquals(y
, x
)
541 class ModuleTests(unittest
.TestCase
):
543 def test_register_module(self
):
546 ldb
.register_module(ExampleModule
)
548 def test_use_module(self
):
553 def __init__(self
, ldb
, next
):
557 def search(self
, *args
, **kwargs
):
558 return self
.next
.search(*args
, **kwargs
)
560 ldb
.register_module(ExampleModule
)
561 if os
.path
.exists("usemodule.ldb"):
562 os
.unlink("usemodule.ldb")
563 l
= ldb
.Ldb("usemodule.ldb")
564 l
.add({"dn": "@MODULES", "@LIST": "bla"})
565 self
.assertEquals([], ops
)
566 l
= ldb
.Ldb("usemodule.ldb")
567 self
.assertEquals(["init"], ops
)
570 if __name__
== '__main__':
572 unittest
.TestProgram()