~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_dirstate.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-17 00:59:30 UTC
  • mfrom: (1551.15.4 Aaron's mergeable stuff)
  • Revision ID: pqm@pqm.ubuntu.com-20070417005930-rofskshyjsfzrahh
Fix ftp transport with servers that don't support atomic rename

Show diffs side-by-side

added added

removed removed

Lines of Context:
173
173
            state.save()
174
174
        finally:
175
175
            state.unlock()
176
 
        del state
 
176
        del state # Callers should unlock
177
177
        state = dirstate.DirState.on_file('dirstate')
178
178
        state.lock_read()
179
179
        try:
200
200
        tree.commit('initial', rev_id='rev-1')
201
201
        revision_id = 'rev-1'
202
202
        # a_packed_stat = dirstate.pack_stat(os.stat('tree/a'))
203
 
        t = self.get_transport('tree')
 
203
        t = self.get_transport().clone('tree')
204
204
        a_text = t.get_bytes('a')
205
205
        a_sha = osutils.sha_string(a_text)
206
206
        a_len = len(a_text)
558
558
            self.assertEqual('', entry[1][0][1])
559
559
            # We should have a real entry.
560
560
            self.assertNotEqual((None, None), entry)
561
 
            # Make sure everything is old enough
562
 
            state._sha_cutoff_time()
563
 
            state._cutoff_time += 10
564
561
            sha1sum = state.update_entry(entry, 'a-file', os.lstat('a-file'))
565
562
            # We should have gotten a real sha1
566
563
            self.assertEqual('ecc5374e9ed82ad3ea3b4d452ea995a5fd3e70e3',
651
648
        try:
652
649
            self.assertIsInstance(state, dirstate.DirState)
653
650
            lines = state.get_lines()
654
 
        finally:
 
651
            self.assertFileEqual(''.join(state.get_lines()),
 
652
                'dirstate')
 
653
            self.check_state_with_reopen(expected_result, state)
 
654
        except:
655
655
            state.unlock()
656
 
        # On win32 you can't read from a locked file, even within the same
657
 
        # process. So we have to unlock and release before we check the file
658
 
        # contents.
659
 
        self.assertFileEqual(''.join(lines), 'dirstate')
660
 
        state.lock_read() # check_state_with_reopen will unlock
661
 
        self.check_state_with_reopen(expected_result, state)
 
656
            raise
662
657
 
663
658
 
664
659
class TestDirStateManipulations(TestCaseWithDirState):
691
686
            # This will unlock it
692
687
            self.check_state_with_reopen(expected_result, state)
693
688
 
694
 
    def test_set_state_from_inventory_mixed_paths(self):
695
 
        tree1 = self.make_branch_and_tree('tree1')
696
 
        self.build_tree(['tree1/a/', 'tree1/a/b/', 'tree1/a-b/',
697
 
                         'tree1/a/b/foo', 'tree1/a-b/bar'])
698
 
        tree1.lock_write()
699
 
        try:
700
 
            tree1.add(['a', 'a/b', 'a-b', 'a/b/foo', 'a-b/bar'],
701
 
                      ['a-id', 'b-id', 'a-b-id', 'foo-id', 'bar-id'])
702
 
            tree1.commit('rev1', rev_id='rev1')
703
 
            root_id = tree1.get_root_id()
704
 
            inv = tree1.inventory
705
 
        finally:
706
 
            tree1.unlock()
707
 
        expected_result1 = [('', '', root_id, 'd'),
708
 
                            ('', 'a', 'a-id', 'd'),
709
 
                            ('', 'a-b', 'a-b-id', 'd'),
710
 
                            ('a', 'b', 'b-id', 'd'),
711
 
                            ('a/b', 'foo', 'foo-id', 'f'),
712
 
                            ('a-b', 'bar', 'bar-id', 'f'),
713
 
                           ]
714
 
        expected_result2 = [('', '', root_id, 'd'),
715
 
                            ('', 'a', 'a-id', 'd'),
716
 
                            ('', 'a-b', 'a-b-id', 'd'),
717
 
                            ('a-b', 'bar', 'bar-id', 'f'),
718
 
                           ]
719
 
        state = dirstate.DirState.initialize('dirstate')
720
 
        try:
721
 
            state.set_state_from_inventory(inv)
722
 
            values = []
723
 
            for entry in state._iter_entries():
724
 
                values.append(entry[0] + entry[1][0][:1])
725
 
            self.assertEqual(expected_result1, values)
726
 
            del inv['b-id']
727
 
            state.set_state_from_inventory(inv)
728
 
            values = []
729
 
            for entry in state._iter_entries():
730
 
                values.append(entry[0] + entry[1][0][:1])
731
 
            self.assertEqual(expected_result2, values)
732
 
        finally:
733
 
            state.unlock()
734
 
 
735
689
    def test_set_path_id_no_parents(self):
736
690
        """The id of a path can be changed trivally with no parents."""
737
691
        state = dirstate.DirState.initialize('dirstate')
1465
1419
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1466
1420
                         link_or_sha1)
1467
1421
 
1468
 
        # The dirblock entry should not cache the file's sha1
1469
 
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
 
1422
        # The dirblock entry should be updated with the new info
 
1423
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1470
1424
                         entry[1])
