1448
1451
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1449
1452
state._dirblock_state)
1453
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
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',
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),
1468
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
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',
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),
1480
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
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)],
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', ''),
1514
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
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'),
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', ''),
1525
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1528
# Another call won't re-read the link
1529
self.assertEqual([('read_link', 'a', ''),
1530
('read_link', 'a', ''),
1531
('read_link', 'a', ''),
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)],
1539
def do_update_entry(self, state, entry, abspath):
1540
stat_value = os.lstat(abspath)
1541
return state.update_entry(entry, abspath, stat_value)
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'))
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)
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)
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)
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)
1524
1577
def create_and_test_file(self, state, entry):
1525
1578
"""Create a file at 'a' and verify the state finds it.
1569
1622
stat_value = os.lstat('a')
1570
1623
packed_stat = dirstate.pack_stat(stat_value)
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)],
1576
1629
return packed_stat
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
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)],
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
1596
self.assertIs(None, state.update_entry(entry, abspath='a'))
1597
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
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)
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)],
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.
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)
1618
1640
self.create_and_test_dir(state, entry)
1677
1709
packed_stat = dirstate.pack_stat(stat_value)
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)
1683
1714
# The row is updated, but the executable bit stays set.
1715
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
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])