Exemple #1
0
        public Process Build()
        {
            Contract.Assert(m_executable != null, "WithExecutable method should be called before calling Build() method");

            return(new Process(
                       executable: m_executable,
                       workingDirectory: m_workingDirectory,
                       arguments: m_arguments ?? m_argumentsFactory(this),
                       responseFile: FileArtifact.Invalid,
                       responseFileData: PipData.Invalid,
                       environmentVariables: ReadOnlyArray <EnvironmentVariable> .From(m_environmentVariables ?? Enumerable.Empty <EnvironmentVariable>()),
                       standardInput: FileArtifact.Invalid,
                       standardOutput: FileArtifact.Invalid,
                       standardError: FileArtifact.Invalid,
                       standardDirectory: m_standardDirectory,
                       warningTimeout: null,
                       timeout: null,
                       dependencies: ReadOnlyArray <FileArtifact> .From(CreateDependencies()),
                       outputs: ReadOnlyArray <FileArtifactWithAttributes> .From(Outputs),
                       directoryDependencies: ReadOnlyArray <DirectoryArtifact> .From(m_directoryDependencies ?? Enumerable.Empty <DirectoryArtifact>()),
                       directoryOutputs: ReadOnlyArray <DirectoryArtifact> .Empty,
                       orderDependencies: ReadOnlyArray <PipId> .From(m_orderDependencies ?? Enumerable.Empty <PipId>()),
                       untrackedPaths: ReadOnlyArray <AbsolutePath> .From(m_untrackedPathes ?? Enumerable.Empty <AbsolutePath>()),
                       untrackedScopes: ReadOnlyArray <AbsolutePath> .From(m_untrackedScopes ?? Enumerable.Empty <AbsolutePath>()),
                       tags: ReadOnlyArray <StringId> .From(m_tags ?? Enumerable.Empty <StringId>()),
                       successExitCodes: ReadOnlyArray <int> .Empty,
                       semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                       provenance: m_pipProvenance ?? PipProvenance.CreateDummy(m_context),
                       toolDescription: StringId.Invalid,
                       additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty,
                       options: m_options,
                       serviceInfo: m_serviceInfo,
                       preserveOutputWhitelist: ReadOnlyArray <AbsolutePath> .From(m_preserveOutputWhitelist ?? Enumerable.Empty <AbsolutePath>()),
                       changeAffectedInputListWrittenFile: m_changeAffectedInputListWrittenFile));
        }
            /// <nodoc />
            public MacOsDefaults(PathTable pathTable, PipGraph.Builder pipGraph)
            {
                m_provenance = new PipProvenance(
                    0,
                    ModuleId.Invalid,
                    StringId.Invalid,
                    FullSymbol.Invalid,
                    LocationData.Invalid,
                    QualifierId.Unqualified,
                    PipData.Invalid);

                m_inputFiles =
                    new[]
                {
                    FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, MacPaths.Etc)),
                    FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, MacPaths.TmpDir)),
                };

                // Sealed Source inputs
                m_inputDirectories =
                    new[]
                {
                    GetSourceSeal(pathTable, pipGraph, MacPaths.Applications),
                    GetSourceSeal(pathTable, pipGraph, MacPaths.UsrBin),
                    GetSourceSeal(pathTable, pipGraph, MacPaths.UsrInclude),
                    GetSourceSeal(pathTable, pipGraph, MacPaths.UsrLib),
                    GetSourceSeal(pathTable, pipGraph, MacPaths.Library),
                    GetSourceSeal(pathTable, pipGraph, MacPaths.UserProvisioning),
                };

                m_untrackedFiles =
                    new[]
                {
                    // login.keychain is created by the OS the first time any process invokes an OS API that references the keychain.
                    // Untracked because build state will not be stored there and code signing will fail if required certs are in the keychain
                    FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, MacPaths.UserKeyChainsDb)),
                    FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, MacPaths.UserKeyChains)),
                    FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, MacPaths.UserCFTextEncoding)),
                };

                m_untrackedDirectories =
                    new[]
                {
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.Bin),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.Dev),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.Private),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.Sbin),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.SystemLibrary),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.UsrLibexec),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.UsrShare),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.UsrStandalone),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.UsrSbin),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.Var),
                    DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, MacPaths.UserPreferences),
                };
            }
Exemple #3
0
 private static ObjectInfo ProvenanceInfo(PipProvenance prov)
 {
     return(new ObjectInfo(
                prov.ToString(),
                new[]
     {
         new Property("Qualifier", prov.QualifierId),
         new Property("Output", prov.OutputValueSymbol),
         new Property("Usage", prov.Usage),
     }));
 }
