~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transform.py

  • Committer: Andrew Bennetts
  • Date: 2007-08-30 08:11:54 UTC
  • mfrom: (2766 +trunk)
  • mto: (2535.3.55 repo-refactor)
  • mto: This revision was merged to the branch mainline in revision 2772.
  • Revision ID: andrew.bennetts@canonical.com-20070830081154-16hebp2xwr15x2hc
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
32
32
                           ReusingTransform, CantMoveRoot, 
33
33
                           PathsNotVersionedError, ExistingLimbo,
34
 
                           ImmortalLimbo, LockError)
 
34
                           ExistingPendingDeletion, ImmortalLimbo,
 
35
                           ImmortalPendingDeletion, LockError)
35
36
from bzrlib.osutils import file_kind, has_symlinks, pathjoin
36
37
from bzrlib.merge import Merge3Merger
37
38
from bzrlib.tests import TestCaseInTempDir, TestSkipped, TestCase
38
39
from bzrlib.transform import (TreeTransform, ROOT_PARENT, FinalPaths, 
39
40
                              resolve_conflicts, cook_conflicts, 
40
41
                              find_interesting, build_tree, get_backup_name,
41
 
                              change_entry)
 
42
                              change_entry, _FileMover)
42
43
 
43
44
 
44
45
class TestTreeTransform(tests.TestCaseWithTransport):
54
55
        return transform, transform.root
55
56
 
56
57
    def test_existing_limbo(self):
57
 
        limbo_name = urlutils.local_path_from_url(
58
 
            self.wt._control_files.controlfilename('limbo'))
59
58
        transform, root = self.get_transform()
 
59
        limbo_name = transform._limbodir
 
60
        deletion_path = transform._deletiondir
60
61
        os.mkdir(pathjoin(limbo_name, 'hehe'))
61
62
        self.assertRaises(ImmortalLimbo, transform.apply)
62
63
        self.assertRaises(LockError, self.wt.unlock)
64
65
        self.assertRaises(LockError, self.wt.unlock)
65
66
        os.rmdir(pathjoin(limbo_name, 'hehe'))
66
67
        os.rmdir(limbo_name)
 
68
        os.rmdir(deletion_path)
67
69
        transform, root = self.get_transform()
68
70
        transform.apply()
69
71
 
 
72
    def test_existing_pending_deletion(self):
 
73
        transform, root = self.get_transform()
 
74
        deletion_path = self._limbodir = urlutils.local_path_from_url(
 
75
            transform._tree._control_files.controlfilename('pending-deletion'))
 
76
        os.mkdir(pathjoin(deletion_path, 'blocking-directory'))
 
77
        self.assertRaises(ImmortalPendingDeletion, transform.apply)
 
78
        self.assertRaises(LockError, self.wt.unlock)
 
79
        self.assertRaises(ExistingPendingDeletion, self.get_transform)
 
80
 
70
81
    def test_build(self):
71
82
        transform, root = self.get_transform() 
72
83
        self.assertIs(transform.get_tree_parent(root), ROOT_PARENT)
1338
1349
        self.assertEqual(name, 'name.~1~')
1339
1350
        name = get_backup_name(MockEntry(), {'a':['1', '2', '3']}, 'a', tt)
1340
1351
        self.assertEqual(name, 'name.~4~')
 
1352
 
 
1353
 
 
1354
class TestFileMover(tests.TestCaseWithTransport):
 
1355
 
 
1356
    def test_file_mover(self):
 
1357
        self.build_tree(['a/', 'a/b', 'c/', 'c/d'])
 
1358
        mover = _FileMover()
 
1359
        mover.rename('a', 'q')
 
1360
        self.failUnlessExists('q')
 
1361
        self.failIfExists('a')
 
1362
        self.failUnlessExists('q/b')
 
1363
        self.failUnlessExists('c')
 
1364
        self.failUnlessExists('c/d')
 
1365
 
 
1366
    def test_pre_delete_rollback(self):
 
1367
        self.build_tree(['a/'])
 
1368
        mover = _FileMover()
 
1369
        mover.pre_delete('a', 'q')
 
1370
        self.failUnlessExists('q')
 
1371
        self.failIfExists('a')
 
1372
        mover.rollback()
 
1373
        self.failIfExists('q')
 
1374
        self.failUnlessExists('a')
 
1375
 
 
1376
    def test_apply_deletions(self):
 
1377
        self.build_tree(['a/', 'b/'])
 
