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); } }
private DirectoryTranslator CreateDirectoryTranslator() { var translator = new DirectoryTranslator(); translator.AddTranslation(@"E:\", @"C:\"); translator.AddTranslation(@"D:\el\io", @"D:\sh\io"); translator.Seal(); return(translator); }
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); } }
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); }
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); } }
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); } }
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); } }
/// <summary> /// Adds a root translation /// </summary> public void AddTranslation(string sourcePath, string targetPath) { m_translator.AddTranslation(sourcePath, targetPath); }