예제 #1
0
        /// <summary>
        /// Creates the PipData from the given object
        /// </summary>
        public static PipData CreatePipData(StringTable stringTable, ObjectLiteral obj, PipDataBuilder pipDataBuilder)
        {
            var settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                Indent   = true,
            };

            using (var stringBuilderWrapper = Pools.StringBuilderPool.GetInstance())
            {
                var stringBuilder = stringBuilderWrapper.Instance;
                using (var writer = new UTF8StringWriter(stringBuilder))
                    using (var xmlWriter = XmlWriter.Create(writer, settings))
                    {
                        var xmlContext = new XmlWritingContext(stringTable, pipDataBuilder, stringBuilderWrapper.Instance, xmlWriter);

                        if (!WriteNode(obj, in xmlContext))
                        {
                            return(PipData.Invalid);
                        }

                        FlushXmlToPipBuilder(in xmlContext);

                        return(pipDataBuilder.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
                    }
            }
        }
예제 #2
0
        private void SetProcessEnvironmentVariables(IReadOnlyDictionary <string, string> environment, ProcessBuilder processBuilder)
        {
            foreach (KeyValuePair <string, string> kvp in environment)
            {
                if (kvp.Value != null)
                {
                    var envPipData = new PipDataBuilder(m_context.StringTable);

                    // Casing for paths is not stable as reported by BuildPrediction. So here we try to guess if the value
                    // represents a path, and normalize it
                    string value = kvp.Value;
                    if (!string.IsNullOrEmpty(value) && AbsolutePath.TryCreate(PathTable, value, out var absolutePath))
                    {
                        envPipData.Add(absolutePath);
                    }
                    else
                    {
                        envPipData.Add(value);
                    }

                    processBuilder.SetEnvironmentVariable(
                        StringId.Create(m_context.StringTable, kvp.Key),
                        envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
                }
            }

            if (m_userDefinedPassthroughVariables != null)
            {
                foreach (string passThroughVariable in m_userDefinedPassthroughVariables)
                {
                    processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, passThroughVariable));
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Creates arguments.
        /// </summary>
        protected PipData CreateArguments(
            IEnumerable <Operation> processOperations,
            StringTable stringTable)
        {
            var pipDataBuilder = new PipDataBuilder(stringTable);

            CreateArguments(pipDataBuilder, processOperations, stringTable);
            return(pipDataBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules));
        }
예제 #4
0
        private void SetEnvironmentVariables(ProcessBuilder processBuilder, NinjaNode node)
        {
            foreach (KeyValuePair <string, string> kvp in m_environmentVariables.Value)
            {
                if (kvp.Value != null)
                {
                    var envPipData = new PipDataBuilder(m_context.StringTable);
                    if (SpecialEnvironmentVariables.PassThroughPrefixes.All(prefix => !kvp.Key.StartsWith(prefix)))
                    {
                        envPipData.Add(kvp.Value);
                        processBuilder.SetEnvironmentVariable(StringId.Create(m_context.StringTable, kvp.Key), envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
                    }
                }
            }

            foreach (var kvp in m_passThroughEnvironmentVariables.Value)
            {
                processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, kvp.Key));
            }

            foreach (var envVar in SpecialEnvironmentVariables.CloudBuildEnvironment)
            {
                processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(m_context.StringTable, envVar));
            }

            // GlobalUnsafePassthroughEnvironmentVariables
            processBuilder.SetGlobalPassthroughEnvironmentVariable(m_frontEndHost.Configuration.FrontEnd.GlobalUnsafePassthroughEnvironmentVariables, m_context.StringTable);

            // We will specify a different MSPDBSRV endpoint for every pip.
            // This means every pip that needs to communicate to MSPDBSRV will
            // spawn a different child process.
            // This is because if two pips use the same endpoint at the same time
            // then second one will fail after the first one finishes, because the
            // first one was the one that spawned MSPDBSRV.EXE as a child
            // (which gets killed).
            //
            // IMPORTANT: This will cause the build to fail if two pips target the same PDB file.
            // Both LINK.EXE and CL.EXE can use MSPDBSRV.EXE:
            //   - If all linkers specify a different /pdb argument (or don't specify this argument and
            //   are linking programs with different names
            //   [https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info])
            //   then this won't happen
            //
            //   - We're forcing the compiler to not output to PDBs (/Z7)
            //
            // so this should work in the normal cases.
            var mspdbsrvPipDataBuilder = new PipDataBuilder(m_context.StringTable);

            mspdbsrvPipDataBuilder.Add(PipConstructionUtilities.ComputeSha256(node.Command));   // Unique value for each pip
            processBuilder.SetEnvironmentVariable(
                StringId.Create(m_context.StringTable, SpecialEnvironmentVariables.MsPdvSrvEndpoint),
                mspdbsrvPipDataBuilder.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
        }
        public FileArtifact WriteFile(AbsolutePath destination, PipDataAtom content, WriteFileEncoding?encoding = null)
        {
            PipDataBuilder pipDataBuilder = new PipDataBuilder(Context.StringTable);

            pipDataBuilder.Add(content);

            if (!PipConstructionHelper.TryWriteFile(
                    destination,
                    pipDataBuilder.ToPipData(Context.StringTable.Empty, PipDataFragmentEscaping.NoEscaping),
                    encoding ?? WriteFileEncoding.Utf8,
                    null,
                    null,
                    out var result))
            {
                throw new BuildXLTestException("Failed to add writefile pip");
            }

            return(result);
        }
