/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__dirstate_helpers.py

  • Committer: Robert Collins
  • Date: 2009-05-23 20:57:12 UTC
  • mfrom: (4371 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4441.
  • Revision ID: robertc@robertcollins.net-20090523205712-lcwbfqk6vwavinuv
MergeĀ .dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for the compiled dirstate helpers."""
18
18
 
23
23
from bzrlib import (
24
24
    dirstate,
25
25
    errors,
 
26
    osutils,
26
27
    tests,
27
28
    )
28
29
from bzrlib.tests import (
29
 
        SymlinkFeature,
30
 
        )
31
 
from bzrlib.tests import test_dirstate
 
30
    test_dirstate,
 
31
    test_osutils,
 
32
    )
 
33
 
 
34
try:
 
35
    from bzrlib import _dirstate_helpers_c
 
36
    has_dirstate_helpers_c = True
 
37
except ImportError:
 
38
    has_dirstate_helpers_c = False
32
39
 
33
40
 
34
41
class _CompiledDirstateHelpersFeature(tests.Feature):
35
42
    def _probe(self):
36
 
        try:
37
 
            import bzrlib._dirstate_helpers_c
38
 
        except ImportError:
39
 
            return False
40
 
        return True
 
43
        return has_dirstate_helpers_c
41
44
 
42
45
    def feature_name(self):
43
46
        return 'bzrlib._dirstate_helpers_c'
44
 
 
45
47
CompiledDirstateHelpersFeature = _CompiledDirstateHelpersFeature()
46
48
 
47
49
 
 
50
def load_tests(basic_tests, module, loader):
 
51
    # FIXME: we should also parametrize against SHA1Provider !
 
52
    suite = loader.suiteClass()
 
53
    remaining_tests = basic_tests
 
54
 
 
55
    dir_reader_scenarios = test_osutils.dir_reader_scenarios()
 
56
 
 
57
    ue_scenarios = [('dirstate_Python',
 
58
                     {'update_entry': dirstate.py_update_entry})]
 
59
    if has_dirstate_helpers_c:
 
60
        c_scenario = ('dirstate_C',
 
61
                     {'update_entry': _dirstate_helpers_c.update_entry})
 
62
        ue_scenarios.append(c_scenario)
 
63
    process_entry_tests, remaining_tests = tests.split_suite_by_condition(
 
64
        remaining_tests, tests.condition_isinstance(TestUpdateEntry))
 
65
    tests.multiply_tests(process_entry_tests,
 
66
                         tests.multiply_scenarios(dir_reader_scenarios,
 
67
                                                  ue_scenarios),
 
68
                         suite)
 
69
 
 
70
    pe_scenarios = [('dirstate_Python',
 
71
                     {'_process_entry': dirstate.ProcessEntryPython})]
 
72
    if has_dirstate_helpers_c:
 
73
        c_scenario = ('dirstate_C',
 
74
                     {'_process_entry': _dirstate_helpers_c.ProcessEntryC})
 
75
        pe_scenarios.append(c_scenario)
 
76
    process_entry_tests, remaining_tests = tests.split_suite_by_condition(
 
77
        remaining_tests, tests.condition_isinstance(TestProcessEntry))
 
78
    tests.multiply_tests(process_entry_tests,
 
79
                         tests.multiply_scenarios(dir_reader_scenarios,
 
80
                                                  pe_scenarios),
 
81
                         suite)
 
82
 
 
83
    dir_reader_tests, remaining_tests = tests.split_suite_by_condition(
 
84
        remaining_tests, tests.condition_isinstance(
 
85
            test_dirstate.TestCaseWithDirState))
 
86
    tests.multiply_tests(dir_reader_tests, dir_reader_scenarios, suite)
 
87
    suite.addTest(remaining_tests)
 
88
 
 
89
    return suite
 
90
 
 
91
 
48
92
class TestBisectPathMixin(object):
49
93
    """Test that _bisect_path_*() returns the expected values.
50
94
 
789
833
class TestUpdateEntry(test_dirstate.TestCaseWithDirState):
790
834
    """Test the DirState.update_entry functions"""
791
835
 
 
836
    # Set by load_tests
 
837
    update_entry = None
 
838
 
 
839
    def setUp(self):
 
840
        super(TestUpdateEntry, self).setUp()
 
841
        orig = dirstate.update_entry
 
842
        def cleanup():
 
843
            dirstate.update_entry = orig
 
844
        self.addCleanup(cleanup)
 
845
        dirstate.update_entry = self.update_entry
 
846
 
792
847
    def get_state_with_a(self):
793
848
        """Create a DirState tracking a single object named 'a'"""
794
849
        state = test_dirstate.InstrumentedDirState.initialize('dirstate')
795
850
        self.addCleanup(state.unlock)
796
851
        state.add('a', 'a-id', 'file', None, '')
797
852
        entry = state._get_entry(0, path_utf8='a')
798
 
        self.set_update_entry()
799
853
        return state, entry
800
854
 
801
 
    def set_update_entry(self):
802
 
        self.update_entry = dirstate.py_update_entry
803
 
 
804
855
    def test_observed_sha1_cachable(self):
805
856
        state, entry = self.get_state_with_a()
806
857
        atime = time.time() - 10
920
971
 
921
972
    def test_update_entry_symlink(self):
922
973
        """Update entry should read symlinks."""
923
 
        self.requireFeature(SymlinkFeature)
 
974
        self.requireFeature(tests.SymlinkFeature)
924
975
        state, entry = self.get_state_with_a()
925
976
        state.save()
926
977
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1021
1072
                         state._dirblock_state)
