public async Task CompilationsDisallowed() { var hitCompliation = false; var compilerServerHost = new TestableCompilerServerHost(delegate { hitCompliation = true; Assert.True(false, "Should not reach compilation when compilations are disallowed"); throw new Exception(""); }); var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); BuildResponse?response = null; var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(ProtocolUtil.EmptyCSharpBuildRequest), WriteBuildResponseFunc = (r, _) => { response = r; return(Task.CompletedTask); } }; var completionData = await clientConnectionHandler.ProcessAsync( Task.FromResult <IClientConnection>(clientConnection), allowCompilationRequests : false).ConfigureAwait(false); Assert.Equal(CompletionData.RequestCompleted, completionData); Assert.True(response is RejectedBuildResponse); Assert.False(hitCompliation); }
public void NotifyCallBackOnRequestHandlerException() { var clientConnection = new TestableClientConnection(); clientConnection.MonitorTask = Task.Delay(-1); clientConnection.ReadBuildRequestTask = Task.FromResult(s_emptyCSharpBuildRequest); var ex = new Exception(); var handler = new Mock <IRequestHandler>(); handler .Setup(x => x.HandleRequest(It.IsAny <BuildRequest>(), It.IsAny <CancellationToken>())) .Throws(ex); var invoked = false; FatalError.OverwriteHandler((providedEx) => { Assert.Same(ex, providedEx); invoked = true; }); var client = new ServerDispatcher.Connection(clientConnection, handler.Object); Assert.Throws(typeof(AggregateException), () => client.ServeConnection().Wait()); Assert.True(invoked); }
public async Task ShutdownRequest(bool allowCompilationRequests) { var hitCompilation = false; var compilerServerHost = new TestableCompilerServerHost(delegate { hitCompilation = true; throw new Exception(""); }); BuildResponse?response = null; var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(BuildRequest.CreateShutdown()), WriteBuildResponseFunc = (r, _) => { response = r; return(Task.CompletedTask); } }; var completionData = await clientConnectionHandler.ProcessAsync( Task.FromResult <IClientConnection>(clientConnection), allowCompilationRequests : allowCompilationRequests).ConfigureAwait(false); Assert.False(hitCompilation); Assert.Equal(new CompletionData(CompletionReason.RequestCompleted, shutdownRequested: true), completionData); Assert.True(response is ShutdownBuildResponse); }
public async Task ThrowWritingResponse() { var compilerServerHost = new TestableCompilerServerHost( delegate { return(ProtocolUtil.EmptyBuildResponse); } ); var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); var threwException = false; var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(ProtocolUtil.EmptyCSharpBuildRequest), WriteBuildResponseFunc = (response, cancellationToken) => { threwException = true; throw new Exception(""); } }; var completionData = await clientConnectionHandler.ProcessAsync( Task.FromResult <IClientConnection>(clientConnection) ); Assert.Equal(CompletionData.RequestError, completionData); Assert.True(threwException); }
public void MutexAcquiredWhenRunningServer() { var pipeName = Guid.NewGuid().ToString("N"); var mutexName = BuildServerConnection.GetServerMutexName(pipeName); var host = new TestableClientConnectionHost(); bool?wasServerMutexOpen = null; host.Add( () => { // Use a thread instead of Task to guarantee this code runs on a different // thread and we can validate the mutex state. var tcs = new TaskCompletionSource <IClientConnection>(); var thread = new Thread( _ => { wasServerMutexOpen = BuildServerConnection.WasServerMutexOpen( mutexName ); var client = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(ProtocolUtil.EmptyCSharpBuildRequest), WriteBuildResponseFunc = (r, _) => Task.CompletedTask, }; tcs.SetResult(client); } ); thread.Start(); return(tcs.Task); } ); host.Add( () => { var client = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(BuildRequest.CreateShutdown()), WriteBuildResponseFunc = (r, _) => Task.CompletedTask, }; return(Task.FromResult <IClientConnection>(client)); } ); var result = BuildServerController.CreateAndRunServer( pipeName, clientConnectionHost: host, keepAlive: TimeSpan.FromMilliseconds(-1) ); Assert.Equal(CommonCompiler.Succeeded, result); Assert.True(wasServerMutexOpen); }
public async Task ThrowDuringBuild() { var compilerServerHost = new TestableCompilerServerHost(delegate { throw new Exception(); }); var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(ProtocolUtil.EmptyCSharpBuildRequest), }; var completionData = await clientConnectionHandler.ProcessAsync(Task.FromResult <IClientConnection>(clientConnection)).ConfigureAwait(false); Assert.Equal(CompletionData.RequestError, completionData); }
public void ReadError() { var handler = new Mock <IRequestHandler>(MockBehavior.Strict); var ex = new Exception("Simulated read error."); var clientConnection = new TestableClientConnection(); var calledClose = false; clientConnection.ReadBuildRequestTask = TaskFromException <BuildRequest>(ex); clientConnection.CloseAction = delegate { calledClose = true; }; var client = new ServerDispatcher.Connection(clientConnection, handler.Object); Assert.Equal(ServerDispatcher.CompletionReason.CompilationNotStarted, client.ServeConnection().Result); Assert.True(calledClose); }
public void WriteError() { var clientConnection = new TestableClientConnection(); clientConnection.MonitorTask = Task.Delay(-1); clientConnection.ReadBuildRequestTask = Task.FromResult(s_emptyCSharpBuildRequest); clientConnection.WriteBuildResponseTask = TaskFromException(new Exception()); var handler = new Mock <IRequestHandler>(); handler .Setup(x => x.HandleRequest(It.IsAny <BuildRequest>(), It.IsAny <CancellationToken>())) .Returns(s_emptyBuildResponse); var client = new ServerDispatcher.Connection(clientConnection, handler.Object); Assert.Equal(ServerDispatcher.CompletionReason.ClientDisconnect, client.ServeConnection().Result); }
public async Task ClientDisconnectDuringBuild() { using var buildStartedMre = new ManualResetEvent(initialState: false); using var clientClosedMre = new ManualResetEvent(initialState: false); var compilerServerHost = new TestableCompilerServerHost( (request, cancellationToken) => { buildStartedMre.Set(); clientClosedMre.WaitOne(); Assert.True(cancellationToken.IsCancellationRequested); return(ProtocolUtil.EmptyBuildResponse); } ); var disconnectTaskCompletionSource = new TaskCompletionSource <object?>(); var isDisposed = false; var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => Task.FromResult(ProtocolUtil.EmptyBasicBuildRequest), DisconnectTask = disconnectTaskCompletionSource.Task, DisposeFunc = () => { isDisposed = true; }, }; var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); var task = clientConnectionHandler.ProcessAsync( Task.FromResult <IClientConnection>(clientConnection) ); // Don't trigger the disconnect until we confirm that the client has issued a // build request. buildStartedMre.WaitOne(); disconnectTaskCompletionSource.TrySetResult(null); var completionData = await task; Assert.Equal(CompletionData.RequestError, completionData); Assert.True(isDisposed); clientClosedMre.Set(); }
public void ClientDisconnectCancelBuildAndReturnsFailure() { var clientConnection = new TestableClientConnection(); clientConnection.ReadBuildRequestTask = Task.FromResult(s_emptyCSharpBuildRequest); var monitorTaskSource = new TaskCompletionSource <bool>(); clientConnection.MonitorTask = monitorTaskSource.Task; var handler = new Mock <IRequestHandler>(); var handlerTaskSource = new TaskCompletionSource <CancellationToken>(); var releaseHandlerSource = new TaskCompletionSource <bool>(); handler .Setup(x => x.HandleRequest(It.IsAny <BuildRequest>(), It.IsAny <CancellationToken>())) .Callback <BuildRequest, CancellationToken>((_, t) => { handlerTaskSource.SetResult(t); releaseHandlerSource.Task.Wait(); }) .Returns(s_emptyBuildResponse); var client = new ServerDispatcher.Connection(clientConnection, handler.Object); var serveTask = client.ServeConnection(new TaskCompletionSource <TimeSpan?>()); // Once this returns we know the Connection object has kicked off a compilation and // started monitoring the disconnect task. Can now initiate a disconnect in a known // state. var cancellationToken = handlerTaskSource.Task.Result; monitorTaskSource.SetResult(true); Assert.Equal(ServerDispatcher.CompletionReason.ClientDisconnect, serveTask.Result); Assert.True(cancellationToken.IsCancellationRequested); // Now that the asserts are done unblock the "build" long running task. Have to do this // last to simulate a build which is still running when the client disconnects. releaseHandlerSource.SetResult(true); }