예제 #6
0
        /// <summary>
        /// Configure the environment for a process
        /// </summary>
        public static void SetProcessEnvironmentVariables(
            IReadOnlyDictionary <string, string> userDefinedEnvironment,
            [CanBeNull] IEnumerable <string> userDefinedPassthroughVariables,
            ProcessBuilder processBuilder,
            PathTable pathTable)
        {
            Contract.RequiresNotNull(userDefinedEnvironment);
            Contract.RequiresNotNull(processBuilder);

            foreach (KeyValuePair <string, string> kvp in userDefinedEnvironment)
            {
                if (kvp.Value != null)
                {
                    var envPipData = new PipDataBuilder(pathTable.StringTable);

                    // Casing for paths is not stable as reported by BuildPrediction. So here we try to guess if the value
                    // represents a path, and normalize it
                    string value = kvp.Value;
                    if (!string.IsNullOrEmpty(value) && AbsolutePath.TryCreate(pathTable, value, out var absolutePath))
                    {
                        envPipData.Add(absolutePath);
                    }
                    else
                    {
                        envPipData.Add(value);
                    }

                    processBuilder.SetEnvironmentVariable(
                        StringId.Create(pathTable.StringTable, kvp.Key),
                        envPipData.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
                }
            }

            if (userDefinedPassthroughVariables != null)
            {
                foreach (string passThroughVariable in userDefinedPassthroughVariables)
                {
                    processBuilder.SetPassthroughEnvironmentVariable(StringId.Create(pathTable.StringTable, passThroughVariable));
                }
            }
        }
        private PerProcessPipPerformanceInformation CreateSamplePip(int index)
        {
            Func <RunnablePip, Task <PipResult> > taskFactory = async(runnablePip) =>
            {
                PipResult result;
                var       operationTracker = new OperationTracker(runnablePip.LoggingContext);
                var       pip = runnablePip.Pip;
                using (var operationContext = operationTracker.StartOperation(PipExecutorCounter.PipRunningStateDuration, pip.PipId, pip.PipType, runnablePip.LoggingContext))
                {
                    result = await TestPipExecutor.ExecuteAsync(operationContext, m_executionEnvironment, pip);
                }

                return(result);
            };

            var pathTable = m_context.PathTable;

            var executable   = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, X("/x/pkgs/tool.exe")));
            var dependencies = new HashSet <FileArtifact> {
                executable
            };

            var processBuilder = new ProcessBuilder()
                                 .WithExecutable(executable)
                                 .WithWorkingDirectory(AbsolutePath.Create(pathTable, X("/x/obj/working")))
                                 .WithArguments(PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "-loadargs"))
                                 .WithStandardDirectory(AbsolutePath.Create(pathTable, X("/x/obj/working.std")))
                                 .WithDependencies(dependencies)
                                 .WithContext(m_context);

            var dataBuilder = new PipDataBuilder(m_context.PathTable.StringTable);
            var pipData     = dataBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping);
            var pip         = processBuilder.WithArguments(pipData).Build();
            var pipId       = m_executionEnvironment.PipTable.Add((uint)(index + 1), pip);

            var runnableProcessPip = (ProcessRunnablePip)(RunnablePip.Create(m_loggingContext, m_executionEnvironment, pipId, PipType.Process, 0, taskFactory, 0));

            m_runnablePips.Add(index, runnableProcessPip);      // For verification

            return(GeneratePipInfoWithRunnablePipAndIndex(ref runnableProcessPip, index));
        }
