/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 breezy/tests/test__dirstate_helpers.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import os
21
21
import time
22
22
 
23
 
from ... import (
 
23
from .. import (
 
24
    errors,
24
25
    osutils,
25
26
    tests,
26
27
    )
27
 
from .. import (
 
28
from ..bzr import (
28
29
    dirstate,
29
30
    _dirstate_helpers_py,
30
31
    )
31
32
from . import (
32
33
    test_dirstate,
33
34
    )
34
 
from ...tests.test_osutils import dir_reader_scenarios
35
 
from ...tests.scenarios import (
 
35
from .test_osutils import dir_reader_scenarios
 
36
from .scenarios import (
36
37
    load_tests_apply_scenarios,
37
38
    multiply_scenarios,
38
39
    )
39
 
from ...tests import (
 
40
from . import (
40
41
    features,
41
42
    )
42
43
 
51
52
# FIXME: we should also parametrize against SHA1Provider !
52
53
 
53
54
ue_scenarios = [('dirstate_Python',
54
 
                 {'update_entry': dirstate.py_update_entry})]
 
55
    {'update_entry': dirstate.py_update_entry})]
55
56
if compiled_dirstate_helpers_feature.available():
56
57
    update_entry = compiled_dirstate_helpers_feature.module.update_entry
57
58
    ue_scenarios.append(('dirstate_Pyrex', {'update_entry': update_entry}))
58
59
 
59
60
pe_scenarios = [('dirstate_Python',
60
 
                 {'_process_entry': dirstate.ProcessEntryPython})]
 
61
    {'_process_entry': dirstate.ProcessEntryPython})]
61
62
if compiled_dirstate_helpers_feature.available():
62
63
    process_entry = compiled_dirstate_helpers_feature.module.ProcessEntryC
63
64
    pe_scenarios.append(('dirstate_Pyrex', {'_process_entry': process_entry}))
65
66
helper_scenarios = [('dirstate_Python', {'helpers': _dirstate_helpers_py})]
66
67
if compiled_dirstate_helpers_feature.available():
67
68
    helper_scenarios.append(('dirstate_Pyrex',
68
 
                             {'helpers': compiled_dirstate_helpers_feature.module}))
 
69
        {'helpers': compiled_dirstate_helpers_feature.module}))
69
70
 
70
71
 
71
72
class TestBisectPathMixin(object):
120
121
                            bisect_split_idx, bisect_path_idx, path)
121
122
                         )
122
123
        if exists:
123
 
            self.assertEqual(path, paths[bisect_path_idx + offset])
 
124
            self.assertEqual(path, paths[bisect_path_idx+offset])
124
125
 
125
126
    def split_for_dirblocks(self, paths):
126
127
        dir_split_paths = []
127
128
        for path in paths:
128
129
            dirname, basename = os.path.split(path)
129
 
            dir_split_paths.append((dirname.split(b'/'), basename))
 
130
            dir_split_paths.append((dirname.split('/'), basename))
130
131
        dir_split_paths.sort()
131
132
        return dir_split_paths
132
133
 
133
134
    def test_simple(self):
134
135
        """In the simple case it works just like bisect_left"""
135
 
        paths = [b'', b'a', b'b', b'c', b'd']
 
136
        paths = ['', 'a', 'b', 'c', 'd']
136
137
        split_paths = self.split_for_dirblocks(paths)
137
138
        for path in paths:
138
139
            self.assertBisect(paths, split_paths, path, exists=True)
139
 
        self.assertBisect(paths, split_paths, b'_', exists=False)
140
 
        self.assertBisect(paths, split_paths, b'aa', exists=False)
141
 
        self.assertBisect(paths, split_paths, b'bb', exists=False)
142
 
        self.assertBisect(paths, split_paths, b'cc', exists=False)
143
 
        self.assertBisect(paths, split_paths, b'dd', exists=False)
144
 
        self.assertBisect(paths, split_paths, b'a/a', exists=False)
145
 
        self.assertBisect(paths, split_paths, b'b/b', exists=False)
146
 
        self.assertBisect(paths, split_paths, b'c/c', exists=False)
147
 
        self.assertBisect(paths, split_paths, b'd/d', exists=False)
 
140
        self.assertBisect(paths, split_paths, '_', exists=False)
 
141
        self.assertBisect(paths, split_paths, 'aa', exists=False)
 
142
        self.assertBisect(paths, split_paths, 'bb', exists=False)
 
143
        self.assertBisect(paths, split_paths, 'cc', exists=False)
 
144
        self.assertBisect(paths, split_paths, 'dd', exists=False)
 
145
        self.assertBisect(paths, split_paths, 'a/a', exists=False)
 
146
        self.assertBisect(paths, split_paths, 'b/b', exists=False)
 
147
        self.assertBisect(paths, split_paths, 'c/c', exists=False)
 
148
        self.assertBisect(paths, split_paths, 'd/d', exists=False)
148
149
 
149
150
    def test_involved(self):
150
151
        """This is where bisect_path_* diverges slightly."""
181
182
        # children are mentioned.
182
183
        # So all the root-directory paths, then all the
183
184
        # first sub directory, etc.
184
 
        paths = [  # content of '/'
185
 
            b'', b'a', b'a-a', b'a-z', b'a=a', b'a=z',
 
185
        paths = [# content of '/'
 
186
                 '', 'a', 'a-a', 'a-z', 'a=a', 'a=z',
186
187
                 # content of 'a/'
187
 
                 b'a/a', b'a/a-a', b'a/a-z',
188
 
                 b'a/a=a', b'a/a=z',
189
 
                 b'a/z', b'a/z-a', b'a/z-z',
190
 
                 b'a/z=a', b'a/z=z',
 
188
                 'a/a', 'a/a-a', 'a/a-z',
 
189
                 'a/a=a', 'a/a=z',
 
190
                 'a/z', 'a/z-a', 'a/z-z',
 
191
                 'a/z=a', 'a/z=z',
191
192
                 # content of 'a/a/'
192
 
                 b'a/a/a', b'a/a/z',
 
193
                 'a/a/a', 'a/a/z',
193
194
                 # content of 'a/a-a'
194
 
                 b'a/a-a/a',
 
195
                 'a/a-a/a',
195
196
                 # content of 'a/a-z'
196
 
                 b'a/a-z/z',
 
197
                 'a/a-z/z',
197
198
                 # content of 'a/a=a'
198
 
                 b'a/a=a/a',
 
199
                 'a/a=a/a',
199
200
                 # content of 'a/a=z'
200
 
                 b'a/a=z/z',
 
201
                 'a/a=z/z',
201
202
                 # content of 'a/z/'
202
 
                 b'a/z/a', b'a/z/z',
 
203
                 'a/z/a', 'a/z/z',
203
204
                 # content of 'a-a'
204
 
                 b'a-a/a',
 
205
                 'a-a/a',
205
206
                 # content of 'a-z'
206
 
                 b'a-z/z',
 
207
                 'a-z/z',
207
208
                 # content of 'a=a'
208
 
                 b'a=a/a',
 
209
                 'a=a/a',
209
210
                 # content of 'a=z'
210
 
                 b'a=z/z',
211
 
            ]
 
211
                 'a=z/z',
 
212
                ]
212
213
        split_paths = self.split_for_dirblocks(paths)
213
214
        sorted_paths = []
214
215
        for dir_parts, basename in split_paths:
215
 
            if dir_parts == [b'']:
 
216
            if dir_parts == ['']:
216
217
                sorted_paths.append(basename)
217
218
            else:
218
 
                sorted_paths.append(b'/'.join(dir_parts + [basename]))
 
219
                sorted_paths.append('/'.join(dir_parts + [basename]))
219
220
 
220
221
        self.assertEqual(sorted_paths, paths)
221
222
 
227
228
    """Run all Bisect Path tests against _bisect_path_left."""
228
229
 
229
230
    def get_bisect_path(self):
230
 
        from .._dirstate_helpers_py import _bisect_path_left
 
231
        from breezy.bzr._dirstate_helpers_py import _bisect_path_left
231
232
        return _bisect_path_left
232
233
 
233
234
    def get_bisect(self):
240
241
    _test_needs_features = [compiled_dirstate_helpers_feature]
241
242
 
242
243
    def get_bisect_path(self):
243
 
        from .._dirstate_helpers_pyx import _bisect_path_left
 
244
        from breezy.bzr._dirstate_helpers_pyx import _bisect_path_left
244
245
        return _bisect_path_left
245
246
 
246
247
 
248
249
    """Run all Bisect Path tests against _bisect_path_right"""
249
250
 
250
251
    def get_bisect_path(self):
251
 
        from .._dirstate_helpers_py import _bisect_path_right
 
252
        from breezy.bzr._dirstate_helpers_py import _bisect_path_right
252
253
        return _bisect_path_right
253
254
 
254
255
    def get_bisect(self):
261
262
    _test_needs_features = [compiled_dirstate_helpers_feature]