1378
        mover = _FileMover()
 
1379
        mover.pre_delete('a', 'q')
 
1380
        mover.pre_delete('b', 'r')
 
1381
        self.failUnlessExists('q')
 
1382
        self.failUnlessExists('r')
 
1383
        self.failIfExists('a')
 
1384
        self.failIfExists('b')
 
1385
        mover.apply_deletions()
 
1386
        self.failIfExists('q')
 
1387
        self.failIfExists('r')
 
1388
        self.failIfExists('a')
 
1389
        self.failIfExists('b')
 
1390
 
 
1391
    def test_file_mover_rollback(self):
 
1392
        self.build_tree(['a/', 'a/b', 'c/', 'c/d/', 'c/e/'])
 
1393
        mover = _FileMover()
 
1394
        mover.rename('c/d', 'c/f')
 
1395
        mover.rename('c/e', 'c/d')
 
1396
        try:
 
1397
            mover.rename('a', 'c')
 
1398
        except OSError, e:
 
1399
            mover.rollback()
 
1400
        self.failUnlessExists('a')
 
1401
        self.failUnlessExists('c/d')
 
1402
 
 
1403
 
 
1404
class Bogus(Exception):
 
1405
    pass
 
1406
 
 
1407
 
 
1408
class TestTransformRollback(tests.TestCaseWithTransport):
 
1409
 
 
1410
    class ExceptionFileMover(_FileMover):
 
1411
 
 
1412
        def __init__(self, bad_source=None, bad_target=None):
 
1413
            _FileMover.__init__(self)
 
1414
            self.bad_source = bad_source
 
1415
            self.bad_target = bad_target
 
1416
 
 
1417
        def rename(self, source, target):
 
1418
            if (self.bad_source is not None and
 
1419
                source.endswith(self.bad_source)):
 
1420
                raise Bogus
 
1421
            elif (self.bad_target is not None and
 
1422
                target.endswith(self.bad_target)):
 
1423
                raise Bogus
 
1424
            else:
 
1425
                _FileMover.rename(self, source, target)
 
1426
 
 
1427
    def test_rollback_rename(self):
 
1428
        tree = self.make_branch_and_tree('.')
 
1429
        self.build_tree(['a/', 'a/b'])
 
1430
        tt = TreeTransform(tree)
 
1431
        self.addCleanup(tt.finalize)
 
1432
        a_id = tt.trans_id_tree_path('a')
 
1433
        tt.adjust_path('c', tt.root, a_id)
 
1434
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
 
1435
        self.assertRaises(Bogus, tt.apply,
 
1436
                          _mover=self.ExceptionFileMover(bad_source='a'))
 
1437
        self.failUnlessExists('a')
 
1438
        self.failUnlessExists('a/b')
 
1439
        tt.apply()
 
1440
        self.failUnlessExists('c')
 
1441
        self.failUnlessExists('c/d')
 
1442
 
 
1443
    def test_rollback_rename_into_place(self):
 
1444
        tree = self.make_branch_and_tree('.')
 
1445
        self.build_tree(['a/', 'a/b'])
 
1446
        tt = TreeTransform(tree)
 
1447
        self.addCleanup(tt.finalize)
 
1448
        a_id = tt.trans_id_tree_path('a')
 
1449
        tt.adjust_path('c', tt.root, a_id)
 
1450
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
 
1451
        self.assertRaises(Bogus, tt.apply,
 
1452
                          _mover=self.ExceptionFileMover(bad_target='c/d'))
 
1453
        self.failUnlessExists('a')
 
1454
        self.failUnlessExists('a/b')
 
1455
        tt.apply()
 
1456
        self.failUnlessExists('c')
 
1457
        self.failUnlessExists('c/d')
 
1458
 
 
1459
    def test_rollback_deletion(self):
 
1460
        tree = self.make_branch_and_tree('.')
 
1461
        self.build_tree(['a/', 'a/b'])
 
1462
        tt = TreeTransform(tree)
 
1463
        self.addCleanup(tt.finalize)
 
1464
        a_id = tt.trans_id_tree_path('a')
 
1465
        tt.delete_contents(a_id)
 
1466
        tt.adjust_path('d', tt.root, tt.trans_id_tree_path('a/b'))
 
1467
        self.assertRaises(Bogus, tt.apply,
 
1468
                          _mover=self.ExceptionFileMover(bad_target='d'))
 
1469
        self.failUnlessExists('a')
 
1470
        self.failUnlessExists('a/b')