Exemple #4
0
        private static Pip CreateCmdPip(BuildXLContext context, string tempDirectory, string outFile, bool is64Bit)
        {
            Contract.Requires(context != null);
            Contract.Requires(tempDirectory != null);
            Contract.Requires(!string.IsNullOrEmpty(outFile));

            var pathTable = context.PathTable;

            string       executable         = is64Bit ? CmdHelper.CmdX64 : CmdHelper.CmdX86;
            FileArtifact executableArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, executable));

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

            AbsolutePath outFilePath     = AbsolutePath.Create(pathTable, outFile);
            FileArtifact outFileArtifact = FileArtifact.CreateSourceFile(outFilePath).CreateNextWrittenVersion();
            var          pip             = new BuildXL.Pips.Operations.Process(
                executableArtifact,
                workingDirectoryAbsolutePath,
                PipDataBuilder.CreatePipData(
                    context.StringTable,
                    " ",
                    PipDataFragmentEscaping.CRuntimeArgumentRules,
                    "/d",
                    "/c",
                    "echo",
                    "hello",
                    ">",
                    outFileArtifact),
                FileArtifact.Invalid,
                PipData.Invalid,
                ReadOnlyArray <EnvironmentVariable> .Empty,
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                AbsolutePath.Create(pathTable, tempDirectory),
                null,
                null,
                ReadOnlyArray <FileArtifact> .FromWithoutCopy(executableArtifact),
                ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(outFileArtifact.WithAttributes()),
                ReadOnlyArray <DirectoryArtifact> .Empty,
                ReadOnlyArray <DirectoryArtifact> .Empty,
                ReadOnlyArray <PipId> .Empty,
                ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencies(pathTable)),
                ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencyScopes(pathTable)),
                ReadOnlyArray <StringId> .Empty,
                ReadOnlyArray <int> .Empty,
                ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                provenance: PipProvenance.CreateDummy(context),
                toolDescription: StringId.Invalid,
                additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty);

            return(pip);
        }
        internal PipProvenance CreatePipProvenance(PipData usage)
        {
            var result = new PipProvenance(
                GetNextSemiStableHash(),
                moduleId: m_moduleId,
                moduleName: StringId.Create(Context.StringTable, m_moduleName),
                outputValueSymbol: m_valuePip.Symbol,
                token: m_valuePip.LocationData,
                qualifierId: m_valuePip.Qualifier,
                usage: usage);

            return(result);
        }
        /// <summary>
        /// Adds a fake process pip that produces only the given path.
        /// </summary>
        public Process AddProcess(AbsolutePath producedPath, DoubleWritePolicy doubleWritePolicy = DoubleWritePolicy.DoubleWritesAreErrors)
        {
            Contract.Assume(!m_pathProducers.ContainsKey(producedPath), "Each path may have only one producer (no rewrites)");

            AbsolutePath workingDirectory = AbsolutePath.Create(m_context.PathTable, PathGeneratorUtilities.GetAbsolutePath("X", ""));
            AbsolutePath exe = AbsolutePath.Create(m_context.PathTable, PathGeneratorUtilities.GetAbsolutePath("X", "fake.exe"));

            var process = new Process(
                executable: FileArtifact.CreateSourceFile(exe),
                workingDirectory: workingDirectory,
                arguments: PipDataBuilder.CreatePipData(m_context.StringTable, string.Empty, PipDataFragmentEscaping.NoEscaping),
                responseFile: FileArtifact.Invalid,
                responseFileData: PipData.Invalid,
                environmentVariables: ReadOnlyArray <EnvironmentVariable> .Empty,
                standardInput: FileArtifact.Invalid,
                standardOutput: FileArtifact.Invalid,
                standardError: FileArtifact.Invalid,
                standardDirectory: workingDirectory,
                warningTimeout: null,
                timeout: null,
                dependencies: ReadOnlyArray <FileArtifact> .FromWithoutCopy(FileArtifact.CreateSourceFile(exe)),
                outputs: ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(FileArtifact.CreateSourceFile(producedPath).CreateNextWrittenVersion().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(m_context),
                toolDescription: StringId.Invalid,
                additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty,
                doubleWritePolicy: doubleWritePolicy);

            process.PipId = AllocateNextPipId();
            m_pips.Add(process.PipId, process);
            m_pathProducers.Add(producedPath, process);

            return(process);
        }
Exemple #7
0
        private static Process CreateDummyProcess(PipExecutionContext context, PipId pipId)
        {
            var exe = FileArtifact.CreateSourceFile(AbsolutePath.Create(context.PathTable, X("/X/exe")));
            List <FileArtifact> dependencies = new List <FileArtifact> {
                exe
            };

            var p = new Process(
                directoryDependencies: ReadOnlyArray <DirectoryArtifact> .Empty,
                executable: exe,
                workingDirectory: AbsolutePath.Create(context.PathTable, X("/X")),
                arguments: new PipDataBuilder(context.StringTable).ToPipData(" ", PipDataFragmentEscaping.NoEscaping),
                responseFile: FileArtifact.Invalid,
                responseFileData: PipData.Invalid,
                environmentVariables: ReadOnlyArray <EnvironmentVariable> .Empty,
                standardInput: FileArtifact.Invalid,
                standardOutput: FileArtifact.Invalid,
                standardError: FileArtifact.Invalid,
                standardDirectory: AbsolutePath.Create(context.PathTable, X("/X/std")),
                warningTimeout: null,
                timeout: null,
                dependencies: ReadOnlyArray <FileArtifact> .From(dependencies),
                outputs: ReadOnlyArray <FileArtifactWithAttributes> .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)
            {
                PipId = pipId
            };

            return(p);
        }
Exemple #8
0
        /// <summary>
        /// Creates a process pip.
        /// </summary>
        protected Process CreateProcess(
            IEnumerable <Operation> processOperations,
            IEnumerable <string> tags = null,
            IEnumerable <EnvironmentVariable> environmentVariables = null,
            IEnumerable <DirectoryArtifact> directoryDependencies  = null,
            IEnumerable <DirectoryArtifact> directoryOutputs       = null,
            IEnumerable <PipId> orderDependencies      = null,
            IEnumerable <AbsolutePath> untrackedPaths  = null,
            IEnumerable <AbsolutePath> untrackedScopes = null,
            FileArtifact?stdOut      = null,
            FileArtifact?stdError    = null,
            PipProvenance provenance = null,
            IEnumerable <AbsolutePath> additionalTempDirectories = null,
            AbsolutePath?tempDirectory           = null,
            IEnumerable <FileArtifact> tempFiles = null /* converted to FileArtifactWithAttributes with FileExistence.Temporary, then concatenated to outputs */)
        {
            FileArtifact executable = TestProcessExecutable;

            var dao = InferIOFromOperations(processOperations);

            return(CreateProcessWithoutInferringAccesses(
                       dependencies: dao.Dependencies,
                       outputs: dao.Outputs,
                       processOperations: processOperations,
                       tags: tags,
                       environmentVariables: environmentVariables,
                       directoryDependencies: directoryDependencies,
                       directoryOutputs: directoryOutputs,
                       orderDependencies: orderDependencies,
                       untrackedPaths: untrackedPaths,
                       untrackedScopes: untrackedScopes,
                       stdOut: stdOut,
                       stdError: stdError,
                       provenance: provenance,
                       additionalTempDirectories: additionalTempDirectories,
                       tempDirectory: tempDirectory,
                       tempFiles: tempFiles));
        }
Exemple #9
0
        /// <summary>
        /// Generates the PipMetadata for a given Pip
        /// </summary>
        public PipMetadata GeneratePipMetadata(Pip pip)
        {
            PipMetadata pipMetadata = new PipMetadata
            {
                PipId          = pip.PipId.Value,
                SemiStableHash = pip.FormattedSemiStableHash,
                PipType        = pip.PipType,
                Tags           = pip.Tags.IsValid ? pip.Tags.Select(tag => tag.ToString(StringTable)).ToList() : null
            };

            pipMetadata.Tags = pipMetadata.Tags.Any() ? pipMetadata.Tags : null;

            PipProvenance provenance = pip.Provenance;

            pipMetadata.Qualifier         = PipGraph.Context.QualifierTable.GetCanonicalDisplayString(provenance.QualifierId);
            pipMetadata.Usage             = provenance.Usage.IsValid ? provenance.Usage.ToString(PathTable) : null;
            pipMetadata.SpecFilePath      = provenance.Token.Path.ToString(PathTable);
            pipMetadata.OutputValueSymbol = provenance.OutputValueSymbol.ToString(SymbolTable);
            pipMetadata.ModuleId          = provenance.ModuleId.Value;
            pipMetadata.SpecFilePath      = provenance.Token.Path.ToString(PathTable);

            pipMetadata.PipDependencies = PipGraph.RetrievePipReferenceImmediateDependencies(pip.PipId, null)
                                          .Where(pipRef => pipRef.PipType != PipType.HashSourceFile)
                                          .Select(pipRef => pipRef.PipId)
                                          .Select(pipId => PipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer))
                                          .Select(pipHash => pipHash.FormattedSemiStableHash)
                                          .ToList();

            pipMetadata.PipDependents = PipGraph.RetrievePipReferenceImmediateDependents(pip.PipId, null)
                                        .Select(pipRef => pipRef.PipId)
                                        .Select(pipId => PipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer))
                                        .Select(pipData => pipData.FormattedSemiStableHash)
                                        .ToList();
            pipMetadata.PipDependencies = pipMetadata.PipDependencies.Any() ? pipMetadata.PipDependencies : null;
            pipMetadata.PipDependents   = pipMetadata.PipDependents.Any() ? pipMetadata.PipDependents : null;

            return(pipMetadata);
        }