예제 #8
0
        /// <summary>
        /// Creates the PipData from the given object
        /// </summary>
        public static PipData CreatePipData(StringTable stringTable, ObjectLiteral obj, string quoteChar, PipDataBuilder pipDataBuilder)
        {
            using (var stringBuilderWrapper = Pools.StringBuilderPool.GetInstance())
            {
                var stringBuilder = stringBuilderWrapper.Instance;
                using (var textWriter = new StringWriter(stringBuilder))
                    using (var jsonWriter = new JsonTextWriter(textWriter))
                    {
                        // textWriter.NewLine = "\n";
                        // Note, we do NOT Force consisten newline endings across platforms.
                        // After talking with the Mac team, it seems there is no hope we'll ever have shared cache entries between them.
                        // As a feature we might at some point allow the pip author to parametrise this (as well as the path separators used) but keeping it simple for now.

                        jsonWriter.Culture     = CultureInfo.InvariantCulture;
                        jsonWriter.Formatting  = Formatting.Indented;
                        jsonWriter.Indentation = 2;

                        // The JSON standard mandates the double quote as the conform quotation symbol with single quotes
                        // only being used in custom implementations by consumers, allow both
                        if (quoteChar != "\'" && quoteChar != "\"")
                        {
                            return(PipData.Invalid);
                        }

                        jsonWriter.IndentChar          = ' ';
                        jsonWriter.QuoteChar           = Convert.ToChar(quoteChar);
                        jsonWriter.AutoCompleteOnClose = false;
                        var jsonContext = new JsonWritingContext(stringTable, pipDataBuilder, stringBuilderWrapper.Instance, jsonWriter);

                        if (!WriteObject(obj, in jsonContext))
                        {
                            return(PipData.Invalid);
                        }

                        FlushJsonToPipBuilder(in jsonContext);

                        return(pipDataBuilder.ToPipData(string.Empty, PipDataFragmentEscaping.NoEscaping));
                    }
            }
        }
예제 #9
0
        /// <summary>
        /// Gets the command line arguments for the process.
        /// </summary>
        public PipData GetArgumentsDataFromProcess(Process process)
        {
            PipData arguments = process.Arguments;

            if (process.ResponseFile.IsValid)
            {
                var            responseFileData = process.ResponseFileData;
                PipDataBuilder pipDataBuilder   = new PipDataBuilder(StringTable);

                // Add all the arguments from the command line excluding the response file (the last fragment)
                foreach (var fragment in process.Arguments.Take(process.Arguments.FragmentCount - 1).Concat(responseFileData))
                {
                    Contract.Assume(fragment.FragmentType != PipFragmentType.Invalid);

                    pipDataBuilder.Add(fragment);
                }

                arguments = pipDataBuilder.ToPipData(arguments.FragmentSeparator, arguments.FragmentEscaping);
            }

            return(arguments);
        }
