private static async Task <bool> CreateAndRunPip( PipProgram program, string tempDirectory, string outFile, IEnumerable <string> restInstructions, bool is64Bit) { Contract.Requires(restInstructions != null); Contract.Requires(tempDirectory != null); Contract.Requires(!string.IsNullOrEmpty(outFile)); BuildXLContext context = BuildXLContext.CreateInstanceForTesting(); using (var fileAccessListener = new FileAccessListener(Events.Log)) { fileAccessListener.RegisterEventSource(BuildXL.Processes.ETWLogger.Log); var fileContentTable = FileContentTable.CreateNew(); var config = ConfigurationHelpers.GetDefaultForTesting(context.PathTable, AbsolutePath.Create(context.PathTable, Path.Combine(tempDirectory, "config.dc"))); config.Sandbox.LogObservedFileAccesses = true; Pip pip = null; var instructions = restInstructions as string[] ?? restInstructions.ToArray(); switch (program) { case PipProgram.Cmd: pip = CreateCmdPip(context, tempDirectory, outFile, is64Bit); break; case PipProgram.Self: pip = CreateSelfPip(context, tempDirectory, outFile, instructions, is64Bit); break; } Contract.Assume(pip != null); PipResult executeResult = await Execute(context, fileContentTable, config, pip); bool valid = false; switch (program) { case PipProgram.Cmd: valid = ValidateCmd(fileAccessListener.FileAccesses, outFile, is64Bit); break; case PipProgram.Self: valid = ValidateSelf( fileAccessListener.FileAccesses, instructions.Length > 0 ? instructions[0] : string.Empty, outFile, is64Bit); break; } return(executeResult.Status == PipResultStatus.Succeeded && valid); } }
public override async Task OnPipCompleted(RunnablePip runnablePip) { var pipId = runnablePip.Pip.PipId; PipResultStatus overrideStatus; if (m_overridePipResults.TryGetValue(pipId, out overrideStatus)) { if (overrideStatus.IndicatesFailure()) { m_loggingContext.SpecifyErrorWasLogged(0); } runnablePip.SetPipResult( overrideStatus.IndicatesExecution() ? PipResult.CreateWithPointPerformanceInfo(overrideStatus) : PipResult.CreateForNonExecution(overrideStatus)); if (overrideStatus.IndicatesFailure()) { m_loggingContext.SpecifyErrorWasLogged(0); } } // Set the 'actual' result. NOTE: override also overrides actual result. // We set this before calling the wrapped PipCompleted handler since we may // be completing the last pip (don't want to race with a test checking pip // result after schedule completion and us setting it. PipResults[pipId] = runnablePip.Result.Value.Status; if (runnablePip.Result.HasValue && runnablePip.PipType == PipType.Process) { PathSets[pipId] = runnablePip.ExecutionResult?.PathSet; RunData.CacheLookupResults[pipId] = ((ProcessRunnablePip)runnablePip).CacheResult; RunData.ExecutionCachingInfos[pipId] = runnablePip.ExecutionResult?.TwoPhaseCachingInfo; } await base.OnPipCompleted(runnablePip); m_testPipQueue.OnPipCompleted(runnablePip.PipId); }
/// <summary> /// Creates a pip result for the given status /// </summary> public PipResult CreatePipResult(PipResultStatus status) { return(PipResult.Create(status, StartTime)); }
private async Task <PipResult> StartServiceOrShutdownServiceAsync( IPipExecutionEnvironment environment, PipId pipId, TaskSourceSlim <bool> serviceLaunchCompletion, bool isStartup) { // Ensure task does not block current thread await Task.Yield(); var loggingContext = m_executePhaseLoggingContext; try { var serviceProcess = HydrateServiceStartOrShutdownProcess(pipId); if (isStartup) { Logger.Log.ScheduleServicePipStarting( loggingContext, serviceProcess.GetDescription(m_context)); Interlocked.Increment(ref m_runningServicesCount); } using (var operationContext = m_operationTracker.StartOperation( isStartup ? PipExecutorCounter.ExecuteServiceDuration : PipExecutorCounter.ExecuteServiceShutdownDuration, pipId, PipType.Process, loggingContext)) { var serviceStartTask = PipExecutor.ExecuteServiceStartOrShutdownAsync( #pragma warning disable AsyncFixer04 // A disposable object used in a fire & forget async call // Bug #1155822: There is a race condition where service start/shutdown can // cause crash in the operation tracker because the parent operation is already completed // this is not fully understood, but the tracking of details of services operations is not // important so this disables it OperationContext.CreateUntracked(loggingContext), #pragma warning restore AsyncFixer04 // A disposable object used in a fire & forget async call environment, serviceProcess, processId => { serviceLaunchCompletion.TrySetResult(isStartup); }); using ( operationContext.StartAsyncOperation( isStartup ? PipExecutorCounter.ExecuteServiceStartupLaunchDuration : PipExecutorCounter.ExecuteServiceShutdownLaunchDuration)) { Analysis.IgnoreResult( await Task.WhenAny(serviceLaunchCompletion.Task, serviceStartTask), justification: "Task<Task> doesn't contain any data." ); } var result = await serviceStartTask; return(PipResult.CreateWithPointPerformanceInfo(result.Result)); } } finally { // Attempt to set the result to false to indicate service startup failure. // This will not succeed if the service is already started // and the result is set to true. if (serviceLaunchCompletion.TrySetResult(false)) { var serviceProcess = HydrateServiceStartOrShutdownProcess(pipId); Logger.Log.ScheduleServiceTerminatedBeforeStartupWasSignaled( loggingContext, serviceProcess.GetDescription(m_context)); } } }