Exemple #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));
        }
Exemple #11
0
        public ObjectInfo GetObjectInfo(object context, object obj)
        {
            obj = obj is EvaluationResult evalResult
                ? evalResult.Value
                : obj;

            if (obj == null || IsInvalid(obj))
            {
                return(s_nullObj);
            }

            if (obj.GetType().IsArray)
            {
                return(ArrayObjInfo(((IEnumerable)obj).Cast <object>().ToArray()));
            }

            var customResult = m_customRenderer?.Invoke(this, context, obj);

            if (customResult != null)
            {
                return(customResult);
            }

            return(obj switch
            {
                ScopeLocals scope => new ObjectInfo(LocalsScopeName, null, Lazy.Create(() => GetLocalsForStackEntry(scope.EvalState, scope.FrameIndex))),
                ScopePipGraph scope => PipGraphInfo(scope.Graph).WithPreview(PipGraphScopeName),
                ScopeAllModules scope => ArrayObjInfo(scope.EvaluatedModules.ToArray()).WithPreview(EvaluatedModulesScopeName),
                IModuleAndContext mc => GetObjectInfo(mc.Tree.RootContext, mc.Module),
                ObjectInfo objInf => objInf,
                IPipGraph graph => PipGraphInfo(graph),
                Pip pip => GenericObjectInfo(pip, $"<{pip.PipType}>").Build(),
                PipProvenance prov => ProvenanceInfo(prov),
                EnvironmentVariable envVar => EnvironmentVariableInfo(envVar),
                PipFragment pipFrag => PipFragmentInfo(context, pipFrag),
                Thunk thunk => thunk.Value != null?GetObjectInfo(context, thunk.Value) : new ObjectInfo("<not evaluated>"),
                    FunctionLikeExpression lambda => LambdaInfo(lambda),
                    Closure cls => LambdaInfo(cls.Function),
                    SymbolAtom sym => new ObjectInfo(sym.ToString(StringTable)),
                    StringId id => new ObjectInfo(id.ToString(StringTable)),
                    PipId id => new ObjectInfo($"{id.Value}"),
                    UndefinedLiteral _ => new ObjectInfo("undefined", UndefinedLiteral.Instance),
                    UndefinedValue _ => new ObjectInfo("undefined", UndefinedValue.Instance),
                    AbsolutePath path => new ObjectInfo($"p`{path.ToString(PathTable)}`", path),
                    RelativePath path => new ObjectInfo($"r`{path.ToString(StringTable)}`", path),
                    PathAtom atom => new ObjectInfo($"a`{atom.ToString(StringTable)}`", atom),
                    FileArtifact file => new ObjectInfo($"f`{file.Path.ToString(PathTable)}`", file),
                    DirectoryArtifact dir => new ObjectInfo($"d`{dir.Path.ToString(PathTable)}`", dir),
                    int num => new ObjectInfo($"{num}"),
                    uint num => new ObjectInfo($"{num}"),
                    short num => new ObjectInfo($"{num}", (int)num),
                    long num => new ObjectInfo($"{num}"),
                    char ch => new ObjectInfo($"'{ch}'", ch.ToString()),
                    string str => new ObjectInfo($"\"{str}\"", str),
                    Enum e => new ObjectInfo($"{e.GetType().Name}.{e}", e),
                    NumberLiteral numLit => new ObjectInfo(numLit.UnboxedValue.ToString(), numLit),
                    Func <object> func => FuncObjInfo(func),
                    ArraySegment <object> arrSeg => ArrayObjInfo(arrSeg),
                    IEnumerable enu => new ObjectInfoBuilder().Preview("IEnumerable").Prop("Result", Lazy.Create <object>(() => enu.Cast <object>().ToArray())).Build(),
                    ArrayLiteral arrLit => ArrayObjInfo(arrLit.Values.Select(v => v.Value).ToArray()).WithOriginal(arrLit),
                    ModuleBinding binding => GetObjectInfo(context, binding.Body),
                    ErrorValue error => ErrorValueInfo(),
                    object o => GenericObjectInfo(o).Build(),
                    _ => s_nullObj
            });
Exemple #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);
        }
