コード例 #1
0
        public void ChangeIntermediateJunctionDoesNotRebuild()
        {
            const string ReadFileName = "file";

            AbsolutePath targetDirectoryA = CreateUniqueDirectory(SourceRoot, "DirA");
            AbsolutePath targetDirectoryB = CreateUniqueDirectory(SourceRoot, "DirB");

            string expandedTargetDirectoryA = targetDirectoryA.ToString(Context.PathTable);
            string expandedTargetDirectoryB = targetDirectoryB.ToString(Context.PathTable);

            AbsolutePath junction1 = CreateUniqueDirectory(SourceRoot, "Junc1");
            AbsolutePath junction2 = CreateUniqueDirectory(SourceRoot, "Junc2");

            string expandedJunction1 = junction1.ToString(Context.PathTable);
            string expandedJunction2 = junction2.ToString(Context.PathTable);

            FileArtifact targetAFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryA);
            FileArtifact targetBFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryB);

            WriteSourceFile(targetAFile);
            WriteSourceFile(targetBFile);

            FileArtifact junction1File = CreateFileArtifactWithName(ReadFileName, expandedJunction1);
            FileArtifact junction2File = CreateFileArtifactWithName(ReadFileName, expandedJunction2);

            // Create junction
            //     Junc1 -> Junc2 -> DirA
            FileUtilities.CreateJunction(expandedJunction2, expandedTargetDirectoryA);
            FileUtilities.CreateJunction(expandedJunction1, expandedJunction2);

            FileArtifact outputP = CreateOutputFileArtifact();

            var builderP = CreatePipBuilder(new Operation[] { Operation.CopyFile(junction2File, outputP, doNotInfer: true) });

            builderP.AddInputFile(junction1File);
            builderP.AddOutputFile(outputP.Path, FileExistence.Required);
            var pipP = SchedulePipBuilder(builderP).Process;

            DirectoryTranslator = new DirectoryTranslator();
            DirectoryTranslator.AddTranslation(expandedTargetDirectoryA, expandedJunction2);
            DirectoryTranslator.AddTranslation(expandedJunction2, expandedJunction1);

            RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId);

            // Change junction
            //     Junc2 -> DirB
            FileUtilities.CreateJunction(expandedJunction2, expandedTargetDirectoryB);

            var result = RunScheduler().AssertSuccess();

            if (Configuration.Schedule.IncrementalScheduling)
            {
                // Junc2 is not tracked because BuildXL only track final translation, which is Junc1.
                result.AssertNotScheduled(pipP.PipId);
            }
            else
            {
                result.AssertCacheMiss(pipP.PipId);
            }
        }
