public async Task ShutdownDoesNotAbortCompilation() { var host = new TestableCompilerServerHost(); using (var startedMre = new ManualResetEvent(initialState: false)) using (var finishedMre = new ManualResetEvent(initialState: false)) using (var serverData = await ServerUtil.CreateServer(compilerServerHost: host)) { // Create a compilation that is guaranteed to complete after the shutdown is seen. host.RunCompilation = (request, cancellationToken) => { startedMre.Set(); finishedMre.WaitOne(); return(s_emptyBuildResponse); }; var compileTask = ServerUtil.Send(serverData.PipeName, s_emptyCSharpBuildRequest); startedMre.WaitOne(); // The compilation is now in progress, send the shutdown. await ServerUtil.SendShutdown(serverData.PipeName); Assert.False(compileTask.IsCompleted); finishedMre.Set(); var response = await compileTask; Assert.Equal(BuildResponse.ResponseType.Completed, response.Type); Assert.Equal(0, ((CompletedBuildResponse)response).ReturnCode); await serverData.Verify(connections : 2, completed : 2); } }
public async Task ShutdownDoesNotAbortCompilation() { using var startedMre = new ManualResetEvent(initialState: false); using var finishedMre = new ManualResetEvent(initialState: false); // Create a compilation that is guaranteed to complete after the shutdown is seen. var compilerServerHost = new TestableCompilerServerHost((request, cancellationToken) => { startedMre.Set(); finishedMre.WaitOne(); return(ProtocolUtil.EmptyBuildResponse); }); using var serverData = await ServerUtil.CreateServer(Logger, compilerServerHost : compilerServerHost); // Get the server to the point that it is running the compilation. var compileTask = serverData.SendAsync(ProtocolUtil.EmptyCSharpBuildRequest); startedMre.WaitOne(); // The compilation is now in progress, send the shutdown and verify that the // compilation is still running. await serverData.SendShutdownAsync(); Assert.False(compileTask.IsCompleted); // Now complete the compilation and verify that it actually ran to completion despite // there being a shutdown request. finishedMre.Set(); var response = await compileTask; Assert.True(response is CompletedBuildResponse { ReturnCode: 0 });
public async Task ClientDisconnectDuringBuild() { using var buildStartedMre = new ManualResetEvent(initialState: false); using var clientClosedMre = new ManualResetEvent(initialState: false); var host = new TestableCompilerServerHost(runCompilation: (request, cancellationToken) => { buildStartedMre.Set(); clientClosedMre.WaitOne(); return(new CompletedBuildResponse(0, utf8output: false, "")); }); using var serverData = await ServerUtil.CreateServer(compilerServerHost : host).ConfigureAwait(false); // Create a short lived client that send a request but does not wait for the using (var client = await BuildServerConnection.TryConnectToServerAsync(serverData.PipeName, Timeout.Infinite, cancellationToken: default).ConfigureAwait(false)) { await s_emptyCSharpBuildRequest.WriteAsync(client).ConfigureAwait(false); await buildStartedMre.WaitOneAsync().ConfigureAwait(false); } clientClosedMre.Set(); var reason = await serverData.ConnectionCompletionCollection.TakeAsync().ConfigureAwait(false); Assert.Equal(CompletionReason.ClientDisconnect, reason); }
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 async Task NoCompilationsProcessShutdown() { var host = new TestableCompilerServerHost(runCompilation: delegate { // We should never get here. Assert.False(true); throw null; }); var(clientStream, serverStream) = await CreateNamedPipePair().ConfigureAwait(false); try { var connection = new NamedPipeClientConnection(host, "identifier", serverStream); await BuildRequest.CreateShutdown().WriteAsync(clientStream).ConfigureAwait(false); var connectionData = await connection.HandleConnection(allowCompilationRequests : false).ConfigureAwait(false); Assert.Equal(CompletionReason.ClientShutdownRequest, connectionData.CompletionReason); Assert.Null(connectionData.KeepAlive); var response = await BuildResponse.ReadAsync(clientStream); Assert.Equal(BuildResponse.ResponseType.Shutdown, response.Type); } finally { clientStream.Close(); serverStream.Close(); } }
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 RejectEmptyTempPath() { using (var temp = new TempRoot()) { var host = new TestableCompilerServerHost(); var request = new RunRequest(LanguageNames.CSharp, currentDirectory: temp.CreateDirectory().Path, tempDirectory: null, libDirectory: null, arguments: Array.Empty <string>()); var response = host.RunCompilation(request, CancellationToken.None); Assert.Equal(ResponseType.Rejected, response.Type); } }
public void RejectEmptyTempPath() { using (var temp = new TempRoot()) { var host = new TestableCompilerServerHost(); var request = new RunRequest(LanguageNames.CSharp, currentDirectory: temp.CreateDirectory().Path, tempDirectory: null, libDirectory: null, arguments: Array.Empty<string>()); var response = host.RunCompilation(request, CancellationToken.None); Assert.Equal(ResponseType.Rejected, response.Type); } }
public async Task CancelWillCancelCompilation() { var host = new TestableCompilerServerHost(); using (var serverData = await ServerUtil.CreateServer(compilerServerHost: host)) using (var mre = new ManualResetEvent(initialState: false)) { const int requestCount = 5; var count = 0; host.RunCompilation = (request, cancellationToken) => { if (Interlocked.Increment(ref count) == requestCount) { mre.Set(); } cancellationToken.WaitHandle.WaitOne(); return(new RejectedBuildResponse()); }; var list = new List <Task <BuildResponse> >(); for (var i = 0; i < requestCount; i++) { var task = ServerUtil.Send(serverData.PipeName, s_emptyCSharpBuildRequest); list.Add(task); } // Wait until all of the connections are being processed by the server then cancel. mre.WaitOne(); serverData.CancellationTokenSource.Cancel(); var stats = await serverData.Complete(); Assert.Equal(requestCount, stats.Connections); Assert.Equal(requestCount, count); foreach (var task in list) { var threw = false; try { await task; } catch { threw = true; } Assert.True(threw); } } }
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 async Task ThrowReadingRequest() { var compilerServerHost = new TestableCompilerServerHost(delegate { Assert.True(false, "Should not reach compilation"); throw new Exception(""); }); var clientConnectionHandler = new ClientConnectionHandler(compilerServerHost); var clientConnection = new TestableClientConnection() { ReadBuildRequestFunc = _ => throw new Exception(), }; var completionData = await clientConnectionHandler.ProcessAsync(Task.FromResult <IClientConnection>(clientConnection)).ConfigureAwait(false); Assert.Equal(CompletionData.RequestError, completionData); }
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 async Task WriteError() { using var compileMre = new ManualResetEvent(initialState: false); using var closedStreamMre = new ManualResetEvent(initialState: false); var host = new TestableCompilerServerHost(runCompilation: delegate { compileMre.Set(); closedStreamMre.WaitOne(); return(s_emptyBuildResponse); }); var(clientStream, serverStream) = await CreateNamedPipePair().ConfigureAwait(false); try { var connection = new NamedPipeClientConnection(host, "identifier", serverStream); await s_emptyCSharpBuildRequest.WriteAsync(clientStream).ConfigureAwait(false); var connectionTask = connection.HandleConnection(); await compileMre.WaitOneAsync().ConfigureAwait(false); clientStream.Close(); closedStreamMre.Set(); var connectionData = await connectionTask.ConfigureAwait(false); Assert.Equal(CompletionReason.ClientDisconnect, connectionData.CompletionReason); Assert.Null(connectionData.KeepAlive); } finally { clientStream.Close(); serverStream.Close(); } }
public async Task ReadFailure() { var host = new TestableCompilerServerHost(runCompilation: delegate { return(s_emptyBuildResponse); }); var(clientStream, serverStream) = await CreateNamedPipePair().ConfigureAwait(false); try { var connection = new NamedPipeClientConnection(host, "identifier", serverStream); clientStream.Close(); var connectionData = await connection.HandleConnection().ConfigureAwait(false); Assert.Equal(CompletionReason.CompilationNotStarted, connectionData.CompletionReason); Assert.Null(connectionData.KeepAlive); } finally { clientStream.Close(); serverStream.Close(); } }