/// <summary> /// Creates a new sandbox and performs the compiling process with a supporting test. /// </summary> /// <param name="request">The request that will contain the sandbox details.</param> /// <param name="compiler">The compiler being used for the process.</param> internal async Task HandleSingleCompileTestSandboxRequest(CompileTestSourceRequest request, Types.Compiler compiler) { var sandbox = new SingleTestSandbox(this._logger, this._dockerClient, request, compiler); this.AddSandbox(sandbox); sandbox.StatusChangeEvent += this.OnStatusChangeEvent; sandbox.CompletedEvent += this.OnSingleTestCompileSandboxCompletionEvent; await sandbox.Run(); }
/// <summary> /// Handles the case in which the sandbox has completed. /// </summary> private async Task HandleSandboxCompletion(SingleTestSandbox completedSandbox, CompileTestSourceResponse response) { Trace.Assert(completedSandbox != null, "completedSandbox must be defined to be handled."); // Get the response for the the executed single test case sandbox. Ensuring to state // that we don't want to clean up the path since this will be done when we are fully // complete. Since we dont know about the result as of yet and it could of failed and // thus want to cleanup. this._executedTestResults.Add(response); this._compilerService.RemoveSandbox(completedSandbox); this._logger.LogInformation( $"multiple test (single): {JsonConvert.SerializeObject(response.TestCaseResult)}"); // If we have another test to be executed, go get the next sandbox and start the process. // Ensuring that we are waiting between at least 100 milliseconds between each execution. // just to not buffer out the event stream. // // If ran in parallel, all containers have already been created, and thus this should not // create anymore. if (this.HashNext() && this.CanContinue() && !this._request.RunAllParallel) { var sandbox = this.Next(); this._compilerService.AddSandbox(sandbox); try { this._logger.LogWarning($"'{this._request.Id}: executing test " + $"case: {this._currentTestPosition + 1}"); await sandbox.Run(); } catch (Exception e) { this.HandleSandboxFailedStartExecution(e); } } else if ((!this._request.RunAllParallel) || (!this.HashNext() && this._executedTestResults.Count == this._request.TestCases.Count)) { // If we don't have any more sandboxes, then we must have completed all the tests and thus // can handle the completion of the entire process. Raising the event allows the parent // compiler service to get the response and publish the finalized results. this.RaiseCompletedChangeEvent(); } }
/// <summary> /// Get the next sandbox for the following test case. /// </summary> /// <returns></returns> private SingleTestSandbox Next() { // increment the test position for the given request. this._currentTestPosition += 1; var test = this._request.TestCases[this._currentTestPosition]; var sandbox = new SingleTestSandbox(this._logger, this._dockerClient, new CompileTestSourceRequest(this._request.Id, this._request.TimeoutSeconds, this._request.MemoryConstraint, this._request.SourceCode, this._compiler.Language, test), this._compiler); sandbox.StatusChangeEvent += this.HandleSandboxStatusEvent; sandbox.CompletedEvent += this.SandboxOnCompletedEvent; return(sandbox); }