262
263
 
263
264
    def get_bisect_path(self):
264
 
        from .._dirstate_helpers_pyx import _bisect_path_right
 
265
        from breezy.bzr._dirstate_helpers_pyx import _bisect_path_right
265
266
        return _bisect_path_right
266
267
 
267
268
 
279
280
 
280
281
    def get_bisect_dirblock(self):
281
282
        """Return an implementation of bisect_dirblock"""
282
 
        from .._dirstate_helpers_py import bisect_dirblock
 
283
        from breezy.bzr._dirstate_helpers_py import bisect_dirblock
283
284
        return bisect_dirblock
284
285
 
285
286
    def assertBisect(self, dirblocks, split_dirblocks, path, *args, **kwargs):
294
295
        bisect_dirblock = self.get_bisect_dirblock()
295
296
        self.assertIsInstance(dirblocks, list)
296
297
        bisect_split_idx = bisect_dirblock(dirblocks, path, *args, **kwargs)
297
 
        split_dirblock = (path.split(b'/'), [])
 
298
        split_dirblock = (path.split('/'), [])
298
299
        bisect_left_idx = bisect.bisect_left(split_dirblocks, split_dirblock,
299
300
                                             *args)
300
301
        self.assertEqual(bisect_left_idx, bisect_split_idx,
309
310
        Also, ensure that the paths are in proper sorted order.
310
311
        """
311
312
        dirblocks = [(path, []) for path in paths]
312
 
        split_dirblocks = [(path.split(b'/'), []) for path in paths]
 
313
        split_dirblocks = [(path.split('/'), []) for path in paths]
313
314
        self.assertEqual(sorted(split_dirblocks), split_dirblocks)
314
315
        return dirblocks, split_dirblocks
315
316
 
316
317
    def test_simple(self):
317
318
        """In the simple case it works just like bisect_left"""
318
 
        paths = [b'', b'a', b'b', b'c', b'd']
 
319
        paths = ['', 'a', 'b', 'c', 'd']
319
320
        dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
320
321
        for path in paths:
321
322
            self.assertBisect(dirblocks, split_dirblocks, path)
322
 
        self.assertBisect(dirblocks, split_dirblocks, b'_')
323
 
        self.assertBisect(dirblocks, split_dirblocks, b'aa')
324
 
        self.assertBisect(dirblocks, split_dirblocks, b'bb')
325
 
        self.assertBisect(dirblocks, split_dirblocks, b'cc')
326
 
        self.assertBisect(dirblocks, split_dirblocks, b'dd')
327
 
        self.assertBisect(dirblocks, split_dirblocks, b'a/a')
328
 
        self.assertBisect(dirblocks, split_dirblocks, b'b/b')
329
 
        self.assertBisect(dirblocks, split_dirblocks, b'c/c')
330
 
        self.assertBisect(dirblocks, split_dirblocks, b'd/d')
 
323
        self.assertBisect(dirblocks, split_dirblocks, '_')
 
324
        self.assertBisect(dirblocks, split_dirblocks, 'aa')
 
325
        self.assertBisect(dirblocks, split_dirblocks, 'bb')
 
326
        self.assertBisect(dirblocks, split_dirblocks, 'cc')
 
327
        self.assertBisect(dirblocks, split_dirblocks, 'dd')
 
328
        self.assertBisect(dirblocks, split_dirblocks, 'a/a')
 
329
        self.assertBisect(dirblocks, split_dirblocks, 'b/b')
 
330
        self.assertBisect(dirblocks, split_dirblocks, 'c/c')
 
331
        self.assertBisect(dirblocks, split_dirblocks, 'd/d')
331
332
 
332
333
    def test_involved(self):
333
334
        """This is where bisect_left diverges slightly."""
334
 
        paths = [b'', b'a',
335
 
                 b'a/a', b'a/a/a', b'a/a/z', b'a/a-a', b'a/a-z',
336
 
                 b'a/z', b'a/z/a', b'a/z/z', b'a/z-a', b'a/z-z',
337
 
                 b'a-a', b'a-z',
338
 
                 b'z', b'z/a/a', b'z/a/z', b'z/a-a', b'z/a-z',
339
 
                 b'z/z', b'z/z/a', b'z/z/z', b'z/z-a', b'z/z-z',
340
 
                 b'z-a', b'z-z',
341
 
                 ]
 
335
        paths = ['', 'a',
 
336
                 'a/a', 'a/a/a', 'a/a/z', 'a/a-a', 'a/a-z',
 
337
                 'a/z', 'a/z/a', 'a/z/z', 'a/z-a', 'a/z-z',
 
338
                 'a-a', 'a-z',
 
339
                 'z', 'z/a/a', 'z/a/z', 'z/a-a', 'z/a-z',
 
340
                 'z/z', 'z/z/a', 'z/z/z', 'z/z-a', 'z/z-z',
 
341
                 'z-a', 'z-z',
 
342
                ]
342
343
        dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
343
344
        for path in paths:
344
345
            self.assertBisect(dirblocks, split_dirblocks, path)
345
346
 
346
347
    def test_involved_cached(self):
347
348
        """This is where bisect_left diverges slightly."""
348
 
        paths = [b'', b'a',
349
 
                 b'a/a', b'a/a/a', b'a/a/z', b'a/a-a', b'a/a-z',
350
 
                 b'a/z', b'a/z/a', b'a/z/z', b'a/z-a', b'a/z-z',
351
 
                 b'a-a', b'a-z',
352
 
                 b'z', b'z/a/a', b'z/a/z', b'z/a-a', b'z/a-z',
353
 
                 b'z/z', b'z/z/a', b'z/z/z', b'z/z-a', b'z/z-z',
354
 
                 b'z-a', b'z-z',
355
 
                 ]
 
349
        paths = ['', 'a',
 
350
                 'a/a', 'a/a/a', 'a/a/z', 'a/a-a', 'a/a-z',
 
351
                 'a/z', 'a/z/a', 'a/z/z', 'a/z-a', 'a/z-z',
 
352
                 'a-a', 'a-z',
 
353
                 'z', 'z/a/a', 'z/a/z', 'z/a-a', 'z/a-z',
 
354
                 'z/z', 'z/z/a', 'z/z/z', 'z/z-a', 'z/z-z',
 
355
                 'z-a', 'z-z',
 
356
                ]
356
357
        cache = {}
357
358
        dirblocks, split_dirblocks = self.paths_to_dirblocks(paths)
358
359
        for path in paths:
373
374
    _test_needs_features = [compiled_dirstate_helpers_feature]
374
375
 
375
376
    def get_bisect_dirblock(self):
376
 
        from .._dirstate_helpers_pyx import bisect_dirblock
 
377
        from breezy.bzr._dirstate_helpers_pyx import bisect_dirblock
377
378
        return bisect_dirblock
378
379
 
379
380
 
389
390
 
390
391
    def get_lt_by_dirs(self):
391
392
        """Get a specific implementation of lt_by_dirs."""
392
 
        from .._dirstate_helpers_py import lt_by_dirs
 
393
        from ..bzr._dirstate_helpers_py import lt_by_dirs
393
394
        return lt_by_dirs
394
395
 
395
396
    def assertCmpByDirs(self, expected, str1, str2):
414
415
 
415
416
    def test_cmp_empty(self):
416
417
        """Compare against the empty string."""
417
 
        self.assertCmpByDirs(0, b'', b'')
418
 
        self.assertCmpByDirs(1, b'a', b'')
419
 
        self.assertCmpByDirs(1, b'ab', b'')
420
 
        self.assertCmpByDirs(1, b'abc', b'')
421
 
        self.assertCmpByDirs(1, b'abcd', b'')
422
 
        self.assertCmpByDirs(1, b'abcde', b'')
423
 
        self.assertCmpByDirs(1, b'abcdef', b'')
424
 
        self.assertCmpByDirs(1, b'abcdefg', b'')
425
 
        self.assertCmpByDirs(1, b'abcdefgh', b'')
426
 
        self.assertCmpByDirs(1, b'abcdefghi', b'')
427
 
        self.assertCmpByDirs(1, b'test/ing/a/path/', b'')
 
418
        self.assertCmpByDirs(0, '', '')
 
419
        self.assertCmpByDirs(1, 'a', '')
 
420
        self.assertCmpByDirs(1, 'ab', '')
 
421
        self.assertCmpByDirs(1, 'abc', '')
 
422
        self.assertCmpByDirs(1, 'abcd', '')
 
423
        self.assertCmpByDirs(1, 'abcde', '')
 
424
        self.assertCmpByDirs(1, 'abcdef', '')
 
425
        self.assertCmpByDirs(1, 'abcdefg', '')
 
426
        self.assertCmpByDirs(1, 'abcdefgh', '')
 
427
        self.assertCmpByDirs(1, 'abcdefghi', '')
 
428
        self.assertCmpByDirs(1, 'test/ing/a/path/', '')
428
429
 
429
430
    def test_cmp_same_str(self):
430
431
        """Compare the same string"""
431
 
        self.assertCmpByDirs(0, b'a', b'a')
432
 
        self.assertCmpByDirs(0, b'ab', b'ab')
433
 
        self.assertCmpByDirs(0, b'abc', b'abc')
434
 
        self.assertCmpByDirs(0, b'abcd', b'abcd')
435
 
        self.assertCmpByDirs(0, b'abcde', b'abcde')
436
 
        self.assertCmpByDirs(0, b'abcdef', b'abcdef')
437
 
        self.assertCmpByDirs(0, b'abcdefg', b'abcdefg')
438
 
        self.assertCmpByDirs(0, b'abcdefgh', b'abcdefgh')
439
 
        self.assertCmpByDirs(0, b'abcdefghi', b'abcdefghi')
440
 
        self.assertCmpByDirs(0, b'testing a long string',
441
 
                             b'testing a long string')
442
 
        self.assertCmpByDirs(0, b'x' * 10000, b'x' * 10000)
443
 
        self.assertCmpByDirs(0, b'a/b', b'a/b')
444
 
        self.assertCmpByDirs(0, b'a/b/c', b'a/b/c')
445
 
        self.assertCmpByDirs(0, b'a/b/c/d', b'a/b/c/d')
446
 
        self.assertCmpByDirs(0, b'a/b/c/d/e', b'a/b/c/d/e')
 
432
        self.assertCmpByDirs(0, 'a', 'a')
 
433
        self.assertCmpByDirs(0, 'ab', 'ab')
 
434
        self.assertCmpByDirs(0, 'abc', 'abc')
 
435
        self.assertCmpByDirs(0, 'abcd', 'abcd')
 
436
        self.assertCmpByDirs(0, 'abcde', 'abcde')
 
437
        self.assertCmpByDirs(0, 'abcdef', 'abcdef')
 
438
        self.assertCmpByDirs(0, 'abcdefg', 'abcdefg')
 
439
        self.assertCmpByDirs(0, 'abcdefgh', 'abcdefgh')
 
440
        self.assertCmpByDirs(0, 'abcdefghi', 'abcdefghi')
 
441
        self.assertCmpByDirs(0, 'testing a long string', 'testing a long string')
 
442
        self.assertCmpByDirs(0, 'x'*10000, 'x'*10000)
 
443
        self.assertCmpByDirs(0, 'a/b', 'a/b')
 
444
        self.assertCmpByDirs(0, 'a/b/c', 'a/b/c')
 
445
        self.assertCmpByDirs(0, 'a/b/c/d', 'a/b/c/d')
 
446
        self.assertCmpByDirs(0, 'a/b/c/d/e', 'a/b/c/d/e')
447
447
 
448
448
    def test_simple_paths(self):
449
449
        """Compare strings that act like normal string comparison"""
450
 
        self.assertCmpByDirs(-1, b'a', b'b')
451
 
        self.assertCmpByDirs(-1, b'aa', b'ab')
452
 
        self.assertCmpByDirs(-1, b'ab', b'bb')
453
 
        self.assertCmpByDirs(-1, b'aaa', b'aab')
454
 
        self.assertCmpByDirs(-1, b'aab', b'abb')
455
 
        self.assertCmpByDirs(-1, b'abb', b'bbb')
456
 
        self.assertCmpByDirs(-1, b'aaaa', b'aaab')
457
 
        self.assertCmpByDirs(-1, b'aaab', b'aabb')
458
 
        self.assertCmpByDirs(-1, b'aabb', b'abbb')
459
 
        self.assertCmpByDirs(-1, b'abbb', b'bbbb')
460
 
        self.assertCmpByDirs(-1, b'aaaaa', b'aaaab')
461
 
        self.assertCmpByDirs(-1, b'a/a', b'a/b')
462
 
        self.assertCmpByDirs(-1, b'a/b', b'b/b')
463
 
        self.assertCmpByDirs(-1, b'a/a/a', b'a/a/b')
464
 
        self.assertCmpByDirs(-1, b'a/a/b', b'a/b/b')
465
 
        self.assertCmpByDirs(-1, b'a/b/b', b'b/b/b')
466
 
        self.assertCmpByDirs(-1, b'a/a/a/a', b'a/a/a/b')
467
 
        self.assertCmpByDirs(-1, b'a/a/a/b', b'a/a/b/b')
468
 
        self.assertCmpByDirs(-1, b'a/a/b/b', b'a/b/b/b')
469
 
        self.assertCmpByDirs(-1, b'a/b/b/b', b'b/b/b/b')
470
 
        self.assertCmpByDirs(-1, b'a/a/a/a/a', b'a/a/a/a/b')
 
450
        self.assertCmpByDirs(-1, 'a', 'b')
 
451
        self.assertCmpByDirs(-1, 'aa', 'ab')
 
452
        self.assertCmpByDirs(-1, 'ab', 'bb')
 
453
        self.assertCmpByDirs(-1, 'aaa', 'aab')
 
454
        self.assertCmpByDirs(-1, 'aab', 'abb')
 
455
        self.assertCmpByDirs(-1, 'abb', 'bbb')
 
456
        self.assertCmpByDirs(-1, 'aaaa', 'aaab')
 
457
        self.assertCmpByDirs(-1, 'aaab', 'aabb')
 
458
        self.assertCmpByDirs(-1, 'aabb', 'abbb')
 
459
        self.assertCmpByDirs(-1, 'abbb', 'bbbb')
 
460
        self.assertCmpByDirs(-1, 'aaaaa', 'aaaab')
 
461
        self.assertCmpByDirs(-1, 'a/a', 'a/b')
 
462
        self.assertCmpByDirs(-1, 'a/b', 'b/b')
 
463
        self.assertCmpByDirs(-1, 'a/a/a', 'a/a/b')
 
464
        self.assertCmpByDirs(-1, 'a/a/b', 'a/b/b')
 
465
        self.assertCmpByDirs(-1, 'a/b/b', 'b/b/b')
 
466
        self.assertCmpByDirs(-1, 'a/a/a/a', 'a/a/a/b')
 
467
        self.assertCmpByDirs(-1, 'a/a/a/b', 'a/a/b/b')
 
468
        self.assertCmpByDirs(-1, 'a/a/b/b', 'a/b/b/b')
 
469
        self.assertCmpByDirs(-1, 'a/b/b/b', 'b/b/b/b')
 
470
        self.assertCmpByDirs(-1, 'a/a/a/a/a', 'a/a/a/a/b')
471
471
 
472
472
    def test_tricky_paths(self):
473
 
        self.assertCmpByDirs(1, b'ab/cd/ef', b'ab/cc/ef')
474
 
        self.assertCmpByDirs(1, b'ab/cd/ef', b'ab/c/ef')
475
 
        self.assertCmpByDirs(-1, b'ab/cd/ef', b'ab/cd-ef')
476
 
        self.assertCmpByDirs(-1, b'ab/cd', b'ab/cd-')
477
 
        self.assertCmpByDirs(-1, b'ab/cd', b'ab-cd')
 
473
        self.assertCmpByDirs(1, 'ab/cd/ef', 'ab/cc/ef')
 
474
        self.assertCmpByDirs(1, 'ab/cd/ef', 'ab/c/ef')
 
475
        self.assertCmpByDirs(-1, 'ab/cd/ef', 'ab/cd-ef')
 
476
        self.assertCmpByDirs(-1, 'ab/cd', 'ab/cd-')
 
477
        self.assertCmpByDirs(-1, 'ab/cd', 'ab-cd')
478
478
 
479
479
    def test_cmp_unicode_not_allowed(self):
480
480
        lt_by_dirs = self.get_lt_by_dirs()
481
 
        self.assertRaises(TypeError, lt_by_dirs, u'Unicode', b'str')
482
 
        self.assertRaises(TypeError, lt_by_dirs, b'str', u'Unicode')
 
481
        self.assertRaises(TypeError, lt_by_dirs, u'Unicode', 'str')
 
482
        self.assertRaises(TypeError, lt_by_dirs, 'str', u'Unicode')
483
483
        self.assertRaises(TypeError, lt_by_dirs, u'Unicode', u'Unicode')
484
484
 
485
485
    def test_cmp_non_ascii(self):
486
 
        self.assertCmpByDirs(-1, b'\xc2\xb5', b'\xc3\xa5')  # u'\xb5', u'\xe5'
487
 
        self.assertCmpByDirs(-1, b'a', b'\xc3\xa5')  # u'a', u'\xe5'
488
 
        self.assertCmpByDirs(-1, b'b', b'\xc2\xb5')  # u'b', u'\xb5'
489
 
        self.assertCmpByDirs(-1, b'a/b', b'a/\xc3\xa5')  # u'a/b', u'a/\xe5'
490
 
        self.assertCmpByDirs(-1, b'b/a', b'b/\xc2\xb5')  # u'b/a', u'b/\xb5'
 
486
        self.assertCmpByDirs(-1, '\xc2\xb5', '\xc3\xa5') # u'\xb5', u'\xe5'
 
487
        self.assertCmpByDirs(-1, 'a', '\xc3\xa5') # u'a', u'\xe5'
 
488
        self.assertCmpByDirs(-1, 'b', '\xc2\xb5') # u'b', u'\xb5'
 
489
        self.assertCmpByDirs(-1, 'a/b', 'a/\xc3\xa5') # u'a/b', u'a/\xe5'
 
490
        self.assertCmpByDirs(-1, 'b/a', 'b/\xc2\xb5') # u'b/a', u'b/\xb5'
491
491
 
492
492
 
493
493
class TestCompiledLtByDirs(TestLtByDirs):
496
496
    _test_needs_features = [compiled_dirstate_helpers_feature]
497
497
 
498
498
    def get_lt_by_dirs(self):
499
 
        from .._dirstate_helpers_pyx import lt_by_dirs
 
499
        from ..bzr._dirstate_helpers_pyx import lt_by_dirs
500
500
        return lt_by_dirs
501
501
 
502
502
 
512
512
 
513
513
    def get_lt_path_by_dirblock(self):
514
514
        """Get a specific implementation of _lt_path_by_dirblock."""
515
 
        from .._dirstate_helpers_py import _lt_path_by_dirblock
 
515
        from ..bzr._dirstate_helpers_py import _lt_path_by_dirblock
516
516
        return _lt_path_by_dirblock
517
517
 
518
518
    def assertLtPathByDirblock(self, paths):
526
526
        # First, make sure the paths being passed in are correct
527
527
        def _key(p):
528
528
            dirname, basename = os.path.split(p)
529
 
            return dirname.split(b'/'), basename
 
529
            return dirname.split('/'), basename
530
530
        self.assertEqual(sorted(paths, key=_key), paths)
531
531
 
532
532
        lt_path_by_dirblock = self.get_lt_path_by_dirblock()
534
534
            for idx2, path2 in enumerate(paths):
535
535
                lt_result = lt_path_by_dirblock(path1, path2)
536
536
                self.assertEqual(idx1 < idx2, lt_result,
537
 
                                 '%s did not state that %r < %r, lt=%s'
538
 
                                 % (lt_path_by_dirblock.__name__,
539
 
                                    path1, path2, lt_result))
 
537
                        '%s did not state that %r < %r, lt=%s'
 
538
                        % (lt_path_by_dirblock.__name__,
 
539
                           path1, path2, lt_result))
540
540
 
541
541
    def test_cmp_simple_paths(self):
542
542
        """Compare against the empty string."""
543
 
        self.assertLtPathByDirblock(
544
 
            [b'', b'a', b'ab', b'abc', b'a/b/c', b'b/d/e'])
545
 
        self.assertLtPathByDirblock([b'kl', b'ab/cd', b'ab/ef', b'gh/ij'])
 
543
        self.assertLtPathByDirblock(['', 'a', 'ab', 'abc', 'a/b/c', 'b/d/e'])
 
544
        self.assertLtPathByDirblock(['kl', 'ab/cd', 'ab/ef', 'gh/ij'])
546
545
 
547
546
    def test_tricky_paths(self):
548
547
        self.assertLtPathByDirblock([
549
548
            # Contents of ''
550
 
            b'', b'a', b'a-a', b'a=a', b'b',
 
549
            '', 'a', 'a-a', 'a=a', 'b',
551
550
            # Contents of 'a'
552
 
            b'a/a', b'a/a-a', b'a/a=a', b'a/b',
 
551
            'a/a', 'a/a-a', 'a/a=a', 'a/b',
553
552
            # Contents of 'a/a'
554
 
            b'a/a/a', b'a/a/a-a', b'a/a/a=a',
 
553
            'a/a/a', 'a/a/a-a', 'a/a/a=a',
555
554
            # Contents of 'a/a/a'
556
 
            b'a/a/a/a', b'a/a/a/b',
 
555
            'a/a/a/a', 'a/a/a/b',
557
556
            # Contents of 'a/a/a-a',
558
 
            b'a/a/a-a/a', b'a/a/a-a/b',
 
557
            'a/a/a-a/a', 'a/a/a-a/b',
559
558
            # Contents of 'a/a/a=a',
560
 
            b'a/a/a=a/a', b'a/a/a=a/b',
 
559
            'a/a/a=a/a', 'a/a/a=a/b',
561
560
            # Contents of 'a/a-a'
562
 
            b'a/a-a/a',
 
561
            'a/a-a/a',
563
562
            # Contents of 'a/a-a/a'
564
 
            b'a/a-a/a/a', b'a/a-a/a/b',
 
563
            'a/a-a/a/a', 'a/a-a/a/b',
565
564
            # Contents of 'a/a=a'
566
 
            b'a/a=a/a',
 
565
            'a/a=a/a',
567
566
            # Contents of 'a/b'
568
 
            b'a/b/a', b'a/b/b',
 
567
            'a/b/a', 'a/b/b',
569
568
            # Contents of 'a-a',
570
 
            b'a-a/a', b'a-a/b',
 
569
            'a-a/a', 'a-a/b',
571
570
            # Contents of 'a=a',
572
 
            b'a=a/a', b'a=a/b',
 
571
            'a=a/a', 'a=a/b',
573
572
            # Contents of 'b',
574
 
            b'b/a', b'b/b',
 
573
            'b/a', 'b/b',
575
574
            ])
576
575
        self.assertLtPathByDirblock([
577
 
            # content of '/'
578
 
            b'', b'a', b'a-a', b'a-z', b'a=a', b'a=z',
 
576
                 # content of '/'
 
577
                 '', 'a', 'a-a', 'a-z', 'a=a', 'a=z',
579
578
                 # content of 'a/'
580
 
                 b'a/a', b'a/a-a', b'a/a-z',
581
 
                 b'a/a=a', b'a/a=z',
582
 
                 b'a/z', b'a/z-a', b'a/z-z',
583
 
                 b'a/z=a', b'a/z=z',
 
579
                 'a/a', 'a/a-a', 'a/a-z',
 
580
                 'a/a=a', 'a/a=z',
 
581
                 'a/z', 'a/z-a', 'a/z-z',
 
582
                 'a/z=a', 'a/z=z',
584
583
                 # content of 'a/a/'
585
 
                 b'a/a/a', b'a/a/z',
 
584
                 'a/a/a', 'a/a/z',
586
585
                 # content of 'a/a-a'
587
 
                 b'a/a-a/a',
 
586
                 'a/a-a/a',
588
587
                 # content of 'a/a-z'
589
 
                 b'a/a-z/z',
 
588
                 'a/a-z/z',
590
589
                 # content of 'a/a=a'
591
 
                 b'a/a=a/a',
 
590
                 'a/a=a/a',
592
591
                 # content of 'a/a=z'
593
 
                 b'a/a=z/z',
 
592
                 'a/a=z/z',
594
593
                 # content of 'a/z/'
595
 
                 b'a/z/a', b'a/z/z',
 
594
                 'a/z/a', 'a/z/z',
596
595
                 # content of 'a-a'
597
 
                 b'a-a/a',
 
596
                 'a-a/a',
598
597
                 # content of 'a-z'
599
 
                 b'a-z/z',
 
598
                 'a-z/z',
600
599
                 # content of 'a=a'
601
 
                 b'a=a/a',
 
600
                 'a=a/a',
602
601
                 # content of 'a=z'
603
 
                 b'a=z/z',
604
 
            ])
 
602
                 'a=z/z',
 
603
                ])
605
604
 
606
605
    def test_unicode_not_allowed(self):
607
606
        lt_path_by_dirblock = self.get_lt_path_by_dirblock()
615
614
    def test_nonascii(self):
616
615
        self.assertLtPathByDirblock([
617
616
            # content of '/'
618
 
            b'', b'a', b'\xc2\xb5', b'\xc3\xa5',
 
617
            '', 'a', '\xc2\xb5', '\xc3\xa5',
619
618
            # content of 'a'
620
 
            b'a/a', b'a/\xc2\xb5', b'a/\xc3\xa5',
 
619
            'a/a', 'a/\xc2\xb5', 'a/\xc3\xa5',
621
620
            # content of 'a/a'
622
 
            b'a/a/a', b'a/a/\xc2\xb5', b'a/a/\xc3\xa5',
 
621
            'a/a/a', 'a/a/\xc2\xb5', 'a/a/\xc3\xa5',
623
622
            # content of 'a/\xc2\xb5'
624
 
            b'a/\xc2\xb5/a', b'a/\xc2\xb5/\xc2\xb5', b'a/\xc2\xb5/\xc3\xa5',
 
623
            'a/\xc2\xb5/a', 'a/\xc2\xb5/\xc2\xb5', 'a/\xc2\xb5/\xc3\xa5',
625
624
            # content of 'a/\xc3\xa5'
626
 
            b'a/\xc3\xa5/a', b'a/\xc3\xa5/\xc2\xb5', b'a/\xc3\xa5/\xc3\xa5',
 
625
            'a/\xc3\xa5/a', 'a/\xc3\xa5/\xc2\xb5', 'a/\xc3\xa5/\xc3\xa5',
627
626
            # content of '\xc2\xb5'
628
 
            b'\xc2\xb5/a', b'\xc2\xb5/\xc2\xb5', b'\xc2\xb5/\xc3\xa5',
 
627
            '\xc2\xb5/a', '\xc2\xb5/\xc2\xb5', '\xc2\xb5/\xc3\xa5',
629
628
            # content of '\xc2\xe5'
630
 
            b'\xc3\xa5/a', b'\xc3\xa5/\xc2\xb5', b'\xc3\xa5/\xc3\xa5',
 
629
            '\xc3\xa5/a', '\xc3\xa5/\xc2\xb5', '\xc3\xa5/\xc3\xa5',
631
630
            ])
632
631
 
633
632
 
637
636
    _test_needs_features = [compiled_dirstate_helpers_feature]
638
637
 
639
638
    def get_lt_path_by_dirblock(self):
640
 
        from .._dirstate_helpers_pyx import _lt_path_by_dirblock
 
639
        from ..bzr._dirstate_helpers_pyx import _lt_path_by_dirblock
641
640
        return _lt_path_by_dirblock
642
641
 
643
642
 
647
646
    _test_needs_features = [compiled_dirstate_helpers_feature]
648
647
 
649
648
    def assertMemRChr(self, expected, s, c):
650
 
        from .._dirstate_helpers_pyx import _py_memrchr
 
649
        from breezy.bzr._dirstate_helpers_pyx import _py_memrchr
651
650
        self.assertEqual(expected, _py_memrchr(s, c))
652
651
 
653
652
    def test_missing(self):
654
 
        self.assertMemRChr(None, b'', b'a')
655
 
        self.assertMemRChr(None, b'', b'c')
656
 
        self.assertMemRChr(None, b'abcdefghijklm', b'q')
657
 
        self.assertMemRChr(None, b'aaaaaaaaaaaaaaaaaaaaaaa', b'b')
 
653
        self.assertMemRChr(None, '', 'a')
 
654
        self.assertMemRChr(None, '', 'c')
 
655
        self.assertMemRChr(None, 'abcdefghijklm', 'q')
 
656
        self.assertMemRChr(None, 'aaaaaaaaaaaaaaaaaaaaaaa', 'b')
658
657
 
659
658
    def test_single_entry(self):
660
 
        self.assertMemRChr(0, b'abcdefghijklm', b'a')
661
 
        self.assertMemRChr(1, b'abcdefghijklm', b'b')
662
 
        self.assertMemRChr(2, b'abcdefghijklm', b'c')
663
 
        self.assertMemRChr(10, b'abcdefghijklm', b'k')
664
 
        self.assertMemRChr(11, b'abcdefghijklm', b'l')
665
 
        self.assertMemRChr(12, b'abcdefghijklm', b'm')
 
659
        self.assertMemRChr(0, 'abcdefghijklm', 'a')
 
660
        self.assertMemRChr(1, 'abcdefghijklm', 'b')
 
661
        self.assertMemRChr(2, 'abcdefghijklm', 'c')
 
662
        self.assertMemRChr(10, 'abcdefghijklm', 'k')
 
663
        self.assertMemRChr(11, 'abcdefghijklm', 'l')
 
664
        self.assertMemRChr(12, 'abcdefghijklm', 'm')
666
665
 
667
666
    def test_multiple(self):
668
 
        self.assertMemRChr(10, b'abcdefjklmabcdefghijklm', b'a')
669
 
        self.assertMemRChr(11, b'abcdefjklmabcdefghijklm', b'b')
670
 
        self.assertMemRChr(12, b'abcdefjklmabcdefghijklm', b'c')
671
 
        self.assertMemRChr(20, b'abcdefjklmabcdefghijklm', b'k')
672
 
        self.assertMemRChr(21, b'abcdefjklmabcdefghijklm', b'l')
673
 
        self.assertMemRChr(22, b'abcdefjklmabcdefghijklm', b'm')
674
 
        self.assertMemRChr(22, b'aaaaaaaaaaaaaaaaaaaaaaa', b'a')
 
667
        self.assertMemRChr(10, 'abcdefjklmabcdefghijklm', 'a')
 
668
        self.assertMemRChr(11, 'abcdefjklmabcdefghijklm', 'b')
 
669
        self.assertMemRChr(12, 'abcdefjklmabcdefghijklm', 'c')
 
670
        self.assertMemRChr(20, 'abcdefjklmabcdefghijklm', 'k')
 
671
        self.assertMemRChr(21, 'abcdefjklmabcdefghijklm', 'l')
 
672
        self.assertMemRChr(22, 'abcdefjklmabcdefghijklm', 'm')
 
673
        self.assertMemRChr(22, 'aaaaaaaaaaaaaaaaaaaaaaa', 'a')
675
674
 
676
675
    def test_with_nulls(self):
677
 
        self.assertMemRChr(10, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'a')
678
 
        self.assertMemRChr(11, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'b')
679
 
        self.assertMemRChr(12, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'c')
680
 
        self.assertMemRChr(20, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'k')
681
 
        self.assertMemRChr(21, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'l')
682
 
        self.assertMemRChr(22, b'abc\0\0\0jklmabc\0\0\0ghijklm', b'm')
683
 
        self.assertMemRChr(22, b'aaa\0\0\0aaaaaaa\0\0\0aaaaaaa', b'a')
684
 
        self.assertMemRChr(9, b'\0\0\0\0\0\0\0\0\0\0', b'\0')
 
676
        self.assertMemRChr(10, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'a')
 
677
        self.assertMemRChr(11, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'b')
 
678
        self.assertMemRChr(12, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'c')
 
679
        self.assertMemRChr(20, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'k')
 
680
        self.assertMemRChr(21, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'l')
 
681
        self.assertMemRChr(22, 'abc\0\0\0jklmabc\0\0\0ghijklm', 'm')
 
682
        self.assertMemRChr(22, 'aaa\0\0\0aaaaaaa\0\0\0aaaaaaa', 'a')
 
683
        self.assertMemRChr(9, '\0\0\0\0\0\0\0\0\0\0', '\0')
685
684
 
686
685
 
687
686
class TestReadDirblocks(test_dirstate.TestCaseWithDirState):
697
696
    # inherits scenarios from test_dirstate
698
697
 
699
698
    def get_read_dirblocks(self):
700
 
        from .._dirstate_helpers_py import _read_dirblocks
 
699
        from breezy.bzr._dirstate_helpers_py import _read_dirblocks
701
700
        return _read_dirblocks
702
701
 
703
702
    def test_smoketest(self):
721
720
        f = open('dirstate', 'ab')
722
721
        try:
723
722
            # Add bogus trailing garbage
724
 
            f.write(b'bogus\n')
 
723
            f.write('bogus\n')
725
724
        finally:
726
725
            f.close()
727
726
            state.lock_read()
728
 
        e = self.assertRaises(dirstate.DirstateCorrupt,
 
727
        e = self.assertRaises(errors.DirstateCorrupt,
729
728
                              state._read_dirblocks_if_needed)
730
729
        # Make sure we mention the bogus characters in the error
731
730
        self.assertContainsRe(str(e), 'bogus')
737
736
    _test_needs_features = [compiled_dirstate_helpers_feature]
738
737
 
739
738
    def get_read_dirblocks(self):
740
 
        from .._dirstate_helpers_pyx import _read_dirblocks
 
739
        from breezy.bzr._dirstate_helpers_pyx import _read_dirblocks
741
740
        return _read_dirblocks
742
741
 
743
742
 
751
750
 
752
751
    def test_bisect_dirblock(self):
753
752
        if compiled_dirstate_helpers_feature.available():
754
 
            from .._dirstate_helpers_pyx import bisect_dirblock
 
753
            from breezy.bzr._dirstate_helpers_pyx import bisect_dirblock
755
754
        else:
756
 
            from .._dirstate_helpers_py import bisect_dirblock
 
755
            from breezy.bzr._dirstate_helpers_py import bisect_dirblock
757
756
        self.assertIs(bisect_dirblock, dirstate.bisect_dirblock)
758
757
 
759
758
    def test__bisect_path_left(self):
760
759
        if compiled_dirstate_helpers_feature.available():
761
 
            from .._dirstate_helpers_pyx import _bisect_path_left
 
760
            from breezy.bzr._dirstate_helpers_pyx import _bisect_path_left
762
761
        else:
763
 
            from .._dirstate_helpers_py import _bisect_path_left
 
762
            from breezy.bzr._dirstate_helpers_py import _bisect_path_left
764
763
        self.assertIs(_bisect_path_left, dirstate._bisect_path_left)
765
764
 
766
765
    def test__bisect_path_right(self):
767
766
        if compiled_dirstate_helpers_feature.available():
768
 
            from .._dirstate_helpers_pyx import _bisect_path_right
 
767
            from breezy.bzr._dirstate_helpers_pyx import _bisect_path_right
769
768
        else:
770
 
            from .._dirstate_helpers_py import _bisect_path_right
 
769
            from breezy.bzr._dirstate_helpers_py import _bisect_path_right
771
770
        self.assertIs(_bisect_path_right, dirstate._bisect_path_right)
772
771
 
773
772
    def test_lt_by_dirs(self):
774
773
        if compiled_dirstate_helpers_feature.available():
775
 
            from .._dirstate_helpers_pyx import lt_by_dirs
 
774
            from ..bzr._dirstate_helpers_pyx import lt_by_dirs
776
775
        else:
777
 
            from .._dirstate_helpers_py import lt_by_dirs
 
776
            from ..bzr._dirstate_helpers_py import lt_by_dirs
778
777
        self.assertIs(lt_by_dirs, dirstate.lt_by_dirs)
779
778
 
780
779
    def test__read_dirblocks(self):
781
780
        if compiled_dirstate_helpers_feature.available():
782
 
            from .._dirstate_helpers_pyx import _read_dirblocks
 
781
            from breezy.bzr._dirstate_helpers_pyx import _read_dirblocks
783
782
        else:
784
 
            from .._dirstate_helpers_py import _read_dirblocks
 
783
            from breezy.bzr._dirstate_helpers_py import _read_dirblocks
785
784
        self.assertIs(_read_dirblocks, dirstate._read_dirblocks)
786
785
 
787
786
    def test_update_entry(self):
788
787
        if compiled_dirstate_helpers_feature.available():
789
 
            from .._dirstate_helpers_pyx import update_entry
 
788
            from breezy.bzr._dirstate_helpers_pyx import update_entry
790
789
        else:
791
 
            from ..dirstate import update_entry
 
790
            from breezy.bzr.dirstate import update_entry
792
791
        self.assertIs(update_entry, dirstate.update_entry)
793
792
 
794
793
    def test_process_entry(self):
795
794
        if compiled_dirstate_helpers_feature.available():
796
 
            from .._dirstate_helpers_pyx import ProcessEntryC
 
795
            from breezy.bzr._dirstate_helpers_pyx import ProcessEntryC
797
796
            self.assertIs(ProcessEntryC, dirstate._process_entry)
798
797
        else:
799
 
            from ..dirstate import ProcessEntryPython
 
798
            from breezy.bzr.dirstate import ProcessEntryPython
800
799
            self.assertIs(ProcessEntryPython, dirstate._process_entry)
801
800
 
802
801
 
817
816
        """Create a DirState tracking a single object named 'a'"""
818
817
        state = test_dirstate.InstrumentedDirState.initialize('dirstate')
819
818
        self.addCleanup(state.unlock)
820
 
        state.add('a', b'a-id', 'file', None, b'')
821
 
        entry = state._get_entry(0, path_utf8=b'a')
 
819
        state.add('a', 'a-id', 'file', None, '')
 
820
        entry = state._get_entry(0, path_utf8='a')
822
821
        return state, entry
823
822
 
824
823
    def test_observed_sha1_cachable(self):
830
829
        statvalue.st_mtime = statvalue.st_ctime = atime
831
830
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
832
831
                         state._dirblock_state)
833
 
        state._observed_sha1(entry, b"foo", statvalue)
834
 
        self.assertEqual(b'foo', entry[1][0][1])
 
832
        state._observed_sha1(entry, "foo", statvalue)
 
833
        self.assertEqual('foo', entry[1][0][1])
835
834
        packed_stat = dirstate.pack_stat(statvalue)
836
835
        self.assertEqual(packed_stat, entry[1][0][4])
837
836
        self.assertEqual(dirstate.DirState.IN_MEMORY_HASH_MODIFIED,
858
857
        tree.lock_write()
859
858
        empty_revid = tree.commit('empty')
860
859
        self.build_tree(['tree/a'])
861
 
        tree.add(['a'], [b'a-id'])
 
860
        tree.add(['a'], ['a-id'])
862
861
        with_a_id = tree.commit('with_a')
863
862
        self.addCleanup(tree.unlock)
864
863
        state.set_parent_trees(
865
864
            [(empty_revid, tree.branch.repository.revision_tree(empty_revid))],
866
865
            [])
867
 
        entry = state._get_entry(0, path_utf8=b'a')
 
866
        entry = state._get_entry(0, path_utf8='a')
868
867
        self.build_tree(['a'])
869
868
        # Add one where we don't provide the stat or sha already
870
 
        self.assertEqual((b'', b'a', b'a-id'), entry[0])
871
 
        self.assertEqual((b'f', b'', 0, False, dirstate.DirState.NULLSTAT),
 
869
        self.assertEqual(('', 'a', 'a-id'), entry[0])
 
870
        self.assertEqual(('f', '', 0, False, dirstate.DirState.NULLSTAT),
872
871
                         entry[1][0])
873
872
        # Flush the buffers to disk
874
873
        state.save()
877
876
 
878
877
        stat_value = os.lstat('a')
879
878
        packed_stat = dirstate.pack_stat(stat_value)
880
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
881
 
                                         stat_value=stat_value)
 
879
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
880
                                          stat_value=stat_value)
882
881
        self.assertEqual(None, link_or_sha1)
883
882
 
884
883
        # The dirblock entry should not have computed or cached the file's
885
884
        # sha1, but it did update the files' st_size. However, this is not
886
885
        # worth writing a dirstate file for, so we leave the state UNMODIFIED
887
 
        self.assertEqual((b'f', b'', 14, False, dirstate.DirState.NULLSTAT),
 
886
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
888
887
                         entry[1][0])
889
888
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
890
889
                         state._dirblock_state)
900
899
        state.adjust_time(-10)
901
900
        del state._log[:]
902
901
 
903
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
904
 
                                         stat_value=stat_value)
 
902
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
903
                                          stat_value=stat_value)
905
904
        self.assertEqual([('is_exec', mode, False)], state._log)
906
905
        self.assertEqual(None, link_or_sha1)
907
906
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
908
907
                         state._dirblock_state)
909
 
        self.assertEqual((b'f', b'', 14, False, dirstate.DirState.NULLSTAT),
 
908
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
910
909
                         entry[1][0])
911
910
        state.save()
912
911
 
914
913
        # won't calculate the sha or cache it.
915
914
        state.adjust_time(+20)
916
915
        del state._log[:]
917
 
        link_or_sha1 = dirstate.update_entry(state, entry, abspath=b'a',
918
 
                                             stat_value=stat_value)
 
916
        link_or_sha1 = dirstate.update_entry(state, entry, abspath='a',
 
917
                                          stat_value=stat_value)
919
918
        self.assertEqual(None, link_or_sha1)
920
919
        self.assertEqual([('is_exec', mode, False)], state._log)
921
 
        self.assertEqual((b'f', b'', 14, False, dirstate.DirState.NULLSTAT),
 
920
        self.assertEqual(('f', '', 14, False, dirstate.DirState.NULLSTAT),
922
921
                         entry[1][0])
923
922
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
924
923
                         state._dirblock_state)
929
928
        state.set_parent_trees(
930
929
            [(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
931
930
            [])
932
 
        entry = state._get_entry(0, path_utf8=b'a')
 
931
        entry = state._get_entry(0, path_utf8='a')
933
932
 
934
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
935
 
                                         stat_value=stat_value)
936
 
        self.assertEqual(b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
 
933
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
934
                                          stat_value=stat_value)
 
935
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
937
936
                         link_or_sha1)
938
 
        self.assertEqual([('is_exec', mode, False), ('sha1', b'a')],
939
 
                         state._log)
940
 
        self.assertEqual((b'f', link_or_sha1, 14, False, packed_stat),
 
937
        self.assertEqual([('is_exec', mode, False), ('sha1', 'a')],
 
938
                          state._log)
 
939
        self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
941
940
                         entry[1][0])
942
941
 
943
942
        # Subsequent calls will just return the cached value
944
943
        del state._log[:]
945
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
946
 
                                         stat_value=stat_value)
947
 
        self.assertEqual(b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
 
944
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
945
                                          stat_value=stat_value)
 
946
        self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
948
947
                         link_or_sha1)
949
948
        self.assertEqual([], state._log)
950
 
        self.assertEqual((b'f', link_or_sha1, 14, False, packed_stat),
 
949
        self.assertEqual(('f', link_or_sha1, 14, False, packed_stat),
951
950
                         entry[1][0])
952
951
 
953
952
    def test_update_entry_symlink(self):
959
958
                         state._dirblock_state)
960
959
        os.symlink('target', 'a')
961
960
 
962
 
        state.adjust_time(-10)  # Make the symlink look new
 
961
        state.adjust_time(-10) # Make the symlink look new
963
962
        stat_value = os.lstat('a')
964
963
        packed_stat = dirstate.pack_stat(stat_value)
965
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
966
 
                                         stat_value=stat_value)
967
 
        self.assertEqual(b'target', link_or_sha1)
968
 
        self.assertEqual([('read_link', b'a', b'')], state._log)
 
964
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
965
                                          stat_value=stat_value)
 
966
        self.assertEqual('target', link_or_sha1)
 
967
        self.assertEqual([('read_link', 'a', '')], state._log)
969
968
        # Dirblock is not updated (the link is too new)
970
 
        self.assertEqual([(b'l', b'', 6, False, dirstate.DirState.NULLSTAT)],
 
969
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
971
970
                         entry[1])
972
971
        # The file entry turned into a symlink, that is considered
973
972
        # HASH modified worthy.
976
975
 
977
976
        # Because the stat_value looks new, we should re-read the target
978
977
        del state._log[:]
979
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
980
 
                                         stat_value=stat_value)
981
 
        self.assertEqual(b'target', link_or_sha1)
982
 
        self.assertEqual([('read_link', b'a', b'')], state._log)
983
 
        self.assertEqual([(b'l', b'', 6, False, dirstate.DirState.NULLSTAT)],
 
978
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
979
                                          stat_value=stat_value)
 
980
        self.assertEqual('target', link_or_sha1)
 
981
        self.assertEqual([('read_link', 'a', '')], state._log)
 
982
        self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
984
983
                         entry[1])
985
984
        state.save()
986
 
        state.adjust_time(+20)  # Skip into the future, all files look old
 
985
        state.adjust_time(+20) # Skip into the future, all files look old
987
986
        del state._log[:]
988
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
989
 
                                         stat_value=stat_value)
 
987
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
988
                                          stat_value=stat_value)
990
989
        # The symlink stayed a symlink. So while it is new enough to cache, we
991
990
        # don't bother setting the flag, because it is not really worth saving
992
991
        # (when we stat the symlink, we'll have paged in the target.)
993
992
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
994
993
                         state._dirblock_state)
995
 
        self.assertEqual(b'target', link_or_sha1)
 
994
        self.assertEqual('target', link_or_sha1)
996
995
        # We need to re-read the link because only now can we cache it
997
 
        self.assertEqual([('read_link', b'a', b'')], state._log)
998
 
        self.assertEqual([(b'l', b'target', 6, False, packed_stat)],
 
996
        self.assertEqual([('read_link', 'a', '')], state._log)
 
997
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
999
998
                         entry[1])
1000
999
 
1001
1000
        del state._log[:]
1002
1001
        # Another call won't re-read the link
1003
1002
        self.assertEqual([], state._log)
1004
 
        link_or_sha1 = self.update_entry(state, entry, abspath=b'a',
1005
 
                                         stat_value=stat_value)
1006
 
        self.assertEqual(b'target', link_or_sha1)
1007
 
        self.assertEqual([(b'l', b'target', 6, False, packed_stat)],
 
1003
        link_or_sha1 = self.update_entry(state, entry, abspath='a',
 
1004
                                          stat_value=stat_value)
 
1005
        self.assertEqual('target', link_or_sha1)
 
1006
        self.assertEqual([('l', 'target', 6, False, packed_stat)],
1008
1007
                         entry[1])
1009
1008
 
1010
1009
    def do_update_entry(self, state, entry, abspath):
1014
1013
    def test_update_entry_dir(self):
1015
1014
        state, entry = self.get_state_with_a()
1016
1015
        self.build_tree(['a/'])
1017
 
        self.assertIs(None, self.do_update_entry(state, entry, b'a'))
 
1016
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1018
1017
 
1019
1018
    def test_update_entry_dir_unchanged(self):
1020
1019
        state, entry = self.get_state_with_a()
1021
1020
        self.build_tree(['a/'])
1022
1021
        state.adjust_time(+20)
1023
 
        self.assertIs(None, self.do_update_entry(state, entry, b'a'))
 
1022
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1024
1023
        # a/ used to be a file, but is now a directory, worth saving
1025
1024
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1026
1025
                         state._dirblock_state)
1028
1027
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1029
1028
                         state._dirblock_state)
1030
1029
        # No changes to a/ means not worth saving.
1031
 
        self.assertIs(None, self.do_update_entry(state, entry, b'a'))
 
1030
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1032
1031
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1033
1032
                         state._dirblock_state)
1034
1033
        # Change the last-modified time for the directory
1039
1038
            # It looks like Win32 + FAT doesn't allow to change times on a dir.
1040
1039
            raise tests.TestSkipped("can't update mtime of a dir on FAT")
1041
1040
        saved_packed_stat = entry[1][0][-1]
1042
 
        self.assertIs(None, self.do_update_entry(state, entry, b'a'))
 
1041
        self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1043
1042
        # We *do* go ahead and update the information in the dirblocks, but we
1044
1043
        # don't bother setting IN_MEMORY_MODIFIED because it is trivial to
1045
1044
        # recompute.
1052
1051
        tree = self.make_branch_and_tree('tree')
1053
1052
        tree.lock_write()
1054
1053
        self.build_tree(['tree/a'])
1055
 
        tree.add(['a'], [b'a-id'])
 
1054
        tree.add(['a'], ['a-id'])
1056
1055
        with_a_id = tree.commit('witha')
1057
1056
        self.addCleanup(tree.unlock)
1058
1057
        state.set_parent_trees(
1059
1058
            [(with_a_id, tree.branch.repository.revision_tree(with_a_id))],
1060
1059
            [])
1061
 
        entry = state._get_entry(0, path_utf8=b'a')
 
1060
        entry = state._get_entry(0, path_utf8='a')
1062
1061
        self.build_tree(['a'])
1063
 
        sha1sum = b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1062
        sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1064
1063
        state.adjust_time(+20)
1065
 
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, b'a'))
 
1064
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1066
1065
        self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1067
1066
                         state._dirblock_state)
1068
1067
        state.save()
1069
1068
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1070
1069
                         state._dirblock_state)
1071
 
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, b'a'))
 
1070
        self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1072
1071
        self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1073
1072
                         state._dirblock_state)
1074
1073
 
1075
1074
    def test_update_entry_tree_reference(self):
1076
1075
        state = test_dirstate.InstrumentedDirState.initialize('dirstate')
1077
1076
        self.addCleanup(state.unlock)
1078
 
        state.add('r', b'r-id', 'tree-reference', None, b'')
 
1077
        state.add('r', 'r-id', 'tree-reference', None, '')
1079
1078
        self.build_tree(['r/'])
1080
 
        entry = state._get_entry(0, path_utf8=b'r')
 
1079
        entry = state._get_entry(0, path_utf8='r')
1081
1080
        self.do_update_entry(state, entry, 'r')
1082
 
        entry = state._get_entry(0, path_utf8=b'r')
1083
 
        self.assertEqual(b't', entry[1][0][0])
 
1081
        entry = state._get_entry(0, path_utf8='r')
 
1082
        self.assertEqual('t', entry[1][0][0])
1084
1083
 
1085
1084
    def create_and_test_file(self, state, entry):
1086
1085
        """Create a file at 'a' and verify the state finds it during update.
1094
1093
 
1095
1094
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1096
1095
        self.assertEqual(None, link_or_sha1)
1097
 
        self.assertEqual([(b'f', b'', 14, False, dirstate.DirState.NULLSTAT)],
 
1096
        self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1098
1097
                         entry[1])
1099
1098
        return packed_stat
1100
1099
 
1108
1107
        stat_value = os.lstat('a')
1109
1108
        packed_stat = dirstate.pack_stat(stat_value)
1110
1109
 
1111
 
        link_or_sha1 = self.do_update_entry(state, entry, abspath=b'a')
 
1110
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1112
1111
        self.assertIs(None, link_or_sha1)
1113
 
        self.assertEqual([(b'd', b'', 0, False, packed_stat)], entry[1])
 
1112
        self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1114
1113
 
1115
1114
        return packed_stat
1116
1115
 
1130
1129
        stat_value = os.lstat('a')
1131
1130
        packed_stat = dirstate.pack_stat(stat_value)
1132
1131
 
1133
 
        link_or_sha1 = self.do_update_entry(state, entry, abspath=b'a')
1134
 
        self.assertEqual(b'path/to/foo', link_or_sha1)
1135
 
        self.assertEqual([(b'l', b'path/to/foo', 11, False, packed_stat)],
 
1132
        link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
 
1133
        self.assertEqual('path/to/foo', link_or_sha1)
 
1134
        self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1136
1135
                         entry[1])
1137
1136
        return packed_stat
1138
1137
 
1200
1199
        state, entry = self.get_state_with_a()
1201
1200
        self.build_tree(['a'])
1202
1201
 
1203
 
        # Make sure we are using the version of _is_executable that doesn't
1204
 
        # check the filesystem mode.
1205
 
        state._use_filesystem_for_exec = False
 
1202
        # Make sure we are using the win32 implementation of _is_executable
 
1203
        state._is_executable = state._is_executable_win32
1206
1204
 
1207
1205
        # The file on disk is not executable, but we are marking it as though
1208
 
        # it is. With _use_filesystem_for_exec disabled we ignore what is on
1209
 
        # disk.
1210
 
        entry[1][0] = (b'f', b'', 0, True, dirstate.DirState.NULLSTAT)
 
1206
        # it is. With _is_executable_win32 we ignore what is on disk.
 
1207
        entry[1][0] = ('f', '', 0, True, dirstate.DirState.NULLSTAT)
1211
1208
 
1212
1209
        stat_value = os.lstat('a')
1213
1210
        packed_stat = dirstate.pack_stat(stat_value)
1214
1211
 
1215
 
        state.adjust_time(-10)  # Make sure everything is new
1216
 
        self.update_entry(state, entry, abspath=b'a', stat_value=stat_value)
 
1212
        state.adjust_time(-10) # Make sure everything is new
 
1213
        self.update_entry(state, entry, abspath='a', stat_value=stat_value)
1217
1214
 
1218
1215
        # The row is updated, but the executable bit stays set.
1219
 
        self.assertEqual([(b'f', b'', 14, True, dirstate.DirState.NULLSTAT)],
 
1216
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1220
1217
                         entry[1])
1221
1218
 
1222
1219
        # Make the disk object look old enough to cache (but it won't cache the
1223
1220
        # sha as it is a new file).
1224
1221
        state.adjust_time(+20)
1225
 
        digest = b'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1226
 
        self.update_entry(state, entry, abspath=b'a', stat_value=stat_value)
1227
 
        self.assertEqual([(b'f', b'', 14, True, dirstate.DirState.NULLSTAT)],
1228
 
                         entry[1])
 
1222
        digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
 
1223
        self.update_entry(state, entry, abspath='a', stat_value=stat_value)
 
1224
        self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
 
1225
            entry[1])
