public void ReadWriteRequest()
 {
     Task.Run(async () =>
     {
         var request = new BuildRequest(
             BuildProtocolConstants.ProtocolVersion,
             BuildProtocolConstants.RequestLanguage.VisualBasicCompile,
             ImmutableArray.Create(
                 new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"),
                 new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file")));
         var memoryStream = new MemoryStream();
         await request.WriteAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false);
         Assert.True(memoryStream.Position > 0);
         memoryStream.Position = 0;
         var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false);
         Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion);
         Assert.Equal(BuildProtocolConstants.RequestLanguage.VisualBasicCompile, read.Language);
         Assert.Equal(2, read.Arguments.Length);
         Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId);
         Assert.Equal(0, read.Arguments[0].ArgumentIndex);
         Assert.Equal("directory", read.Arguments[0].Value);
         Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId);
         Assert.Equal(1, read.Arguments[1].ArgumentIndex);
         Assert.Equal("file", read.Arguments[1].Value);
     }).Wait();
 }
Beispiel #2
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);
        }
Beispiel #3
0
        public async Task ReadWriteRequest()
        {
            var request = new BuildRequest(
                BuildProtocolConstants.ProtocolVersion,
                RequestLanguage.VisualBasicCompile,
                "HashValue",
                ImmutableArray.Create(
                    new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"),
                    new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file")));
            var memoryStream = new MemoryStream();
            await request.WriteAsync(memoryStream, default(CancellationToken));

            Assert.True(memoryStream.Position > 0);
            memoryStream.Position = 0;
            var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken));

            Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion);
            Assert.Equal(RequestLanguage.VisualBasicCompile, read.Language);
            Assert.Equal("HashValue", read.CompilerHash);
            Assert.Equal(2, read.Arguments.Count);
            Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId);
            Assert.Equal(0, read.Arguments[0].ArgumentIndex);
            Assert.Equal("directory", read.Arguments[0].Value);
            Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId);
            Assert.Equal(1, read.Arguments[1].ArgumentIndex);
            Assert.Equal("file", read.Arguments[1].Value);
        }
Beispiel #4
0
 public void ReadWriteRequest()
 {
     Task.Run(async() =>
     {
         var request = new BuildRequest(
             BuildProtocolConstants.ProtocolVersion,
             BuildProtocolConstants.RequestLanguage.VisualBasicCompile,
             ImmutableArray.Create(
                 new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"),
                 new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file")));
         var memoryStream = new MemoryStream();
         await request.WriteAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false);
         Assert.True(memoryStream.Position > 0);
         memoryStream.Position = 0;
         var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false);
         Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion);
         Assert.Equal(BuildProtocolConstants.RequestLanguage.VisualBasicCompile, read.Language);
         Assert.Equal(2, read.Arguments.Length);
         Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId);
         Assert.Equal(0u, read.Arguments[0].ArgumentIndex);
         Assert.Equal("directory", read.Arguments[0].Value);
         Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId);
         Assert.Equal(1u, read.Arguments[1].ArgumentIndex);
         Assert.Equal("file", read.Arguments[1].Value);
     }).Wait();
 }
Beispiel #5
0
        internal async Task <BuildResponse> SendAsync(BuildRequest request, CancellationToken cancellationToken = default)
        {
            using var client = await BuildServerConnection.TryConnectToServerAsync(PipeName, Timeout.Infinite, cancellationToken).ConfigureAwait(false);

            await request.WriteAsync(client).ConfigureAwait(false);

            return(await BuildResponse.ReadAsync(client).ConfigureAwait(false));
        }
