44
48
# set_path_id setting id when state is in memory modified
47
def load_tests(basic_tests, module, loader):
48
suite = loader.suiteClass()
49
dir_reader_tests, remaining_tests = tests.split_suite_by_condition(
50
basic_tests, tests.condition_isinstance(TestCaseWithDirState))
51
tests.multiply_tests(dir_reader_tests,
52
test_osutils.dir_reader_scenarios(), suite)
53
suite.addTest(remaining_tests)
57
class TestCaseWithDirState(tests.TestCaseWithTransport):
51
class TestCaseWithDirState(TestCaseWithTransport):
58
52
"""Helper functions for creating DirState objects with various content."""
61
_dir_reader_class = None
62
_native_to_unicode = None # Not used yet
65
tests.TestCaseWithTransport.setUp(self)
67
# Save platform specific info and reset it
68
cur_dir_reader = osutils._selected_dir_reader
71
osutils._selected_dir_reader = cur_dir_reader
72
self.addCleanup(restore)
74
osutils._selected_dir_reader = self._dir_reader_class()
76
54
def create_empty_dirstate(self):
77
55
"""Return a locked but empty dirstate"""
78
56
state = dirstate.DirState.initialize('dirstate')
419
397
(('', '', tree.get_root_id()), # common details
420
398
[('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
421
399
('d', '', 0, False, rev_id), # first parent details
422
('d', '', 0, False, rev_id), # second parent details
400
('d', '', 0, False, rev_id2), # second parent details
424
402
state = dirstate.DirState.from_tree(tree, 'dirstate')
425
403
self.check_state_with_reopen(expected_result, state)
500
478
(('', '', tree.get_root_id()), # common details
501
479
[('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
502
480
('d', '', 0, False, rev_id), # first parent details
503
('d', '', 0, False, rev_id), # second parent details
481
('d', '', 0, False, rev_id2), # second parent details
505
483
(('', 'a file', 'a-file-id'), # common
506
484
[('f', '', 0, False, dirstate.DirState.NULLSTAT), # current
1000
980
[(('', '', root_id), [
1001
981
('d', '', 0, False, dirstate.DirState.NULLSTAT),
1002
982
('d', '', 0, False, revid1),
1003
('d', '', 0, False, revid1)
983
('d', '', 0, False, revid2)
1005
985
list(state._iter_entries()))
1034
1014
(('', '', root_id), [
1035
1015
('d', '', 0, False, dirstate.DirState.NULLSTAT),
1036
1016
('d', '', 0, False, revid1.encode('utf8')),
1037
('d', '', 0, False, revid1.encode('utf8'))
1017
('d', '', 0, False, revid2.encode('utf8'))
1039
1019
(('', 'a file', 'file-id'), [
1040
1020
('a', '', 0, False, ''),
1087
1067
state = dirstate.DirState.on_file('dirstate')
1088
1068
state.lock_read()
1089
self.addCleanup(state.unlock)
1090
self.assertEqual(expected_entries, list(state._iter_entries()))
1070
self.assertEqual(expected_entries, list(state._iter_entries()))
1092
1074
def test_add_path_to_unversioned_directory(self):
1093
1075
"""Adding a path to an unversioned directory should error.
1099
1081
self.build_tree(['unversioned/', 'unversioned/a file'])
1100
1082
state = dirstate.DirState.initialize('dirstate')
1101
self.addCleanup(state.unlock)
1102
self.assertRaises(errors.NotVersionedError, state.add,
1103
'unversioned/a file', 'a-file-id', 'file', None, None)
1084
self.assertRaises(errors.NotVersionedError, state.add,
1085
'unversioned/a file', 'a-file-id', 'file', None, None)
1105
1089
def test_add_directory_to_root_no_parents_all_data(self):
1106
1090
# The most trivial addition of a dir is when there are no parents and
1127
1111
state = dirstate.DirState.on_file('dirstate')
1128
1112
state.lock_read()
1129
self.addCleanup(state.unlock)
1130
1113
state._validate()
1131
self.assertEqual(expected_entries, list(state._iter_entries()))
1115
self.assertEqual(expected_entries, list(state._iter_entries()))
1133
def _test_add_symlink_to_root_no_parents_all_data(self, link_name, target):
1119
def test_add_symlink_to_root_no_parents_all_data(self):
1134
1120
# The most trivial addition of a symlink when there are no parents and
1135
1121
# its in the root and all data about the file is supplied
1136
1122
# bzr doesn't support fake symlinks on windows, yet.
1137
self.requireFeature(tests.SymlinkFeature)
1138
os.symlink(target, link_name)
1139
stat = os.lstat(link_name)
1123
self.requireFeature(SymlinkFeature)
1124
os.symlink('target', 'a link')
1125
stat = os.lstat('a link')
1140
1126
expected_entries = [
1141
1127
(('', '', 'TREE_ROOT'), [
1142
1128
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
1144
(('', link_name.encode('UTF-8'), 'a link id'), [
1145
('l', target.encode('UTF-8'), stat[6],
1146
False, dirstate.pack_stat(stat)), # current tree
1130
(('', 'a link', 'a link id'), [
1131
('l', 'target', 6, False, dirstate.pack_stat(stat)), # current tree
1149
1134
state = dirstate.DirState.initialize('dirstate')
1151
state.add(link_name, 'a link id', 'symlink', stat,
1152
target.encode('UTF-8'))
1136
state.add('a link', 'a link id', 'symlink', stat, 'target')
1153
1137
# having added it, it should be in the output of iter_entries.
1154
1138
self.assertEqual(expected_entries, list(state._iter_entries()))
1155
1139
# saving and reloading should not affect this.
1159
1143
state = dirstate.DirState.on_file('dirstate')
1160
1144
state.lock_read()
1161
self.addCleanup(state.unlock)
1162
self.assertEqual(expected_entries, list(state._iter_entries()))
1164
def test_add_symlink_to_root_no_parents_all_data(self):
1165
self._test_add_symlink_to_root_no_parents_all_data('a link', 'target')
1167
def test_add_symlink_unicode_to_root_no_parents_all_data(self):
1168
self.requireFeature(tests.UnicodeFilenameFeature)
1169
self._test_add_symlink_to_root_no_parents_all_data(
1170
u'\N{Euro Sign}link', u'targ\N{Euro Sign}et')
1146
self.assertEqual(expected_entries, list(state._iter_entries()))
1172
1150
def test_add_directory_and_child_no_parents_all_data(self):
1173
1151
# after adding a directory, we should be able to add children to it.
1199
1177
state = dirstate.DirState.on_file('dirstate')
1200
1178
state.lock_read()
1201
self.addCleanup(state.unlock)
1202
self.assertEqual(expected_entries, list(state._iter_entries()))
1180
self.assertEqual(expected_entries, list(state._iter_entries()))
1204
1184
def test_add_tree_reference(self):
1205
1185
# make a dirstate and add a tree reference
1220
1200
# now check we can read it back
1221
1201
state.lock_read()
1222
self.addCleanup(state.unlock)
1223
1202
state._validate()
1224
entry2 = state._get_entry(0, 'subdir-id', 'subdir')
1225
self.assertEqual(entry, entry2)
1226
self.assertEqual(entry, expected_entry)
1227
# and lookup by id should work too
1228
entry2 = state._get_entry(0, fileid_utf8='subdir-id')
1229
self.assertEqual(entry, expected_entry)
1204
entry2 = state._get_entry(0, 'subdir-id', 'subdir')
1205
self.assertEqual(entry, entry2)
1206
self.assertEqual(entry, expected_entry)
1207
# and lookup by id should work too
1208
entry2 = state._get_entry(0, fileid_utf8='subdir-id')
1209
self.assertEqual(entry, expected_entry)
1231
1213
def test_add_forbidden_names(self):
1232
1214
state = dirstate.DirState.initialize('dirstate')
1236
1218
self.assertRaises(errors.BzrError,
1237
1219
state.add, '..', 'ass-id', 'directory', None, None)
1239
def test_set_state_with_rename_b_a_bug_395556(self):
1240
# bug 395556 uncovered a bug where the dirstate ends up with a false
1241
# relocation record - in a tree with no parents there should be no
1242
# absent or relocated records. This then leads to further corruption
1243
# when a commit occurs, as the incorrect relocation gathers an
1244
# incorrect absent in tree 1, and future changes go to pot.
1245
tree1 = self.make_branch_and_tree('tree1')
1246
self.build_tree(['tree1/b'])
1249
tree1.add(['b'], ['b-id'])
1250
root_id = tree1.get_root_id()
1251
inv = tree1.inventory
1252
state = dirstate.DirState.initialize('dirstate')
1254
# Set the initial state with 'b'
1255
state.set_state_from_inventory(inv)
1256
inv.rename('b-id', root_id, 'a')
1257
# Set the new state with 'a', which currently corrupts.
1258
state.set_state_from_inventory(inv)
1259
expected_result1 = [('', '', root_id, 'd'),
1260
('', 'a', 'b-id', 'f'),
1263
for entry in state._iter_entries():
1264
values.append(entry[0] + entry[1][0][:1])
1265
self.assertEqual(expected_result1, values)
1272
1222
class TestGetLines(TestCaseWithDirState):
2257
2207
self.assertEqual(exp_dirblocks, state._dirblocks)
2260
class Test_InvEntryToDetails(tests.TestCase):
2210
class Test_InvEntryToDetails(TestCaseWithDirState):
2262
2212
def assertDetails(self, expected, inv_entry):
2263
2213
details = dirstate.DirState._inv_entry_to_details(inv_entry)
2270
2220
self.assertIsInstance(tree_data, str)
2272
2222
def test_unicode_symlink(self):
2273
inv_entry = inventory.InventoryLink('link-file-id',
2274
u'nam\N{Euro Sign}e',
2223
# In general, the code base doesn't support a target that contains
2224
# non-ascii characters. So we just assert tha
2225
inv_entry = inventory.InventoryLink('link-file-id', 'name',
2275
2226
'link-parent-id')
2276
2227
inv_entry.revision = 'link-revision-id'
2277
target = u'link-targ\N{Euro Sign}t'
2278
inv_entry.symlink_target = target
2279
self.assertDetails(('l', target.encode('UTF-8'), 0, False,
2280
'link-revision-id'), inv_entry)
2283
class TestSHA1Provider(tests.TestCaseInTempDir):
2228
inv_entry.symlink_target = u'link-target'
2229
details = self.assertDetails(('l', 'link-target', 0, False,
2230
'link-revision-id'), inv_entry)
2233
class TestSHA1Provider(TestCaseInTempDir):
2285
2235
def test_sha1provider_is_an_interface(self):
2286
2236
p = dirstate.SHA1Provider()