1229
1226
 
1230
1227
    def _prepare_tree(self):
1231
1228
        # Create a tree
1232
 
        text = b'Hello World\n'
 
1229
        text = 'Hello World\n'
1233
1230
        tree = self.make_branch_and_tree('tree')
1234
1231
        self.build_tree_contents([('tree/a file', text)])
1235
 
        tree.add('a file', b'a-file-id')
 
1232
        tree.add('a file', 'a-file-id')
1236
1233
        # Note: dirstate does not sha prior to the first commit
1237
1234
        # so commit now in order for the test to work
1238
1235
        tree.commit('first')
1241
1238
    def test_sha1provider_sha1_used(self):
1242
1239
        tree, text = self._prepare_tree()
1243
1240
        state = dirstate.DirState.from_tree(tree, 'dirstate',
1244
 
                                            UppercaseSHA1Provider())
 
1241
            UppercaseSHA1Provider())
1245
1242
        self.addCleanup(state.unlock)
1246
 
        expected_sha = osutils.sha_string(text.upper() + b"foo")
1247
 
        entry = state._get_entry(0, path_utf8=b'a file')
1248
 
        self.assertNotEqual((None, None), entry)
 
1243
        expected_sha = osutils.sha_string(text.upper() + "foo")
 
1244
        entry = state._get_entry(0, path_utf8='a file')