Exemple #13
0
        private static Pip CreateSelfPip(
            BuildXLContext context,
            string tempDirectory,
            string outFile,
            IEnumerable <string> restInstructions,
            bool is64Bit)
        {
            Contract.Requires(context != null);
            Contract.Requires(tempDirectory != null);
            Contract.Requires(!string.IsNullOrEmpty(outFile));

            var pathTable = context.PathTable;

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

            AbsolutePath appdataPath       = AbsolutePath.Create(pathTable, Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
            AbsolutePath windowsFolderPath = AbsolutePath.Create(pathTable, Environment.GetFolderPath(Environment.SpecialFolder.Windows));

            string       executable         = is64Bit ? TestExecutableX64 : TestExecutableX86;
            FileArtifact executableArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, Path.Combine(workingDirectory, executable)));

            AbsolutePath outFilePath     = AbsolutePath.Create(pathTable, outFile);
            FileArtifact outFileArtifact = FileArtifact.CreateSourceFile(outFilePath).CreateNextWrittenVersion();
            var          pip             = new BuildXL.Pips.Operations.Process(
                executableArtifact,
                workingDirectoryAbsolutePath,
                PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, restInstructions.Select(ri => (PipDataAtom)ri).ToArray()),
                FileArtifact.Invalid,
                PipData.Invalid,
                ReadOnlyArray <EnvironmentVariable> .Empty,
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                FileArtifact.Invalid,
                AbsolutePath.Create(pathTable, tempDirectory),
                null,
                null,
                ReadOnlyArray <FileArtifact> .FromWithoutCopy(executableArtifact),
                ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(outFileArtifact.WithAttributes()),
                ReadOnlyArray <DirectoryArtifact> .Empty,
                ReadOnlyArray <DirectoryArtifact> .Empty,
                ReadOnlyArray <PipId> .Empty,
                ReadOnlyArray <AbsolutePath> .Empty,
                ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    new[]
            {
                workingDirectoryAbsolutePath,
                windowsFolderPath,

                // For unknown reasons, on some machines the process is accessing LOCALAPPDATA\Microsoft\Windows\Temporary Internet Files\counters.dat
                appdataPath,
            }),
                ReadOnlyArray <StringId> .Empty,
                ReadOnlyArray <int> .Empty,
                ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                provenance: PipProvenance.CreateDummy(context),
                toolDescription: StringId.Invalid,
                additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty);

            return(pip);
        }
