~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transform.py

  • Committer: Martin Pool
  • Date: 2011-02-07 01:39:42 UTC
  • mto: This revision was merged to the branch mainline in revision 5650.
  • Revision ID: mbp@canonical.com-20110207013942-roj88kez6jir13tr
Add brief user documentation of command line splitting

Show diffs side-by-side

added added

removed removed

Lines of Context:
93
93
        self.addCleanup(transform.finalize)
94
94
        return transform, transform.root
95
95
 
96
 
    def get_transform_for_sha1_test(self):
97
 
        trans, root = self.get_transform()
98
 
        self.wt.lock_tree_write()
99
 
        self.addCleanup(self.wt.unlock)
100
 
        contents = ['just some content\n']
101
 
        sha1 = osutils.sha_strings(contents)
102
 
        # Roll back the clock
103
 
        trans._creation_mtime = time.time() - 20.0
104
 
        return trans, root, contents, sha1
105
 
 
106
96
    def test_existing_limbo(self):
107
97
        transform, root = self.get_transform()
108
98
        limbo_name = transform._limbodir
171
161
        transform.finalize()
172
162
        transform.finalize()
173
163
 
174
 
    def test_apply_informs_tree_of_observed_sha1(self):
175
 
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
176
 
        trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
177
 
                                  sha1=sha1)
178
 
        calls = []
179
 
        orig = self.wt._observed_sha1
180
 
        def _observed_sha1(*args):
181
 
            calls.append(args)
182
 
            orig(*args)
183
 
        self.wt._observed_sha1 = _observed_sha1
184
 
        trans.apply()
185
 
        self.assertEqual([(None, 'file1', trans._observed_sha1s[trans_id])],
186
 
                         calls)
187
 
 
188
 
    def test_create_file_caches_sha1(self):
189
 
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
190
 
        trans_id = trans.create_path('file1', root)
191
 
        trans.create_file(contents, trans_id, sha1=sha1)
192
 
        st_val = osutils.lstat(trans._limbo_name(trans_id))
193
 
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
194
 
        self.assertEqual(o_sha1, sha1)
195
 
        self.assertEqualStat(o_st_val, st_val)
196
 
 
197
 
    def test__apply_insertions_updates_sha1(self):
198
 
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
199
 
        trans_id = trans.create_path('file1', root)
200
 
        trans.create_file(contents, trans_id, sha1=sha1)
201
 
        st_val = osutils.lstat(trans._limbo_name(trans_id))
202
 
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
203
 
        self.assertEqual(o_sha1, sha1)
204
 
        self.assertEqualStat(o_st_val, st_val)
205
 
        creation_mtime = trans._creation_mtime + 10.0
206
 
        # We fake a time difference from when the file was created until now it
207
 
        # is being renamed by using os.utime. Note that the change we actually
208
 
        # want to see is the real ctime change from 'os.rename()', but as long
209
 
        # as we observe a new stat value, we should be fine.
210
 
        os.utime(trans._limbo_name(trans_id), (creation_mtime, creation_mtime))
211
 
        trans.apply()
212
 
        new_st_val = osutils.lstat(self.wt.abspath('file1'))
213
 
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
214
 
        self.assertEqual(o_sha1, sha1)
215
 
        self.assertEqualStat(o_st_val, new_st_val)
216
 
        self.assertNotEqual(st_val.st_mtime, new_st_val.st_mtime)
217
 
 
218
 
    def test_new_file_caches_sha1(self):
219
 
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
220
 
        trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
221
 
                                  sha1=sha1)
222
 
        st_val = osutils.lstat(trans._limbo_name(trans_id))
223
 
        o_sha1, o_st_val = trans._observed_sha1s[trans_id]
224
 
        self.assertEqual(o_sha1, sha1)
225
 
        self.assertEqualStat(o_st_val, st_val)
226
 
 
227
 
    def test_cancel_creation_removes_observed_sha1(self):
228
 
        trans, root, contents, sha1 = self.get_transform_for_sha1_test()
229
 
        trans_id = trans.new_file('file1', root, contents, file_id='file1-id',
230
 
                                  sha1=sha1)
231
 
        self.assertTrue(trans_id in trans._observed_sha1s)
232
 
        trans.cancel_creation(trans_id)
233
 
        self.assertFalse(trans_id in trans._observed_sha1s)
234
 
 
235
164
    def test_create_files_same_timestamp(self):
236
165
        transform, root = self.get_transform()
237
166
        self.wt.lock_tree_write()
295
224
        trans_id = target_transform.create_path('file1', target_transform.root)
