2464
2464
self.assertPathExists('a/b')
2467
class TestCleanup(tests.TestCaseWithTransport):
2469
def _override_globals_in_method(self, instance, method_name, globals):
2470
"""Replace method on instance with one with updated globals"""
2472
func = getattr(instance, method_name).im_func
2473
new_globals = dict(func.func_globals)
2474
new_globals.update(globals)
2475
new_func = types.FunctionType(func.func_code, new_globals,
2476
func.func_name, func.func_defaults)
2477
setattr(instance, method_name,
2478
types.MethodType(new_func, instance, instance.__class__))
2479
self.addCleanup(delattr, instance, method_name)
2482
def _fake_open_raises_before(name, mode):
2483
"""Like open() but raises before doing anything"""
2487
def _fake_open_raises_after(name, mode):
2488
"""Like open() but raises after creating file without returning"""
2489
open(name, mode).close()
2492
def create_transform_and_root_trans_id(self):
2493
"""Setup a transform creating a file in limbo"""
2494
tree = self.make_branch_and_tree('.')
2495
tt = TreeTransform(tree)
2496
return tt, tt.create_path("a", tt.root)
2498
def create_transform_and_subdir_trans_id(self):
2499
"""Setup a transform creating a directory containing a file in limbo"""
2500
tree = self.make_branch_and_tree('.')
2501
tt = TreeTransform(tree)
2502
d_trans_id = tt.create_path("d", tt.root)
2503
tt.create_directory(d_trans_id)
2504
f_trans_id = tt.create_path("a", d_trans_id)
2505
tt.adjust_path("a", d_trans_id, f_trans_id)
2506
return tt, f_trans_id
2508
def test_root_create_file_open_raises_before_creation(self):
2509
tt, trans_id = self.create_transform_and_root_trans_id()
2510
self._override_globals_in_method(tt, "create_file",
2511
{"open": self._fake_open_raises_before})
2512
self.assertRaises(RuntimeError, tt.create_file, ["contents"], trans_id)
2513
path = tt._limbo_name(trans_id)
2514
self.assertPathDoesNotExist(path)
2516
self.assertPathDoesNotExist(tt._limbodir)
2518
def test_root_create_file_open_raises_after_creation(self):
2519
tt, trans_id = self.create_transform_and_root_trans_id()
2520
self._override_globals_in_method(tt, "create_file",
2521
{"open": self._fake_open_raises_after})
2522
self.assertRaises(RuntimeError, tt.create_file, ["contents"], trans_id)
2523
path = tt._limbo_name(trans_id)
2524
self.assertPathExists(path)
2525
# GZ 2011-05-17: Why raise ImmortalLimbo, masking the earlier error,
2526
# rather than just emitting a warning or similar?
2527
self.assertRaises(errors.ImmortalLimbo, tt.finalize)
2528
self.assertPathExists(path)
2529
self.assertPathExists(tt._limbodir)
2531
def test_subdir_create_file_open_raises_before_creation(self):
2532
tt, trans_id = self.create_transform_and_subdir_trans_id()
2533
self._override_globals_in_method(tt, "create_file",
2534
{"open": self._fake_open_raises_before})
2535
self.assertRaises(RuntimeError, tt.create_file, ["contents"], trans_id)
2536
path = tt._limbo_name(trans_id)
2537
self.assertPathDoesNotExist(path)
2539
self.assertPathDoesNotExist(tt._limbodir)
2541
def test_subdir_create_file_open_raises_after_creation(self):
2542
tt, trans_id = self.create_transform_and_subdir_trans_id()
2543
self._override_globals_in_method(tt, "create_file",
2544
{"open": self._fake_open_raises_after})
2545
self.assertRaises(RuntimeError, tt.create_file, ["contents"], trans_id)
2546
path = tt._limbo_name(trans_id)
2547
self.assertPathExists(path)
2549
self.assertPathDoesNotExist(path)
2550
self.assertPathDoesNotExist(tt._limbodir)
2467
2553
class TestTransformMissingParent(tests.TestCaseWithTransport):
2469
2555
def make_tt_with_versioned_dir(self):