Exemple #14
0
        public async Task Stress()
        {
            const int N              = 5;
            const int M              = N * N;
            var       context        = BuildXLContext.CreateInstanceForTesting();
            var       loggingContext = CreateLoggingContextForTest();
            var       pathTable      = context.PathTable;

            using (var tempFiles = new TempFileStorage(canGetFileNames: true))
            {
                var config = ConfigHelpers.CreateDefault(pathTable, tempFiles.GetUniqueFileName(), tempFiles);

                using (var pipTable = new PipTable(
                           context.PathTable,
                           context.SymbolTable,
                           initialBufferSize: 1024,
                           maxDegreeOfParallelism: (Environment.ProcessorCount + 2) / 3,
                           debug: false))
                {
                    var executionEnvironment = new PipQueueTestExecutionEnvironment(
                        context,
                        config,
                        pipTable,
                        Path.Combine(TestOutputDirectory, "temp"),
                        TryGetSubstSourceAndTarget(out string substSource, out string substTarget) ? (substSource, substTarget) : default((string, string)?),
                        GetSandboxConnection());

                    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, executionEnvironment, pip);
                        }

                        executionEnvironment.MarkExecuted(pip);
                        return(result);
                    };

                    string       executable         = CmdHelper.OsShellExe;
                    FileArtifact executableArtifact = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, executable));

                    // This is the only file artifact we reference without a producer. Rather than scheduling a hashing pip, let's just invent one (so fingerprinting can succeed).
                    executionEnvironment.AddWellKnownFile(executableArtifact, WellKnownContentHashes.UntrackedFile);

                    using (var phase1PipQueue = new PipQueue(executionEnvironment.Configuration.Schedule))
                    {
                        // phase 1: create some files
                        var baseFileArtifacts = new List <FileArtifact>();
                        for (int i = 0; i < N; i++)
                        {
                            string       destination             = tempFiles.GetUniqueFileName();
                            AbsolutePath destinationAbsolutePath = AbsolutePath.Create(pathTable, destination);
                            FileArtifact destinationArtifact     = FileArtifact.CreateSourceFile(destinationAbsolutePath).CreateNextWrittenVersion();
                            baseFileArtifacts.Add(destinationArtifact);

                            PipData contents = PipDataBuilder.CreatePipData(
                                context.StringTable,
                                " ",
                                PipDataFragmentEscaping.CRuntimeArgumentRules,
                                i.ToString(CultureInfo.InvariantCulture));

                            var writeFile = new WriteFile(destinationArtifact, contents, WriteFileEncoding.Utf8, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(context));
                            var pipId     = pipTable.Add((uint)(i + 1), writeFile);

                            var contentHash = ContentHashingUtilities.HashString(contents.ToString(pathTable));
                            executionEnvironment.AddExpectedWrite(writeFile, destinationArtifact, contentHash);

                            var runnable = RunnablePip.Create(loggingContext, executionEnvironment, pipId, pipTable.GetPipType(pipId), 0, taskFactory, 0);
                            runnable.Start(new OperationTracker(loggingContext), loggingContext);
                            runnable.SetDispatcherKind(DispatcherKind.IO);
                            phase1PipQueue.Enqueue(runnable);
                        }

                        phase1PipQueue.SetAsFinalized();
                        phase1PipQueue.DrainQueues();
                        await Task.WhenAll(
                            Enumerable.Range(0, 2).Select(
                                async range =>
                        {
                            using (var phase2PipQueue = new PipQueue(executionEnvironment.Configuration.Schedule))
                            {
                                // phase 2: do some more with those files
                                var pips         = new ConcurrentDictionary <PipId, Tuple <string, int> >();
                                var checkerTasks = new ConcurrentQueue <Task>();
                                Action <PipId, Task <PipResult> > callback =
                                    (id, task) =>
                                {
                                    XAssert.IsTrue(task.Status == TaskStatus.RanToCompletion);
                                    XAssert.IsFalse(task.Result.Status.IndicatesFailure());
                                    Tuple <string, int> t;
                                    if (!pips.TryRemove(id, out t))
                                    {
                                        XAssert.Fail();
                                    }

                                    checkerTasks.Enqueue(
                                        Task.Run(
                                            () =>
                                    {
                                        string actual = File.ReadAllText(t.Item1).Trim();

                                        // TODO: Make this async
                                        XAssert.AreEqual(actual, t.Item2.ToString());
                                    }));
                                };
                                var r = new Random(0);
                                for (int i = 0; i < M; i++)
                                {
                                    int sourceIndex             = r.Next(baseFileArtifacts.Count);
                                    FileArtifact sourceArtifact = baseFileArtifacts[sourceIndex];

                                    string destination = tempFiles.GetUniqueFileName();
                                    AbsolutePath destinationAbsolutePath = AbsolutePath.Create(pathTable, destination);
                                    FileArtifact destinationArtifact     = FileArtifact.CreateSourceFile(destinationAbsolutePath).CreateNextWrittenVersion();
                                    Pip pip;

                                    DispatcherKind queueKind;
                                    switch (r.Next(2))
                                    {
                                    case 0:
                                        pip       = new CopyFile(sourceArtifact, destinationArtifact, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(context));
                                        queueKind = DispatcherKind.IO;
                                        executionEnvironment.AddExpectedWrite(pip, destinationArtifact, executionEnvironment.GetExpectedContent(sourceArtifact));
                                        break;

                                    case 1:
                                        string workingDirectory =
                                            OperatingSystemHelper.IsUnixOS ? "/tmp" :
                                            Environment.GetFolderPath(Environment.SpecialFolder.Windows);

                                        AbsolutePath workingDirectoryAbsolutePath = AbsolutePath.Create(pathTable, workingDirectory);

                                        var pipData = OperatingSystemHelper.IsUnixOS ?
                                                      PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "-c", "'", "cp", sourceArtifact, destinationArtifact, "'") :
                                                      PipDataBuilder.CreatePipData(pathTable.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "/d", "/c", "copy", "/B", sourceArtifact, destinationArtifact);

                                        queueKind = DispatcherKind.CPU;
                                        pip       = new Process(
                                            executableArtifact,
                                            workingDirectoryAbsolutePath,
                                            pipData,
                                            FileArtifact.Invalid,
                                            PipData.Invalid,
                                            ReadOnlyArray <EnvironmentVariable> .Empty,
                                            FileArtifact.Invalid,
                                            FileArtifact.Invalid,
                                            FileArtifact.Invalid,
                                            tempFiles.GetUniqueDirectory(pathTable),
                                            null,
                                            null,
                                            ReadOnlyArray <FileArtifact> .FromWithoutCopy(executableArtifact, sourceArtifact),
                                            ReadOnlyArray <FileArtifactWithAttributes> .FromWithoutCopy(destinationArtifact.WithAttributes()),
                                            ReadOnlyArray <DirectoryArtifact> .Empty,
                                            ReadOnlyArray <DirectoryArtifact> .Empty,
                                            ReadOnlyArray <PipId> .Empty,
                                            ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencies(pathTable)),
                                            ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencyScopes(pathTable)),
                                            ReadOnlyArray <StringId> .Empty,
                                            ReadOnlyArray <int> .Empty,
                                            ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                                            provenance: PipProvenance.CreateDummy(context),
                                            toolDescription: StringId.Invalid,
                                            additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty);
                                        executionEnvironment.AddExpectedWrite(pip, destinationArtifact, executionEnvironment.GetExpectedContent(sourceArtifact));
                                        break;

                                    default:
                                        Contract.Assert(false);
                                        continue;
                                    }

                                    var pipId = pipTable.Add((uint)((range *M) + N + i + 1), pip);

                                    Func <RunnablePip, Task> taskFactoryWithCallback = async(runnablePip) =>
                                    {
                                        var task      = taskFactory(runnablePip);
                                        var pipResult = await task;
                                        callback(pipId, task);
                                    };

                                    var runnable = RunnablePip.Create(loggingContext, executionEnvironment, pipId, pipTable.GetPipType(pipId), 0, taskFactoryWithCallback, 0);
                                    runnable.Start(new OperationTracker(loggingContext), loggingContext);
                                    runnable.SetDispatcherKind(queueKind);
                                    phase2PipQueue.Enqueue(runnable);

                                    if (!pips.TryAdd(pipId, Tuple.Create(destination, sourceIndex)))
                                    {
                                        Contract.Assert(false);
                                    }
                                }

                                phase2PipQueue.SetAsFinalized();
                                phase2PipQueue.DrainQueues();
                                XAssert.AreEqual(0, pips.Count);
                                await Task.WhenAll(checkerTasks);
                            }
                        }));
                    }
                }
            }
        }
        public void TestLogLimit()
        {
            var failingCopyFile1 = new CopyFile(FileArtifact.CreateSourceFile(CreateUniqueSourcePath(SourceRootPrefix)), CreateOutputFileArtifact(), ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(Context));
            var failingCopyFile2 = new CopyFile(FileArtifact.CreateSourceFile(CreateUniqueSourcePath(SourceRootPrefix)), CreateOutputFileArtifact(), ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(Context));

            PipGraphBuilder.AddCopyFile(failingCopyFile1);
            PipGraphBuilder.AddCopyFile(failingCopyFile2);

            Configuration.Logging.DumpFailedPipsLogLimit = 1;

            var schedulerResult = RunScheduler().AssertFailure();

            var logFolder = Path.Combine(schedulerResult.Config.Logging.LogsDirectory.ToString(Context.PathTable), "FailedPips");

            SetExpectedFailures(2, 0);
            AssertErrorCount();
            AssertVerboseEventLogged(LogEventId.RuntimeDumpPipLiteLogLimitReached, count: 1);
            Assert.True(Directory.GetFiles(logFolder).Length == 1);
        }
        public void TestPassingAndFailingPips()
        {
            var existantCopyFileSrc  = CreateSourceFile();
            var existantCopyFileDest = CreateOutputFileArtifact();

            File.WriteAllText(existantCopyFileSrc.Path.ToString(Context.PathTable), "copy file test");

            var failingCopyFile = new CopyFile(FileArtifact.CreateSourceFile(CreateUniqueSourcePath(SourceRootPrefix)), CreateOutputFileArtifact(), ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(Context));
            var passingCopyFile = CreateCopyFile(existantCopyFileSrc, existantCopyFileDest);

            PipGraphBuilder.AddCopyFile(failingCopyFile);
            PipGraphBuilder.AddCopyFile(passingCopyFile);

            var schedulerResult = RunScheduler().AssertFailure();
            var logFolder       = Path.Combine(schedulerResult.Config.Logging.LogsDirectory.ToString(Context.PathTable), "FailedPips");
            var failingLogFile  = Path.Combine(logFolder, $"{failingCopyFile.FormattedSemiStableHash}.json");
            var passingLogFile  = Path.Combine(logFolder, $"{passingCopyFile.FormattedSemiStableHash}.json");

            SetExpectedFailures(1, 0); // One error logged for the failing pip
            AssertErrorCount();

            Assert.True(File.Exists(failingLogFile));
            Assert.False(File.Exists(passingLogFile));
        }