296
225
        target_transform.create_hardlink(self.wt.abspath('file1'), trans_id)
297
226
        target_transform.apply()
298
 
        self.assertPathExists('target/file1')
 
227
        self.failUnlessExists('target/file1')
299
228
        source_stat = os.stat(self.wt.abspath('file1'))
300
229
        target_stat = os.stat('target/file1')
301
230
        self.assertEqual(source_stat, target_stat)
467
396
        transform.new_file('FiLe', transform.root, 'content')
468
397
        resolve_conflicts(transform)
469
398
        transform.apply()
470
 
        self.assertPathExists('tree/file')
471
 
        self.assertPathExists('tree/FiLe.moved')
 
399
        self.failUnlessExists('tree/file')
 
400
        self.failUnlessExists('tree/FiLe.moved')
472
401
 
473
402
    def test_resolve_checkout_case_conflict(self):
474
403
        tree = self.make_branch_and_tree('tree')
483
412
        resolve_conflicts(transform,
484
413
                          pass_func=lambda t, c: resolve_checkout(t, c, []))
485
414
        transform.apply()
486
 
        self.assertPathExists('tree/file')
487
 
        self.assertPathExists('tree/FiLe.moved')
 
415
        self.failUnlessExists('tree/file')
 
416
        self.failUnlessExists('tree/FiLe.moved')
488
417
 
489
418
    def test_apply_case_conflict(self):
490
419
        """Ensure that a transform with case conflicts can always be applied"""
498
427
        transform.new_file('dirFiLe', dir, 'content')
499
428
        resolve_conflicts(transform)
500
429
        transform.apply()
501
 
        self.assertPathExists('tree/file')
 
430
        self.failUnlessExists('tree/file')
502
431
        if not os.path.exists('tree/FiLe.moved'):
503
 
            self.assertPathExists('tree/FiLe')
504
 
        self.assertPathExists('tree/dir/dirfile')
 
432
            self.failUnlessExists('tree/FiLe')
 
433
        self.failUnlessExists('tree/dir/dirfile')
505
434
        if not os.path.exists('tree/dir/dirFiLe.moved'):
506
 
            self.assertPathExists('tree/dir/dirFiLe')
 
435
            self.failUnlessExists('tree/dir/dirFiLe')
507
436
 
508
437
    def test_case_insensitive_limbo(self):
509
438
        tree = self.make_branch_and_tree('tree')
1255
1184
        parent2 = transform.new_directory('parent2', root)
1256
1185
        transform.adjust_path('child1', parent2, child1)
1257
1186
        transform.apply()
1258
 
        self.assertPathDoesNotExist(self.wt.abspath('parent1/child1'))
1259
 
        self.assertPathExists(self.wt.abspath('parent2/child1'))
 
1187
        self.failIfExists(self.wt.abspath('parent1/child1'))
 
1188
        self.failUnlessExists(self.wt.abspath('parent2/child1'))
1260
1189
        # rename limbo/new-1 => parent1, rename limbo/new-3 => parent2
1261
1190
        # no rename for child1 (counting only renames during apply)
1262
 
        self.assertEqual(2, transform.rename_count)
 
1191
        self.failUnlessEqual(2, transform.rename_count)
1263
1192
 
1264
1193
    def test_cancel_parent(self):
