PEP8: fix E226: missing whitespace around arithmetic operator
[nivanova/samba-autobuild/.git] / source4 / dsdb / tests / python / deletetest.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from __future__ import print_function
5 import optparse
6 import sys
7 import os
8
9 sys.path.insert(0, "bin/python")
10 import samba
11
12 from samba.tests.subunitrun import SubunitOptions, TestProgram
13
14 import samba.getopt as options
15
16 from samba.auth import system_session
17 from ldb import SCOPE_BASE, LdbError, Message, MessageElement, Dn, FLAG_MOD_ADD, FLAG_MOD_DELETE, FLAG_MOD_REPLACE
18 from ldb import ERR_NO_SUCH_OBJECT, ERR_NOT_ALLOWED_ON_NON_LEAF, ERR_ENTRY_ALREADY_EXISTS, ERR_ATTRIBUTE_OR_VALUE_EXISTS
19 from ldb import ERR_UNWILLING_TO_PERFORM, ERR_OPERATIONS_ERROR
20 from samba.samdb import SamDB
21 from samba.tests import delete_force
22 from samba import dsdb
23
24 parser = optparse.OptionParser("deletetest.py [options] <host|file>")
25 sambaopts = options.SambaOptions(parser)
26 parser.add_option_group(sambaopts)
27 parser.add_option_group(options.VersionOptions(parser))
28 # use command line creds if available
29 credopts = options.CredentialsOptions(parser)
30 parser.add_option_group(credopts)
31 subunitopts = SubunitOptions(parser)
32 parser.add_option_group(subunitopts)
33 opts, args = parser.parse_args()
34
35 if len(args) < 1:
36     parser.print_usage()
37     sys.exit(1)
38
39 host = args[0]
40
41 lp = sambaopts.get_loadparm()
42 creds = credopts.get_credentials(lp)
43
44 class BaseDeleteTests(samba.tests.TestCase):
45
46     def GUID_string(self, guid):
47         return self.ldb.schema_format_value("objectGUID", guid)
48
49     def setUp(self):
50         super(BaseDeleteTests, self).setUp()
51         self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp)
52
53         self.base_dn = self.ldb.domain_dn()
54         self.configuration_dn = self.ldb.get_config_basedn().get_linearized()
55
56     def search_guid(self, guid):
57         print("SEARCH by GUID %s" % self.GUID_string(guid))
58
59         res = self.ldb.search(base="<GUID=%s>" % self.GUID_string(guid),
60                               scope=SCOPE_BASE,
61                               controls=["show_deleted:1"],
62                               attrs=["*", "parentGUID"])
63         self.assertEquals(len(res), 1)
64         return res[0]
65
66     def search_dn(self,dn):
67         print("SEARCH by DN %s" % dn)
68
69         res = self.ldb.search(expression="(objectClass=*)",
70                               base=dn,
71                               scope=SCOPE_BASE,
72                               controls=["show_deleted:1"],
73                               attrs=["*", "parentGUID"])
74         self.assertEquals(len(res), 1)
75         return res[0]
76
77
78 class BasicDeleteTests(BaseDeleteTests):
79
80     def setUp(self):
81         super(BasicDeleteTests, self).setUp()
82
83     def del_attr_values(self, delObj):
84         print("Checking attributes for %s" % delObj["dn"])
85
86         self.assertEquals(delObj["isDeleted"][0],"TRUE")
87         self.assertTrue(not("objectCategory" in delObj))
88         self.assertTrue(not("sAMAccountType" in delObj))
89
90     def preserved_attributes_list(self, liveObj, delObj):
91         print("Checking for preserved attributes list")
92
93         preserved_list = ["nTSecurityDescriptor", "attributeID", "attributeSyntax", "dNReferenceUpdate", "dNSHostName",
94                           "flatName", "governsID", "groupType", "instanceType", "lDAPDisplayName", "legacyExchangeDN",
95                           "isDeleted", "isRecycled", "lastKnownParent", "msDS-LastKnownRDN", "mS-DS-CreatorSID",
96                           "mSMQOwnerID", "nCName", "objectClass", "distinguishedName", "objectGUID", "objectSid",
97                           "oMSyntax", "proxiedObjectName", "name", "replPropertyMetaData", "sAMAccountName",
98                           "securityIdentifier", "sIDHistory", "subClassOf", "systemFlags", "trustPartner", "trustDirection",
99                           "trustType", "trustAttributes", "userAccountControl", "uSNChanged", "uSNCreated", "whenCreated"]
100
101         for a in liveObj:
102             if a in preserved_list:
103                 self.assertTrue(a in delObj)
104
105     def check_rdn(self, liveObj, delObj, rdnName):
106         print("Checking for correct rDN")
107         rdn = liveObj[rdnName][0]
108         rdn2 = delObj[rdnName][0]
109         name2 = delObj["name"][0]
110         dn_rdn = delObj.dn.get_rdn_value()
111         guid = liveObj["objectGUID"][0]
112         self.assertEquals(rdn2, rdn + "\nDEL:" + self.GUID_string(guid))
113         self.assertEquals(name2, rdn + "\nDEL:" + self.GUID_string(guid))
114         self.assertEquals(name2, dn_rdn)
115
116     def delete_deleted(self, ldb, dn):
117         print("Testing the deletion of the already deleted dn %s" % dn)
118
119         try:
120             ldb.delete(dn)
121             self.fail()
122         except LdbError as e:
123             (num, _) = e.args
124             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
125
126     def test_delete_protection(self):
127         """Delete protection tests"""
128
129         print(self.base_dn)
130
131         delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
132         delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
133         delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
134
135         self.ldb.add({
136             "dn": "cn=ldaptestcontainer," + self.base_dn,
137             "objectclass": "container"})
138         self.ldb.add({
139             "dn": "cn=entry1,cn=ldaptestcontainer," + self.base_dn,
140             "objectclass": "container"})
141         self.ldb.add({
142             "dn": "cn=entry2,cn=ldaptestcontainer," + self.base_dn,
143             "objectclass": "container"})
144
145         try:
146             self.ldb.delete("cn=ldaptestcontainer," + self.base_dn)
147             self.fail()
148         except LdbError as e1:
149             (num, _) = e1.args
150             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
151
152         self.ldb.delete("cn=ldaptestcontainer," + self.base_dn, ["tree_delete:1"])
153
154         try:
155             res = self.ldb.search("cn=ldaptestcontainer," + self.base_dn,
156                                   scope=SCOPE_BASE, attrs=[])
157             self.fail()
158         except LdbError as e2:
159             (num, _) = e2.args
160             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
161         try:
162             res = self.ldb.search("cn=entry1,cn=ldaptestcontainer," + self.base_dn,
163                                   scope=SCOPE_BASE, attrs=[])
164             self.fail()
165         except LdbError as e3:
166             (num, _) = e3.args
167             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
168         try:
169             res = self.ldb.search("cn=entry2,cn=ldaptestcontainer," + self.base_dn,
170                                   scope=SCOPE_BASE, attrs=[])
171             self.fail()
172         except LdbError as e4:
173             (num, _) = e4.args
174             self.assertEquals(num, ERR_NO_SUCH_OBJECT)
175
176         delete_force(self.ldb, "cn=entry1,cn=ldaptestcontainer," + self.base_dn)
177         delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn)
178         delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn)
179
180         # Performs some protected object delete testing
181
182         res = self.ldb.search(base="", expression="", scope=SCOPE_BASE,
183                               attrs=["dsServiceName", "dNSHostName"])
184         self.assertEquals(len(res), 1)
185
186         # Delete failing since DC's nTDSDSA object is protected
187         try:
188             self.ldb.delete(res[0]["dsServiceName"][0])
189             self.fail()
190         except LdbError as e5:
191             (num, _) = e5.args
192             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
193
194         res = self.ldb.search(self.base_dn, attrs=["rIDSetReferences"],
195                               expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
196         self.assertEquals(len(res), 1)
197
198         # Deletes failing since DC's rIDSet object is protected
199         try:
200             self.ldb.delete(res[0]["rIDSetReferences"][0])
201             self.fail()
202         except LdbError as e6:
203             (num, _) = e6.args
204             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
205         try:
206             self.ldb.delete(res[0]["rIDSetReferences"][0], ["tree_delete:1"])
207             self.fail()
208         except LdbError as e7:
209             (num, _) = e7.args
210             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
211
212         # Deletes failing since three main crossRef objects are protected
213
214         try:
215             self.ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
216             self.fail()
217         except LdbError as e8:
218             (num, _) = e8.args
219             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
220         try:
221             self.ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn, ["tree_delete:1"])
222             self.fail()
223         except LdbError as e9:
224             (num, _) = e9.args
225             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
226
227         try:
228             self.ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn)
229             self.fail()
230         except LdbError as e10:
231             (num, _) = e10.args
232             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
233         try:
234             self.ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn, ["tree_delete:1"])
235             self.fail()
236         except LdbError as e11:
237             (num, _) = e11.args
238             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
239
240         res = self.ldb.search("cn=Partitions," + self.configuration_dn, attrs=[],
241                               expression="(nCName=%s)" % self.base_dn)
242         self.assertEquals(len(res), 1)
243
244         try:
245             self.ldb.delete(res[0].dn)
246             self.fail()
247         except LdbError as e12:
248             (num, _) = e12.args
249             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
250         try:
251             self.ldb.delete(res[0].dn, ["tree_delete:1"])
252             self.fail()
253         except LdbError as e13:
254             (num, _) = e13.args
255             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
256
257         # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
258         try:
259             self.ldb.delete("CN=Users," + self.base_dn)
260             self.fail()
261         except LdbError as e14:
262             (num, _) = e14.args
263             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
264
265         # Tree-delete failing since "isCriticalSystemObject"
266         try:
267             self.ldb.delete("CN=Computers," + self.base_dn, ["tree_delete:1"])
268             self.fail()
269         except LdbError as e15:
270             (num, _) = e15.args
271             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
272
273 class BasicTreeDeleteTests(BasicDeleteTests):
274
275     def setUp(self):
276         super(BasicTreeDeleteTests, self).setUp()
277
278         # user current time in ms to make unique objects
279         import time
280         marker = str(int(round(time.time() * 1000)))
281         usr1_name = "u_" + marker
282         usr2_name = "u2_" + marker
283         grp_name = "g1_" + marker
284         site_name = "s1_" + marker
285
286         self.usr1 = "cn=%s,cn=users,%s" % (usr1_name, self.base_dn)
287         self.usr2 = "cn=%s,cn=users,%s" % (usr2_name, self.base_dn)
288         self.grp1 = "cn=%s,cn=users,%s" % (grp_name, self.base_dn)
289         self.sit1 = "cn=%s,cn=sites,%s" % (site_name, self.configuration_dn)
290         self.ss1 = "cn=NTDS Site Settings,cn=%s,cn=sites,%s" % (site_name, self.configuration_dn)
291         self.srv1 = "cn=Servers,cn=%s,cn=sites,%s" % (site_name, self.configuration_dn)
292         self.srv2 = "cn=TESTSRV,cn=Servers,cn=%s,cn=sites,%s" % (site_name, self.configuration_dn)
293
294         delete_force(self.ldb, self.usr1)
295         delete_force(self.ldb, self.usr2)
296         delete_force(self.ldb, self.grp1)
297         delete_force(self.ldb, self.ss1)
298         delete_force(self.ldb, self.srv2)
299         delete_force(self.ldb, self.srv1)
300         delete_force(self.ldb, self.sit1)
301
302         self.ldb.add({
303             "dn": self.usr1,
304             "objectclass": "user",
305             "description": "test user description",
306             "samaccountname": usr1_name})
307
308         self.ldb.add({
309             "dn": self.usr2,
310             "objectclass": "user",
311             "description": "test user 2 description",
312             "samaccountname": usr2_name})
313
314         self.ldb.add({
315             "dn": self.grp1,
316             "objectclass": "group",
317             "description": "test group",
318             "samaccountname": grp_name,
319             "member": [self.usr1, self.usr2],
320             "isDeleted": "FALSE"})
321
322         self.ldb.add({
323             "dn": self.sit1,
324             "objectclass": "site"})
325
326         self.ldb.add({
327             "dn": self.ss1,
328             "objectclass": ["applicationSiteSettings", "nTDSSiteSettings"]})
329
330         self.ldb.add({
331             "dn": self.srv1,
332             "objectclass": "serversContainer"})
333
334         self.ldb.add({
335             "dn": self.srv2,
336             "objectClass": "server"})
337
338         self.objLive1 = self.search_dn(self.usr1)
339         self.guid1 = self.objLive1["objectGUID"][0]
340
341         self.objLive2 = self.search_dn(self.usr2)
342         self.guid2 = self.objLive2["objectGUID"][0]
343
344         self.objLive3 = self.search_dn(self.grp1)
345         self.guid3 = self.objLive3["objectGUID"][0]
346
347         self.objLive4 = self.search_dn(self.sit1)
348         self.guid4 = self.objLive4["objectGUID"][0]
349
350         self.objLive5 = self.search_dn(self.ss1)
351         self.guid5 = self.objLive5["objectGUID"][0]
352
353         self.objLive6 = self.search_dn(self.srv1)
354         self.guid6 = self.objLive6["objectGUID"][0]
355
356         self.objLive7 = self.search_dn(self.srv2)
357         self.guid7 = self.objLive7["objectGUID"][0]
358
359         self.deleted_objects_config_dn \
360             = self.ldb.get_wellknown_dn(self.ldb.get_config_basedn(),
361                                         dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
362         deleted_objects_config_obj \
363             = self.search_dn(self.deleted_objects_config_dn)
364
365         self.deleted_objects_config_guid \
366             = deleted_objects_config_obj["objectGUID"][0]
367
368         self.deleted_objects_domain_dn \
369             = self.ldb.get_wellknown_dn(self.ldb.get_default_basedn(),
370                                         dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
371         deleted_objects_domain_obj \
372             = self.search_dn(self.deleted_objects_domain_dn)
373
374         self.deleted_objects_domain_guid \
375             = deleted_objects_domain_obj["objectGUID"][0]
376
377         self.deleted_objects_domain_dn \
378             = self.ldb.get_wellknown_dn(self.ldb.get_default_basedn(),
379                                         dsdb.DS_GUID_DELETED_OBJECTS_CONTAINER)
380         sites_obj = self.search_dn("cn=sites,%s" \
381                                    % self.ldb.get_config_basedn())
382         self.sites_dn = sites_obj.dn
383         self.sites_guid \
384             = sites_obj["objectGUID"][0]
385
386     def test_all(self):
387         """Basic delete tests"""
388
389         self.ldb.delete(self.usr1)
390         self.ldb.delete(self.usr2)
391         self.ldb.delete(self.grp1)
392         self.ldb.delete(self.srv1, ["tree_delete:1"])
393         self.ldb.delete(self.sit1, ["tree_delete:1"])
394
395         self.check_all()
396
397     def test_tree_delete(self):
398         """Basic delete tests,
399            but use just one tree delete for the config records
400         """
401
402         self.ldb.delete(self.usr1)
403         self.ldb.delete(self.usr2)
404         self.ldb.delete(self.grp1)
405         self.ldb.delete(self.sit1, ["tree_delete:1"])
406
407         self.check_all()
408
409     def check_all(self):
410         objDeleted1 = self.search_guid(self.guid1)
411         objDeleted2 = self.search_guid(self.guid2)
412         objDeleted3 = self.search_guid(self.guid3)
413         objDeleted4 = self.search_guid(self.guid4)
414         objDeleted5 = self.search_guid(self.guid5)
415         objDeleted6 = self.search_guid(self.guid6)
416         objDeleted7 = self.search_guid(self.guid7)
417
418         self.del_attr_values(objDeleted1)
419         self.del_attr_values(objDeleted2)
420         self.del_attr_values(objDeleted3)
421         self.del_attr_values(objDeleted4)
422         self.del_attr_values(objDeleted5)
423         self.del_attr_values(objDeleted6)
424         self.del_attr_values(objDeleted7)
425
426         self.preserved_attributes_list(self.objLive1, objDeleted1)
427         self.preserved_attributes_list(self.objLive2, objDeleted2)
428         self.preserved_attributes_list(self.objLive3, objDeleted3)
429         self.preserved_attributes_list(self.objLive4, objDeleted4)
430         self.preserved_attributes_list(self.objLive5, objDeleted5)
431         self.preserved_attributes_list(self.objLive6, objDeleted6)
432         self.preserved_attributes_list(self.objLive7, objDeleted7)
433
434         self.check_rdn(self.objLive1, objDeleted1, "cn")
435         self.check_rdn(self.objLive2, objDeleted2, "cn")
436         self.check_rdn(self.objLive3, objDeleted3, "cn")
437         self.check_rdn(self.objLive4, objDeleted4, "cn")
438         self.check_rdn(self.objLive5, objDeleted5, "cn")
439         self.check_rdn(self.objLive6, objDeleted6, "cn")
440         self.check_rdn(self.objLive7, objDeleted7, "cn")
441
442         self.delete_deleted(self.ldb, self.usr1)
443         self.delete_deleted(self.ldb, self.usr2)
444         self.delete_deleted(self.ldb, self.grp1)
445         self.delete_deleted(self.ldb, self.sit1)
446         self.delete_deleted(self.ldb, self.ss1)
447         self.delete_deleted(self.ldb, self.srv1)
448         self.delete_deleted(self.ldb, self.srv2)
449
450         self.assertTrue("CN=Deleted Objects" in str(objDeleted1.dn))
451         self.assertEqual(objDeleted1.dn.parent(),
452                          self.deleted_objects_domain_dn)
453         self.assertEqual(objDeleted1["parentGUID"][0],
454                          self.deleted_objects_domain_guid)
455
456         self.assertTrue("CN=Deleted Objects" in str(objDeleted2.dn))
457         self.assertEqual(objDeleted2.dn.parent(),
458                          self.deleted_objects_domain_dn)
459         self.assertEqual(objDeleted2["parentGUID"][0],
460                          self.deleted_objects_domain_guid)
461
462         self.assertTrue("CN=Deleted Objects" in str(objDeleted3.dn))
463         self.assertEqual(objDeleted3.dn.parent(),
464                          self.deleted_objects_domain_dn)
465         self.assertEqual(objDeleted3["parentGUID"][0],
466                          self.deleted_objects_domain_guid)
467
468         self.assertFalse("CN=Deleted Objects" in str(objDeleted4.dn))
469         self.assertEqual(objDeleted4.dn.parent(),
470                          self.sites_dn)
471         self.assertEqual(objDeleted4["parentGUID"][0],
472                          self.sites_guid)
473
474         self.assertTrue("CN=Deleted Objects" in str(objDeleted5.dn))
475         self.assertEqual(objDeleted5.dn.parent(),
476                          self.deleted_objects_config_dn)
477         self.assertEqual(objDeleted5["parentGUID"][0],
478                          self.deleted_objects_config_guid)
479
480         self.assertFalse("CN=Deleted Objects" in str(objDeleted6.dn))
481         self.assertEqual(objDeleted6.dn.parent(),
482                          objDeleted4.dn)
483         self.assertEqual(objDeleted6["parentGUID"][0],
484                          objDeleted4["objectGUID"][0])
485
486         self.assertFalse("CN=Deleted Objects" in str(objDeleted7.dn))
487         self.assertEqual(objDeleted7.dn.parent(),
488                          objDeleted6.dn)
489         self.assertEqual(objDeleted7["parentGUID"][0],
490                          objDeleted6["objectGUID"][0])
491
492
493         objDeleted1 = self.search_guid(self.guid1)
494         objDeleted2 = self.search_guid(self.guid2)
495         objDeleted3 = self.search_guid(self.guid3)
496         objDeleted4 = self.search_guid(self.guid4)
497         objDeleted5 = self.search_guid(self.guid5)
498         objDeleted6 = self.search_guid(self.guid6)
499         objDeleted7 = self.search_guid(self.guid7)
500
501         self.del_attr_values(objDeleted1)
502         self.del_attr_values(objDeleted2)
503         self.del_attr_values(objDeleted3)
504         self.del_attr_values(objDeleted4)
505         self.del_attr_values(objDeleted5)
506         self.del_attr_values(objDeleted6)
507         self.del_attr_values(objDeleted7)
508
509         self.preserved_attributes_list(self.objLive1, objDeleted1)
510         self.preserved_attributes_list(self.objLive2, objDeleted2)
511         self.preserved_attributes_list(self.objLive3, objDeleted3)
512         self.preserved_attributes_list(self.objLive4, objDeleted4)
513         self.preserved_attributes_list(self.objLive5, objDeleted5)
514         self.preserved_attributes_list(self.objLive6, objDeleted6)
515         self.preserved_attributes_list(self.objLive7, objDeleted7)
516
517         self.check_rdn(self.objLive1, objDeleted1, "cn")
518         self.check_rdn(self.objLive2, objDeleted2, "cn")
519         self.check_rdn(self.objLive3, objDeleted3, "cn")
520         self.check_rdn(self.objLive4, objDeleted4, "cn")
521         self.check_rdn(self.objLive5, objDeleted5, "cn")
522         self.check_rdn(self.objLive6, objDeleted6, "cn")
523         self.check_rdn(self.objLive7, objDeleted7, "cn")
524
525         self.delete_deleted(self.ldb, self.usr1)
526         self.delete_deleted(self.ldb, self.usr2)
527         self.delete_deleted(self.ldb, self.grp1)
528         self.delete_deleted(self.ldb, self.sit1)
529         self.delete_deleted(self.ldb, self.ss1)
530         self.delete_deleted(self.ldb, self.srv1)
531         self.delete_deleted(self.ldb, self.srv2)
532
533         self.assertTrue("CN=Deleted Objects" in str(objDeleted1.dn))
534         self.assertEqual(objDeleted1.dn.parent(),
535                          self.deleted_objects_domain_dn)
536         self.assertEqual(objDeleted1["parentGUID"][0],
537                          self.deleted_objects_domain_guid)
538         self.assertTrue("CN=Deleted Objects" in str(objDeleted2.dn))
539         self.assertEqual(objDeleted2.dn.parent(),
540                          self.deleted_objects_domain_dn)
541         self.assertEqual(objDeleted2["parentGUID"][0],
542                          self.deleted_objects_domain_guid)
543         self.assertTrue("CN=Deleted Objects" in str(objDeleted3.dn))
544         self.assertEqual(objDeleted3.dn.parent(),
545                          self.deleted_objects_domain_dn)
546         self.assertEqual(objDeleted3["parentGUID"][0],
547                          self.deleted_objects_domain_guid)
548         self.assertFalse("CN=Deleted Objects" in str(objDeleted4.dn))
549         self.assertTrue("CN=Deleted Objects" in str(objDeleted5.dn))
550         self.assertEqual(objDeleted5.dn.parent(),
551                          self.deleted_objects_config_dn)
552         self.assertEqual(objDeleted5["parentGUID"][0],
553                          self.deleted_objects_config_guid)
554         self.assertFalse("CN=Deleted Objects" in str(objDeleted6.dn))
555         self.assertFalse("CN=Deleted Objects" in str(objDeleted7.dn))
556
557
558
559 if not "://" in host:
560     if os.path.isfile(host):
561         host = "tdb://%s" % host
562     else:
563         host = "ldap://%s" % host
564
565 TestProgram(module=__name__, opts=subunitopts)