1471
1425
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1472
1426
                         state._dirblock_state)
1491
1445
                         link_or_sha1)
1492
1446
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1493
1447
                         state._dirblock_state)
1494
 
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1495
 
                         entry[1])
1496
1448
        state.save()
1497
1449
 
1498
1450
        # However, if we move the clock forward so the file is considered
1499
 
        # "stable", it should just cache the value.
1500
 
        state.adjust_time(+20)
 
1451
        # "stable", it should just returned the cached value.
 
1452
        state.adjust_time(20)
1501
1453
        link_or_sha1 = state.update_entry(entry, abspath='a',
1502
1454
                                          stat_value=stat_value)
1503
1455
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1504
1456
                         link_or_sha1)
1505
1457
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1506
1458
                          ('sha1', 'a'), ('is_exec', mode, False),
1507
 
                          ('sha1', 'a'), ('is_exec', mode, False),
1508
1459
                         ], state._log)
1509
 
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1510
 
                         entry[1])
1511
1460
 
1512
 
        # Subsequent calls will just return the cached value
1513
 
        link_or_sha1 = state.update_entry(entry, abspath='a',
1514
 
                                          stat_value=stat_value)
 
1461
    def test_update_entry_no_stat_value(self):
 
1462
        """Passing the stat_value is optional."""
 
1463
        state, entry = self.get_state_with_a()
 
1464
        state.adjust_time(-10) # Make sure the file looks new
 
1465
        self.build_tree(['a'])
 
1466
        # Add one where we don't provide the stat or sha already
 
1467
        link_or_sha1 = state.update_entry(entry, abspath='a')
1515
1468
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1516
1469
                         link_or_sha1)
1517
 
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1518
 
                          ('sha1', 'a'), ('is_exec', mode, False),
1519
 
                          ('sha1', 'a'), ('is_exec', mode, False),
 
1470
        stat_value = os.lstat('a')
 
1471
        self.assertEqual([('lstat', 'a'), ('sha1', 'a'),
 
1472
                          ('is_exec', stat_value.st_mode, False),
1520
1473
                         ], state._log)
1521
 
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1522
 
                         entry[1])
1523
1474
 
1524
1475
    def test_update_entry_symlink(self):
1525
1476
        """Update entry should read symlinks."""
1539
1490
                                          stat_value=stat_value)
1540
1491
        self.assertEqual('target', link_or_sha1)
1541
1492
        self.assertEqual([('read_link', 'a', '')], state._log)
1542
 
        # Dirblock is not updated (the link is too new)
1543
 
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
 
1493
        # Dirblock is updated
 
1494
        self.assertEqual([('l', link_or_sha1, 6, False, packed_stat)],
1544
1495
                         entry[1])
1545
1496
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1546
1497
                         state._dirblock_state)
1550
1501
                                          stat_value=stat_value)
1551
1502
        self.assertEqual('target', link_or_sha1)
1552
1503
        self.assertEqual([('read_link', 'a', ''),
1553
 
                          ('read_link', 'a', ''),
 
1504
                          ('read_link', 'a', 'target'),
1554
1505
                         ], state._log)
1555
 
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1556
 
                         entry[1])
1557
1506
        state.adjust_time(+20) # Skip into the future, all files look old
1558
1507
        link_or_sha1 = state.update_entry(entry, abspath='a',
1559
1508
                                          stat_value=stat_value)
1560
1509
        self.assertEqual('target', link_or_sha1)
1561
 
        # We need to re-read the link because only now can we cache it
