1489
1492
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1490
1493
state._dirblock_state)
1494
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1493
1498
# However, if we move the clock forward so the file is considered
1494
# "stable", it should just returned the cached value.
1495
state.adjust_time(20)
1499
# "stable", it should just cache the value.
1500
state.adjust_time(+20)
1496
1501
link_or_sha1 = state.update_entry(entry, abspath='a',
1497
1502
stat_value=stat_value)
1498
1503
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1500
1505
self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1501
1506
('sha1', 'a'), ('is_exec', mode, False),
1507
('sha1', 'a'), ('is_exec', mode, False),
1509
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1504
def test_update_entry_no_stat_value(self):
1505
"""Passing the stat_value is optional."""
1506
state, entry = self.get_state_with_a()
1507
state.adjust_time(-10) # Make sure the file looks new
1508
self.build_tree(['a'])
1509
# Add one where we don't provide the stat or sha already
1510
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)
1511
1515
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1513
stat_value = os.lstat('a')
1514
self.assertEqual([('lstat', 'a'), ('sha1', 'a'),
1515
('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),
1521
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1518
1524
def test_update_entry_symlink(self):
1519
1525
"""Update entry should read symlinks."""
1533
1539
stat_value=stat_value)
1534
1540
self.assertEqual('target', link_or_sha1)
1535
1541
self.assertEqual([('read_link', 'a', '')], state._log)
1536
# Dirblock is updated
1537
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)],
1539
1545
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1540
1546
state._dirblock_state)
1544
1550
stat_value=stat_value)
1545
1551
self.assertEqual('target', link_or_sha1)
1546
1552
self.assertEqual([('read_link', 'a', ''),
1547
('read_link', 'a', 'target'),
1553
('read_link', 'a', ''),
1555
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1549
1557
state.adjust_time(+20) # Skip into the future, all files look old
1550
1558
link_or_sha1 = state.update_entry(entry, abspath='a',
1551
1559
stat_value=stat_value)
1552
1560
self.assertEqual('target', link_or_sha1)
1553
# There should not be a new read_link call.
1554
# (this is a weak assertion, because read_link is fairly inexpensive,
1555
# versus the number of symlinks that we would have)
1556
self.assertEqual([('read_link', 'a', ''),
1557
('read_link', 'a', 'target'),
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', ''),
1566
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1569
# Another call won't re-read the link
1570
self.assertEqual([('read_link', 'a', ''),
1571
('read_link', 'a', ''),
1572
('read_link', 'a', ''),
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)],
1580
def do_update_entry(self, state, entry, abspath):
1581
stat_value = os.lstat(abspath)
1582
return state.update_entry(entry, abspath, stat_value)
1560
1584
def test_update_entry_dir(self):
1561
1585
state, entry = self.get_state_with_a()
1562
1586
self.build_tree(['a/'])
1563
self.assertIs(None, state.update_entry(entry, 'a'))
1587
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
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)
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)
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)
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)
1565
1618
def create_and_test_file(self, state, entry):
1566
1619
"""Create a file at 'a' and verify the state finds it.
1610
1663
stat_value = os.lstat('a')
1611
1664
packed_stat = dirstate.pack_stat(stat_value)
1613
link_or_sha1 = state.update_entry(entry, abspath='a')
1666
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1614
1667
self.assertEqual('path/to/foo', link_or_sha1)
1615
1668
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1617
1670
return packed_stat
1619
def test_update_missing_file(self):
1620
state, entry = self.get_state_with_a()
1621
packed_stat = self.create_and_test_file(state, entry)
1622
# Now if we delete the file, update_entry should recover and
1625
self.assertIs(None, state.update_entry(entry, abspath='a'))
1626
# And the record shouldn't be changed.
1627
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1628
self.assertEqual([('f', digest, 14, False, packed_stat)],
1631
def test_update_missing_dir(self):
1632
state, entry = self.get_state_with_a()
1633
packed_stat = self.create_and_test_dir(state, entry)
1634
# Now if we delete the directory, update_entry should recover and
1637
self.assertIs(None, state.update_entry(entry, abspath='a'))
1638
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1640
def test_update_missing_symlink(self):
1641
if not osutils.has_symlinks():
1642
# PlatformDeficiency / TestSkipped
1643
raise TestSkipped("No symlink support")
1644
state, entry = self.get_state_with_a()
1645
packed_stat = self.create_and_test_symlink(state, entry)
1647
self.assertIs(None, state.update_entry(entry, abspath='a'))
1648
# And the record shouldn't be changed.
1649
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1652
1672
def test_update_file_to_dir(self):
1653
1673
"""If a file changes to a directory we return None for the sha.
1654
1674
We also update the inventory record.
1656
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)
1657
1679
self.create_and_test_file(state, entry)
1659
1681
self.create_and_test_dir(state, entry)
1718
1750
packed_stat = dirstate.pack_stat(stat_value)
1720
1752
state.adjust_time(-10) # Make sure everything is new
1721
# Make sure it wants to kkkkkkkk
1722
1753
state.update_entry(entry, abspath='a', stat_value=stat_value)
1724
1755
# The row is updated, but the executable bit stays set.
1756
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1759
# Make the disk object look old enough to cache
1760
state.adjust_time(+20)
1725
1761
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1762
state.update_entry(entry, abspath='a', stat_value=stat_value)
1726
1763
self.assertEqual([('f', digest, 14, True, packed_stat)], entry[1])