public void CheckpointableStateManager_RecoverCanBeCancelled() { var busy = new TaskCompletionSource <bool>(); var done = new TaskCompletionSource <bool>(); var cancelled = false; var e = new TestEngine( (_, ct, p) => Task.FromResult(true), async(_, ct, p) => { ct.Register(() => cancelled = true); busy.SetResult(true); await done.Task; }, (p) => Task.FromResult(true) ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var cts = new CancellationTokenSource(); var t = s.RecoverAsync(new TestReader(), cts.Token); busy.Task.Wait(); cts.Cancel(); done.SetResult(true); t.Wait(); Assert.IsTrue(cancelled); }
public void CheckpointableStateManager_UnloadDuringRecoverQueuesUp() { var recoveryDone = new TaskCompletionSource <bool>(); var recovering = false; var unloading = false; var e = new TestEngine( (_, ct, p) => Task.FromResult(true), (_, ct, p) => { recovering = true; return(recoveryDone.Task); }, (p) => { unloading = true; return(Task.FromResult(true)); } ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var c = s.RecoverAsync(new TestReader()); Assert.IsTrue(recovering); var u1 = s.UnloadAsync(); Assert.IsFalse(unloading); var u2 = s.UnloadAsync(); Assert.IsFalse(unloading); recoveryDone.SetResult(true); c.Wait(); Assert.IsTrue(unloading); u1.Wait(); u2.Wait(); }
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_RecoverCanBeCancelledImmediately() { 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.RecoverAsync(new TestReader(), 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(); }
public void CheckpointableStateManager_UnloadDuringRecoverCausesReaderShutdown() { var recoveryDone = new TaskCompletionSource <bool>(); var unloadStarted = new TaskCompletionSource <bool>(); var recovering = false; var unloading = false; var e = new TestEngine( (_, ct, p) => Task.FromResult(true), async(r, ct, p) => { recovering = true; await unloadStarted.Task; Assert.ThrowsException <EngineUnloadedException>(() => { r.GetCategories(); }); Assert.ThrowsException <EngineUnloadedException>(() => { r.TryGetItemKeys("bar", out _); }); Assert.ThrowsException <EngineUnloadedException>(() => { r.TryGetItemReader("bar", "foo", out _); }); await recoveryDone.Task; }, (p) => { unloading = true; return(Task.FromResult(true)); } ); var s = new CheckpointableStateManager(e, new Uri("qe:/test"), traceSource: null); var c = s.RecoverAsync(new TestReader()); Assert.IsTrue(recovering); var u = s.UnloadAsync(); Assert.IsFalse(unloading); unloadStarted.SetResult(true); recoveryDone.SetResult(true); c.Wait(); Assert.IsTrue(unloading); u.Wait(); }
public void CheckpointableStateManager_ErrorDuringRecoverKeepsEngineRunning() { var fail = true; var e = new TestEngine( (_, ct, p) => Task.FromResult(true), async(_, ct, p) => { if (Volatile.Read(ref fail)) { throw new ArithmeticException("Oops!"); } await Task.Yield(); }, (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.RecoverAsync(new TestReader())).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); Assert.ThrowsExceptionAsync <ArithmeticException>(() => s.RecoverAsync(new TestReader())).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); Volatile.Write(ref fail, false); s.RecoverAsync(new TestReader()).Wait(); Assert.AreEqual(QueryEngineStatus.Running, s.Status); }
public void CheckpointableStateManager_UnloadDuringCheckpointCausesCancellation() { var checkpointDone = new TaskCompletionSource <bool>(); var checkpointing = false; var unloading = false; var cancelled = false; var e = new TestEngine( (_, ct, p) => { checkpointing = true; ct.Register(() => cancelled = 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); Assert.IsTrue(cancelled); var u2 = s.UnloadAsync(); Assert.IsFalse(unloading); checkpointDone.SetResult(true); c.Wait(); Assert.IsTrue(unloading); u1.Wait(); u2.Wait(); }