Exemple #17
0
        /// <summary>
        /// Creates a process pip.
        /// </summary>
        protected Process CreateCmdProcess(
            IEnumerable <FileArtifact> dependencies,
            IEnumerable <FileArtifact> outputs,
            PipData?arguments         = null,
            IEnumerable <string> tags = null,
            PipProvenance provenance  = null,
            IEnumerable <DirectoryArtifact> directoryDependencies = null,
            IEnumerable <PipId> orderDependencies = null,
            IEnumerable <EnvironmentVariable> environmentVariables = null,
            FileArtifact?stdOut   = null,
            FileArtifact?stdError = null,
            bool withWarning      = false,
            string value          = null,
            IEnumerable <FileArtifact> untrackedFiles        = null,
            IEnumerable <DirectoryArtifact> directoryOutputs = null)
        {
            Contract.Requires(dependencies != null);
            Contract.Requires(outputs != null);

            FileArtifact executable = CmdExecutable;

            IEnumerable <AbsolutePath> untrackedDependencies = CmdHelper.GetCmdDependencies(Context.PathTable);

            if (untrackedFiles != null)
            {
                List <AbsolutePath> files = new List <AbsolutePath>(untrackedDependencies);
                foreach (FileArtifact oneFile in untrackedFiles)
                {
                    files.Add(oneFile.Path);
                }
                untrackedDependencies = files;
            }

            untrackedFiles = untrackedFiles ?? Enumerable.Empty <FileArtifact>();

            var process =
                new Process(
                    executable: executable,
                    workingDirectory: GetWorkingDirectory(),
                    arguments: arguments ?? CreateCmdArguments(Context.StringTable, dependencies.Concat(untrackedFiles), outputs, includeWarning: withWarning),
                    responseFile: FileArtifact.Invalid,
                    responseFileData: PipData.Invalid,
                    environmentVariables: environmentVariables != null
                        ? ReadOnlyArray <EnvironmentVariable> .From(environmentVariables)
                        : ReadOnlyArray <EnvironmentVariable> .Empty,
                    standardInput: FileArtifact.Invalid,
                    standardOutput: stdOut ?? FileArtifact.Invalid,
                    standardError: stdError ?? FileArtifact.Invalid,
                    standardDirectory: GetStandardDirectory(),
                    warningTimeout: null,
                    timeout: null,

                    // TODO:1759: Fix response file handling. Should be able to appear in the dependencies list, but should appear in the graph as a WriteFile pip.
                    dependencies: ReadOnlyArray <FileArtifact> .From((new[] { executable /*, responseFile*/ }).Concat(dependencies ?? CollectionUtilities.EmptyArray <FileArtifact>())),
                    outputs: ReadOnlyArray <FileArtifactWithAttributes> .From(outputs.Select(o => o.WithAttributes()).ToArray()),
                    directoryDependencies: ReadOnlyArray <DirectoryArtifact> .From(directoryDependencies ?? new DirectoryArtifact[0]),
                    directoryOutputs: ReadOnlyArray <DirectoryArtifact> .From(directoryOutputs ?? new DirectoryArtifact[0]),
                    orderDependencies: orderDependencies != null ? ReadOnlyArray <PipId> .From(orderDependencies) : ReadOnlyArray <PipId> .Empty,
                    untrackedPaths: ReadOnlyArray <AbsolutePath> .From(untrackedDependencies),
                    untrackedScopes: ReadOnlyArray <AbsolutePath> .From(CmdHelper.GetCmdDependencyScopes(Context.PathTable)),
                    tags: ConvertToStringIdArray(tags),
                    successExitCodes: ReadOnlyArray <int> .Empty,
                    semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                    provenance: provenance,
                    toolDescription: StringId.Invalid,
                    additionalTempDirectories: ReadOnlyArray <AbsolutePath> .Empty,
                    warningRegex:
                    withWarning
                            ? new RegexDescriptor(StringId.Create(Context.StringTable, WarningRegexDescription), RegexOptions.IgnoreCase)
                            : default(RegexDescriptor));

            return(process);
        }
