~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_dirstate.py

  • Committer: Martin Pool
  • Date: 2007-06-15 07:01:24 UTC
  • mfrom: (2528 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2530.
  • Revision ID: mbp@sourcefrog.net-20070615070124-clpwqh5gxc4wbf9l
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
561
564
            sha1sum = state.update_entry(entry, 'a-file', os.lstat('a-file'))
562
565
            # We should have gotten a real sha1
563
566
            self.assertEqual('ecc5374e9ed82ad3ea3b4d452ea995a5fd3e70e3',
688
691
            # This will unlock it
689
692
            self.check_state_with_reopen(expected_result, state)
690
693
 
 
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
 
691
735
    def test_set_path_id_no_parents(self):
692
736
        """The id of a path can be changed trivally with no parents."""
693
737
        state = dirstate.DirState.initialize('dirstate')
1421
1465
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1422
1466
                         link_or_sha1)
1423
1467
 
1424
 
        # The dirblock entry should be updated with the new info
1425
 
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1468
        # The dirblock entry should not cache the file's sha1
 
1469
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1426
1470
                         entry[1])
1427
1471
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1428
1472
                         state._dirblock_state)
1447
1491
                         link_or_sha1)
1448
1492
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1449
1493
                         state._dirblock_state)
 
1494
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
 
1495
                         entry[1])
1450
1496
        state.save()
1451
1497
 
1452
1498
        # However, if we move the clock forward so the file is considered
1453
 
        # "stable", it should just returned the cached value.
1454
 
        state.adjust_time(20)
 
1499
        # "stable", it should just cache the value.
 
1500
        state.adjust_time(+20)
1455
1501
        link_or_sha1 = state.update_entry(entry, abspath='a',
1456
1502
                                          stat_value=stat_value)
1457
1503
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1458
1504
                         link_or_sha1)
1459
1505
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1460
1506
                          ('sha1', 'a'), ('is_exec', mode, False),
 
1507
                          ('sha1', 'a'), ('is_exec', mode, False),
1461
1508
                         ], state._log)
 
1509
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1510
                         entry[1])
1462
1511
 
1463
 
    def test_update_entry_no_stat_value(self):
1464
 
        """Passing the stat_value is optional."""
1465
 
        state, entry = self.get_state_with_a()
1466
 
        state.adjust_time(-10) # Make sure the file looks new
1467
 
        self.build_tree(['a'])
1468
 
        # Add one where we don't provide the stat or sha already
1469
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1512
        # Subsequent calls will just return the cached value
 
1513
        link_or_sha1 = state.update_entry(entry, abspath='a',
 
1514
                                          stat_value=stat_value)
1470
1515
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1471
1516
                         link_or_sha1)
1472
 
        stat_value = os.lstat('a')
1473
 
        self.assertEqual([('lstat', 'a'), ('sha1', 'a'),
1474
 
                          ('is_exec', stat_value.st_mode, False),
 
1517
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
 
1518
                          ('sha1', 'a'), ('is_exec', mode, False),
 
1519
                          ('sha1', 'a'), ('is_exec', mode, False),
1475
1520
                         ], state._log)
 
1521
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1522
                         entry[1])
1476
1523
 
1477
1524
    def test_update_entry_symlink(self):
1478
1525
        """Update entry should read symlinks."""
1492
1539
                                          stat_value=stat_value)
1493
1540
        self.assertEqual('target', link_or_sha1)
1494
1541
        self.assertEqual([('read_link', 'a', '')], state._log)
1495
 
        # Dirblock is updated
1496
 
        self.assertEqual([('l', link_or_sha1, 6, False, packed_stat)],
 
1542
        # Dirblock is not updated (the link is too new)
 
1543
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1497
1544
                         entry[1])
1498
1545
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1499
1546
                         state._dirblock_state)
1503
1550
                                          stat_value=stat_value)
1504
1551
        self.assertEqual('target', link_or_sha1)
1505
1552
        self.assertEqual([('read_link', 'a', ''),
1506
 
                          ('read_link', 'a', 'target'),
 
1553
                          ('read_link', 'a', ''),
1507
1554
                         ], state._log)
 
1555
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
 
1556
                         entry[1])
1508
1557
        state.adjust_time(+20) # Skip into the future, all files look old
1509
1558
        link_or_sha1 = state.update_entry(entry, abspath='a',
1510
1559
                                          stat_value=stat_value)
1511
1560
        self.assertEqual('target', link_or_sha1)
1512
 
        # There should not be a new read_link call.
1513
 
        # (this is a weak assertion, because read_link is fairly inexpensive,
1514
 
        # versus the number of symlinks that we would have)
1515
 
        self.assertEqual([('read_link', 'a', ''),
1516
 
                          ('read_link', 'a', 'target'),
1517
 
                         ], state._log)
 
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)
1518
1583
 
1519
1584
    def test_update_entry_dir(self):
1520
1585
        state, entry = self.get_state_with_a()
1521
1586
        self.build_tree(['a/'])