1022
1073
 
1023
1074
    def test_update_entry_tree_reference(self):
1024
 
        self.set_update_entry()
1025
1075
        state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1026
1076
        self.addCleanup(state.unlock)
1027
1077
        state.add('r', 'r-id', 'tree-reference', None, '')
1063
1113
 
1064
1114
        return packed_stat
1065
1115
 
 
1116
    # FIXME: Add unicode version
1066
1117
    def create_and_test_symlink(self, state, entry):
1067
1118
        """Create a symlink at 'a' and verify the state finds it.
1068
1119
 
1097
1148
 
1098
1149
    def test_update_file_to_symlink(self):
1099
1150
        """File becomes a symlink"""
1100
 
        self.requireFeature(SymlinkFeature)
 
1151
        self.requireFeature(tests.SymlinkFeature)
1101
1152
        state, entry = self.get_state_with_a()
1102
1153
        # The file sha1 won't be cached unless the file is old
1103
1154
        state.adjust_time(+10)
1116
1167
 
1117
1168
    def test_update_dir_to_symlink(self):
1118
1169
        """Directory becomes a symlink"""
1119
 
        self.requireFeature(SymlinkFeature)
 
1170
        self.requireFeature(tests.SymlinkFeature)
1120
1171
        state, entry = self.get_state_with_a()
1121
1172
        # The symlink target won't be cached if it isn't old
1122
1173
        state.adjust_time(+10)
1126
1177
 
1127
1178
    def test_update_symlink_to_file(self):
1128
1179
        """Symlink becomes a file"""
1129
 
        self.requireFeature(SymlinkFeature)
 
1180
        self.requireFeature(tests.SymlinkFeature)
1130
1181
        state, entry = self.get_state_with_a()
1131
1182
        # The symlink and file info won't be cached unless old
1132
1183
        state.adjust_time(+10)
1136
1187
 
1137
1188
    def test_update_symlink_to_dir(self):
1138
1189
        """Symlink becomes a directory"""
1139
 
        self.requireFeature(SymlinkFeature)
 
1190
        self.requireFeature(tests.SymlinkFeature)
1140
1191
        state, entry = self.get_state_with_a()
1141
1192
        # The symlink target won't be cached if it isn't old
1142
1193
        state.adjust_time(+10)
1165
1216
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1166
1217
                         entry[1])
1167
1218
 
1168
 
        # Make the disk object look old enough to cache (but it won't cache the sha
1169
 
        # as it is a new file).
 
1219
        # Make the disk object look old enough to cache (but it won't cache the
 
1220
        # sha as it is a new file).
1170
1221
        state.adjust_time(+20)
1171
1222
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1172
1223
        self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1173
1224
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1174
1225
            entry[1])
1175
1226
 
1176
 
 
1177
 
class TestCompiledUpdateEntry(TestUpdateEntry):
1178
 
    """Test the pyrex implementation of _read_dirblocks"""
1179
 
 
1180
 
    _test_needs_features = [CompiledDirstateHelpersFeature]
1181
 
 
1182
 
    def set_update_entry(self):
1183
 
        from bzrlib._dirstate_helpers_c import update_entry
1184
 
        self.update_entry = update_entry
 
1227
    def _prepare_tree(self):
 
1228
        # Create a tree
 
1229
        text = 'Hello World\n'
 
1230
        tree = self.make_branch_and_tree('tree')
 
1231
        self.build_tree_contents([('tree/a file', text)])
 
1232
        tree.add('a file', 'a-file-id')
 
1233
        # Note: dirstate does not sha prior to the first commit
 
1234
        # so commit now in order for the test to work
 
1235
        tree.commit('first')
 
1236
        return tree, text
 
1237
 
 
1238
    def test_sha1provider_sha1_used(self):
 
1239
        tree, text = self._prepare_tree()
 
1240
        state = dirstate.DirState.from_tree(tree, 'dirstate',
 
1241
            UppercaseSHA1Provider())
 
1242
        self.addCleanup(state.unlock)
 
1243
        expected_sha = osutils.sha_string(text.upper() + "foo")
 
1244
        entry = state._get_entry(0, path_utf8='a file')
 
1245
        state._sha_cutoff_time()
 
1246
        state._cutoff_time += 10
 
1247
        sha1 = self.update_entry(state, entry, 'tree/a file',
 
1248
                                 os.lstat('tree/a file'))
 
1249
        self.assertEqual(expected_sha, sha1)
 
1250
 
 
1251
    def test_sha1provider_stat_and_sha1_used(self):
 
1252
        tree, text = self._prepare_tree()
 
1253
        tree.lock_write()
 
1254
        self.addCleanup(tree.unlock)
 
1255
        state = tree._current_dirstate()
 
1256
        state._sha1_provider = UppercaseSHA1Provider()
 
1257
        # If we used the standard provider, it would look like nothing has
 
1258
        # changed
 
1259
        file_ids_changed = [change[0] for change
 
1260
                            in tree.iter_changes(tree.basis_tree())]
 
1261
        self.assertEqual(['a-file-id'], file_ids_changed)
 
1262
 
 
1263
 
 
1264
class UppercaseSHA1Provider(dirstate.SHA1Provider):
 
1265
    """A custom SHA1Provider."""
 
1266
 
 
1267
    def sha1(self, abspath):
 
1268
        return self.stat_and_sha1(abspath)[1]
 
1269
 
 
1270
    def stat_and_sha1(self, abspath):
 
1271
        file_obj = file(abspath, 'rb')
 
1272
        try:
 
1273
            statvalue = os.fstat(file_obj.fileno())
 
1274
            text = ''.join(file_obj.readlines())
 
1275
            sha1 = osutils.sha_string(text.upper() + "foo")
 
1276
        finally:
 
1277
            file_obj.close()
 
1278
        return statvalue, sha1
 
1279
 
 
1280
 
 
1281
class TestProcessEntry(test_dirstate.TestCaseWithDirState):
 
1282
 
 
1283
    # Set by load_tests
 
1284
    _process_entry = None
 
1285
 
 
1286
    def setUp(self):
 
1287
        super(TestProcessEntry, self).setUp()
 
1288
        orig = dirstate._process_entry
 
1289
        def cleanup():
 
1290
            dirstate._process_entry = orig
 
1291
        self.addCleanup(cleanup)
 
1292
        dirstate._process_entry = self._process_entry
 
1293
 
 
1294
    def assertChangedFileIds(self, expected, tree):
 
1295
        tree.lock_read()
 
1296
        try:
 
1297
            file_ids = [info[0] for info
 
1298
                        in tree.iter_changes(tree.basis_tree())]
 
1299
        finally:
 
1300
            tree.unlock()
 
1301
        self.assertEqual(sorted(expected), sorted(file_ids))
 
1302
 
 
1303
    def test_simple_changes(self):
 
1304
        tree = self.make_branch_and_tree('tree')
 
1305
        self.build_tree(['tree/file'])
 
1306
        tree.add(['file'], ['file-id'])
 
1307
        self.assertChangedFileIds([tree.get_root_id(), 'file-id'], tree)
 
1308
        tree.commit('one')
 
1309
        self.assertChangedFileIds([], tree)
 
1310
 
 
1311
    def test_sha1provider_stat_and_sha1_used(self):
 
1312
        tree = self.make_branch_and_tree('tree')
 
1313
        self.build_tree(['tree/file'])
 
1314
        tree.add(['file'], ['file-id'])
 
1315
        tree.commit('one')
 
1316
        tree.lock_write()
 
1317
        self.addCleanup(tree.unlock)
 
1318
        state = tree._current_dirstate()
 
1319
        state._sha1_provider = UppercaseSHA1Provider()
 
1320
        self.assertChangedFileIds(['file-id'], tree)
 
1321