Exemple #18
0
            /// <nodoc />
            public MacOsDefaults(PathTable pathTable, IMutablePipGraph pipGraph)
            {
                m_provenance = new PipProvenance(
                    0,
                    ModuleId.Invalid,
                    StringId.Invalid,
                    FullSymbol.Invalid,
                    LocationData.Invalid,
                    QualifierId.Unqualified,
                    PipData.Invalid);

                m_sourceSealDirectoryPaths =
                    new[]
                {
                    MacPaths.Applications,
                    MacPaths.Library,
                    MacPaths.UserProvisioning
                }
                .Select(p => AbsolutePath.Create(pathTable, p))
                .ToArray();

                // Sealed Source inputs
                // (using Lazy so that these directories are sealed and added to the graph only if explicitly requested by a process)
                m_lazySourceSealDirectories = Lazy.Create(() =>
                                                          new DefaultSourceSealDirectories(m_sourceSealDirectoryPaths.Select(p => GetSourceSeal(pipGraph, p)).ToArray()));

                m_untrackedFiles =
                    new[]
                {
                    // login.keychain is created by the OS the first time any process invokes an OS API that references the keychain.
                    // Untracked because build state will not be stored there and code signing will fail if required certs are in the keychain
                    MacPaths.Etc,
                    MacPaths.UserKeyChainsDb,
                    MacPaths.UserKeyChains,
                    MacPaths.UserCFTextEncoding,
                    MacPaths.TmpDir
                }
                .Select(p => FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, p)))
                .ToArray();

                m_untrackedDirectories =
                    new[]
                {
                    MacPaths.Bin,
                    MacPaths.Dev,
                    MacPaths.Private,
                    MacPaths.Sbin,
                    MacPaths.SystemLibrary,
                    MacPaths.UsrBin,
                    MacPaths.UsrInclude,
                    MacPaths.UsrLibexec,
                    MacPaths.UsrShare,
                    MacPaths.UsrStandalone,
                    MacPaths.UsrSbin,
                    MacPaths.Var,
                    MacPaths.UserPreferences,
                    // it's important to untrack /usr/lib instead of creating a sealed source directory
                    //   - the set of dynamically loaded libraries during an execution of a process is
                    //     not necessarily deterministic, i.e., when the same process---which itself is
                    //     deterministic---is executed multiple times on same inputs, the set of
                    //     dynamically loaded libraries is not necessarily going to stay the same.
                    MacPaths.UsrLib
                }
                .Select(p => DirectoryArtifact.CreateWithZeroPartialSealId(pathTable, p))
                .ToArray();
            }
Exemple #19
0
 public ProcessBuilder WithProvenance(PipProvenance pipProvenance)
 {
     m_pipProvenance = pipProvenance;
     return(this);
 }
Exemple #20
0
        /// <summary>
        /// Creates a process pip without inferring any accesses from processOperations. This allows the consumer to specify
        /// all file acceses
        /// </summary>
        protected Process CreateProcessWithoutInferringAccesses(
            IEnumerable <FileArtifact> dependencies,
            IEnumerable <FileArtifact> outputs,
            IEnumerable <Operation> processOperations,
            IEnumerable <string> tags = null,
            IEnumerable <EnvironmentVariable> environmentVariables = null,
            IEnumerable <DirectoryArtifact> directoryDependencies  = null,
            IEnumerable <DirectoryArtifact> directoryOutputs       = null,
            IEnumerable <PipId> orderDependencies      = null,
            IEnumerable <AbsolutePath> untrackedPaths  = null,
            IEnumerable <AbsolutePath> untrackedScopes = null,
            FileArtifact?stdOut      = null,
            FileArtifact?stdError    = null,
            PipProvenance provenance = null,
            IEnumerable <AbsolutePath> additionalTempDirectories = null,
            AbsolutePath?tempDirectory           = null,
            IEnumerable <FileArtifact> tempFiles = null /* converted to FileArtifactWithAttributes with FileExistence.Temporary, then concatenated to outputs */)
        {
            Contract.Requires(dependencies != null);
            Contract.Requires(outputs != null);

            FileArtifact executable = TestProcessExecutable;

            untrackedScopes = untrackedScopes ?? new AbsolutePath[0];
            if (tempDirectory != null)

            // Make temp directories untracked scopes to mimic pips built through PipBuilder
            {
                untrackedScopes = untrackedScopes.Concat(new AbsolutePath[] { (AbsolutePath)tempDirectory });
            }
            untrackedScopes = untrackedScopes.Concat(additionalTempDirectories ?? new AbsolutePath[0]);

            // Add C://Windows dependency for test executable
            untrackedScopes = untrackedScopes.Concat(TestProcessDependencies);

            IEnumerable <FileArtifactWithAttributes> outputsWithAttributes = outputs.Select(o => o.WithAttributes());

            if (tempFiles != null)
            {
                outputsWithAttributes = outputsWithAttributes.Concat(tempFiles.Select(tf => FileArtifactWithAttributes.FromFileArtifact(tf, FileExistence.Temporary)));
            }

            var process =
                new Process(
                    executable: executable,
                    workingDirectory: GetWorkingDirectory(),
                    arguments: CreateArguments(processOperations, Context.StringTable),
                    responseFile: FileArtifact.Invalid,
                    responseFileData: PipData.Invalid,
                    environmentVariables: environmentVariables != null
                        ? ReadOnlyArray <EnvironmentVariable> .From(environmentVariables)
                        : ReadOnlyArray <EnvironmentVariable> .Empty,
                    standardInput: FileArtifact.Invalid,
                    standardOutput: stdOut ?? FileArtifact.Invalid,
                    standardError: stdError ?? FileArtifact.Invalid,
                    standardDirectory: GetStandardDirectory(),
                    warningTimeout: null,
                    timeout: null,
                    dependencies: ReadOnlyArray <FileArtifact> .From((new[] { executable }).Concat(dependencies ?? CollectionUtilities.EmptyArray <FileArtifact>())),
                    outputs: ReadOnlyArray <FileArtifactWithAttributes> .From(outputsWithAttributes),
                    directoryDependencies: ReadOnlyArray <DirectoryArtifact> .From(directoryDependencies ?? new DirectoryArtifact[0]),
                    directoryOutputs: ReadOnlyArray <DirectoryArtifact> .From(directoryOutputs ?? new DirectoryArtifact[0]),
                    orderDependencies: orderDependencies != null ? ReadOnlyArray <PipId> .From(orderDependencies) : ReadOnlyArray <PipId> .Empty,
                    untrackedPaths: ReadOnlyArray <AbsolutePath> .From(untrackedPaths ?? ReadOnlyArray <AbsolutePath> .Empty),
                    untrackedScopes: ReadOnlyArray <AbsolutePath> .From(untrackedScopes),
                    tags: ConvertToStringIdArray(tags),
                    successExitCodes: ReadOnlyArray <int> .Empty,
                    semaphores: ReadOnlyArray <ProcessSemaphoreInfo> .Empty,
                    provenance: provenance ?? CreateProvenance(),
                    toolDescription: StringId.Invalid,
                    additionalTempDirectories: ReadOnlyArray <AbsolutePath> .From(additionalTempDirectories ?? ReadOnlyArray <AbsolutePath> .Empty),
                    tempDirectory: tempDirectory ?? default(AbsolutePath)
                    );

            return(process);
        }
