Add missing dependencies for com_err.
[mat/samba.git] / source4 / lib / ldb / tests / python / api.py
1 #!/usr/bin/env python
2 # Simple tests for the ldb python bindings.
3 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
4
5 import os
6 import unittest
7
8 import ldb
9
10
11 def filename():
12     return os.tempnam()
13
14 class NoContextTests(unittest.TestCase):
15
16     def test_valid_attr_name(self):
17         self.assertTrue(ldb.valid_attr_name("foo"))
18         self.assertFalse(ldb.valid_attr_name("24foo"))
19
20     def test_timestring(self):
21         self.assertEquals("19700101000000.0Z", ldb.timestring(0))
22         self.assertEquals("20071119191012.0Z", ldb.timestring(1195499412))
23
24     def test_string_to_time(self):
25         self.assertEquals(0, ldb.string_to_time("19700101000000.0Z"))
26         self.assertEquals(1195499412, ldb.string_to_time("20071119191012.0Z"))
27
28
29 class SimpleLdb(unittest.TestCase):
30
31     def test_connect(self):
32         ldb.Ldb(filename())
33
34     def test_connect_none(self):
35         ldb.Ldb()
36
37     def test_connect_later(self):
38         x = ldb.Ldb()
39         x.connect(filename())
40
41     def test_repr(self):
42         x = ldb.Ldb()
43         self.assertTrue(repr(x).startswith("<ldb connection"))
44
45     def test_set_create_perms(self):
46         x = ldb.Ldb()
47         x.set_create_perms(0600)
48
49     def test_set_modules_dir(self):
50         x = ldb.Ldb()
51         x.set_modules_dir("/tmp")
52
53     def test_modules_none(self):
54         x = ldb.Ldb()
55         self.assertEquals([], x.modules())
56
57     def test_modules_tdb(self):
58         x = ldb.Ldb("bar.ldb")
59         self.assertEquals("[<ldb module 'tdb'>]", repr(x.modules()))
60
61     def test_search(self):
62         l = ldb.Ldb(filename())
63         self.assertEquals(len(l.search()), 1)
64
65     def test_search_controls(self):
66         l = ldb.Ldb(filename())
67         self.assertEquals(len(l.search(controls=["paged_results:0:5"])), 1)
68
69     def test_search_attrs(self):
70         l = ldb.Ldb(filename())
71         self.assertEquals(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
72
73     def test_search_string_dn(self):
74         l = ldb.Ldb(filename())
75         self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
76
77     def test_search_attr_string(self):
78         l = ldb.Ldb("foo.tdb")
79         self.assertRaises(TypeError, l.search, attrs="dc")
80
81     def test_opaque(self):
82         l = ldb.Ldb(filename())
83         l.set_opaque("my_opaque", l)
84         self.assertTrue(l.get_opaque("my_opaque") is not None)
85         self.assertEquals(None, l.get_opaque("unknown"))
86
87     def test_search_scope_base(self):
88         l = ldb.Ldb(filename())
89         self.assertEquals(len(l.search(ldb.Dn(l, "dc=foo1"), 
90                           ldb.SCOPE_ONELEVEL)), 0)
91
92     def test_delete(self):
93         l = ldb.Ldb(filename())
94         self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2")))
95
96     def test_delete_w_unhandled_ctrl(self):
97         l = ldb.Ldb(filename())
98         m = ldb.Message()
99         m.dn = ldb.Dn(l, "dc=foo1")
100         m["b"] = ["a"]
101         l.add(m)
102         self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"]))
103         l.delete(m.dn)
104
105     def test_contains(self):
106         l = ldb.Ldb(filename())
107         self.assertFalse(ldb.Dn(l, "dc=foo3") in l)
108         l = ldb.Ldb(filename())
109         m = ldb.Message()
110         m.dn = ldb.Dn(l, "dc=foo3")
111         m["b"] = ["a"]
112         l.add(m)
113         try:
114             self.assertTrue(ldb.Dn(l, "dc=foo3") in l)
115         finally:
116             l.delete(m.dn)
117
118     def test_get_config_basedn(self):
119         l = ldb.Ldb(filename())
120         self.assertEquals(None, l.get_config_basedn())
121
122     def test_get_root_basedn(self):
123         l = ldb.Ldb(filename())
124         self.assertEquals(None, l.get_root_basedn())
125
126     def test_get_schema_basedn(self):
127         l = ldb.Ldb(filename())
128         self.assertEquals(None, l.get_schema_basedn())
129
130     def test_get_default_basedn(self):
131         l = ldb.Ldb(filename())
132         self.assertEquals(None, l.get_default_basedn())
133
134     def test_add(self):
135         l = ldb.Ldb(filename())
136         m = ldb.Message()
137         m.dn = ldb.Dn(l, "dc=foo4")
138         m["bla"] = "bla"
139         self.assertEquals(len(l.search()), 1)
140         l.add(m)
141         try:
142             self.assertEquals(len(l.search()), 2)
143         finally:
144             l.delete(ldb.Dn(l, "dc=foo4"))
145
146     def test_add_w_unhandled_ctrl(self):
147         l = ldb.Ldb(filename())
148         m = ldb.Message()
149         m.dn = ldb.Dn(l, "dc=foo4")
150         m["bla"] = "bla"
151         self.assertEquals(len(l.search()), 1)
152         self.assertRaises(ldb.LdbError, lambda: l.add(m,["search_options:1:2"]))
153
154     def test_add_dict(self):
155         l = ldb.Ldb(filename())
156         m = {"dn": ldb.Dn(l, "dc=foo5"),
157              "bla": "bla"}
158         self.assertEquals(len(l.search()), 1)
159         l.add(m)
160         try:
161             self.assertEquals(len(l.search()), 2)
162         finally:
163             l.delete(ldb.Dn(l, "dc=foo5"))
164
165     def test_add_dict_string_dn(self):
166         l = ldb.Ldb(filename())
167         m = {"dn": "dc=foo6", "bla": "bla"}
168         self.assertEquals(len(l.search()), 1)
169         l.add(m)
170         try:
171             self.assertEquals(len(l.search()), 2)
172         finally:
173             l.delete(ldb.Dn(l, "dc=foo6"))
174
175     def test_rename(self):
176         l = ldb.Ldb(filename())
177         m = ldb.Message()
178         m.dn = ldb.Dn(l, "dc=foo7")
179         m["bla"] = "bla"
180         self.assertEquals(len(l.search()), 1)
181         l.add(m)
182         try:
183             l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar"))
184             self.assertEquals(len(l.search()), 2)
185         finally:
186             l.delete(ldb.Dn(l, "dc=bar"))
187
188     def test_rename_string_dns(self):
189         l = ldb.Ldb(filename())
190         m = ldb.Message()
191         m.dn = ldb.Dn(l, "dc=foo8")
192         m["bla"] = "bla"
193         self.assertEquals(len(l.search()), 1)
194         l.add(m)
195         self.assertEquals(len(l.search()), 2)
196         try:
197             l.rename("dc=foo8", "dc=bar")
198             self.assertEquals(len(l.search()), 2)
199         finally:
200             l.delete(ldb.Dn(l, "dc=bar"))
201
202     def test_modify_delete(self):
203         l = ldb.Ldb(filename())
204         m = ldb.Message()
205         m.dn = ldb.Dn(l, "dc=modifydelete")
206         m["bla"] = ["1234"]
207         l.add(m)
208         rm = l.search(m.dn)[0]
209         self.assertEquals(["1234"], list(rm["bla"]))
210         try:
211             m = ldb.Message()
212             m.dn = ldb.Dn(l, "dc=modifydelete")
213             m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla")
214             self.assertEquals(ldb.FLAG_MOD_DELETE, m["bla"].flags())
215             l.modify(m)
216             rm = l.search(m.dn)[0]
217             self.assertEquals(1, len(rm))
218             rm = l.search(m.dn, attrs=["bla"])[0]
219             self.assertEquals(0, len(rm))
220         finally:
221             l.delete(ldb.Dn(l, "dc=modifydelete"))
222
223     def test_modify_add(self):
224         l = ldb.Ldb(filename())
225         m = ldb.Message()
226         m.dn = ldb.Dn(l, "dc=add")
227         m["bla"] = ["1234"]
228         l.add(m)
229         try:
230             m = ldb.Message()
231             m.dn = ldb.Dn(l, "dc=add")
232             m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
233             self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags())
234             l.modify(m)
235             rm = l.search(m.dn)[0]
236             self.assertEquals(2, len(rm))
237             self.assertEquals(["1234", "456"], list(rm["bla"]))
238         finally:
239             l.delete(ldb.Dn(l, "dc=add"))
240
241     def test_modify_replace(self):
242         l = ldb.Ldb(filename())
243         m = ldb.Message()
244         m.dn = ldb.Dn(l, "dc=modify2")
245         m["bla"] = ["1234", "456"]
246         l.add(m)
247         try:
248             m = ldb.Message()
249             m.dn = ldb.Dn(l, "dc=modify2")
250             m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla")
251             self.assertEquals(ldb.FLAG_MOD_REPLACE, m["bla"].flags())
252             l.modify(m)
253             rm = l.search(m.dn)[0]
254             self.assertEquals(2, len(rm))
255             self.assertEquals(["789"], list(rm["bla"]))
256             rm = l.search(m.dn, attrs=["bla"])[0]
257             self.assertEquals(1, len(rm))
258         finally:
259             l.delete(ldb.Dn(l, "dc=modify2"))
260
261     def test_modify_flags_change(self):
262         l = ldb.Ldb(filename())
263         m = ldb.Message()
264         m.dn = ldb.Dn(l, "dc=add")
265         m["bla"] = ["1234"]
266         l.add(m)
267         try:
268             m = ldb.Message()
269             m.dn = ldb.Dn(l, "dc=add")
270             m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
271             self.assertEquals(ldb.FLAG_MOD_ADD, m["bla"].flags())
272             l.modify(m)
273             rm = l.search(m.dn)[0]
274             self.assertEquals(2, len(rm))
275             self.assertEquals(["1234", "456"], list(rm["bla"]))
276             
277             #Now create another modify, but switch the flags before we do it
278             m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")
279             m["bla"].set_flags(ldb.FLAG_MOD_DELETE)
280             l.modify(m)
281             rm = l.search(m.dn, attrs=["bla"])[0]
282             self.assertEquals(1, len(rm))
283             self.assertEquals(["1234"], list(rm["bla"]))
284             
285         finally:
286             l.delete(ldb.Dn(l, "dc=add"))
287
288     def test_transaction_commit(self):
289         l = ldb.Ldb(filename())
290         l.transaction_start()
291         m = ldb.Message(ldb.Dn(l, "dc=foo9"))
292         m["foo"] = ["bar"]
293         l.add(m)
294         l.transaction_commit()
295         l.delete(m.dn)
296
297     def test_transaction_cancel(self):
298         l = ldb.Ldb(filename())
299         l.transaction_start()
300         m = ldb.Message(ldb.Dn(l, "dc=foo10"))
301         m["foo"] = ["bar"]
302         l.add(m)
303         l.transaction_cancel()
304         self.assertEquals(0, len(l.search(ldb.Dn(l, "dc=foo10"))))
305
306     def test_set_debug(self):
307         def my_report_fn(level, text):
308             pass
309         l = ldb.Ldb(filename())
310         l.set_debug(my_report_fn)
311
312     def test_zero_byte_string(self):
313         """Testing we do not get trapped in the \0 byte in a property string."""
314         l = ldb.Ldb(filename())
315         l.add({
316             "dn" : "dc=somedn",
317             "objectclass" : "user",
318             "cN" : "LDAPtestUSER",
319             "givenname" : "ldap",
320             "displayname" : "foo\0bar",
321         })
322         res = l.search(expression="(dn=dc=somedn)")
323         self.assertEquals("foo\0bar", res[0]["displayname"][0])
324
325     def test_no_crash_broken_expr(self):
326         l = ldb.Ldb(filename())
327         self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"]))
328
329
330 class DnTests(unittest.TestCase):
331
332     def setUp(self):
333         self.ldb = ldb.Ldb(filename())
334
335     def test_set_dn_invalid(self):
336         x = ldb.Message()
337         def assign():
338             x.dn = "astring"
339         self.assertRaises(TypeError, assign)
340
341     def test_eq(self):
342         x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe")
343         y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe")
344         self.assertEquals(x, y)
345
346     def test_str(self):
347         x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe")
348         self.assertEquals(x.__str__(), "dc=foo12,bar=bloe")
349
350     def test_repr(self):
351         x = ldb.Dn(self.ldb, "dc=foo13,bla=blie")
352         self.assertEquals(x.__repr__(), "Dn('dc=foo13,bla=blie')")
353
354     def test_get_casefold(self):
355         x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe")
356         self.assertEquals(x.get_casefold(), "DC=FOO14,BAR=bloe")
357
358     def test_validate(self):
359         x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe")
360         self.assertTrue(x.validate())
361
362     def test_parent(self):
363         x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe")
364         self.assertEquals("bar=bloe", x.parent().__str__())
365
366     def test_parent_nonexistant(self):
367         x = ldb.Dn(self.ldb, "@BLA")
368         self.assertEquals(None, x.parent())
369
370     def test_compare(self):
371         x = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
372         y = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")
373         self.assertEquals(x, y)
374         z = ldb.Dn(self.ldb, "dc=foo17,bar=blie")
375         self.assertNotEquals(z, y)
376
377     def test_is_valid(self):
378         x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe")
379         self.assertTrue(x.is_valid())
380         x = ldb.Dn(self.ldb, "")
381         # is_valid()'s return values appears to be a side effect of 
382         # some other ldb functions. yuck.
383         # self.assertFalse(x.is_valid())
384
385     def test_is_special(self):
386         x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe")
387         self.assertFalse(x.is_special())
388         x = ldb.Dn(self.ldb, "@FOOBAR")
389         self.assertTrue(x.is_special())
390
391     def test_check_special(self):
392         x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe")
393         self.assertFalse(x.check_special("FOOBAR"))
394         x = ldb.Dn(self.ldb, "@FOOBAR")
395         self.assertTrue(x.check_special("@FOOBAR"))
396
397     def test_len(self):
398         x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe")
399         self.assertEquals(2, len(x))
400         x = ldb.Dn(self.ldb, "dc=foo21")
401         self.assertEquals(1, len(x))
402
403     def test_add_child(self):
404         x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe")
405         self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe")))
406         self.assertEquals("bla=bloe,dc=foo22,bar=bloe", x.__str__())
407
408     def test_add_base(self):
409         x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe")
410         base = ldb.Dn(self.ldb, "bla=bloe")
411         self.assertTrue(x.add_base(base))
412         self.assertEquals("dc=foo23,bar=bloe,bla=bloe", x.__str__())
413
414     def test_add(self):
415         x = ldb.Dn(self.ldb, "dc=foo24")
416         y = ldb.Dn(self.ldb, "bar=bla")
417         self.assertEquals("dc=foo24,bar=bla", str(y + x))
418
419     def test_parse_ldif(self):
420         msgs = self.ldb.parse_ldif("dn: foo=bar\n")
421         msg = msgs.next()
422         self.assertEquals("foo=bar", str(msg[1].dn))
423         self.assertTrue(isinstance(msg[1], ldb.Message))
424         ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE)
425         self.assertEquals("dn: foo=bar\n\n", ldif)
426         
427     def test_parse_ldif_more(self):
428         msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar")
429         msg = msgs.next()
430         self.assertEquals("foo=bar", str(msg[1].dn))
431         msg = msgs.next()
432         self.assertEquals("bar=bar", str(msg[1].dn))
433
434     def test_canonical_string(self):
435         x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe")
436         self.assertEquals("/bloe/foo25", x.canonical_str())
437
438     def test_canonical_ex_string(self):
439         x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe")
440         self.assertEquals("/bloe\nfoo26", x.canonical_ex_str())
441
442
443 class LdbMsgTests(unittest.TestCase):
444
445     def setUp(self):
446         self.msg = ldb.Message()
447
448     def test_init_dn(self):
449         self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27"))
450         self.assertEquals("dc=foo27", str(self.msg.dn))
451
452     def test_iter_items(self):
453         self.assertEquals(0, len(self.msg.items()))
454         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo28")
455         self.assertEquals(1, len(self.msg.items()))
456
457     def test_repr(self):
458         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo29")
459         self.msg["dc"] = "foo"
460         self.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self.msg))
461
462     def test_len(self):
463         self.assertEquals(0, len(self.msg))
464
465     def test_notpresent(self):
466         self.assertRaises(KeyError, lambda: self.msg["foo"])
467
468     def test_del(self):
469         del self.msg["foo"]
470
471     def test_add_value(self):
472         self.assertEquals(0, len(self.msg))
473         self.msg["foo"] = ["foo"]
474         self.assertEquals(1, len(self.msg))
475
476     def test_add_value_multiple(self):
477         self.assertEquals(0, len(self.msg))
478         self.msg["foo"] = ["foo", "bla"]
479         self.assertEquals(1, len(self.msg))
480         self.assertEquals(["foo", "bla"], list(self.msg["foo"]))
481
482     def test_set_value(self):
483         self.msg["foo"] = ["fool"]
484         self.assertEquals(["fool"], list(self.msg["foo"]))
485         self.msg["foo"] = ["bar"]
486         self.assertEquals(["bar"], list(self.msg["foo"]))
487
488     def test_keys(self):
489         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
490         self.msg["foo"] = ["bla"]
491         self.msg["bar"] = ["bla"]
492         self.assertEquals(["dn", "foo", "bar"], self.msg.keys())
493
494     def test_dn(self):
495         self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO")
496         self.assertEquals("@BASEINFO", self.msg.dn.__str__())
497
498     def test_get_dn(self):
499         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
500         self.assertEquals("@BASEINFO", self.msg.get("dn").__str__())
501
502     def test_get_invalid(self):
503         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
504         self.assertRaises(TypeError, self.msg.get, 42)
505
506     def test_get_other(self):
507         self.msg["foo"] = ["bar"]
508         self.assertEquals("bar", self.msg.get("foo")[0])
509
510     def test_get_unknown(self):
511         self.assertEquals(None, self.msg.get("lalalala"))
512
513     def test_msg_diff(self):
514         l = ldb.Ldb()
515         msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n")
516         msg1 = msgs.next()[1]
517         msg2 = msgs.next()[1]
518         msgdiff = l.msg_diff(msg1, msg2)
519         self.assertEquals("foo=bar", msgdiff.get("dn").__str__())
520         self.assertRaises(KeyError, lambda: msgdiff["foo"])
521         self.assertEquals(1, len(msgdiff))
522
523     def test_equal_empty(self):
524         msg1 = ldb.Message()
525         msg2 = ldb.Message()
526         self.assertEquals(msg1, msg2)
527
528     def test_equal_simplel(self):
529         db = ldb.Ldb("foo.tdb")
530         msg1 = ldb.Message()
531         msg1.dn = ldb.Dn(db, "foo=bar")
532         msg2 = ldb.Message()
533         msg2.dn = ldb.Dn(db, "foo=bar")
534         self.assertEquals(msg1, msg2)
535         msg1['foo'] = 'bar'
536         msg2['foo'] = 'bar'
537         self.assertEquals(msg1, msg2)
538         msg2['foo'] = 'blie'
539         self.assertNotEquals(msg1, msg2)
540         msg2['foo'] = 'blie'
541
542
543
544 class MessageElementTests(unittest.TestCase):
545
546     def test_cmp_element(self):
547         x = ldb.MessageElement(["foo"])
548         y = ldb.MessageElement(["foo"])
549         z = ldb.MessageElement(["bzr"])
550         self.assertEquals(x, y)
551         self.assertNotEquals(x, z)
552
553     def test_create_iterable(self):
554         x = ldb.MessageElement(["foo"])
555         self.assertEquals(["foo"], list(x))
556
557     def test_repr(self):
558         x = ldb.MessageElement(["foo"])
559         self.assertEquals("MessageElement(['foo'])", repr(x))
560         x = ldb.MessageElement(["foo", "bla"])
561         self.assertEquals(2, len(x))
562         self.assertEquals("MessageElement(['foo','bla'])", repr(x))
563
564     def test_get_item(self):
565         x = ldb.MessageElement(["foo", "bar"])
566         self.assertEquals("foo", x[0])
567         self.assertEquals("bar", x[1])
568         self.assertEquals("bar", x[-1])
569         self.assertRaises(IndexError, lambda: x[45])
570
571     def test_len(self):
572         x = ldb.MessageElement(["foo", "bar"])
573         self.assertEquals(2, len(x))
574
575     def test_eq(self):
576         x = ldb.MessageElement(["foo", "bar"])
577         y = ldb.MessageElement(["foo", "bar"])
578         self.assertEquals(y, x)
579         x = ldb.MessageElement(["foo"])
580         self.assertNotEquals(y, x)
581         y = ldb.MessageElement(["foo"])
582         self.assertEquals(y, x)
583
584
585 class ModuleTests(unittest.TestCase):
586
587     def test_register_module(self):
588         class ExampleModule:
589             name = "example"
590         ldb.register_module(ExampleModule)
591
592     def test_use_module(self):
593         ops = []
594         class ExampleModule:
595             name = "bla"
596
597             def __init__(self, ldb, next):
598                 ops.append("init")
599                 self.next = next
600
601             def search(self, *args, **kwargs):
602                 return self.next.search(*args, **kwargs)
603
604         ldb.register_module(ExampleModule)
605         if os.path.exists("usemodule.ldb"):
606             os.unlink("usemodule.ldb")
607         l = ldb.Ldb("usemodule.ldb")
608         l.add({"dn": "@MODULES", "@LIST": "bla"})
609         self.assertEquals([], ops)
610         l = ldb.Ldb("usemodule.ldb")
611         self.assertEquals(["init"], ops)
612
613
614 class VersionTests(unittest.TestCase):
615
616     def test_version(self):
617         self.assertTrue(isinstance(ldb.__version__, str))
618
619
620 if __name__ == '__main__':
621     import unittest
622     unittest.TestProgram()