1265
1194
        """Cancelling a parent doesn't cause deletion of a non-empty directory
1288
1217
        parent2 = transform.new_directory('parent2', root)
1289
1218
        transform.adjust_path('child1', parent2, child1)
1290
1219
        transform.apply()
1291
 
        self.assertPathDoesNotExist(self.wt.abspath('parent1'))
1292
 
        self.assertPathExists(self.wt.abspath('parent2/child1'))
 
1220
        self.failIfExists(self.wt.abspath('parent1'))
 
1221
        self.failUnlessExists(self.wt.abspath('parent2/child1'))
1293
1222
        # rename limbo/new-3 => parent2, rename limbo/new-2 => child1
1294
 
        self.assertEqual(2, transform.rename_count)
 
1223
        self.failUnlessEqual(2, transform.rename_count)
1295
1224
 
1296
1225
    def test_adjust_and_cancel(self):
1297
1226
        """Make sure adjust_path keeps track of limbo children properly"""
1330
1259
        child = transform.new_directory('child', parent)
1331
1260
        transform.adjust_path('parent', root, parent)
1332
1261
        transform.apply()
1333
 
        self.assertPathExists(self.wt.abspath('parent/child'))
 
1262
        self.failUnlessExists(self.wt.abspath('parent/child'))
1334
1263
        self.assertEqual(1, transform.rename_count)
1335
1264
 
1336
1265
    def test_reuse_name(self):
1467
1396
        tt.create_file(["aa\n"], bar_trans_id)
1468
1397
        tt.version_file("bar-1", bar_trans_id)
1469
1398
        tt.apply()
1470
 
        self.assertPathExists("foo/bar")
 
1399
        self.failUnlessExists("foo/bar")
1471
1400
        wt.lock_read()
1472
1401
        try:
1473
1402
            self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1490
1419
        tt.delete_contents(foo_trans_id)
1491
1420
        tt.create_symlink("bar", foo_trans_id)
1492
1421
        tt.apply()
1493
 
        self.assertPathExists("foo")
 
1422
        self.failUnlessExists("foo")
1494
1423
        wt.lock_read()
1495
1424
        self.addCleanup(wt.unlock)
1496
1425
        self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1509
1438
        tt.delete_versioned(bar_trans_id)
1510
1439
        tt.create_file(["aa\n"], foo_trans_id)
1511
1440
        tt.apply()
1512
 
        self.assertPathExists("foo")
 
1441
        self.failUnlessExists("foo")
1513
1442
        wt.lock_read()
1514
1443
        self.addCleanup(wt.unlock)
1515
1444
        self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1530
1459
        self.build_tree(['baz'])
1531
1460
        tt.create_hardlink("baz", foo_trans_id)
1532
1461
        tt.apply()
1533
 
        self.assertPathExists("foo")
1534
 
        self.assertPathExists("baz")
 
1462
        self.failUnlessExists("foo")
 
1463
        self.failUnlessExists("baz")
1535
1464
        wt.lock_read()
1536
1465
        self.addCleanup(wt.unlock)
1537
1466
        self.assertEqual(wt.inventory.get_file_kind(wt.path2id("foo")),
1814
1743
        tree.add_reference(subtree)
1815
1744
        tree.commit('a revision')
1816
1745
        tree.branch.create_checkout('target')
1817
 
        self.assertPathExists('target')
1818
 
        self.assertPathExists('target/subtree')
 
1746
        self.failUnlessExists('target')
 
1747
        self.failUnlessExists('target/subtree')
1819
1748
 
1820
1749
    def test_file_conflict_handling(self):
1821
1750
        """Ensure that when building trees, conflict handling is done"""
1868
1797
        source.commit('added file')
1869
1798
        build_tree(source.basis_tree(), target)
1870
1799
        self.assertEqual([], target.conflicts())
1871
 
        self.assertPathExists('target/dir1/file')
 
1800
        self.failUnlessExists('target/dir1/file')
1872
1801
 
1873
1802
        # Ensure contents are merged
1874
1803
        target = self.make_branch_and_tree('target2')
1875
1804
        self.build_tree(['target2/dir1/', 'target2/dir1/file2'])
1876
1805
        build_tree(source.basis_tree(), target)
1877
1806
        self.assertEqual([], target.conflicts())
1878
 
        self.assertPathExists('target2/dir1/file2')
1879
 
        self.assertPathExists('target2/dir1/file')
 
1807
        self.failUnlessExists('target2/dir1/file2')
 
1808
        self.failUnlessExists('target2/dir1/file')
1880
1809
 
1881
1810
        # Ensure new contents are suppressed for existing branches
1882
1811
        target = self.make_branch_and_tree('target3')
1883
1812
        self.make_branch('target3/dir1')
1884
1813
        self.build_tree(['target3/dir1/file2'])
1885
1814
        build_tree(source.basis_tree(), target)
1886
 
        self.assertPathDoesNotExist('target3/dir1/file')
1887
 
        self.assertPathExists('target3/dir1/file2')
1888
 
        self.assertPathExists('target3/dir1.diverted/file')
 
1815
        self.failIfExists('target3/dir1/file')
 
1816
        self.failUnlessExists('target3/dir1/file2')
 
1817
        self.failUnlessExists('target3/dir1.diverted/file')
1889
1818
        self.assertEqual([DuplicateEntry('Diverted to',
1890
1819
            'dir1.diverted', 'dir1', 'new-dir1', None)],
1891
1820
            target.conflicts())
1894
1823
        self.build_tree(['target4/dir1/'])
1895
1824
        self.make_branch('target4/dir1/file')
1896
1825
        build_tree(source.basis_tree(), target)
1897
 
        self.assertPathExists('target4/dir1/file')
 
1826
        self.failUnlessExists('target4/dir1/file')
1898
1827
        self.assertEqual('directory', file_kind('target4/dir1/file'))
1899
 
        self.assertPathExists('target4/dir1/file.diverted')
 
1828
        self.failUnlessExists('target4/dir1/file.diverted')
1900
1829
        self.assertEqual([DuplicateEntry('Diverted to',
1901
1830
            'dir1/file.diverted', 'dir1/file', 'new-file', None)],
1902
1831
            target.conflicts())
1970
1899
        self.addCleanup(target.unlock)
1971
1900
        self.assertEqual([], list(target.iter_changes(revision_tree)))
1972
1901
 
1973
 
    def test_build_tree_accelerator_tree_observes_sha1(self):
1974
 
        source = self.create_ab_tree()
1975
 
        sha1 = osutils.sha_string('A')
1976
 
        target = self.make_branch_and_tree('target')
1977
 
        target.lock_write()
1978
 
        self.addCleanup(target.unlock)
1979
 
        state = target.current_dirstate()
1980
 
        state._cutoff_time = time.time() + 60
1981
 
        build_tree(source.basis_tree(), target, source)
1982
 
        entry = state._get_entry(0, path_utf8='file1')
1983
 
        self.assertEqual(sha1, entry[1][0][1])
1984
 
 
1985
1902
    def test_build_tree_accelerator_tree_missing_file(self):
1986
1903
        source = self.create_ab_tree()
1987
1904
        os.unlink('source/file1')
2145
2062
        self.assertEqual('file.moved', target.id2path('lower-id'))
2146
2063
        self.assertEqual('FILE', target.id2path('upper-id'))
2147
2064
 
2148
 
    def test_build_tree_observes_sha(self):
2149
 
        source = self.make_branch_and_tree('source')
2150
 
        self.build_tree(['source/file1', 'source/dir/', 'source/dir/file2'])
2151
 
        source.add(['file1', 'dir', 'dir/file2'],
2152
 
                   ['file1-id', 'dir-id', 'file2-id'])
2153
 
        source.commit('new files')
2154
 
        target = self.make_branch_and_tree('target')
2155
 
        target.lock_write()
2156
 
        self.addCleanup(target.unlock)
2157
 
        # We make use of the fact that DirState caches its cutoff time. So we
2158
 
        # set the 'safe' time to one minute in the future.
2159
 
        state = target.current_dirstate()
2160
 
        state._cutoff_time = time.time() + 60
2161
 
        build_tree(source.basis_tree(), target)
2162
 
        entry1_sha = osutils.sha_file_by_name('source/file1')
2163
 
        entry2_sha = osutils.sha_file_by_name('source/dir/file2')
2164
 
        # entry[1] is the state information, entry[1][0] is the state of the
2165
 
        # working tree, entry[1][0][1] is the sha value for the current working
2166
 
        # tree
2167
 
        entry1 = state._get_entry(0, path_utf8='file1')
2168
 
        self.assertEqual(entry1_sha, entry1[1][0][1])
2169
 
        # The 'size' field must also be set.
2170
 
        self.assertEqual(25, entry1[1][0][2])
2171
 
        entry1_state = entry1[1][0]
2172
 
        entry2 = state._get_entry(0, path_utf8='dir/file2')
2173
 
        self.assertEqual(entry2_sha, entry2[1][0][1])
2174
 
        self.assertEqual(29, entry2[1][0][2])
2175
 
        entry2_state = entry2[1][0]
2176
 
        # Now, make sure that we don't have to re-read the content. The
2177
 
        # packed_stat should match exactly.
2178
 
        self.assertEqual(entry1_sha, target.get_file_sha1('file1-id', 'file1'))
2179
 
        self.assertEqual(entry2_sha,
2180
 
                         target.get_file_sha1('file2-id', 'dir/file2'))
2181
 
        self.assertEqual(entry1_state, entry1[1][0])
2182
 
        self.assertEqual(entry2_state, entry2[1][0])
2183
 
 
2184
2065
 
2185
2066
class TestCommitTransform(tests.TestCaseWithTransport):
2186
2067
 
2351
2232
        self.build_tree(['a/', 'a/b', 'c/', 'c/d'])
2352
2233
        mover = _FileMover()
2353
2234
        mover.rename('a', 'q')
2354
 
        self.assertPathExists('q')
2355
 
        self.assertPathDoesNotExist('a')
2356
 
        self.assertPathExists('q/b')
2357
 
        self.assertPathExists('c')
2358
 
        self.assertPathExists('c/d')
 
2235
        self.failUnlessExists('q')
 
2236
        self.failIfExists('a')
 
2237
        self.failUnlessExists('q/b')
 
2238
        self.failUnlessExists('c')
 
2239
        self.failUnlessExists('c/d')
2359
2240
 
2360
2241
    def test_pre_delete_rollback(self):
2361
2242
        self.build_tree(['a/'])
2362
2243
        mover = _FileMover()
2363
2244
        mover.pre_delete('a', 'q')
2364
 
        self.assertPathExists('q')
2365
 
        self.assertPathDoesNotExist('a')
 
2245
        self.failUnlessExists('q')
 
2246
        self.failIfExists('a')
2366
2247
        mover.rollback()
2367
 
        self.assertPathDoesNotExist('q')
2368
 
        self.assertPathExists('a')
 
2248
        self.failIfExists('q')
 
2249
        self.failUnlessExists('a')
2369
2250
 
2370
2251
    def test_apply_deletions(self):
2371
2252
        self.build_tree(['a/', 'b/'])
2372
2253
        mover = _FileMover()
2373
2254
        mover.pre_delete('a', 'q')
2374
2255
        mover.pre_delete('b', 'r')
2375
 
        self.assertPathExists('q')
2376
 
        self.assertPathExists('r')
2377
 
        self.assertPathDoesNotExist('a')
2378
 
        self.assertPathDoesNotExist('b')
 
2256
        self.failUnlessExists('q')
 
2257
        self.failUnlessExists('r')
 
2258
        self.failIfExists('a')
 
2259
        self.failIfExists('b')
2379
2260
        mover.apply_deletions()
2380
 
        self.assertPathDoesNotExist('q')
2381
 
        self.assertPathDoesNotExist('r')
2382
 
        self.assertPathDoesNotExist('a')
2383
 
        self.assertPathDoesNotExist('b')
 
2261
        self.failIfExists('q')
 
2262
        self.failIfExists('r')
 
2263
        self.failIfExists('a')
 
2264
        self.failIfExists('b')
2384
2265
 
2385
2266
    def test_file_mover_rollback(self):
2386
2267
        self.build_tree(['a/', 'a/b', 'c/', 'c/d/', 'c/e/'])
2391
2272
            mover.rename('a', 'c')
2392
2273
        except errors.FileExists, e:
2393
2274
            mover.rollback()
2394
 
        self.assertPathExists('a')
2395
 
        self.assertPathExists('c/d')
 
2275
        self.failUnlessExists('a')
 
2276
        self.failUnlessExists('c/d')
2396
2277
 
2397
2278
 
2398
2279
class Bogus(Exception):
2428
2309
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
2429
2310
        self.assertRaises(Bogus, tt.apply,
2430
2311
                          _mover=self.ExceptionFileMover(bad_source='a'))
2431
 
        self.assertPathExists('a')
2432
 
        self.assertPathExists('a/b')
 
2312
        self.failUnlessExists('a')
 
2313
        self.failUnlessExists('a/b')
2433
2314
        tt.apply()
2434
 
        self.assertPathExists('c')
2435
 
        self.assertPathExists('c/d')
 
2315
        self.failUnlessExists('c')
 
2316
        self.failUnlessExists('c/d')
2436
2317
 
2437
2318
    def test_rollback_rename_into_place(self):
2438
2319
        tree = self.make_branch_and_tree('.')
2444
2325
        tt.adjust_path('d', a_id, tt.trans_id_tree_path('a/b'))
2445
2326
        self.assertRaises(Bogus, tt.apply,
2446
2327
                          _mover=self.ExceptionFileMover(bad_target='c/d'))
2447
 
        self.assertPathExists('a')
2448
 
        self.assertPathExists('a/b')
 
2328
        self.failUnlessExists('a')
 
2329
        self.failUnlessExists('a/b')
2449
2330
        tt.apply()
2450
 
        self.assertPathExists('c')
2451
 
        self.assertPathExists('c/d')
 
2331
        self.failUnlessExists('c')
 
2332
        self.failUnlessExists('c/d')
2452
2333
 
2453
2334
    def test_rollback_deletion(self):
2454
2335
        tree = self.make_branch_and_tree('.')
2460
2341
        tt.adjust_path('d', tt.root, tt.trans_id_tree_path('a/b'))
2461
2342
        self.assertRaises(Bogus, tt.apply,
2462
2343
                          _mover=self.ExceptionFileMover(bad_target='d'))
2463
 
        self.assertPathExists('a')
2464
 
        self.assertPathExists('a/b')
 
2344
        self.failUnlessExists('a')
 
2345
        self.failUnlessExists('a/b')
2465
2346
 
2466
2347
 
2467
2348
class TestTransformMissingParent(tests.TestCaseWithTransport):