/// <summary> /// Compiles some source code and returns the bytes that were contained in the compiled DLL file. /// /// Each time that this function is called, it will be compiled in a different directory. /// /// The default flags are "/shared /deterministic+ /nologo /t:library". /// </summary> /// <param name="source"> The source code for the program that will be compiled </param> /// <returns> An array of bytes that were read from the compiled DLL</returns> private async Task <(byte[] assemblyBytes, string finalFlags)> CompileAndGetBytes(string source) { // Setup var tempDir = Temp.CreateDirectory(); var srcFile = tempDir.CreateFile("test.cs").WriteAllText(source).Path; var outFile = srcFile.Replace("test.cs", "test.dll"); try { string finalFlags = null; using (var serverData = ServerUtil.CreateServer()) { finalFlags = $"{ _flags } /shared:{ serverData.PipeName } /pathmap:{tempDir.Path}=/ /out:{ outFile } { srcFile }"; var result = CompilerServerUnitTests.RunCommandLineCompiler( CompilerServerUnitTests.CSharpCompilerClientExecutable, finalFlags, currentDirectory: tempDir); if (result.ExitCode != 0) { AssertEx.Fail($"Deterministic compile failed \n stdout: { result.Output }"); } await serverData.Verify(connections : 1, completed : 1).ConfigureAwait(true); } var bytes = File.ReadAllBytes(outFile); AssertEx.NotNull(bytes); return(bytes, finalFlags); } finally { File.Delete(srcFile); File.Delete(outFile); } }
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 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 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 });
private ServerData CreateServer(string pipeName) { var serverData = ServerUtil.CreateServer(_logger, pipeName).GetAwaiter().GetResult(); _serverDataList.Add(serverData); return(serverData); }
public async Task UseExistingServer() { using var serverData = await ServerUtil.CreateServer(Logger); var ran = false; var workingDirectory = TempRoot.CreateDirectory().Path; for (var i = 0; i < 5; i++) { var response = await BuildServerConnection.RunServerBuildRequestAsync( ProtocolUtil.CreateEmptyCSharp(workingDirectory), serverData.PipeName, timeoutOverride : Timeout.Infinite, tryCreateServerFunc : (_, _) => { ran = true; return(false); }, Logger, cancellationToken : default); Assert.True(response is CompletedBuildResponse); } Assert.False(ran); }
private ServerData CreateServer(string pipeName, ICompilerServerHost compilerServerHost = null) { var serverData = ServerUtil.CreateServer(pipeName, compilerServerHost).GetAwaiter().GetResult(); _serverDataList.Add(serverData); return(serverData); }
public async Task IncorrectServerHashReturnsIncorrectHashResponse() { using var serverData = await ServerUtil.CreateServer(Logger); var buildResponse = await serverData.SendAsync(new BuildRequest(BuildProtocolConstants.ProtocolVersion, RequestLanguage.CSharpCompile, "abc", new List <BuildRequest.Argument> { })); Assert.Equal(BuildResponse.ResponseType.IncorrectHash, buildResponse.Type); }
public async Task IncorrectProtocolReturnsMismatchedVersionResponse() { using var serverData = await ServerUtil.CreateServer(Logger); var buildResponse = await serverData.SendAsync(new BuildRequest(1, RequestLanguage.CSharpCompile, "abc", new List <BuildRequest.Argument> { })); Assert.Equal(BuildResponse.ResponseType.MismatchedVersion, buildResponse.Type); }
public async Task RejectEmptyTempPath() { using var temp = new TempRoot(); using var serverData = await ServerUtil.CreateServer(); var request = BuildRequest.Create(RequestLanguage.CSharpCompile, workingDirectory: temp.CreateDirectory().Path, tempDirectory: null, BuildProtocolConstants.GetCommitHash(), libDirectory: null, args: Array.Empty <string>()); var response = await ServerUtil.Send(serverData.PipeName, request); Assert.Equal(ResponseType.Rejected, response.Type); }
public async Task ShutdownRequestDirect() { using (var serverData = await ServerUtil.CreateServer()) { var serverProcessId = await ServerUtil.SendShutdown(serverData.PipeName); Assert.Equal(Process.GetCurrentProcess().Id, serverProcessId); await serverData.Verify(connections : 1, completed : 1); } }
public async Task Standard() { using (var serverData = ServerUtil.CreateServer()) { // Make sure the server is listening for this particular test. await serverData.ListenTask; var exitCode = await RunShutdownAsync(serverData.PipeName, waitForProcess : false).ConfigureAwait(false); Assert.Equal(CommonCompiler.Succeeded, exitCode); await serverData.Verify(connections : 1, completed : 1); } }
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); } } }
private bool TryCreateServer(string pipeName) { if (!_allowServer) { _failedCreatedServerCount++; return(false); } var serverData = ServerUtil.CreateServer(pipeName); _serverDataList.Add(serverData); return(true); }
public async Task RunServerWithLongTempPath() { string pipeName = BuildServerConnection.GetPipeNameForPathOpt(Guid.NewGuid().ToString()); string tempPath = new string('a', 100); using (var serverData = await ServerUtil.CreateServer(pipeName, tempPath: tempPath)) { // Make sure the server is listening for this particular test. await serverData.ListenTask; var exitCode = await RunShutdownAsync(serverData.PipeName, waitForProcess : false).ConfigureAwait(false); Assert.Equal(CommonCompiler.Succeeded, exitCode); await serverData.Verify(connections : 1, completed : 1); } }
public async Task Standard() { using var serverData = await ServerUtil.CreateServer(Logger); var exitCode = await RunShutdownAsync(serverData.PipeName, waitForProcess : false); Assert.Equal(CommonCompiler.Succeeded, exitCode); // Await the server task here to verify it actually shuts down vs. us shutting down the server. var listener = await serverData.ServerTask; Assert.Equal( new CompletionData(CompletionReason.RequestCompleted, shutdownRequested: true), listener.CompletionDataList.Single()); }