~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-05-31 21:08:33 UTC
  • mfrom: (2485.3.14 dirstate_optim_2)
  • Revision ID: pqm@pqm.ubuntu.com-20070531210833-8ptk86ocu822hjd5
(John Arbash Meinel, r=robert) Tweak _iter_changes and update_entry to make bzr status and bzr diff much faster

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',
1421
1424
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1422
1425
                         link_or_sha1)
1423
1426
 
1424
 
        # The dirblock entry should be updated with the new info
1425
 
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1427
        # The dirblock entry should not cache the file's sha1
 
1428
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1426
1429
                         entry[1])
1427
1430
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1428
1431
                         state._dirblock_state)
1447
1450
                         link_or_sha1)
1448
1451
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1449
1452
                         state._dirblock_state)
 
1453
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
 
1454
                         entry[1])
1450
1455
        state.save()
1451
1456
 
1452
1457
        # 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)
 
1458
        # "stable", it should just cache the value.
 
1459
        state.adjust_time(+20)
1455
1460
        link_or_sha1 = state.update_entry(entry, abspath='a',
1456
1461
                                          stat_value=stat_value)
1457
1462
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1458
1463
                         link_or_sha1)
1459
1464
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1460
1465
                          ('sha1', 'a'), ('is_exec', mode, False),
 
1466
                          ('sha1', 'a'), ('is_exec', mode, False),
1461
1467
                         ], state._log)
 
1468
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1469
                         entry[1])
1462
1470
 
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')
 
1471
        # Subsequent calls will just return the cached value
 
1472
        link_or_sha1 = state.update_entry(entry, abspath='a',
 
1473
                                          stat_value=stat_value)
1470
1474
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1471
1475
                         link_or_sha1)
1472
 
        stat_value = os.lstat('a')
1473
 
        self.assertEqual([('lstat', 'a'), ('sha1', 'a'),
1474
 
                          ('is_exec', stat_value.st_mode, False),
 
1476
        self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
 
1477
                          ('sha1', 'a'), ('is_exec', mode, False),
 
1478
                          ('sha1', 'a'), ('is_exec', mode, False),
1475
1479
                         ], state._log)
 
1480
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
 
1481
                         entry[1])
1476
1482
 
1477
1483
    def test_update_entry_symlink(self):
1478
1484
        """Update entry should read symlinks."""
1492
1498
                                          stat_value=stat_value)
1493
1499
        self.assertEqual('target', link_or_sha1)
1494
1500
        self.assertEqual([('read_link', 'a', '')], state._log)
1495
 
        # Dirblock is updated
1496
 
        self.assertEqual([('l', link_or_sha1, 6, False, packed_stat)],
 
1501
        # Dirblock is not updated (the link is too new)
 
1502
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1497
1503
                         entry[1])
1498
1504
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1499
1505
                         state._dirblock_state)
1503
1509
                                          stat_value=stat_value)
1504
1510
        self.assertEqual('target', link_or_sha1)
1505
1511
        self.assertEqual([('read_link', 'a', ''),
1506
 
                          ('read_link', 'a', 'target'),
 
1512
                          ('read_link', 'a', ''),
1507
1513
                         ], state._log)
 
1514
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
 
1515
                         entry[1])
1508
1516
        state.adjust_time(+20) # Skip into the future, all files look old
1509
1517
        link_or_sha1 = state.update_entry(entry, abspath='a',
1510
1518
                                          stat_value=stat_value)
1511
1519
        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)
 
1520
        # We need to re-read the link because only now can we cache it
 
1521
        self.assertEqual([('read_link', 'a', ''),
 
1522
                          ('read_link', 'a', ''),
 
1523
                          ('read_link', 'a', ''),
 
1524
                         ], state._log)
 
1525
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
 
1526
                         entry[1])
 
1527
 
 
1528
        # Another call won't re-read the link
 
1529
        self.assertEqual([('read_link', 'a', ''),
 
1530
                          ('read_link', 'a', ''),
 
1531
                          ('read_link', 'a', ''),
 
1532
                         ], state._log)
 
1533
        link_or_sha1 = state.update_entry(entry, abspath='a',
 
1534
                                          stat_value=stat_value)
 
1535
        self.assertEqual('target', link_or_sha1)
 
1536
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
 
1537
                         entry[1])
 
1538
 
 
1539
    def do_update_entry(self, state, entry, abspath):
 
1540
        stat_value = os.lstat(abspath)
 
1541
        return state.update_entry(entry, abspath, stat_value)
1518
1542
 
1519
1543
    def test_update_entry_dir(self):
1520
1544
        state, entry = self.get_state_with_a()
1521
1545
        self.build_tree(['a/'])
1522
 
        self.assertIs(None, state.update_entry(entry, 'a'))
 
1546
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1547
 
 
1548
    def test_update_entry_dir_unchanged(self):
 
1549
        state, entry = self.get_state_with_a()
 
1550
        self.build_tree(['a/'])
 
1551
        state.adjust_time(+20)
 
1552
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1553
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
1554
                         state._dirblock_state)
 
1555
        state.save()
 