Beispiel #6
0
        internal static async Task <BuildResponse> Send(string pipeName, BuildRequest request)
        {
            using (var client = await BuildServerConnection.TryConnectToServerAsync(pipeName, Timeout.Infinite, cancellationToken: default).ConfigureAwait(false))
            {
                await request.WriteAsync(client).ConfigureAwait(false);

                return(await BuildResponse.ReadAsync(client).ConfigureAwait(false));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Try to compile using the server. Returns null if a response from the
        /// server cannot be retrieved.
        /// </summary>
        private static async Task <BuildResponse> TryCompile(NamedPipeClientStream pipeStream,
                                                             BuildRequest request,
                                                             CancellationToken cancellationToken)
        {
            BuildResponse response;

            using (pipeStream)
            {
                // Write the request
                try
                {
                    Log("Begin writing request");
                    await request.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false);

                    Log("End writing request");
                }
                catch (Exception e)
                {
                    LogException(e, "Error writing build request.");
                    return(null);
                }

                // Wait for the compilation and a monitor to dectect if the server disconnects
                var serverCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                Log("Begin reading response");

                var responseTask = BuildResponse.ReadAsync(pipeStream, serverCts.Token);
                var monitorTask  = CreateMonitorDisconnectTask(pipeStream, serverCts.Token);
                await Task.WhenAny(responseTask, monitorTask).ConfigureAwait(false);

                Log("End reading response");

                if (responseTask.IsCompleted)
                {
                    // await the task to log any exceptions
                    try
                    {
                        response = await responseTask.ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        LogException(e, "Error reading response");
                        response = null;
                    }
                }
                else
                {
                    Log("Server disconnect");
                    response = null;
                }

                // Cancel whatever task is still around
                serverCts.Cancel();
                return(response);
            }
        }
Beispiel #8
0
        internal static async Task <BuildResponse> Send(string pipeName, BuildRequest request)
        {
            using (var client = new NamedPipeClientStream(pipeName))
            {
                await client.ConnectAsync();

                await request.WriteAsync(client);

                return(await BuildResponse.ReadAsync(client));
            }
        }
Beispiel #9
0
        public async Task WriteError()
        {
            var realStream = new MemoryStream();
            await s_emptyCSharpBuildRequest.WriteAsync(realStream, CancellationToken.None).ConfigureAwait(true);

            realStream.Position = 0;

            var stream = new Mock <Stream>(MockBehavior.Strict);

            stream
            .Setup(x => x.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
            .Returns((byte[] array, int start, int length, CancellationToken ct) => Task.FromResult(realStream.Read(array, start, length)));

            var connection = CreateConnection(stream.Object);

            connection.ServeBuildRequestFunc = delegate { return(Task.FromResult(s_emptyBuildResponse)); };
            var connectionData = await connection.HandleConnection().ConfigureAwait(true);

            Assert.Equal(CompletionReason.ClientDisconnect, connectionData.CompletionReason);
            Assert.Null(connectionData.KeepAlive);
        }
Beispiel #10
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();
            }
        }
Beispiel #11
0
        private async Task <BuildResponse> DoCompilationAsync(NamedPipeClientStream pipeStream,
                                                              BuildRequest req,
                                                              CancellationToken cancellationToken)
        {
            using (pipeStream)
            {
                try
                {
                    // Start a monitor that cancels if the pipe closes on us
                    var  monitorCancellation = new CancellationTokenSource();
                    Task disconnectMonitor   = MonitorPipeForDisconnectionAsync(pipeStream, monitorCancellation.Token);

                    // Write the request.
                    CompilerServerLogger.Log("Writing request");
                    await req.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false);

                    // Read the response.
                    CompilerServerLogger.Log("Reading response");
                    BuildResponse response = await BuildResponse.ReadAsync(pipeStream, cancellationToken).ConfigureAwait(false);

                    // Stop monitoring pipe
                    monitorCancellation.Cancel(throwOnFirstException: true);
                    await disconnectMonitor.ConfigureAwait(false);

                    Debug.Assert(response != null);
                    CompilerServerLogger.Log("BuildResponse received; exit code={0}", response.ReturnCode);

                    return(response);
                }
                catch (PipeBrokenException e)
                {
                    CompilerServerLogger.LogException(e, "Server process died; pipe broken.");
                    return(null);
                }
                catch (ObjectDisposedException e)
                {
                    CompilerServerLogger.LogException(e, "Pipe stream unexpectedly disposed");
                    return(null);
                }
            }
        }