1562
 
        self.assertEqual([('read_link', 'a', ''),
1563
 
                          ('read_link', 'a', ''),
1564
 
                          ('read_link', 'a', ''),
1565
 
                         ], state._log)
1566
 
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
1567
 
                         entry[1])
1568
 
 
1569
 
        # Another call won't re-read the link
1570
 
        self.assertEqual([('read_link', 'a', ''),
1571
 
                          ('read_link', 'a', ''),
1572
 
                          ('read_link', 'a', ''),
1573
 
                         ], state._log)
1574
 
        link_or_sha1 = state.update_entry(entry, abspath='a',
1575
 
                                          stat_value=stat_value)
1576
 
        self.assertEqual('target', link_or_sha1)
1577
 
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
1578
 
                         entry[1])
1579
 
 
1580
 
    def do_update_entry(self, state, entry, abspath):
1581
 
        stat_value = os.lstat(abspath)
1582
 
        return state.update_entry(entry, abspath, stat_value)
 
1510
        # There should not be a new read_link call.
 
1511
        # (this is a weak assertion, because read_link is fairly inexpensive,
 
1512
        # versus the number of symlinks that we would have)
 
1513
        self.assertEqual([('read_link', 'a', ''),
 
1514
                          ('read_link', 'a', 'target'),
 
1515
                         ], state._log)
1583
1516
 
1584
1517
    def test_update_entry_dir(self):
1585
1518
        state, entry = self.get_state_with_a()
1586
1519
        self.build_tree(['a/'])
1587
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1588
 
 
1589
 
    def test_update_entry_dir_unchanged(self):
1590
 
        state, entry = self.get_state_with_a()
1591
 
        self.build_tree(['a/'])
1592
 
        state.adjust_time(+20)
1593
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1594
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1595
 
                         state._dirblock_state)
1596
 
        state.save()
1597
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1598
 
                         state._dirblock_state)
1599
 
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1600
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1601
 
                         state._dirblock_state)
1602
 
 
1603
 
    def test_update_entry_file_unchanged(self):
1604
 
        state, entry = self.get_state_with_a()
1605
 
        self.build_tree(['a'])
1606
 
        sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1607
 
        state.adjust_time(+20)
1608
 
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1609
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1610
 
                         state._dirblock_state)
1611
 
        state.save()
1612
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1613
 
                         state._dirblock_state)
1614
 
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1615
 
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1616
 
                         state._dirblock_state)
 
1520
        self.assertIs(None, state.update_entry(entry, 'a'))
1617
1521
 
1618
1522
    def create_and_test_file(self, state, entry):
1619
1523
        """Create a file at 'a' and verify the state finds it.
1625
1529
        stat_value = os.lstat('a')
1626
1530
        packed_stat = dirstate.pack_stat(stat_value)
1627
1531
 
1628
 
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
 
1532
        link_or_sha1 = state.update_entry(entry, abspath='a')
1629
1533
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1630
1534
                         link_or_sha1)
1631
1535
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1642
1546
        stat_value = os.lstat('a')
1643
1547
        packed_stat = dirstate.pack_stat(stat_value)
1644
1548
 
1645
 
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
 
1549
        link_or_sha1 = state.update_entry(entry, abspath='a')
1646
1550
        self.assertIs(None, link_or_sha1)
1647
1551
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1648
1552
 
1663
1567
        stat_value = os.lstat('a')
1664
1568
        packed_stat = dirstate.pack_stat(stat_value)
1665
1569
 
1666
 
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
 
1570
        link_or_sha1 = state.update_entry(entry, abspath='a')
1667
1571
        self.assertEqual('path/to/foo', link_or_sha1)
1668
1572
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1669
1573
                         entry[1])
1670
1574
        return packed_stat
1671
1575
 
 
1576
    def test_update_missing_file(self):
 
1577
        state, entry = self.get_state_with_a()
 
1578
        packed_stat = self.create_and_test_file(state, entry)
 
1579
        # Now if we delete the file, update_entry should recover and
 
1580
        # return None.
 
1581
        os.remove('a')
 
1582
        self.assertIs(None, state.update_entry(entry, abspath='a'))
 
1583
        # And the record shouldn't be changed.
 
1584
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1585
        self.assertEqual([('f', digest, 14, False, packed_stat)],
 
1586
                         entry[1])
 
1587
 
 
1588
    def test_update_missing_dir(self):
 
1589
        state, entry = self.get_state_with_a()
 
1590
        packed_stat = self.create_and_test_dir(state, entry)
 
1591
        # Now if we delete the directory, update_entry should recover and
 
1592
        # return None.
 
1593
        os.rmdir('a')
 
1594
        self.assertIs(None, state.update_entry(entry, abspath='a'))
 
1595
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
 
1596
 
 
1597
    def test_update_missing_symlink(self):
 
1598
        if not osutils.has_symlinks():
 
1599
            # PlatformDeficiency / TestSkipped
 
1600
            raise TestSkipped("No symlink support")
 
1601
        state, entry = self.get_state_with_a()
 
1602
        packed_stat = self.create_and_test_symlink(state, entry)
 
1603
        os.remove('a')
 
1604
        self.assertIs(None, state.update_entry(entry, abspath='a'))
 
1605
        # And the record shouldn't be changed.
 
1606
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
 
1607
                         entry[1])
 
1608
 
1672
1609
    def test_update_file_to_dir(self):
1673
1610
        """If a file changes to a directory we return None for the sha.
