public void TransitiveAffectedDirectoryInputWithSealTest(InputAccessType pipBInputAccessType, bool accessExistingFile = false) { // aInputDir -> (pipA) ->pip-a-out-file-> (copy) ->pip-a-output-file-copy -> (seal) -> copyDir -> (pipB) -> bOutputDir -> (pipC) -> pip-c-out-file // |- pip-a-input-file / |- pip-a-output-file-copy |- pip-b-out-file // existing-file |- existing-file // // Execepted change affected input for pipC is pip-b-out-file or "" var aInputDir = Path.Combine(ObjectRoot, "input"); var aInputDirPath = AbsolutePath.Create(Context.PathTable, aInputDir); var aInputDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(aInputDirPath); var aInputFile = CreateSourceFile(root: aInputDirPath, prefix: "pip-a-input-file"); File.WriteAllText(ArtifactToString(aInputFile), "pipABuild1"); var sealInputDir = SealDirectory(aInputDirPath, SealDirectoryKind.SourceAllDirectories); var aOutputDir = Path.Combine(ObjectRoot, "aOutputDir"); var aOutputDirPath = AbsolutePath.Create(Context.PathTable, aOutputDir); var aOutputDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(aOutputDirPath); var aOutputFileInOutputeDir = CreateOutputFileArtifact(root: aOutputDir, prefix: "pip-a-out-file"); var copyDir = Path.Combine(ObjectRoot, "copyDir"); var copyDirPath = AbsolutePath.Create(Context.PathTable, copyDir); var copyFilePath = CreateSourceFile(root: copyDirPath, prefix: "pip-a-output-file-copy").Path; var aExistingFileInOutputeDir = CreateSourceFile(root: copyDirPath, prefix: "existing-file"); File.WriteAllText(ArtifactToString(aExistingFileInOutputeDir), "This is an existing file"); var bOutDir = Path.Combine(ObjectRoot, "bOutputDir"); var bOutDirPath = AbsolutePath.Create(Context.PathTable, bOutDir); var bOutDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(bOutDirPath); var bOutFileArtifact = CreateOutputFileArtifact(root: bOutDirArtifact, prefix: "pip-b-out-file"); var cOutFileArtifact = CreateOutputFileArtifact(prefix: "pip-c-out-file"); var expectedAffectedInput = ""; var pipBuilderA = CreatePipBuilder(new Operation[] { Operation.ReadFile(aInputFile, doNotInfer: true), Operation.WriteFile(aOutputFileInOutputeDir), }); pipBuilderA.AddInputDirectory(sealInputDir); var pipA = SchedulePipBuilder(pipBuilderA); var copiedFile = CopyFile(aOutputFileInOutputeDir, copyFilePath); var sealedaOutput = SealDirectory(copyDirPath, SealDirectoryKind.Full, aExistingFileInOutputeDir, copiedFile); var operations = new List <Operation>() { }; if (pipBInputAccessType == InputAccessType.DynamicFileAccess) { if (accessExistingFile) { operations.Add(Operation.ReadFile(aExistingFileInOutputeDir, doNotInfer: true)); } else { operations.Add(Operation.ReadFile(copiedFile, doNotInfer: true)); expectedAffectedInput = bOutFileArtifact.Path.GetName(Context.PathTable).ToString(Context.PathTable.StringTable); } } operations.Add(Operation.WriteFile(bOutFileArtifact, doNotInfer: true)); var pipBuilderB = CreatePipBuilder(operations); pipBuilderB.AddInputDirectory(sealedaOutput); pipBuilderB.AddOutputDirectory(bOutDirArtifact, SealDirectoryKind.Opaque); var pipB = SchedulePipBuilder(pipBuilderB); var changeAffectedWrittenFile = CreateOutputFileArtifact(); var pipBuilderC = CreatePipBuilder(new Operation[] { Operation.ReadFile(bOutFileArtifact, doNotInfer: true), Operation.WriteFile(cOutFileArtifact), }); pipBuilderC.AddInputDirectory(bOutDirArtifact); pipBuilderC.SetChangeAffectedInputListWrittenFilePath(changeAffectedWrittenFile); var pipC = SchedulePipBuilder(pipBuilderC); var inputChangesFile = CreateOutputFileArtifact(); File.WriteAllText(ArtifactToString(inputChangesFile), ArtifactToString(aInputFile)); Configuration.Schedule.InputChanges = inputChangesFile.Path; RunScheduler().AssertSuccess(); var actualAffectedInput = File.ReadAllText(ArtifactToString(changeAffectedWrittenFile)); XAssert.AreEqual(expectedAffectedInput, actualAffectedInput); }
public void TransitiveAffectedDirectoryInputTest(InputAccessType pipBInputAccessType) { // aInputDir -> (pipA) -> aOutputDir -> (pipB) -> bOutputDir -> (pipC) -> pip-c-out-file // |- pip-a-input-file |- pip-a-out-file |- pip-b-out-file // |- aSubOutputDir // |- pip-a-out-in-sub-file // Expected change affected input for pipC is pip-b-out-file // Creating an input dir for pipA var aInputDir = Path.Combine(ObjectRoot, "input"); var aInputDirPath = AbsolutePath.Create(Context.PathTable, aInputDir); var aInputDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(aInputDirPath); var aInputFile = CreateSourceFile(root: aInputDirPath, prefix: "pip-a-input-file"); File.WriteAllText(ArtifactToString(aInputFile), "pipABuild1"); var sealInputDir = SealDirectory(aInputDirPath, SealDirectoryKind.SourceAllDirectories); // Creating an output dir Artifact (containing a outfile and a sub output dir) for pipB // This output dir will be input dir for pipB var aOutputDir = Path.Combine(ObjectRoot, "aOutputDir"); var aOutputDirPath = AbsolutePath.Create(Context.PathTable, aOutputDir); var aOutputDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(aOutputDirPath); var aOutputFileInOutputeDir = CreateOutputFileArtifact(root: aOutputDir, prefix: "pip-a-out-file"); var aOutputSubDir = Path.Combine(aOutputDir, "aSubOutputDir"); var aOutputSubDirPath = AbsolutePath.Create(Context.PathTable, aOutputSubDir); var aOutputSubDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(aOutputSubDirPath); var aOutputFileInOutputSubDir = CreateOutputFileArtifact(root: aOutputSubDir, prefix: "pip-a-out-in-sub-file"); // Creating an output dir for pipB, this will be the input dir for pipC var bOutDir = Path.Combine(ObjectRoot, "bOutputDir"); var bOutDirPath = AbsolutePath.Create(Context.PathTable, bOutDir); var bOutDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(bOutDirPath); var bOutFileArtifact = CreateOutputFileArtifact(root: bOutDirArtifact, prefix: "pip-b-out-file"); // pipC output a file var cOutFileArtifact = CreateOutputFileArtifact(prefix: "pip-c-out-file"); var expectedAffectedInput = ""; var pipBuilderA = CreatePipBuilder(new Operation[] { Operation.ReadFile(aInputFile, doNotInfer: true), Operation.WriteFile(aOutputFileInOutputeDir, doNotInfer: true), Operation.CreateDir(aOutputSubDirArtifact, doNotInfer: true), Operation.WriteFile(aOutputFileInOutputSubDir, doNotInfer: true), }); pipBuilderA.AddInputDirectory(sealInputDir); pipBuilderA.AddOutputDirectory(aOutputDirArtifact, SealDirectoryKind.Opaque); var pipA = SchedulePipBuilder(pipBuilderA); var operations = new List <Operation>() { }; if (pipBInputAccessType == InputAccessType.DynamicFileAccess) { operations.Add(Operation.ReadFile(aOutputFileInOutputeDir, doNotInfer: true)); expectedAffectedInput = ArtifactToString(bOutFileArtifact); } operations.Add(Operation.WriteFile(bOutFileArtifact, doNotInfer: true)); var pipBuilderB = CreatePipBuilder(operations); pipBuilderB.AddInputDirectory(pipA.ProcessOutputs.GetOpaqueDirectory(aOutputDirPath)); pipBuilderB.AddOutputDirectory(bOutDirArtifact, SealDirectoryKind.Opaque); var pipB = SchedulePipBuilder(pipBuilderB); var changeAffectedWrittenFile = CreateUniqueObjPath("change"); var pipBuilderC = CreatePipBuilder(new Operation[] { // Ensure that pip reads the changeAffectedWrittenFile if it exists. Operation.ReadFile(FileArtifact.CreateSourceFile(changeAffectedWrittenFile), doNotInfer: true), Operation.ReadFile(bOutFileArtifact, doNotInfer: true), Operation.WriteFile(cOutFileArtifact), }); pipBuilderC.AddInputDirectory(bOutDirArtifact); pipBuilderC.SetChangeAffectedInputListWrittenFile(changeAffectedWrittenFile); var pipC = SchedulePipBuilder(pipBuilderC); var inputChangesFile = CreateOutputFileArtifact(); File.WriteAllText(ArtifactToString(inputChangesFile), ArtifactToString(aInputFile)); Configuration.Schedule.InputChanges = inputChangesFile.Path; RunScheduler().AssertSuccess(); var actualAffectedInput = File.ReadAllText(changeAffectedWrittenFile.ToString(Context.PathTable)); XAssert.AreEqual(expectedAffectedInput, actualAffectedInput); }