コード例 #2
0
        private DirectoryTranslator CreateDirectoryTranslator()
        {
            var translator = new DirectoryTranslator();

            translator.AddTranslation(@"E:\", @"C:\");
            translator.AddTranslation(@"D:\el\io", @"D:\sh\io");

            translator.Seal();
            return(translator);
        }
コード例 #3
0
        private void ReparsePointWithSymlinkTest(string targetPath, string reparsePoint, bool useDirTranslation)
        {
            const string TARGET_NAME     = "targetName";
            const string TARGET_SYM_NAME = "targetSymFile";

            // Target file artifacts
            FileArtifact targetFile = CreateFileArtifactWithName(TARGET_NAME, targetPath);

            WriteSourceFile(targetFile);
            FileArtifact symlinkFileOnTarget = CreateFileArtifactWithName(TARGET_SYM_NAME, targetPath);

            // Create a symlink file on target
            XAssert.PossiblySucceeded(FileUtilities.TryCreateSymbolicLink(ArtifactToString(symlinkFileOnTarget), ArtifactToString(targetFile), isTargetFile: true));

            // junction file artifacts to read in pipA
            FileArtifact symlinkFileOnReparsePoint = CreateFileArtifactWithName(TARGET_SYM_NAME, reparsePoint);

            // ........... PIP A ...........
            var builderA = CreatePipBuilder(new Operation[]
            {
                Operation.ReadFile(symlinkFileOnReparsePoint, doNotInfer: true),
                Operation.WriteFile(CreateOutputFileArtifact(targetPath))
            });

            builderA.AddInputFile(symlinkFileOnTarget);
            builderA.AddInputFile(targetFile);
            var pipA = SchedulePipBuilder(builderA);

            if (useDirTranslation)
            {
                string junctionPathStr = reparsePoint;
                string targetPathStr   = targetPath;

                // ............CREATING DIRECTORY TRANSLATOR....................
                // Before scheduling, we need to:
                // (1) init the directory translator
                // (2) add any translations
                // (3) then seal
                // - bullets 1 and 2 are happening for us now in the SchedulerIntegrationTestBase
                DirectoryTranslator.AddTranslation(junctionPathStr, targetPathStr);

                RunScheduler().AssertSuccess();
            }
            else
            {
                // No directory translation will cause an error
                RunScheduler().AssertFailure();
                AssertVerboseEventLogged(LogEventId.DependencyViolationMissingSourceDependency);
                AssertVerboseEventLogged(EventId.PipProcessDisallowedFileAccess);
                AssertWarningEventLogged(EventId.ProcessNotStoredToCacheDueToFileMonitoringViolations);
                AssertErrorEventLogged(EventId.FileMonitoringError);
            }
        }
コード例 #4
0
        public void UseJunctionRoots()
        {
            AbsolutePath targetPath      = CreateUniqueDirectory(SourceRoot);
            AbsolutePath junctionPath    = CreateUniqueDirectory(SourceRoot);
            string       targetPathStr   = targetPath.ToString(Context.PathTable);
            string       junctionPathStr = junctionPath.ToString(Context.PathTable);

            // .......... Creating the Junction ..........
            FileUtilities.CreateJunction(junctionPath.ToString(Context.PathTable), targetPathStr);

            FileArtifact sourceFile = CreateSourceFile(junctionPathStr);

            Configuration.Engine.DirectoriesToTranslate.Add(
                new BuildXLConfiguration.TranslateDirectoryData(
                    targetPath.ToString(Context.PathTable) + @"\<" + junctionPath.ToString(Context.PathTable) + @"\", targetPath, junctionPath));

            DirectoryTranslator.AddTranslation(targetPath, junctionPath, Context.PathTable);

            var pipBuilder = CreatePipBuilder(new Operation[]
            {
                Operation.ReadFile(sourceFile),
                Operation.WriteFile(CreateOutputFileArtifact())
            });

            SchedulePipBuilder(pipBuilder);
            RunScheduler().AssertSuccess();

            // Remove junction and recreate one with the same target
            AssertTrue(FileUtilities.TryRemoveDirectory(junctionPathStr, out var hr));
            Directory.CreateDirectory(junctionPathStr);
            FileUtilities.CreateJunction(junctionPath.ToString(Context.PathTable), targetPathStr);

            RunScheduler().AssertSuccess();
            AssertVerboseEventLogged(EventId.ValidateJunctionRoot);
            AssertVerboseEventLogged(StorageLogEventId.IgnoredRecordsDueToUnchangedJunctionRootCount);

            // Remove junction and recreate one with the same target
            AssertTrue(FileUtilities.TryRemoveDirectory(junctionPathStr, out var hr2));
            Directory.CreateDirectory(junctionPathStr);
            FileUtilities.CreateJunction(junctionPath.ToString(Context.PathTable), targetPathStr);

            RunScheduler().AssertSuccess();
            AssertVerboseEventLogged(EventId.ValidateJunctionRoot);
            AssertVerboseEventLogged(StorageLogEventId.IgnoredRecordsDueToUnchangedJunctionRootCount);
        }
コード例 #5
0
        public void TranslateGlobalUntrackedScope(bool translate, Process.Options requireGlobalDependencies)
        {
            DirectoryArtifact sourceDirectory       = DirectoryArtifact.CreateWithZeroPartialSealId(CreateUniqueDirectory(SourceRoot, prefix: "sourceDir"));
            DirectoryArtifact targetDirectory       = DirectoryArtifact.CreateWithZeroPartialSealId(CreateUniqueDirectory(SourceRoot, prefix: "targetDir"));
            FileArtifact      outputFileInTargetDir = CreateOutputFileArtifact(ArtifactToString(targetDirectory));
            FileArtifact      inputFileInTargetDir  = CreateSourceFile(ArtifactToString(targetDirectory));

            Configuration.Sandbox.GlobalUnsafeUntrackedScopes.Add(sourceDirectory);

            if (translate)
            {
                DirectoryTranslator = new DirectoryTranslator();
                DirectoryTranslator.AddTranslation(ArtifactToString(sourceDirectory), ArtifactToString(targetDirectory));
            }

            var ops = new Operation[]
            {
                Operation.ReadFile(inputFileInTargetDir, doNotInfer: true),
                Operation.WriteFile(outputFileInTargetDir)
            };

            var builder = CreatePipBuilder(ops);

            builder.Options |= requireGlobalDependencies;

            Process pip = SchedulePipBuilder(builder).Process;

            if (translate && ((requireGlobalDependencies & Process.Options.RequireGlobalDependencies) == Process.Options.RequireGlobalDependencies))
            {
                RunScheduler().AssertCacheMiss(pip.PipId);
                RunScheduler().AssertCacheHit(pip.PipId);
            }
            else
            {
                RunScheduler().AssertFailure();
                AssertWarningEventLogged(EventId.ProcessNotStoredToCacheDueToFileMonitoringViolations);
                AssertErrorEventLogged(EventId.FileMonitoringError);
            }
        }
コード例 #6
0
        public void ChangeJunctionWithTranslateDirectoryShouldRebuild()
        {
            const string ReadFileName = "file";

            AbsolutePath targetDirectoryA = CreateUniqueDirectory(SourceRoot, "DirA");
            AbsolutePath targetDirectoryB = CreateUniqueDirectory(SourceRoot, "DirB");
            AbsolutePath targetDirectoryC = CreateUniqueDirectory(SourceRoot, "DirC");

            string expandedTargetDirectoryA = targetDirectoryA.ToString(Context.PathTable);
            string expandedTargetDirectoryB = targetDirectoryB.ToString(Context.PathTable);
            string expandedTargetDirectoryC = targetDirectoryC.ToString(Context.PathTable);

            AbsolutePath junction1 = CreateUniqueDirectory(SourceRoot, "Junc1");
            AbsolutePath junction2 = CreateUniqueDirectory(SourceRoot, "Junc2");

            string expandedJunction1 = junction1.ToString(Context.PathTable);
            string expandedJunction2 = junction2.ToString(Context.PathTable);

            FileArtifact targetAFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryA);
            FileArtifact targetBFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryB);
            FileArtifact targetCFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryC);

            WriteSourceFile(targetAFile);
            WriteSourceFile(targetBFile);
            WriteSourceFile(targetCFile);

            FileArtifact junction1File = CreateFileArtifactWithName(ReadFileName, expandedJunction1);
            FileArtifact junction2File = CreateFileArtifactWithName(ReadFileName, expandedJunction2);

            // Create junction
            //     Junc1 -> DirA
            //     Junc2 -> DirC
            FileUtilities.CreateJunction(expandedJunction1, expandedTargetDirectoryA);
            FileUtilities.CreateJunction(expandedJunction2, expandedTargetDirectoryC);

            FileArtifact outputP = CreateOutputFileArtifact();
            FileArtifact outputQ = CreateOutputFileArtifact();

            var builderP = CreatePipBuilder(new Operation[] { Operation.CopyFile(junction1File, outputP) });
            var pipP     = SchedulePipBuilder(builderP).Process;

            var builderQ = CreatePipBuilder(new Operation[] { Operation.CopyFile(targetCFile, outputQ, doNotInfer: true) });

            builderQ.AddInputFile(junction2File);
            builderQ.AddOutputFile(outputQ.Path, FileExistence.Required);
            var pipQ = SchedulePipBuilder(builderQ).Process;

            DirectoryTranslator = new DirectoryTranslator();
            DirectoryTranslator.AddTranslation(expandedTargetDirectoryA, expandedJunction1);
            DirectoryTranslator.AddTranslation(expandedTargetDirectoryC, expandedJunction2);

            RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId, pipQ.PipId);

            // Change junction
            //     Junc2 -> DirB
            FileUtilities.CreateJunction(expandedJunction1, expandedTargetDirectoryB);

            var result = RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId);

            if (Configuration.Schedule.IncrementalScheduling)
            {
                // pipQ should not be affected at all.
                result.AssertNotScheduled(pipQ.PipId);
            }
            else
            {
                // pipQ is scheduled but results in cache hit.
                result.AssertScheduled(pipQ.PipId).AssertCacheHit(pipQ.PipId);
            }
        }