1674
1611
        We also update the inventory record.
1675
1612
        """
1676
1613
        state, entry = self.get_state_with_a()
1677
 
        # The file sha1 won't be cached unless the file is old
1678
 
        state.adjust_time(+10)
1679
1614
        self.create_and_test_file(state, entry)
1680
1615
        os.remove('a')
1681
1616
        self.create_and_test_dir(state, entry)
1686
1621
            # PlatformDeficiency / TestSkipped
1687
1622
            raise TestSkipped("No symlink support")
1688
1623
        state, entry = self.get_state_with_a()
1689
 
        # The file sha1 won't be cached unless the file is old
1690
 
        state.adjust_time(+10)
1691
1624
        self.create_and_test_file(state, entry)
1692
1625
        os.remove('a')
1693
1626
        self.create_and_test_symlink(state, entry)
1695
1628
    def test_update_dir_to_file(self):
1696
1629
        """Directory becoming a file updates the entry."""
1697
1630
        state, entry = self.get_state_with_a()
1698
 
        # The file sha1 won't be cached unless the file is old
1699
 
        state.adjust_time(+10)
1700
1631
        self.create_and_test_dir(state, entry)
1701
1632
        os.rmdir('a')
1702
1633
        self.create_and_test_file(state, entry)
1707
1638
            # PlatformDeficiency / TestSkipped
1708
1639
            raise TestSkipped("No symlink support")
1709
1640
        state, entry = self.get_state_with_a()
1710
 
        # The symlink target won't be cached if it isn't old
1711
 
        state.adjust_time(+10)
1712
1641
        self.create_and_test_dir(state, entry)
1713
1642
        os.rmdir('a')
1714
1643
        self.create_and_test_symlink(state, entry)
1718
1647
        if not has_symlinks():
1719
1648
            raise TestSkipped("No symlink support")
1720
1649
        state, entry = self.get_state_with_a()
1721
 
        # The symlink and file info won't be cached unless old
1722
 
        state.adjust_time(+10)
1723
1650
        self.create_and_test_symlink(state, entry)
1724
1651
        os.remove('a')
1725
1652
        self.create_and_test_file(state, entry)
1729
1656
        if not has_symlinks():
1730
1657
            raise TestSkipped("No symlink support")
1731
1658
        state, entry = self.get_state_with_a()
1732
 
        # The symlink target won't be cached if it isn't old
1733
 
        state.adjust_time(+10)
1734
1659
        self.create_and_test_symlink(state, entry)
1735
1660
        os.remove('a')
1736
1661
        self.create_and_test_dir(state, entry)
1750
1675
        packed_stat = dirstate.pack_stat(stat_value)
1751
1676
 
1752
1677
        state.adjust_time(-10) # Make sure everything is new
 
1678
        # Make sure it wants to kkkkkkkk
1753
1679
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1754
1680
 
1755
1681
        # The row is updated, but the executable bit stays set.
1756
 
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1757
 
                         entry[1])
1758
 
 
1759
 
        # Make the disk object look old enough to cache
1760
 
        state.adjust_time(+20)
1761
1682
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1762
 
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1763
1683
        self.assertEqual([('f', digest, 14, True, packed_stat)], entry[1])
1764
1684
 
1765
1685