1556
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1557
                         state._dirblock_state)
 
1558
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
 
1559
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1560
                         state._dirblock_state)
 
1561
 
 
1562
    def test_update_entry_file_unchanged(self):
 
1563
        state, entry = self.get_state_with_a()
 
1564
        self.build_tree(['a'])
 
1565
        sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1566
        state.adjust_time(+20)
 
1567
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
 
1568
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
 
1569
                         state._dirblock_state)
 
1570
        state.save()
 
1571
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1572
                         state._dirblock_state)
 
1573
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
 
1574
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
 
1575
                         state._dirblock_state)
1523
1576
 
1524
1577
    def create_and_test_file(self, state, entry):
1525
1578
        """Create a file at 'a' and verify the state finds it.
1531
1584
        stat_value = os.lstat('a')
1532
1585
        packed_stat = dirstate.pack_stat(stat_value)
1533
1586
 
1534
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1587
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1535
1588
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1536
1589
                         link_or_sha1)
1537
1590
        self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1548
1601
        stat_value = os.lstat('a')
1549
1602
        packed_stat = dirstate.pack_stat(stat_value)
1550
1603
 
1551
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1604
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1552
1605
        self.assertIs(None, link_or_sha1)
1553
1606
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1554
1607
 
1569
1622
        stat_value = os.lstat('a')
1570
1623
        packed_stat = dirstate.pack_stat(stat_value)
1571
1624
 
1572
 
        link_or_sha1 = state.update_entry(entry, abspath='a')
 
1625
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1573
1626
        self.assertEqual('path/to/foo', link_or_sha1)
1574
1627
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1575
1628
                         entry[1])
1576
1629
        return packed_stat
1577
1630
 
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
1631
    def test_update_file_to_dir(self):
1612
1632
        """If a file changes to a directory we return None for the sha.
1613
1633
        We also update the inventory record.
1614
1634
        """
1615
1635
        state, entry = self.get_state_with_a()
 
1636
        # The file sha1 won't be cached unless the file is old
 
1637
        state.adjust_time(+10)
1616
1638
        self.create_and_test_file(state, entry)
1617
1639
        os.remove('a')
1618
1640
        self.create_and_test_dir(state, entry)
1623
1645
            # PlatformDeficiency / TestSkipped
1624
1646
            raise TestSkipped("No symlink support")
1625
1647
        state, entry = self.get_state_with_a()
 
1648
        # The file sha1 won't be cached unless the file is old
 
1649
        state.adjust_time(+10)
1626
1650
        self.create_and_test_file(state, entry)
1627
1651
        os.remove('a')
1628
1652
        self.create_and_test_symlink(state, entry)
1630
1654
    def test_update_dir_to_file(self):
1631
1655
        """Directory becoming a file updates the entry."""
1632
1656
        state, entry = self.get_state_with_a()
 
1657
        # The file sha1 won't be cached unless the file is old
 
1658
        state.adjust_time(+10)
1633
1659
        self.create_and_test_dir(state, entry)
1634
1660
        os.rmdir('a')
1635
1661
        self.create_and_test_file(state, entry)
1640
1666
            # PlatformDeficiency / TestSkipped
1641
1667
            raise TestSkipped("No symlink support")
1642
1668
        state, entry = self.get_state_with_a()
 
1669
        # The symlink target won't be cached if it isn't old
 
1670
        state.adjust_time(+10)
1643
1671
        self.create_and_test_dir(state, entry)
1644
1672
        os.rmdir('a')
1645
1673
        self.create_and_test_symlink(state, entry)
1649
1677
        if not has_symlinks():
1650
1678
            raise TestSkipped("No symlink support")
1651
1679
        state, entry = self.get_state_with_a()
 
1680
        # The symlink and file info won't be cached unless old
 
1681
        state.adjust_time(+10)
1652
1682
        self.create_and_test_symlink(state, entry)
1653
1683
        os.remove('a')
1654
1684
        self.create_and_test_file(state, entry)
1658
1688
        if not has_symlinks():
1659
1689
            raise TestSkipped("No symlink support")
1660
1690
        state, entry = self.get_state_with_a()
 
1691
        # The symlink target won't be cached if it isn't old
 
1692
        state.adjust_time(+10)
1661
1693
        self.create_and_test_symlink(state, entry)
1662
1694
        os.remove('a')
1663
1695
        self.create_and_test_dir(state, entry)
1677
1709
        packed_stat = dirstate.pack_stat(stat_value)
1678
1710
 
1679
1711
        state.adjust_time(-10) # Make sure everything is new
1680
 
        # Make sure it wants to kkkkkkkk
1681
1712
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1682
1713
 
1683
1714
        # The row is updated, but the executable bit stays set.
 
1715
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
 
1716
                         entry[1])
 
1717
 
 
1718
        # Make the disk object look old enough to cache
 
1719
        state.adjust_time(+20)
1684
1720
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1721
        state.update_entry(entry, abspath='a', stat_value=stat_value)
1685
1722
        self.assertEqual([('f', digest, 14, True, packed_stat)], entry[1])
1686
1723
 
1687
1724