Package ldaptor :: Package test :: Module test_ldiftree
[hide private]
[frames] | no frames]

Source Code for Module ldaptor.test.test_ldiftree

  1  """ 
  2  Test cases for LDIF directory tree writing/reading. 
  3  """ 
  4   
  5  from twisted.trial import unittest 
  6  import os, random, errno, shutil, sets 
  7  from ldaptor import ldiftree, entry, delta, testutil 
  8  from ldaptor.entry import BaseLDAPEntry 
  9  from ldaptor.protocols.ldap import ldaperrors, ldifprotocol 
 10   
11 -def writeFile(path, content):
12 f = file(path, 'w') 13 f.write(content) 14 f.close()
15
16 -class RandomizeListdirMixin(object):
17 - def randomListdir(self, *args, **kwargs):
18 r = self.__listdir(*args, **kwargs) 19 random.shuffle(r) 20 return r
21
22 - def setUpClass(self):
23 self.__listdir = os.listdir 24 os.listdir = self.randomListdir
25
26 - def tearDownClass(self):
27 os.listdir = self.__listdir
28
29 -class Dir2LDIF(RandomizeListdirMixin, unittest.TestCase):
30 - def setUp(self):
31 self.tree = self.mktemp() 32 os.mkdir(self.tree) 33 com = os.path.join(self.tree, 'dc=com.dir') 34 os.mkdir(com) 35 example = os.path.join(com, 'dc=example.dir') 36 os.mkdir(example) 37 writeFile(os.path.join(example, 'cn=foo.ldif'), 38 """\ 39 dn: cn=foo,dc=example,dc=com 40 cn: foo 41 objectClass: top 42 43 """) 44 writeFile(os.path.join(example, 'cn=bad-two-entries.ldif'), 45 """\ 46 dn: cn=bad-two-entries,dc=example,dc=com 47 cn: bad-two-entries 48 objectClass: top 49 50 dn: cn=more,dc=example,dc=com 51 cn: more 52 objectClass: top 53 54 """) 55 writeFile(os.path.join(example, 'cn=bad-missing-end.ldif'), 56 """\ 57 dn: cn=bad-missing-end,dc=example,dc=com 58 cn: bad-missing-end 59 objectClass: top 60 """) 61 writeFile(os.path.join(example, 'cn=bad-empty.ldif'), '') 62 writeFile(os.path.join(example, 'cn=bad-only-newline.ldif'), '\n') 63 sales = os.path.join(example, 'ou=Sales.dir') 64 os.mkdir(sales) 65 writeFile(os.path.join(sales, 'cn=sales-thingie.ldif'), 66 """\ 67 dn: cn=sales-thingie,ou=Sales,dc=example,dc=com 68 cn: sales-thingie 69 objectClass: top 70 71 """)
72
73 - def testSimpleRead(self):
74 want = BaseLDAPEntry(dn='cn=foo,dc=example,dc=com', 75 attributes={ 76 'objectClass': ['top'], 77 'cn': ['foo'], 78 }) 79 d = ldiftree.get(self.tree, want.dn) 80 d.addCallback(self.failUnlessEqual, want) 81 return d
82
83 - def testNoAccess(self):
84 os.chmod(os.path.join(self.tree, 85 'dc=com.dir', 86 'dc=example.dir', 87 'cn=foo.ldif'), 88 0) 89 d = ldiftree.get(self.tree, 'cn=foo,dc=example,dc=com') 90 def eb(fail): 91 fail.trap(IOError) 92 self.assertEquals(fail.value.errno, errno.EACCES)
93 d.addCallbacks(testutil.mustRaise, eb) 94 return d
95 96 if os.getuid() == 0: 97 testNoAccess.skip = "Can't test as root" 98
99 - def gettingDNRaises(self, dn, exceptionClass):
100 d = ldiftree.get(self.tree, dn) 101 def eb(fail): 102 fail.trap(exceptionClass)
103 d.addCallbacks(testutil.mustRaise, eb) 104 return d 105
106 - def testMultipleError(self):
107 return self.gettingDNRaises( 108 'cn=bad-two-entries,dc=example,dc=com', 109 ldiftree.LDIFTreeEntryContainsMultipleEntries)
110
111 - def testMissingEndError(self):
112 return self.gettingDNRaises( 113 'cn=bad-missing-end,dc=example,dc=com', 114 ldiftree.LDIFTreeEntryContainsNoEntries)
115
116 - def testEmptyError(self):
117 return self.gettingDNRaises( 118 'cn=bad-empty,dc=example,dc=com', 119 ldiftree.LDIFTreeEntryContainsNoEntries)
120
121 - def testOnlyNewlineError(self):
122 return self.gettingDNRaises( 123 'cn=bad-only-newline,dc=example,dc=com', 124 ldifprotocol.LDIFLineWithoutSemicolonError)
125
126 - def testTreeBranches(self):
127 want = BaseLDAPEntry(dn='cn=sales-thingie,ou=Sales,dc=example,dc=com', 128 attributes={ 129 'objectClass': ['top'], 130 'cn': ['sales-thingie'], 131 }) 132 d = ldiftree.get(self.tree, want.dn) 133 d.addCallback(self.failUnlessEqual, want) 134 return d
135
136 -class LDIF2Dir(RandomizeListdirMixin, unittest.TestCase):
137 - def setUp(self):
138 self.tree = self.mktemp() 139 os.mkdir(self.tree) 140 com = os.path.join(self.tree, 'dc=com.dir') 141 os.mkdir(com) 142 example = os.path.join(com, 'dc=example.dir') 143 os.mkdir(example) 144 writeFile(os.path.join(example, 'cn=pre-existing.ldif'), 145 """\ 146 dn: cn=pre-existing,dc=example,dc=com 147 cn: pre-existing 148 objectClass: top 149 150 """) 151 writeFile(os.path.join(example, 'ou=OrgUnit.ldif'), 152 """\ 153 dn: ou=OrgUnit,dc=example,dc=com 154 ou: OrgUnit 155 objectClass: organizationalUnit 156 157 """)
158
159 - def testSimpleWrite(self):
160 e = BaseLDAPEntry(dn='cn=foo,dc=example,dc=com', 161 attributes={ 162 'objectClass': ['top'], 163 'cn': ['foo'], 164 }) 165 d = ldiftree.put(self.tree, e) 166 d.addCallback(self._cb_testSimpleWrite) 167 return d
168
169 - def _cb_testSimpleWrite(self, entry):
170 path = os.path.join(self.tree, 'dc=com.dir', 'dc=example.dir', 'cn=foo.ldif') 171 self.failUnless(os.path.isfile(path)) 172 self.failUnlessEqual(file(path).read(), 173 """\ 174 dn: cn=foo,dc=example,dc=com 175 objectClass: top 176 cn: foo 177 178 """)
179
180 - def testDirCreation(self):
181 e = BaseLDAPEntry(dn='cn=create-me,ou=OrgUnit,dc=example,dc=com', 182 attributes={ 183 'objectClass': ['top'], 184 'cn': ['create-me'], 185 }) 186 d = ldiftree.put(self.tree, e) 187 d.addCallback(self._cb_testDirCreation) 188 return d
189
190 - def _cb_testDirCreation(self, entry):
191 path = os.path.join(self.tree, 'dc=com.dir', 'dc=example.dir', 192 'ou=OrgUnit.dir', 'cn=create-me.ldif') 193 self.failUnless(os.path.isfile(path)) 194 self.failUnlessEqual(file(path).read(), 195 """\ 196 dn: cn=create-me,ou=OrgUnit,dc=example,dc=com 197 objectClass: top 198 cn: create-me 199 200 """)
201
202 - def testDirExists(self):
203 e = BaseLDAPEntry(dn='cn=create-me,ou=OrgUnit,dc=example,dc=com', 204 attributes={ 205 'objectClass': ['top'], 206 'cn': ['create-me'], 207 }) 208 dirpath = os.path.join(self.tree, 'dc=com.dir', 'dc=example.dir', 209 'ou=OrgUnit.dir') 210 os.mkdir(dirpath) 211 d = ldiftree.put(self.tree, e) 212 d.addCallback(self._cb_testDirExists, dirpath) 213 return d
214
215 - def _cb_testDirExists(self, entry, dirpath):
216 path = os.path.join(dirpath, 'cn=create-me.ldif') 217 self.failUnless(os.path.isfile(path)) 218 self.failUnlessEqual(file(path).read(), 219 """\ 220 dn: cn=create-me,ou=OrgUnit,dc=example,dc=com 221 objectClass: top 222 cn: create-me 223 224 """)
225
226 - def testMissingLinkError(self):
227 e = BaseLDAPEntry(dn='cn=bad-create,ou=NoSuchOrgUnit,dc=example,dc=com', 228 attributes={ 229 'objectClass': ['top'], 230 'cn': ['bad-create'], 231 }) 232 d = ldiftree.put(self.tree, e) 233 d.addCallbacks(self._cb_testMissingLinkError, 234 self._eb_testMissingLinkError) 235 return d
236
237 - def _cb_testMissingLinkError(self):
238 raise unittest.FailTest('Should have raised an exception.')
239 - def _eb_testMissingLinkError(self, fail):
241
242 - def testAddTopLevel(self):
243 e = BaseLDAPEntry(dn='dc=org', 244 attributes={ 245 'objectClass': ['dcObject'], 246 'dc': ['org'], 247 }) 248 d = ldiftree.put(self.tree, e) 249 d.addCallback(self._cb_testAddTopLevel) 250 return d
251
252 - def _cb_testAddTopLevel(self, entry):
253 path = os.path.join(self.tree, 'dc=org.ldif') 254 self.failUnless(os.path.isfile(path)) 255 self.failUnlessEqual(file(path).read(), 256 """\ 257 dn: dc=org 258 objectClass: dcObject 259 dc: org 260 261 """)
262 263
264 -class Tree(RandomizeListdirMixin, unittest.TestCase):
265 # TODO share the actual tests with inmemory and any other 266 # implementations of the same interface
267 - def setUp(self):
268 self.tree = self.mktemp() 269 os.mkdir(self.tree) 270 com = os.path.join(self.tree, 'dc=com.dir') 271 os.mkdir(com) 272 example = os.path.join(com, 'dc=example.dir') 273 os.mkdir(example) 274 meta = os.path.join(example, 'ou=metasyntactic.dir') 275 os.mkdir(meta) 276 writeFile(os.path.join(example, 'ou=metasyntactic.ldif'), 277 """\ 278 dn: ou=metasyntactic,dc=example,dc=com 279 objectClass: a 280 objectClass: b 281 ou: metasyntactic 282 283 """) 284 foo = os.path.join(meta, 'cn=foo.dir') 285 writeFile(os.path.join(meta, 'cn=foo.ldif'), 286 """\ 287 dn: cn=foo,ou=metasyntactic,dc=example,dc=com 288 objectClass: a 289 objectClass: b 290 cn: foo 291 292 """) 293 bar = os.path.join(meta, 'cn=bar.dir') 294 writeFile(os.path.join(meta, 'cn=bar.ldif'), 295 """\ 296 dn: cn=bar,ou=metasyntactic,dc=example,dc=com 297 objectClass: a 298 objectClass: b 299 cn: bar 300 301 """) 302 empty = os.path.join(example, 'ou=empty.dir') 303 writeFile(os.path.join(example, 'ou=empty.ldif'), 304 """\ 305 dn: ou=empty,dc=example,dc=com 306 objectClass: a 307 objectClass: b 308 ou: empty 309 310 """) 311 oneChild = os.path.join(example, 'ou=oneChild.dir') 312 os.mkdir(oneChild) 313 writeFile(os.path.join(example, 'ou=oneChild.ldif'), 314 """\ 315 dn: ou=oneChild,dc=example,dc=com 316 objectClass: a 317 objectClass: b 318 ou: oneChild 319 320 """) 321 theChild = os.path.join(oneChild, 'cn=theChild.dir') 322 writeFile(os.path.join(oneChild, 'cn=theChild.ldif'), 323 """\ 324 dn: cn=theChild,ou=oneChild,dc=example,dc=com 325 objectClass: a 326 objectClass: b 327 cn: theChild 328 329 """) 330 self.root = ldiftree.LDIFTreeEntry(self.tree) 331 self.example = ldiftree.LDIFTreeEntry(example, 'dc=example,dc=com') 332 self.empty = ldiftree.LDIFTreeEntry(empty, 'ou=empty,dc=example,dc=com') 333 self.meta = ldiftree.LDIFTreeEntry(meta, 'ou=metasyntactic,dc=example,dc=com') 334 self.foo = ldiftree.LDIFTreeEntry(foo, 'cn=foo,ou=metasyntactic,dc=example,dc=com') 335 self.bar = ldiftree.LDIFTreeEntry(bar, 'cn=bar,ou=metasyntactic,dc=example,dc=com') 336 self.oneChild = ldiftree.LDIFTreeEntry(oneChild, 'ou=oneChild,dc=example,dc=com') 337 self.theChild = ldiftree.LDIFTreeEntry(theChild, 'cn=theChild,ou=oneChild,dc=example,dc=com')
338
339 - def test_children_empty(self):
340 d = self.empty.children() 341 def cb(children): 342 self.assertEquals(children, [])
343 d.addCallback(cb) 344 return d
345
346 - def test_children_oneChild(self):
347 d = self.oneChild.children() 348 d.addCallback(self._cb_test_children_oneChild) 349 return d
350
351 - def _cb_test_children_oneChild(self, children):
352 self.assertEquals(len(children), 1) 353 got = [e.dn for e in children] 354 want = ['cn=theChild,ou=oneChild,dc=example,dc=com'] 355 got.sort() 356 want.sort() 357 self.assertEquals(got, want)
358
359 - def test_children_repeat(self):
360 """Test that .children() returns a copy of the data so that modifying it does not affect behaviour.""" 361 d = self.oneChild.children() 362 d.addCallback(self._cb_test_children_repeat_1) 363 return d
364
365 - def _cb_test_children_repeat_1(self, children1):
366 self.assertEquals(len(children1), 1) 367 368 children1.pop() 369 370 d = self.oneChild.children() 371 d.addCallback(self._cb_test_children_repeat_2) 372 return d
373
374 - def _cb_test_children_repeat_2(self, children2):
375 self.assertEquals(len(children2), 1)
376
377 - def test_children_twoChildren(self):
378 d = self.meta.children() 379 d.addCallback(self._cb_test_children_twoChildren) 380 return d
381
382 - def _cb_test_children_twoChildren(self, children):
383 self.assertEquals(len(children), 2) 384 want = [ 385 'cn=foo,ou=metasyntactic,dc=example,dc=com', 386 'cn=bar,ou=metasyntactic,dc=example,dc=com', 387 ] 388 got = [e.dn for e in children] 389 got.sort() 390 want.sort() 391 self.assertEquals(got, want)
392
393 - def test_children_twoChildren_callback(self):
394 children = [] 395 d = self.meta.children(callback=children.append) 396 d.addCallback(self._cb_test_children_twoChildren_callback, children) 397 return d
398
399 - def _cb_test_children_twoChildren_callback(self, r, children):
400 self.assertIdentical(r, None) 401 self.assertEquals(len(children), 2) 402 want = [ 403 'cn=foo,ou=metasyntactic,dc=example,dc=com', 404 'cn=bar,ou=metasyntactic,dc=example,dc=com', 405 ] 406 got = [e.dn for e in children] 407 got.sort() 408 want.sort() 409 self.assertEquals(got, want)
410
411 - def test_children_noAccess_dir_noRead(self):
412 os.chmod(self.meta.path, 0300) 413 d = self.meta.children() 414 def eb(fail): 415 fail.trap(OSError) 416 self.assertEquals(fail.value.errno, errno.EACCES) 417 os.chmod(self.meta.path, 0755)
418 d.addCallbacks(testutil.mustRaise, eb) 419 return d 420 421 if os.getuid() == 0: 422 test_children_noAccess_dir_noRead.skip = "Can't test as root" 423
424 - def test_children_noAccess_dir_noExec(self):
425 os.chmod(self.meta.path, 0600) 426 d = self.meta.children() 427 def eb(fail): 428 fail.trap(IOError) 429 self.assertEquals(fail.value.errno, errno.EACCES) 430 os.chmod(self.meta.path, 0755)
431 d.addCallbacks(testutil.mustRaise, eb) 432 return d 433 434 if os.getuid() == 0: 435 test_children_noAccess_dir_noExec.skip = "Can't test as root" 436
437 - def test_children_noAccess_file(self):
438 os.chmod(os.path.join(self.meta.path, 'cn=foo.ldif'), 0) 439 d = self.meta.children() 440 def eb(fail): 441 fail.trap(IOError) 442 self.assertEquals(fail.value.errno, errno.EACCES)
443 d.addCallbacks(testutil.mustRaise, eb) 444 return d 445 446 if os.getuid() == 0: 447 test_children_noAccess_file.skip = "Can't test as root" 448
449 - def test_addChild(self):
450 self.empty.addChild( 451 rdn='a=b', 452 attributes={ 453 'objectClass': ['a', 'b'], 454 'a': 'b', 455 }) 456 d = self.empty.children() 457 d.addCallback(self._cb_test_addChild) 458 return d
459
460 - def _cb_test_addChild(self, children):
461 self.assertEquals(len(children), 1) 462 got = [e.dn for e in children] 463 want = [ 464 'a=b,ou=empty,dc=example,dc=com', 465 ] 466 got.sort() 467 want.sort() 468 self.assertEquals(got, want)
469
470 - def test_addChild_Exists(self):
471 self.assertRaises(ldaperrors.LDAPEntryAlreadyExists, 472 self.meta.addChild, 473 rdn='cn=foo', 474 attributes={ 475 'objectClass': ['a'], 476 'cn': 'foo', 477 })
478
479 - def test_parent(self):
480 self.assertEquals(self.foo.parent(), self.meta) 481 self.assertEquals(self.meta.parent(), self.example) 482 self.assertEquals(self.root.parent(), None)
483 484
485 - def test_subtree_empty(self):
486 d = self.empty.subtree() 487 d.addCallback(self._cb_test_subtree_empty) 488 return d
489
490 - def _cb_test_subtree_empty(self, entries):
491 self.assertEquals(len(entries), 1)
492
493 - def test_subtree_oneChild(self):
494 d = self.oneChild.subtree() 495 d.addCallback(self._cb_test_subtree_oneChild) 496 return d
497
498 - def _cb_test_subtree_oneChild(self, results):
499 got = results 500 want = [ 501 self.oneChild, 502 self.theChild, 503 ] 504 self.assertEquals(got, want)
505
506 - def test_subtree_oneChild_cb(self):
507 got = [] 508 d = self.oneChild.subtree(got.append) 509 d.addCallback(self._cb_test_subtree_oneChild_cb, got) 510 return d
511
512 - def _cb_test_subtree_oneChild_cb(self, r, got):
513 self.assertEquals(r, None) 514 515 want = [ 516 self.oneChild, 517 self.theChild, 518 ] 519 self.assertEquals(got, want)
520
521 - def test_subtree_many(self):
522 d = self.example.subtree() 523 d.addCallback(self._cb_test_subtree_many) 524 return d
525
526 - def _cb_test_subtree_many(self, results):
527 got = results 528 want = [ 529 self.example, 530 self.oneChild, 531 self.theChild, 532 self.empty, 533 self.meta, 534 self.bar, 535 self.foo, 536 ] 537 got.sort() 538 want.sort() 539 self.assertEquals(got, want)
540
541 - def test_subtree_many_cb(self):
542 got = [] 543 d = self.example.subtree(callback=got.append) 544 d.addCallback(self._cb_test_subtree_many_cb, got) 545 return d
546
547 - def _cb_test_subtree_many_cb(self, r, got):
548 self.assertEquals(r, None) 549 550 want = [ 551 self.example, 552 self.oneChild, 553 self.theChild, 554 self.empty, 555 self.meta, 556 self.bar, 557 self.foo, 558 ] 559 got.sort() 560 want.sort() 561 self.assertEquals(got, want)
562
563 - def test_lookup_fail(self):
564 dn = 'cn=thud,ou=metasyntactic,dc=example,dc=com' 565 d = self.root.lookup(dn) 566 def eb(fail): 567 fail.trap(ldaperrors.LDAPNoSuchObject) 568 self.assertEquals(fail.value.message, dn)
569 d.addCallbacks(testutil.mustRaise, eb) 570 return d 571
572 - def test_lookup_fail_outOfTree(self):
573 dn = 'dc=invalid' 574 d = self.root.lookup(dn) 575 def eb(fail): 576 fail.trap(ldaperrors.LDAPNoSuchObject) 577 self.assertEquals(fail.value.message, dn)
578 d.addCallbacks(testutil.mustRaise, eb) 579 return d 580
581 - def test_lookup_fail_outOfTree_2(self):
582 dn = 'dc=invalid' 583 d = self.example.lookup(dn) 584 def eb(fail): 585 fail.trap(ldaperrors.LDAPNoSuchObject) 586 self.assertEquals(fail.value.message, dn)
587 d.addCallbacks(testutil.mustRaise, eb) 588
589 - def test_lookup_fail_multipleError(self):
590 writeFile(os.path.join(self.example.path, 591 'cn=bad-two-entries.ldif'), 592 """\ 593 dn: cn=bad-two-entries,dc=example,dc=com 594 cn: bad-two-entries 595 objectClass: top 596 597 dn: cn=more,dc=example,dc=com 598 cn: more 599 objectClass: top 600 601 """) 602 self.assertRaises( 603 ldiftree.LDIFTreeEntryContainsMultipleEntries, 604 self.example.lookup, 605 'cn=bad-two-entries,dc=example,dc=com')
606
607 - def test_lookup_fail_emptyError(self):
608 writeFile(os.path.join(self.example.path, 609 'cn=bad-empty.ldif'), 610 "") 611 self.assertRaises( 612 ldiftree.LDIFTreeEntryContainsNoEntries, 613 self.example.lookup, 614 'cn=bad-empty,dc=example,dc=com')
615
616 - def test_lookup_deep(self):
617 dn = 'cn=bar,ou=metasyntactic,dc=example,dc=com' 618 d = self.root.lookup(dn) 619 d.addCallback(self._cb_test_lookup_deep) 620 return d
621
622 - def _cb_test_lookup_deep(self, r):
623 self.assertEquals(r, self.bar)
624
625 - def test_delete_root(self):
626 d = self.root.delete() 627 def eb(fail): 628 fail.trap(ldiftree.LDAPCannotRemoveRootError)
629 d.addCallbacks(testutil.mustRaise, eb) 630 return d 631
632 - def test_delete_nonLeaf(self):
633 d = self.meta.delete() 634 def eb(fail): 635 fail.trap(ldaperrors.LDAPNotAllowedOnNonLeaf)
636 d.addCallbacks(testutil.mustRaise, eb) 637 return d 638
639 - def test_delete(self):
640 d = self.foo.delete() 641 d.addCallback(self._cb_test_delete_1) 642 return d
643
644 - def _cb_test_delete_1(self, r):
645 self.assertEquals(r, self.foo) 646 d = self.meta.children() 647 d.addCallback(self._cb_test_delete_2) 648 return d
649
650 - def _cb_test_delete_2(self, r):
651 self.assertEquals(r, [self.bar])
652
653 - def test_deleteChild(self):
654 d = self.meta.deleteChild('cn=bar') 655 d.addCallback(self._cb_test_deleteChild_1) 656 return d
657
658 - def _cb_test_deleteChild_1(self, r):
659 self.assertEquals(r, self.bar) 660 d = self.meta.children() 661 d.addCallback(self._cb_test_deleteChild_2) 662 return d
663
664 - def _cb_test_deleteChild_2(self, r):
665 self.assertEquals(r, [self.foo])
666
667 - def test_deleteChild_NonExisting(self):
668 d = self.root.deleteChild('cn=not-exist') 669 def eb(fail): 670 fail.trap(ldaperrors.LDAPNoSuchObject)
671 d.addCallbacks(testutil.mustRaise, eb) 672 return d 673
674 - def test_setPassword(self):
675 self.foo.setPassword('s3krit', salt='\xf2\x4a') 676 self.failUnless('userPassword' in self.foo) 677 self.assertEquals(self.foo['userPassword'], 678 ['{SSHA}0n/Iw1NhUOKyaI9gm9v5YsO3ZInySg=='])
679
680 - def test_setPassword_noSalt(self):
681 self.foo.setPassword('s3krit') 682 self.failUnless('userPassword' in self.foo) 683 d = self.foo.bind('s3krit') 684 d.addCallback(self.assertIdentical, self.foo) 685 d.addCallback(lambda _: self.foo.bind('s4krit')) 686 def eb(fail): 687 fail.trap(ldaperrors.LDAPInvalidCredentials)
688 d.addCallbacks(testutil.mustRaise, eb) 689 return d 690
691 - def test_diffTree_self(self):
692 d = self.root.diffTree(self.root) 693 d.addCallback(self.assertEquals, []) 694 return d
695
696 - def test_diffTree_copy(self):
697 otherDir = self.mktemp() 698 shutil.copytree(self.tree, otherDir) 699 other = ldiftree.LDIFTreeEntry(otherDir) 700 d = self.root.diffTree(other) 701 d.addCallback(self.assertEquals, []) 702 return d
703
704 - def test_diffTree_addChild(self):
705 otherDir = self.mktemp() 706 shutil.copytree(self.tree, otherDir) 707 other = ldiftree.LDIFTreeEntry(otherDir) 708 e = entry.BaseLDAPEntry(dn='cn=foo,dc=example,dc=com') 709 d = ldiftree.put(otherDir, e) 710 711 def cb1(dummy): 712 return other.lookup('cn=foo,dc=example,dc=com')
713 d.addCallback(cb1) 714 715 def cb2(r): 716 d = self.root.diffTree(other) 717 d.addCallback(self.assertEquals, [delta.AddOp(r)]) 718 return d 719 d.addCallback(cb2) 720 return d 721 722
723 - def test_diffTree_delChild(self):
724 otherDir = self.mktemp() 725 shutil.copytree(self.tree, otherDir) 726 other = ldiftree.LDIFTreeEntry(otherDir) 727 728 d = other.lookup('ou=empty,dc=example,dc=com') 729 def cb1(otherEmpty): 730 return otherEmpty.delete()
731 d.addCallback(cb1) 732 def cb2(dummy): 733 return self.root.diffTree(other) 734 d.addCallback(cb2) 735 def cb3(got): 736 self.assertEquals(got, [delta.DeleteOp(self.empty)]) 737 d.addCallback(cb3) 738 return d 739
740 - def test_diffTree_edit(self):
741 otherDir = self.mktemp() 742 shutil.copytree(self.tree, otherDir) 743 other = ldiftree.LDIFTreeEntry(otherDir) 744 745 d = other.lookup('ou=empty,dc=example,dc=com') 746 def cb1(otherEmpty): 747 otherEmpty['foo'] = ['bar'] 748 return otherEmpty.commit()
749 d.addCallback(cb1) 750 751 def cb2(dummy): 752 return self.root.diffTree(other) 753 d.addCallback(cb2) 754 755 def cb3(got): 756 self.assertEquals(got, [ 757 delta.ModifyOp(self.empty.dn, 758 [delta.Add('foo', ['bar'])], 759 ), 760 ]) 761 d.addCallback(cb3) 762 return d 763 764
765 - def test_move_noChildren_sameSuperior(self):
766 d = self.empty.move('ou=moved,dc=example,dc=com') 767 def getChildren(dummy): 768 return self.example.children()
769 d.addCallback(getChildren) 770 d.addCallback(sets.Set) 771 d.addCallback(self.assertEquals, sets.Set([ 772 self.meta, 773 BaseLDAPEntry( 774 dn='ou=moved,dc=example,dc=com', 775 attributes={ 'objectClass': ['a', 'b'], 776 'ou': ['moved'], 777 }), 778 self.oneChild, 779 ])) 780 return d 781
782 - def test_move_children_sameSuperior(self):
783 d = self.meta.move('ou=moved,dc=example,dc=com') 784 def getChildren(dummy): 785 return self.example.children()
786 d.addCallback(getChildren) 787 d.addCallback(sets.Set) 788 d.addCallback(self.assertEquals, sets.Set([ 789 BaseLDAPEntry(dn='ou=moved,dc=example,dc=com', 790 attributes={ 'objectClass': ['a', 'b'], 791 'ou': ['moved'], 792 }), 793 self.empty, 794 self.oneChild, 795 ])) 796 return d 797 798
799 - def test_move_noChildren_newSuperior(self):
800 d = self.empty.move('ou=moved,ou=oneChild,dc=example,dc=com') 801 def getChildren(dummy): 802 return self.example.children()
803 d.addCallback(getChildren) 804 d.addCallback(sets.Set) 805 d.addCallback(self.assertEquals, sets.Set([ 806 self.meta, 807 self.oneChild, 808 ])) 809 def getChildren2(dummy): 810 return self.oneChild.children() 811 d.addCallback(getChildren2) 812 d.addCallback(sets.Set) 813 d.addCallback(self.assertEquals, sets.Set([ 814 self.theChild, 815 BaseLDAPEntry( 816 dn='ou=moved,ou=oneChild,dc=example,dc=com', 817 attributes={ 'objectClass': ['a', 'b'], 818 'ou': ['moved'], 819 }), 820 ])) 821 return d 822
823 - def test_move_children_newSuperior(self):
824 d = self.meta.move('ou=moved,ou=oneChild,dc=example,dc=com') 825 def getChildren(dummy): 826 return self.example.children()
827 d.addCallback(getChildren) 828 d.addCallback(sets.Set) 829 d.addCallback(self.assertEquals, sets.Set([ 830 self.empty, 831 self.oneChild, 832 ])) 833 def getChildren2(dummy): 834 return self.oneChild.children() 835 d.addCallback(getChildren2) 836 d.addCallback(sets.Set) 837 d.addCallback(self.assertEquals, sets.Set([ 838 self.theChild, 839 BaseLDAPEntry(dn='ou=moved,ou=oneChild,dc=example,dc=com', 840 attributes={ 'objectClass': ['a', 'b'], 841 'ou': ['moved'], 842 }), 843 ])) 844 return d 845