public void CheckpointableStateManager_UnloadCanBeRetried() { var i = 0; var fail = true; var e = new TestEngine( (_, ct, p) => Task.FromResult(true), (_, ct, p) => Task.FromResult(true), async p => { if (Volatile.Read(ref fail)) { var j = Interlocked.Increment(ref i) - 1; throw new Exception("Oops! " + j); } await Task.Yield(); } ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); try { s.UnloadAsync().Wait(); Assert.Fail(); } catch (AggregateException ex) { ex.Handle(err => err.Message == "Oops! 0"); } Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.CheckpointAsync(new TestWriter())).Wait(); Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.RecoverAsync(new TestReader())).Wait(); try { s.UnloadAsync().Wait(); Assert.Fail(); } catch (AggregateException ex) { ex.Handle(err => err.Message == "Oops! 1"); } Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.CheckpointAsync(new TestWriter())).Wait(); Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.RecoverAsync(new TestReader())).Wait(); Volatile.Write(ref fail, false); s.UnloadAsync().Wait(); Assert.AreEqual(2, Volatile.Read(ref i)); Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.CheckpointAsync(new TestWriter())).Wait(); Assert.ThrowsExceptionAsync <InvalidOperationException>(() => s.RecoverAsync(new TestReader())).Wait(); s.UnloadAsync().Wait(); Assert.AreEqual(2, Volatile.Read(ref i)); }
public void CheckpointableStateManager_CheckpointCanBeCancelled() { var busy = new TaskCompletionSource <bool>(); var done = new TaskCompletionSource <bool>(); var cancelled = false; var e = new TestEngine( async(_, ct, p) => { ct.Register(() => cancelled = true); busy.SetResult(true); await done.Task; }, (_, ct, p) => Task.FromResult(true), (p) => Task.FromResult(true) ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var cts = new CancellationTokenSource(); var t = s.CheckpointAsync(new TestWriter(), cts.Token); busy.Task.Wait(); cts.Cancel(); done.SetResult(true); t.Wait(); Assert.IsTrue(cancelled); }
public void CheckpointableStateManager_UnloadDuringCheckpointQueuesUp() { var checkpointDone = new TaskCompletionSource <bool>(); var checkpointing = false; var unloading = false; var e = new TestEngine( (_, ct, p) => { checkpointing = true; return(checkpointDone.Task); }, (_, ct, p) => Task.FromResult(true), (p) => { unloading = true; return(Task.FromResult(true)); } ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var c = s.CheckpointAsync(new TestWriter()); Assert.IsTrue(checkpointing); var u1 = s.UnloadAsync(); Assert.IsFalse(unloading); var u2 = s.UnloadAsync(); Assert.IsFalse(unloading); checkpointDone.SetResult(true); c.Wait(); Assert.IsTrue(unloading); u1.Wait(); u2.Wait(); }
public void CheckpointableStateManager_ErrorDuringCheckpointKeepsEngineRunning() { var fail = true; var e = new TestEngine( async(_, ct, p) => { if (Volatile.Read(ref fail)) { throw new ArithmeticException("Oops!"); } await Task.Yield(); }, (_, ct, p) => Task.FromResult(true), (p) => Task.FromResult(true) ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); Assert.AreEqual(QueryEngineStatus.Running, s.Status); Assert.ThrowsExceptionAsync <ArithmeticException>(() => s.CheckpointAsync(new TestWriter())).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); Assert.ThrowsExceptionAsync <ArithmeticException>(() => s.CheckpointAsync(new TestWriter())).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); Volatile.Write(ref fail, false); s.CheckpointAsync(new TestWriter()).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); }
public void CheckpointableStateManager_CheckpointCanBeCancelledImmediately() { var e = new TestEngine( (_, ct, p) => Task.FromResult(true), (_, ct, p) => Task.FromResult(true), (p) => Task.FromResult(true) ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var cts = new CancellationTokenSource(); cts.Cancel(); Assert.ThrowsExceptionAsync <OperationCanceledException>(() => s.CheckpointAsync(new TestWriter(), cts.Token)).Wait(); }
public void CheckpointableStateManager_StateWriterWrapper() { var engine = new WriterTestEngine(); var writer = new TestWriter(); var s = new CheckpointableStateManager(engine, new Uri("qe:/test"), traceSource: null); s.CheckpointAsync(writer).Wait(); Assert.IsTrue(writer.Log.SequenceEqual(new[] { "GetItemWriter(foo, bar)", "DeleteItem(qux, baz)", "Rollback()", "CommitAsync()", "Dispose()", })); }
public void CheckpointableStateManager_UnloadDuringCheckpointCausesWriterShutdown() { var checkpointDone = new TaskCompletionSource <bool>(); var unloadStarted = new TaskCompletionSource <bool>(); var checkpointing = false; var unloading = false; var e = new TestEngine( async(w, ct, p) => { checkpointing = true; await unloadStarted.Task; Assert.ThrowsException <EngineUnloadedException>(() => w.DeleteItem("foo", "bar")); Assert.ThrowsException <EngineUnloadedException>(() => w.GetItemWriter("foo", "bar")); Assert.ThrowsException <EngineUnloadedException>(() => w.Rollback()); await Assert.ThrowsExceptionAsync <EngineUnloadedException>(() => w.CommitAsync()); await checkpointDone.Task; }, (_, ct, p) => Task.FromResult(true), (p) => { unloading = true; return(Task.FromResult(true)); } ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var c = s.CheckpointAsync(new TestWriter()); Assert.IsTrue(checkpointing); var u = s.UnloadAsync(); Assert.IsFalse(unloading); unloadStarted.SetResult(true); checkpointDone.SetResult(true); c.Wait(); Assert.IsTrue(unloading); u.Wait(); }