Exemple #21
0
        public void TestDumpPipLite()
        {
            var copyFile = new CopyFile(CreateSourceFile(), CreateOutputFileArtifact(), new List <StringId>().ToReadOnlyArray(), PipProvenance.CreateDummy(Context));

            PipGraphBuilder.AddCopyFile(copyFile);

            var schedulerResult = RunScheduler().AssertSuccess();

            var logFolder   = Path.Combine(schedulerResult.Config.Logging.LogsDirectory.ToString(Context.PathTable), "FailedPips");
            var pipDumpFile = Path.Combine(logFolder, $"{copyFile.FormattedSemiStableHash}.json");

            List <Option> options = new List <Option>
            {
                new Option()
                {
                    Name  = "o",
                    Value = schedulerResult.Config.Logging.LogsDirectory.ToString(Context.PathTable)
                },
                new Option()
                {
                    Name  = "p",
                    Value = copyFile.FormattedSemiStableHash
                }
            };

            RunAnalyzer(schedulerResult, null, options);

            Assert.True(Directory.Exists(logFolder));
            Assert.True(File.Exists(pipDumpFile));
        }
Exemple #22
0
        public void TestDumpPipLiteWithPassingAndFailingPips()
        {
            var passingCopyFile = new CopyFile(CreateSourceFile(), CreateOutputFileArtifact(), new List <StringId>().ToReadOnlyArray(), PipProvenance.CreateDummy(Context));
            var failingCopyFile = new CopyFile(FileArtifact.CreateSourceFile(CreateUniqueSourcePath(SourceRootPrefix)), CreateOutputFileArtifact(), new List <StringId>().ToReadOnlyArray(), PipProvenance.CreateDummy(Context));

            PipGraphBuilder.AddCopyFile(passingCopyFile);
            PipGraphBuilder.AddCopyFile(failingCopyFile);

            var schedulerResult = RunScheduler().AssertFailure();

            var logFolder          = Path.Combine(schedulerResult.Config.Logging.LogsDirectory.ToString(Context.PathTable), "FailedPips");
            var failingPipDumpFile = Path.Combine(logFolder, $"{failingCopyFile.FormattedSemiStableHash}.json");
            var passingPipDumpFile = Path.Combine(logFolder, $"{passingCopyFile.FormattedSemiStableHash}.json");


            List <Option> options = new List <Option>
            {
                new Option()
                {
                    Name = "d+"
                }
            };

            RunAnalyzer(schedulerResult, null, options);

            Assert.True(Directory.Exists(logFolder));
            Assert.True(File.Exists(failingPipDumpFile));
            Assert.True(!File.Exists(passingPipDumpFile));
        }
Exemple #23
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());
        }
Exemple #24
0
        /// <summary>
        /// Adds a fake copy file pip that produces to the given destination path.
        /// </summary>
        public CopyFile AddCopyFilePip(FileArtifact source, FileArtifact destination)
        {
            Contract.Requires(source != null);
            Contract.Requires(destination != null);

            var copyFile = new CopyFile(source, destination, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(m_context));

            copyFile.PipId = AllocateNextPipId();
            m_pips.Add(copyFile.PipId, copyFile);
            m_pathProducers.Add(destination.Path, copyFile);

            return(copyFile);
        }
Exemple #25
0
        /// <summary>
        /// Adds a fake write file pip that produces to the given destination path.
        /// </summary>
        public WriteFile AddWriteFilePip(AbsolutePath destinationPath)
        {
            Contract.Requires(destinationPath != null);

            FileArtifact destinationArtifact = FileArtifact.CreateSourceFile(destinationPath).CreateNextWrittenVersion();
            PipData      contents            = PipDataBuilder.CreatePipData(m_context.StringTable, " ", PipDataFragmentEscaping.CRuntimeArgumentRules, "content");

            var writeFile = new WriteFile(destinationArtifact, contents, WriteFileEncoding.Utf8, ReadOnlyArray <StringId> .Empty, PipProvenance.CreateDummy(m_context));

            writeFile.PipId = AllocateNextPipId();
            m_pips.Add(writeFile.PipId, writeFile);
            m_pathProducers.Add(destinationArtifact, writeFile);

            return(writeFile);
        }