예제 #1
0
        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);
                    }
        }
예제 #2
0
            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
                });
예제 #3
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);
        }
예제 #5
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 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);
     }
 }
예제 #9
0
 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);
     }
 }
예제 #10
0
        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);
        }
예제 #13
0
        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();
        }
예제 #14
0
        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();
            }
        }
예제 #15
0
        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();
            }
        }