예제 #10
0
        public static Process CreateDummyProcessWithInputs(IEnumerable <FileArtifact> inputs, BuildXLContext context)
        {
            FileArtifact output = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\output" + s_procCounter + ".txt")).CreateNextWrittenVersion();

            s_procCounter++;
            FileArtifact exe = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\tool.exe"));

            var pipDataBuilder = new PipDataBuilder(context.StringTable);

            return(new Process(
                       executable: exe,
                       workingDirectory: AbsolutePath.Create(context.PathTable, @"\\FAKEPATH\"),
                       arguments: pipDataBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping),
                       responseFile: FileArtifact.Invalid,
                       responseFileData: PipData.Invalid,
                       environmentVariables: ReadOnlyArray <EnvironmentVariable> .Empty,
                       standardInput: FileArtifact.Invalid,
                       standardOutput: FileArtifact.Invalid,
                       standardError: FileArtifact.Invalid,
                       standardDirectory: output.Path.GetParent(context.PathTable),
                       warningTimeout: null,
                       timeout: null,
                       dependencies: ReadOnlyArray <FileArtifact> .From(inputs.Union(new[] { exe })),
                       outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(output.WithAttributes()),
                       directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty,
                       directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty,
                       orderDependencies: ReadOnlyArray <PipId> .Empty,
                       untrackedPaths: ReadOnlyArray <AbsolutePath> .Empty,
                       untrackedScopes: ReadOnlyArray <AbsolutePath> .Empty,
                       tags: ReadOnlyArray <StringId> .Empty,
                       successExitCodes: ReadOnlyArray <int> .Empty,
                       semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                       provenance: PipProvenance.CreateDummy(context),
                       toolDescription: StringId.Invalid,
                       additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty));
        }
예제 #11
0
        public void PipDataReadWrite()
        {
            var pipData = m_pipDataBuilder.ToPipData(EnclosingSeparator, EnclosingEscaping);

            byte[] bytes      = new byte[10000];
            int    startIndex = 23;
            int    index      = startIndex;

            foreach (var entry in pipData.Entries)
            {
                var expectedIndex = index + PipDataEntry.BinarySize;
                entry.Write(bytes, ref index);

                // Ensure the correct number of bytes are written
                Assert.Equal(expectedIndex, index);
            }

            var endIndex = index;

            index = startIndex;

            List <PipDataEntry> readEntries = new List <PipDataEntry>();

            while (index < endIndex)
            {
                var expectedIndex = index + PipDataEntry.BinarySize;
                readEntries.Add(PipDataEntry.Read(bytes, ref index));

                // Ensure the correct number of bytes are read
                Assert.Equal(expectedIndex, index);
            }

            var readPipData = PipData.CreateInternal(pipData.HeaderEntry, PipDataEntryList.FromEntries(readEntries), StringId.Invalid);

            VerifyFullPipData(readPipData);
        }