コード例 #7
0
        public void ChangeJunctionShouldRebuild()
        {
            const string ReadFileName = "file";

            AbsolutePath targetDirectoryA = CreateUniqueDirectory(SourceRoot, "DirA");
            AbsolutePath targetDirectoryB = CreateUniqueDirectory(SourceRoot, "DirB");

            string expandedTargetDirectoryA = targetDirectoryA.ToString(Context.PathTable);
            string expandedTargetDirectoryB = targetDirectoryB.ToString(Context.PathTable);

            AbsolutePath junction1 = CreateUniqueDirectory(SourceRoot, "Junc1");

            string expandedJunction1 = junction1.ToString(Context.PathTable);

            FileArtifact targetAFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryA);
            FileArtifact targetBFile = CreateFileArtifactWithName(ReadFileName, expandedTargetDirectoryB);

            WriteSourceFile(targetAFile);
            WriteSourceFile(targetBFile);

            FileArtifact junction1File = CreateFileArtifactWithName(ReadFileName, expandedJunction1);

            // Create junction
            //     Junc1 -> DirA
            FileUtilities.CreateJunction(expandedJunction1, expandedTargetDirectoryA);

            FileArtifact outputP = CreateOutputFileArtifact();
            FileArtifact outputQ = CreateOutputFileArtifact();

            var pipP = SchedulePipBuilder(CreatePipBuilder(new Operation[] { Operation.CopyFile(junction1File, outputP) })).Process;

            // We don't need directory translator here because pipP reads through junction1File.
            // But we want to show that incremental scheduling is not sensitive to directory translator.
            DirectoryTranslator = new DirectoryTranslator();
            DirectoryTranslator.AddTranslation(expandedTargetDirectoryA, expandedJunction1);

            RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId);

            // Change junction
            //     Junc1 -> DirB
            FileUtilities.CreateJunction(expandedJunction1, expandedTargetDirectoryB);

            DirectoryTranslator = new DirectoryTranslator();
            DirectoryTranslator.AddTranslation(expandedTargetDirectoryB, expandedJunction1);

            RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId);

            // Modify DirB\File
            WriteSourceFile(targetBFile);
            RunScheduler().AssertSuccess().AssertCacheMiss(pipP.PipId);

            // Modify DirA\File
            WriteSourceFile(targetAFile);

            // Note that, even though DirA\File has nothing to do with the build as the junction has changed to DirB,
            // incremental scheduling, when enabled, will still mark pipP dirty. In the first build the file change tracker
            // tracked DirA\File, and introduced a mapping from FileId(DirA\File) to Path(Junc1\File). Thus, when DirA\File
            // changes, Path(Junc1\File) is affected, and since pipP specifies Path(Junc1\File) as its input, pipP is affected as well.
            RunScheduler().AssertSuccess().AssertScheduled(pipP.PipId).AssertCacheHit(pipP.PipId);

            // Modify again DirA\File.
            // After the above run, the mapping FileId(DirA\File) to Path(Junc1\File) has been removed, and thus,
            // any change to DirA\File should not affect pipP.
            WriteSourceFile(targetAFile);

            var result = RunScheduler().AssertSuccess();

            if (Configuration.Schedule.IncrementalScheduling)
            {
                result.AssertNotScheduled(pipP.PipId);
            }
            else
            {
                result.AssertCacheHit(pipP.PipId);
            }
        }
コード例 #8
0
 /// <summary>
 /// Adds a root translation
 /// </summary>
 public void AddTranslation(string sourcePath, string targetPath)
 {
     m_translator.AddTranslation(sourcePath, targetPath);
 }