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);
        }
Пример #2
0
        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);
        }
Пример #4
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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
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();
        }
Пример #10
0
        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);
        }