예제 #12
0
        private static Process CreateConsoleProcessInContainer(
            BuildXLContext context,
            TempFileStorage tempFiles,
            PathTable pt,
            string arguments,
            ReadOnlyArray <FileArtifactWithAttributes> outputFiles,
            ReadOnlyArray <DirectoryArtifact> directoryOutputs,
            ContainerIsolationLevel containerIsolationLevel = ContainerIsolationLevel.IsolateAllOutputs)
        {
            var executableFileArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, CmdHelper.CmdX64));

            var argumentBuilder = new PipDataBuilder(context.PathTable.StringTable);

            argumentBuilder.Add("/d");
            argumentBuilder.Add("/c");
            using (argumentBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, " "))
            {
                foreach (var arg in arguments.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries))
                {
                    argumentBuilder.Add(arg);
                }
            }

            string workingDirectory             = tempFiles.GetUniqueDirectory();
            var    workingDirectoryAbsolutePath = AbsolutePath.Create(context.PathTable, workingDirectory);

            string uniqueOutputDirectory     = tempFiles.GetUniqueDirectory();
            var    uniqueOutputDirectoryPath = AbsolutePath.Create(context.PathTable, uniqueOutputDirectory);

            string uniqueRedirectedOutputDirectory     = tempFiles.GetUniqueDirectory("redirected");
            var    uniqueRedirectedOutputDirectoryPath = AbsolutePath.Create(context.PathTable, uniqueRedirectedOutputDirectory);

            var pip = new Process(
                executableFileArtifact,
                workingDirectoryAbsolutePath,
                argumentBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping),
                FileArtifact.Invalid,
                PipData.Invalid,
                ReadOnlyArray <EnvironmentVariable> .FromWithoutCopy(),
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                tempFiles.GetUniqueDirectory(pt),
                null,
                null,
                dependencies: ReadOnlyArray <FileArtifact> .FromWithoutCopy(new[] { executableFileArtifact }),
                outputs: outputFiles,
                directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty,
                directoryOutputs: directoryOutputs,
                orderDependencies: ReadOnlyArray <PipId> .Empty,
                untrackedPaths: ReadOnlyArray <AbsolutePath> .Empty,
                untrackedScopes: ReadOnlyArray <AbsolutePath> .Empty,
                tags: ReadOnlyArray <StringId> .Empty,
                successExitCodes: ReadOnlyArray <int> .Empty,
                semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                provenance: PipProvenance.CreateDummy(context),
                toolDescription: StringId.Invalid,
                additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty,
                options: Process.Options.NeedsToRunInContainer,
                uniqueOutputDirectory: uniqueOutputDirectoryPath,
                uniqueRedirectedDirectoryRoot: uniqueRedirectedOutputDirectoryPath,
                containerIsolationLevel: containerIsolationLevel);

            return(pip);
        }
예제 #13
0
        public void ExecutionProcessReadingStdIn()
        {
            FileArtifact   stdOut      = CreateOutputFileArtifact();
            ProcessBuilder builder     = CreatePipBuilder(new[] { Operation.ReadStdIn() });
            PipDataBuilder dataBuilder = new PipDataBuilder(Context.PathTable.StringTable);

            dataBuilder.Add("Data0");
            dataBuilder.Add("Data1");
            dataBuilder.Add("Data2");
            builder.StandardInput = global::BuildXL.Pips.StandardInput.CreateFromData(dataBuilder.ToPipData(Environment.NewLine, PipDataFragmentEscaping.NoEscaping));
            builder.SetStandardOutputFile(stdOut.Path);
            builder.Options |= Process.Options.RequiresAdmin;
            ProcessWithOutputs process = SchedulePipBuilder(builder);

            RunScheduler().AssertSuccess();

            string[] output        = File.ReadAllLines(ArtifactToString(stdOut));
            string   actualContent = string.Join(Environment.NewLine, output);

            XAssert.AreEqual(3, output.Length, "Actual content: {0}{1}", Environment.NewLine, string.Join(Environment.NewLine, output));
            for (int i = 0; i < 3; ++i)
            {
                XAssert.AreEqual("Data" + i, output[i], "Actual content: {0}", output[i]);
            }
        }