1249
1245
        state._sha_cutoff_time()
1250
1246
        state._cutoff_time += 10
1251
1247
        sha1 = self.update_entry(state, entry, 'tree/a file',
1260
1256
        state._sha1_provider = UppercaseSHA1Provider()
1261
1257
        # If we used the standard provider, it would look like nothing has
1262
1258
        # changed
1263
 
        file_ids_changed = [change.file_id for change
 
1259
        file_ids_changed = [change[0] for change
1264
1260
                            in tree.iter_changes(tree.basis_tree())]
1265
 
        self.assertEqual([b'a-file-id'], file_ids_changed)
 
1261
        self.assertEqual(['a-file-id'], file_ids_changed)
1266
1262
 
1267
1263
 
1268
1264
class UppercaseSHA1Provider(dirstate.SHA1Provider):
1272
1268
        return self.stat_and_sha1(abspath)[1]
1273
1269
 
1274
1270
    def stat_and_sha1(self, abspath):
1275
 
        with open(abspath, 'rb') as file_obj:
 
1271
        file_obj = file(abspath, 'rb')
 
1272
        try:
1276
1273
            statvalue = os.fstat(file_obj.fileno())
1277
 
            text = b''.join(file_obj.readlines())
1278
 
            sha1 = osutils.sha_string(text.upper() + b"foo")
 
1274
            text = ''.join(file_obj.readlines())
 
1275
            sha1 = osutils.sha_string(text.upper() + "foo")
 
1276
        finally:
 
1277
            file_obj.close()
1279
1278
        return statvalue, sha1
1280
1279
 
1281
1280
 
1291
1290
        self.overrideAttr(dirstate, '_process_entry', self._process_entry)
1292
1291
 
1293
1292
    def assertChangedFileIds(self, expected, tree):
1294
 
        with tree.lock_read():
1295
 
            file_ids = [info.file_id for info
 
1293
        tree.lock_read()
 
1294
        try:
 
1295
            file_ids = [info[0] for info
1296
1296
                        in tree.iter_changes(tree.basis_tree())]
 
1297
        finally:
 
1298
            tree.unlock()
1297
1299
        self.assertEqual(sorted(expected), sorted(file_ids))
1298
1300
 
1299
1301
    def test_exceptions_raised(self):
1308
1310
        tree.lock_read()
1309
1311
        self.addCleanup(tree.unlock)
1310
1312
        basis_tree = tree.basis_tree()
1311
 
 
1312
1313
        def is_inside_raises(*args, **kwargs):
1313
1314
            raise RuntimeError('stop this')
1314
 
        self.overrideAttr(dirstate, 'is_inside', is_inside_raises)
1315
 
        try:
1316
 
            from .. import _dirstate_helpers_pyx
1317
 
        except ImportError:
1318
 
            pass
1319
 
        else:
1320
 
            self.overrideAttr(_dirstate_helpers_pyx,
1321
 
                              'is_inside', is_inside_raises)
1322
1315
        self.overrideAttr(osutils, 'is_inside', is_inside_raises)
1323
1316
        self.assertListRaises(RuntimeError, tree.iter_changes, basis_tree)
1324
1317
 
1325
1318
    def test_simple_changes(self):
1326
1319
        tree = self.make_branch_and_tree('tree')
1327
1320
        self.build_tree(['tree/file'])
1328
 
        tree.add(['file'], [b'file-id'])
1329
 
        self.assertChangedFileIds([tree.path2id(''), b'file-id'], tree)
 
1321
        tree.add(['file'], ['file-id'])
 
1322
        self.assertChangedFileIds([tree.get_root_id(), 'file-id'], tree)
1330
1323
        tree.commit('one')
1331
1324
        self.assertChangedFileIds([], tree)
1332
1325
 
1333
1326
    def test_sha1provider_stat_and_sha1_used(self):
1334
1327
        tree = self.make_branch_and_tree('tree')
1335
1328
        self.build_tree(['tree/file'])
1336
 
        tree.add(['file'], [b'file-id'])
 
1329
        tree.add(['file'], ['file-id'])
1337
1330
        tree.commit('one')
1338
1331
        tree.lock_write()
1339
1332
        self.addCleanup(tree.unlock)
1340
1333
        state = tree._current_dirstate()
1341
1334
        state._sha1_provider = UppercaseSHA1Provider()
1342
 
        self.assertChangedFileIds([b'file-id'], tree)
 
1335
        self.assertChangedFileIds(['file-id'], tree)
1343
1336
 
1344
1337
 
1345
1338
class TestPackStat(tests.TestCase):
1355
1348
        return _dirstate_helpers_py._unpack_stat(packed_string)[stat_field]
1356
1349
 
1357
1350
    def test_result(self):
1358
 
        self.assertEqual(b"AAAQAAAAABAAAAARAAAAAgAAAAEAAIHk",
1359
 
                         self.pack((33252, 1, 2, 0, 0, 0, 4096, 15.5, 16.5, 17.5)))
 
1351
        self.assertEqual("AAAQAAAAABAAAAARAAAAAgAAAAEAAIHk",
 
1352
            self.pack((33252, 1, 2, 0, 0, 0, 4096, 15.5, 16.5, 17.5)))
1360
1353
 
1361
1354
    def test_giant_inode(self):
1362
1355
        packed = self.pack((33252, 0xF80000ABC, 0, 0, 0, 0, 0, 0, 0, 0))