def test_rsync(self, dest_dir): # Need to copy a bigger amount of files ... however it's dependent on time anyway, so this one # might fail in a few years raise SkipTest("This test is too slow and depends on timing, making it unreliable") source = Path(__file__).dirname().dirname() for subdir in (None, "rsync_destination"): destination = dest_dir if subdir is not None: destination /= subdir # END handle destination p = StoringProgressIndicator() for dry_run in reversed(list(range(2))): t = Transaction(log, dry_run=dry_run, progress=p) ro = RsyncOperation(t, source, destination) assert t.apply().succeeded(), "should work in any way" self._assert_rsync_state(ro) assert ro.actual_destination().exists() != dry_run assert not t.rollback().succeeded( ), "Rollback always works, evern in dry run mode where it doesn't do anything" assert not ro.actual_destination().exists() # END for each dryrun mode # abort operation - make it a bit slower t.clear() ro = RsyncOperation(t, source, destination, max_bandwidth_kb=1000) cr = ConcurrentRun(t.apply, log).start() time.sleep(0.25) assert t.is_running(), "transaction should still be running" assert ro.actual_destination().exists(), "destination dir should have been created at least" t.abort(True) assert t.is_aborting() s = time.time() assert cr.result() is t, "Waited for result, which was not what we expected" elapsed = time.time() - s assert elapsed < 1.0, "Should have joined much faster, it took %f" % elapsed assert not t.is_aborting(), "Shouldnt be in abort mode anymore after we aborted and rolled back" assert not ro.actual_destination().exists( ), "Destination should not exist any more as we triggered a rollback" assert not t.succeeded()
def test_base(self): t = Transaction(log) assert t.succeeded() == False, "Should be unsuccessful if it didn't run yet" assert not t.is_done(), "Should not yet be done" assert t.exception() is None, "There should be no exception if it didn't run" assert not t.is_aborting(), "It shouldn't yet abort" assert t.progress() is None, "Should have no progress while its not running" assert not t.is_running(), "shouldn't be running after instantiation" assert not t.is_rolling_back(), "Shouldn't be rolling back after init" assert not t.rollback().succeeded(), "Cannot rollback without having performed the operation" assert not t.aborted(), "Shouldn't be aborted in a plain vanilla transaction" # successful operation ###################### so = SuccessOp(t) so2 = SuccessOp(t) assert t.apply().succeeded(), "Transaction should be successfull after it ran" assert t.is_done(), "transaction should be done now" assert t.exception() is None assert so._value == 2 assert so2._value == 2 assert t.progress() is None, "no progress after transaction" assert t.is_running() == False, "its not running anymore" assert t.apply().succeeded(), "Transaction doesn't actually run multiple times" assert so._value == 2 and so2._value == 2 # Rollback ########## assert not t.rollback().succeeded(), "After rollback its like nothing happened" assert so._value == 0 and so2._value == 0, "Rollback should have been called on operation" assert not t.is_running() and t.progress() is None, "Shouldn't be running anymore" # can re-apply assert t.apply().succeeded(), "Should be successful after apply" assert so._value == 2, "operation should have been called" # Failling operation #################### t = Transaction(log) so = SuccessOp(t) fo = FailOp(t) assert not t.apply().succeeded(), "Transaction should fail this time" assert so._value == 0 and fo._value == 0 assert isinstance(t.exception(), Exception), "exception was expected" assert not t.rollback().succeeded(), "Rollback should not work without apply()" assert not t.apply().succeeded(), "apply() should fail in second run as well" assert so._value == 0 # Abort long-running operations ################################ t.clear() lo = LongRunningOp(t) cr = ConcurrentRun(t.apply, t.log).start() time.sleep(0.002) assert t.is_running(), "Should be runnning now" assert t.progress() is not None, "When running, there is a progress" assert lo._value > 0, "Should have managed to do some work after waiting" assert not t.is_aborting() assert t.abort(True).is_aborting(), "Should be aborting after setting the state - if this fails its an async issue" assert cr.result() is t, "Wait for transaction yielded unexpected result" assert lo._value == 0, "Rollback should have occurred" assert not t.succeeded(), "op shold not have been successful after abort" assert not t.is_rolling_back(), "Shouldn't be rolling back once we are done with it"