예제 #14
0
        private async Task ProcessWindowsCallHelper(
            string functionName,
            SandboxConfiguration config            = null,
            IEnumerable <string> extraDependencies = null,
            IEnumerable <string> extraOutputs      = null,
            int callCount                   = 1,
            string commandPrefix            = "",
            bool readsAndWritesDirectories  = false,
            bool untrackedOutputs           = false,
            string[] expectedWarningStrings = null,
            string[] expectedErrorStrings   = null)
        {
            if (config == null)
            {
                config = new SandboxConfiguration {
                    FileAccessIgnoreCodeCoverage = true, FailUnexpectedFileAccesses = true
                };
            }

            var context          = BuildXLContext.CreateInstanceForTesting();
            var pathTable        = context.PathTable;
            var fileContentTable = FileContentTable.CreateNew(LoggingContext);

            // have to force the config for truncation
            config.OutputReportingMode = OutputReportingMode.FullOutputOnWarningOrError;

            bool expectSuccess = expectedErrorStrings == null && expectedWarningStrings == null;

            using (var tempFiles = new TempFileStorage(canGetFileNames: true, rootPath: TemporaryDirectory))
            {
                string currentCodeFolder = Path.GetDirectoryName(AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()));
                Contract.Assume(currentCodeFolder != null);

                string executable = Path.Combine(currentCodeFolder, DetourTestFolder, "DetoursTests.exe");

                string       workingDirectory             = tempFiles.GetUniqueDirectory();
                AbsolutePath workingDirectoryAbsolutePath = AbsolutePath.Create(pathTable, workingDirectory);

                XAssert.IsTrue(File.Exists(executable), "Could not find the test file: " + executable);
                FileArtifact executableFileArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, executable));

                var extraUntrackedScopes = new List <AbsolutePath>();

                var dependencies = new List <FileArtifact> {
                    executableFileArtifact
                };
                if (extraDependencies != null)
                {
                    foreach (string file in extraDependencies)
                    {
                        string       filePath = Path.Combine(workingDirectory, file);
                        AbsolutePath path     = AbsolutePath.Create(pathTable, filePath);

                        if (readsAndWritesDirectories)
                        {
                            Directory.CreateDirectory(filePath);

                            // We don't support directories as inputs in BuildXL yet.
                            extraUntrackedScopes.Add(path);
                        }
                        else
                        {
                            File.WriteAllText(filePath, "Definitely a file");
                            FileArtifact fileArtifact = FileArtifact.CreateSourceFile(path);
                            dependencies.Add(fileArtifact);
                        }
                    }
                }

                var outputs = new List <FileArtifactWithAttributes>();
                if (extraOutputs != null)
                {
                    foreach (string file in extraOutputs)
                    {
                        string       filePath = Path.Combine(workingDirectory, file);
                        AbsolutePath path     = AbsolutePath.Create(pathTable, filePath);

                        if (readsAndWritesDirectories)
                        {
                            // We don't support directory outputs in BuildXL at the moment, so e.g. deleting a directory needs to be untracked.
                            extraUntrackedScopes.Add(path);
                        }
                        else if (untrackedOutputs)
                        {
                            extraUntrackedScopes.Add(path);
                        }
                        else
                        {
                            FileArtifact fileArtifact = FileArtifact.CreateSourceFile(path).CreateNextWrittenVersion();
                            outputs.Add(fileArtifact.WithAttributes());
                        }
                    }
                }

                var tempDirectory        = tempFiles.GetUniqueDirectory();
                var environmentVariables = new List <EnvironmentVariable>();
                var environmentValue     = new PipDataBuilder(pathTable.StringTable);
                var tempPath             = AbsolutePath.Create(pathTable, tempDirectory);
                environmentValue.Add(tempPath);
                environmentVariables.Add(new EnvironmentVariable(StringId.Create(pathTable.StringTable, "TMP"), environmentValue.ToPipData(" ", PipDataFragmentEscaping.NoEscaping)));
                environmentVariables.Add(new EnvironmentVariable(StringId.Create(pathTable.StringTable, "TEMP"), environmentValue.ToPipData(" ", PipDataFragmentEscaping.NoEscaping)));

                var untrackedPaths  = CmdHelper.GetCmdDependencies(pathTable);
                var untrackedScopes = extraUntrackedScopes.Concat(CmdHelper.GetCmdDependencyScopes(pathTable).Concat(new[] { tempPath })).Distinct();

                var pip = new Process(
                    executableFileArtifact,
                    workingDirectoryAbsolutePath,
                    PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.NoEscaping, commandPrefix + functionName + "Logging"),
                    FileArtifact.Invalid,
                    PipData.Invalid,
                    ReadOnlyArray <EnvironmentVariable> .From(environmentVariables),
                    FileArtifact.Invalid,
                    FileArtifact.Invalid,
                    FileArtifact.Invalid,
                    tempFiles.GetUniqueDirectory(pathTable),
                    null,
                    null,
                    ReadOnlyArray <FileArtifact> .From(dependencies),
                    ReadOnlyArray <FileArtifactWithAttributes> .From(outputs),
                    ReadOnlyArray <DirectoryArtifact> .Empty,
                    ReadOnlyArray <DirectoryArtifact> .Empty,
                    ReadOnlyArray <PipId> .Empty,
                    ReadOnlyArray <AbsolutePath> .From(untrackedPaths),
                    ReadOnlyArray <AbsolutePath> .From(untrackedScopes),
                    ReadOnlyArray <StringId> .Empty,
                    ReadOnlyArray <int> .Empty,
                    ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                    provenance: PipProvenance.CreateDummy(context),
                    toolDescription: StringId.Invalid,
                    additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty);

                if (expectSuccess)
                {
                    await AssertProcessSucceedsAsync(
                        context,
                        config,
                        pip);
                }
                else
                {
                    await AssertProcessCompletesWithStatusAsync(
                        SandboxedProcessPipExecutionStatus.ExecutionFailed,
                        context,
                        config,
                        pip,
                        null);
                }
            }

            int expectedErrorCount   = 0;
            int expectedWarningCount = 0;
            IEnumerable <string> requiredLogMessageSubstrings = new string[] { };

            if (expectedErrorStrings != null)
            {
                expectedErrorCount           = expectedErrorStrings.Count();
                requiredLogMessageSubstrings = requiredLogMessageSubstrings.Concat(expectedErrorStrings);
            }

            if (expectedWarningStrings != null)
            {
                expectedWarningCount         = expectedWarningStrings.Count();
                requiredLogMessageSubstrings = requiredLogMessageSubstrings.Concat(expectedWarningStrings);
            }

            SetExpectedFailures(expectedErrorCount, expectedWarningCount, requiredLogMessageSubstrings.ToArray());
        }
