public void SharedCompilationIsTurnedOnWhenAvailable() { var project = CreateProjectWithPredictions("A.proj"); // We need to explicitly turn on shared compilation because for tests it is off by default var testProj = Start(new MsBuildResolverSettings { UseLegacyProjectIsolation = true, UseManagedSharedCompilation = true }) .Add(project) .ScheduleAll() .AssertSuccess(). RetrieveSuccessfulProcess(project); var arguments = RetrieveProcessArguments(testProj); // When supported, we should: // - not turn off shared compilation, // - let VBCSCompiler escape the sandbox // - attach the VBCSCompiler logger to compensate for missing accesses if (ProcessUtilities.SandboxSupportsProcessBreakaway()) { Assert.DoesNotContain("/p:UseSharedCompilation=false", arguments); Assert.Equal(PathAtom.Create(StringTable, "VBCSCompiler.exe"), testProj.ChildProcessesToBreakawayFromSandbox.Single()); Assert.Contains(PipConstructor.VBCSCompilerLogger, arguments); } else { Assert.Contains("/p:UseSharedCompilation=false", arguments); Assert.Empty(testProj.ChildProcessesToBreakawayFromSandbox); } }
/// <summary> /// Class constructor /// </summary> public Process( FileArtifact executable, AbsolutePath workingDirectory, PipData arguments, FileArtifact responseFile, PipData responseFileData, ReadOnlyArray <EnvironmentVariable> environmentVariables, StandardInput standardInput, FileArtifact standardOutput, FileArtifact standardError, AbsolutePath standardDirectory, TimeSpan?warningTimeout, TimeSpan?timeout, ReadOnlyArray <FileArtifact> dependencies, ReadOnlyArray <FileArtifactWithAttributes> outputs, ReadOnlyArray <DirectoryArtifact> directoryDependencies, ReadOnlyArray <DirectoryArtifact> directoryOutputs, ReadOnlyArray <PipId> orderDependencies, ReadOnlyArray <AbsolutePath> untrackedPaths, ReadOnlyArray <AbsolutePath> untrackedScopes, ReadOnlyArray <StringId> tags, ReadOnlyArray <int> successExitCodes, ReadOnlyArray <ProcessSemaphoreInfo> semaphores, PipProvenance provenance, StringId toolDescription, ReadOnlyArray <AbsolutePath> additionalTempDirectories, RegexDescriptor warningRegex = default, RegexDescriptor errorRegex = default, bool enableMultiLineErrorScanning = false, AbsolutePath uniqueOutputDirectory = default, AbsolutePath uniqueRedirectedDirectoryRoot = default, AbsolutePath tempDirectory = default, Options options = default, bool testRetries = false, ServiceInfo serviceInfo = null, ReadOnlyArray <int>?retryExitCodes = null, ReadOnlyArray <PathAtom>?allowedSurvivingChildProcessNames = null, TimeSpan?nestedProcessTerminationTimeout = null, AbsentPathProbeInUndeclaredOpaquesMode absentPathProbeMode = AbsentPathProbeInUndeclaredOpaquesMode.Unsafe, DoubleWritePolicy doubleWritePolicy = DoubleWritePolicy.DoubleWritesAreErrors, ContainerIsolationLevel containerIsolationLevel = ContainerIsolationLevel.None, int?weight = null, int?priority = null, ReadOnlyArray <AbsolutePath>?preserveOutputWhitelist = null, FileArtifact changeAffectedInputListWrittenFile = default, int?preserveOutputsTrustLevel = null, ReadOnlyArray <PathAtom>?childProcessesToBreakawayFromSandbox = null) { Contract.Requires(executable.IsValid); Contract.Requires(workingDirectory.IsValid); Contract.Requires(arguments.IsValid); Contract.RequiresForAll(environmentVariables, environmentVariable => environmentVariable.Name.IsValid); Contract.RequiresForAll(environmentVariables, environmentVariable => environmentVariable.Value.IsValid ^ environmentVariable.IsPassThrough); Contract.Requires(dependencies.IsValid); Contract.RequiresForAll(dependencies, dependency => dependency.IsValid); Contract.Requires(directoryDependencies.IsValid); Contract.RequiresForAll(directoryDependencies, directoryDependency => directoryDependency.IsValid); Contract.Requires(outputs.IsValid); Contract.RequiresForAll(outputs, output => output.IsValid); Contract.Requires(directoryOutputs.IsValid); Contract.RequiresForAll(outputs, output => !output.IsSourceFile); Contract.RequiresForAll(directoryOutputs, directoryOutput => directoryOutput.IsValid); Contract.Requires(orderDependencies.IsValid); Contract.RequiresForAll(orderDependencies, dependency => dependency != PipId.Invalid); Contract.Requires(untrackedPaths.IsValid); Contract.RequiresForAll(untrackedPaths, path => path.IsValid); Contract.Requires(untrackedScopes.IsValid); Contract.RequiresForAll(untrackedScopes, scope => scope.IsValid); Contract.Requires(!timeout.HasValue || timeout.Value <= MaxTimeout); Contract.Requires(standardDirectory.IsValid || (standardOutput.IsValid && standardError.IsValid)); Contract.Requires(provenance != null); Contract.Requires(additionalTempDirectories.IsValid); Contract.RequiresForAll(additionalTempDirectories, path => path.IsValid); Contract.Requires(tags.IsValid); // If the process needs to run in a container, the redirected directory has to be set Contract.Requires((options & Options.NeedsToRunInContainer) == Options.None || uniqueRedirectedDirectoryRoot.IsValid); #if DEBUG // a little too expensive for release builds Contract.Requires(Contract.Exists(dependencies, d => d == executable), "The executable must be declared as a dependency"); Contract.Requires( !standardInput.IsFile || Contract.Exists(dependencies, d => d == standardInput.File), "If provided, the standard-input artifact must be declared as a dependency"); Contract.Requires( !standardOutput.IsValid || Contract.Exists(outputs, o => o.ToFileArtifact() == standardOutput), "If provided, the standard-error artifact must be declared as an expected output"); Contract.Requires( !standardError.IsValid || Contract.Exists(outputs, o => o.ToFileArtifact() == standardError), "If provided, the standard-error artifact must be declared as an expected output"); Contract.Requires( !responseFile.IsValid ^ responseFileData.IsValid, "If provided, the response-file artifact must have a corresponding ResponseFileData"); Contract.Requires(outputs.Length == outputs.Distinct().Count()); Contract.Requires(directoryOutputs.Length == directoryOutputs.Distinct().Count()); Contract.Requires(dependencies.Length == dependencies.Distinct().Count()); Contract.Requires(directoryDependencies.Length == directoryDependencies.Distinct().Count()); Contract.Requires(untrackedPaths.Length == untrackedPaths.Distinct().Count()); Contract.Requires(untrackedScopes.Length == untrackedScopes.Distinct().Count()); Contract.Requires(additionalTempDirectories.Length == additionalTempDirectories.Distinct().Count()); Contract.RequiresForAll(semaphores, s => s.IsValid); Contract.Requires(semaphores.Length == semaphores.Distinct().Count()); Contract.Requires(!(childProcessesToBreakawayFromSandbox?.Length > 0) || ProcessUtilities.SandboxSupportsProcessBreakaway(), "A process is only allowed to specify child processes to breakaway if the underlying sandbox allows for it"); #endif Provenance = provenance; Tags = tags; Executable = executable; ToolDescription = toolDescription; WorkingDirectory = workingDirectory; Arguments = arguments; ResponseFile = responseFile; ResponseFileData = responseFileData; StandardOutput = standardOutput; StandardError = standardError; StandardInput = standardInput; StandardDirectory = standardDirectory; WarningTimeout = warningTimeout; Timeout = timeout; // We allow any IEnumerable for these fields, but perform a copy up-front. // See the remarks of RemoveDuplicateFileArtifacts for why it is used on the input / output lists. Dependencies = dependencies; DirectoryDependencies = directoryDependencies; FileOutputs = outputs; DirectoryOutputs = directoryOutputs; OrderDependencies = orderDependencies; UntrackedPaths = untrackedPaths; UntrackedScopes = untrackedScopes; EnvironmentVariables = environmentVariables; SuccessExitCodes = successExitCodes; RetryExitCodes = retryExitCodes ?? ReadOnlyArray <int> .Empty; WarningRegex = warningRegex; ErrorRegex = errorRegex; EnableMultiLineErrorScanning = enableMultiLineErrorScanning; UniqueOutputDirectory = uniqueOutputDirectory; UniqueRedirectedDirectoryRoot = uniqueRedirectedDirectoryRoot; Semaphores = semaphores; TempDirectory = tempDirectory; TestRetries = testRetries; ServiceInfo = serviceInfo; AdditionalTempDirectories = additionalTempDirectories; AllowedSurvivingChildProcessNames = allowedSurvivingChildProcessNames ?? ReadOnlyArray <PathAtom> .Empty; NestedProcessTerminationTimeout = nestedProcessTerminationTimeout; ProcessAbsentPathProbeInUndeclaredOpaquesMode = absentPathProbeMode; DoubleWritePolicy = doubleWritePolicy; ContainerIsolationLevel = containerIsolationLevel; Weight = weight.HasValue && weight.Value >= MinWeight ? weight.Value : MinWeight; Priority = priority.HasValue && priority.Value >= MinPriority ? (priority <= MaxPriority ? priority.Value : MaxPriority) : MinPriority; PreserveOutputWhitelist = preserveOutputWhitelist ?? ReadOnlyArray <AbsolutePath> .Empty; ChangeAffectedInputListWrittenFile = changeAffectedInputListWrittenFile; if (PreserveOutputWhitelist.Length != 0) { options |= Options.HasPreserveOutputWhitelist; } ProcessOptions = options; PreserveOutputsTrustLevel = preserveOutputsTrustLevel ?? (int)PreserveOutputsTrustValue.Lowest; ChildProcessesToBreakawayFromSandbox = childProcessesToBreakawayFromSandbox ?? ReadOnlyArray <PathAtom> .Empty; }