1522
 
        self.assertIs(None, state.update_entry(entry, '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)
1523
1617
 
1524
1618
    def create_and_test_file(self, state, entry):
1525
1619
        """Create a file at 'a' and verify the state finds it.
1531
1625
        stat_value = os.lstat('a')
1532
1626
        packed_stat = dirstate.pack_stat(stat_value)
1533
1627
 
1534
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1628
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1535
1629
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1536
1630
                         link_or_sha1)
1537
1631
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1548
1642
        stat_value = os.lstat('a')
1549
1643
        packed_stat = dirstate.pack_stat(stat_value)
1550
1644
 
1551
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1645
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1552
1646
        self.assertIs(None, link_or_sha1)
1553
1647
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1554
1648
 
1569
1663
        stat_value = os.lstat('a')
1570
1664
        packed_stat = dirstate.pack_stat(stat_value)
1571
1665
 
1572
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1666
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1573
1667
        self.assertEqual('path/to/foo', link_or_sha1)
1574
1668
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1575
1669
                         entry[1])
1576
1670
        return packed_stat
1577
1671
 
1578
 
    def test_update_missing_file(self):
1579
 
        state, entry = self.get_state_with_a()
1580
 
        packed_stat = self.create_and_test_file(state, entry)
1581
 
        # Now if we delete the file, update_entry should recover and
1582
 
        # return None.
1583
 
        os.remove('a')
1584
 
        self.assertIs(None, state.update_entry(entry, abspath='a'))
1585
 
        # And the record shouldn't be changed.
1586
 
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1587
 
        self.assertEqual([('f', digest, 14, False, packed_stat)],
1588
 
                         entry[1])
1589
 
 
1590
 
    def test_update_missing_dir(self):
1591
 
        state, entry = self.get_state_with_a()
1592
 
        packed_stat = self.create_and_test_dir(state, entry)
1593
 
        # Now if we delete the directory, update_entry should recover and
1594
 
        # return None.
1595
 
        os.rmdir('a')
1596
 
        self.assertIs(None, state.update_entry(entry, abspath='a'))
1597
 
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1598
 
 
1599
 
    def test_update_missing_symlink(self):
1600
 
        if not osutils.has_symlinks():
1601
 
            # PlatformDeficiency / TestSkipped
1602
 
            raise TestSkipped("No symlink support")
1603
 
        state, entry = self.get_state_with_a()
1604
 
        packed_stat = self.create_and_test_symlink(state, entry)
1605
 
        os.remove('a')
1606
 
        self.assertIs(None, state.update_entry(entry, abspath='a'))
1607
 
        # And the record shouldn't be changed.
1608
 
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1609
 
                         entry[1])
1610
 
 
1611
1672
    def test_update_file_to_dir(self):
1612
1673
        """If a file changes to a directory we return None for the sha.
1613
1674
        We also update the inventory record.
1614
1675
        """
1615
1676
        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)
1616
1679
        self.create_and_test_file(state, entry)
1617
1680
        os.remove('a')
1618
1681
        self.create_and_test_dir(state, entry)
1623
1686
            # PlatformDeficiency / TestSkipped
1624
1687
            raise TestSkipped("No symlink support")
1625
1688
        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)
1626
1691
        self.create_and_test_file(state, entry)
1627
1692
        os.remove('a')
1628
1693
        self.create_and_test_symlink(state, entry)
1630
1695
    def test_update_dir_to_file(self):
1631
1696
        """Directory becoming a file updates the entry."""
1632
1697
        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)
1633
1700
        self.create_and_test_dir(state, entry)
1634
1701
        os.rmdir('a')
1635
1702
        self.create_and_test_file(state, entry)
1640
1707
            # PlatformDeficiency / TestSkipped
1641
1708
            raise TestSkipped("No symlink support")
1642
1709
        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)
1643
1712
        self.create_and_test_dir(state, entry)
1644
1713
        os.rmdir('a')
1645
1714
        self.create_and_test_symlink(state, entry)
1649
1718
        if not has_symlinks():
1650
1719
            raise TestSkipped("No symlink support")
1651
1720
        state, entry = self.get_state_with_a()
 
1721
        # The symlink and file info won't be cached unless old
 
1722
        state.adjust_time(+10)
1652
1723
        self.create_and_test_symlink(state, entry)
1653
1724
        os.remove('a')
1654
1725
        self.create_and_test_file(state, entry)
1658
1729
        if not has_symlinks():
1659
1730
            raise TestSkipped("No symlink support")
1660
1731
        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)
1661
1734
        self.create_and_test_symlink(state, entry)
1662
1735
        os.remove('a')
1663
1736
        self.create_and_test_dir(state, entry)
1677
1750
        packed_stat = dirstate.pack_stat(stat_value)
1678
1751
 
1679
1752
        state.adjust_time(-10) # Make sure everything is new
1680
 
        # Make sure it wants to kkkkkkkk
1681
1753
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1682
1754
 
1683
1755
        # 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)
1684
1761
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1762
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1685
1763
        self.assertEqual([('f', digest, 14, True, packed_stat)], entry[1])
1686
1764
 
1687
1765