예제 #15
0
        /// <summary>
        /// Completes this instance of <see cref="ArgumentsDataBuilder"/>.
        /// </summary>
        public PipData Finish()
        {
            m_finished = true;

            return(m_builder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules));
        }
예제 #16
0
        /// <summary>
        /// Creates arguments.
        /// </summary>
        internal static PipData CreateCmdArguments(
            StringTable stringTable,
            IEnumerable <FileArtifact> dependencies,
            IEnumerable <FileArtifact> outputs,
            bool includeWarning = false)
        {
            Contract.Requires(dependencies != null, "Argument dependencies cannot be null");
            Contract.Requires(outputs != null, "Argument outputs cannot be null");

            var pipDataBuilder = new PipDataBuilder(stringTable);
            int i = 0;

            pipDataBuilder.Add("/d");
            pipDataBuilder.Add("/c");

            foreach (FileArtifact output in outputs)
            {
                if (i > 0)
                {
                    pipDataBuilder.Add("&");
                }

                using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, " "))
                {
                    var allDependencies = dependencies.ToList();

                    pipDataBuilder.Add("type");
                    foreach (FileArtifact dependency in allDependencies)
                    {
                        pipDataBuilder.Add(dependency);
                    }

                    pipDataBuilder.Add(">");
                    pipDataBuilder.Add(output);
                }

                pipDataBuilder.Add("&");

                using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, " "))
                {
                    pipDataBuilder.Add("echo");
                    pipDataBuilder.Add("buildxl");
                    pipDataBuilder.Add(">>");
                    pipDataBuilder.Add(output);
                }

                i++;
            }

            if (includeWarning)
            {
                if (outputs.Any())
                {
                    pipDataBuilder.Add("&&");
                }

                using (pipDataBuilder.StartFragment(PipDataFragmentEscaping.CRuntimeArgumentRules, " "))
                {
                    pipDataBuilder.Add("echo");
                    pipDataBuilder.Add(WarningRegexDescription);
                }
            }

            return(pipDataBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules));
        }