public void AbsentProbeOnOutputFileIsBlocked() { var sharedOpaqueDirPath = AbsolutePath.Create(Context.PathTable, SharedOpaqueDirectoryRoot); FileArtifact source = CreateSourceFile(sharedOpaqueDirPath); // Create a pip that creates and deletes the source file under a shared opaque var sharedOpaqueDirArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(sharedOpaqueDirPath); var deletePipBuilder = CreatePipBuilder(new[] { Operation.WriteFile(source.CreateNextWrittenVersion(), doNotInfer: true), Operation.DeleteFile(source.CreateNextWrittenVersion(), doNotInfer: true), Operation.WriteFile(CreateOutputFileArtifact()) // dummy output }); deletePipBuilder.AddOutputDirectory(sharedOpaqueDirArtifact, SealDirectoryKind.SharedOpaque); var deletePip = SchedulePipBuilder(deletePipBuilder); // Creates a pip that probes the (deleted) source file (undeclared). // Make the reader depend on the dummy output of the writer to ensure read happens after write ScheduleProcessWithUndeclaredReads(source, fileDependencies: deletePip.ProcessOutputs.GetOutputFiles(), probeInsteadOfRead: true); RunScheduler().AssertFailure(); AssertErrorEventLogged(LogEventId.DependencyViolationWriteInUndeclaredSourceRead); }
public void ReadViolationsAreDetectedEvenWhenRunningFromCache() { // Read a file and cache the pip FileArtifact source = CreateSourceFile(); var readPip = ScheduleProcessWithUndeclaredReads(source); RunScheduler().AssertSuccess().AssertCacheMiss(readPip.Process.PipId); ResetPipGraphBuilder(); // Schedule the same read. It should run from the cache readPip = ScheduleProcessWithUndeclaredReads(source); // Also schedule a write into the same source file var writePipBuilder = CreatePipBuilder(new[] { Operation.WriteFile(source.CreateNextWrittenVersion()) }); writePipBuilder.AddInputFile(readPip.ProcessOutputs.GetOutputFiles().First()); SchedulePipBuilder(writePipBuilder); // We should get the violation anyway RunScheduler().AssertFailure(); AssertErrorEventLogged(LogEventId.DependencyViolationWriteInUndeclaredSourceRead); }
public void SourceOrOutput() { var pathTable = new PathTable(); FileArtifact fa1 = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, A("C", "AAA", "CCC"))); XAssert.IsTrue(fa1.IsSourceFile); XAssert.IsFalse(fa1.IsOutputFile); FileArtifact fa2 = fa1.CreateNextWrittenVersion(); XAssert.IsFalse(fa2.IsSourceFile); XAssert.IsTrue(fa2.IsOutputFile); }
/// <summary> /// Schedules a pip to produce a file at the specified path under the given output directory. /// </summary> private static bool TryScheduleRewrite( TestEnv env, FileArtifact source, FileArtifact target, out FileArtifact written) { Contract.Requires(env != null); Contract.Requires(source.IsValid); Contract.Requires(target.IsValid); written = target.CreateNextWrittenVersion(); var pip = new CopyFile( source, written, ReadOnlyArray <StringId> .Empty, env.CreatePipProvenance(StringId.Invalid)); return(env.PipGraph.AddCopyFile(pip, PipId.Invalid)); }
public void NonExistentAllowedSourceReadIsASafeRewrite() { string sharedOpaqueDir = Path.Combine(ObjectRoot, "sod"); AbsolutePath sharedOpaqueDirPath = AbsolutePath.Create(Context.PathTable, sharedOpaqueDir); FileArtifact source = FileArtifact.CreateSourceFile(sharedOpaqueDirPath.Combine(Context.PathTable, "source.txt")); // A reader before the writer. The reader tries to read a non-existent file, which gets classified as an undeclared source read var reader = CreatePipBuilder(new Operation[] { Operation.ReadFile(source, doNotInfer: true), // non-existent file Operation.WriteFile(CreateOutputFileArtifact()) // dummy output }); reader.Options |= Process.Options.AllowUndeclaredSourceReads; reader.RewritePolicy = RewritePolicy.SafeSourceRewritesAreAllowed; var beforeReader = SchedulePipBuilder(reader); // The writer writes and delete the file var sourceAsOutput = source.CreateNextWrittenVersion(); var writerBuilder = CreatePipBuilder(new Operation[] { Operation.WriteFile(sourceAsOutput, doNotInfer: true), Operation.DeleteFile(sourceAsOutput, doNotInfer: true), }); writerBuilder.Options |= Process.Options.AllowUndeclaredSourceReads; writerBuilder.RewritePolicy = RewritePolicy.SafeSourceRewritesAreAllowed; writerBuilder.AddOutputDirectory(sharedOpaqueDirPath, kind: SealDirectoryKind.SharedOpaque); writerBuilder.AddInputFile(beforeReader.ProcessOutputs.GetOutputFiles().Single()); var writer = SchedulePipBuilder(writerBuilder); // An unordered reader var unorderedReader = SchedulePipBuilder(CreateReader(source)); // Run should succeed. All readers are guaranteed to see the same content across the build. // Make sure the unordered reader runs after the writer just to avoid write locks. RunScheduler(constraintExecutionOrder: new[] { ((Pip)writer.Process, (Pip)unorderedReader.Process) }).AssertSuccess();
public void FileArtifactEquality() { var pathTable = new PathTable(); FileArtifact file1 = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, A("t", "file1.txt"))); FileArtifact file2 = FileArtifact.CreateSourceFile(AbsolutePath.Create(pathTable, A("t", "file2.txt"))); StructTester.TestEquality( baseValue: FileArtifactWithAttributes.Create(file1, FileExistence.Required), equalValue: FileArtifactWithAttributes.Create(file1, FileExistence.Required), notEqualValues: new[] { FileArtifactWithAttributes.Create(file1, FileExistence.Optional), FileArtifactWithAttributes.Create(file1, FileExistence.Optional).CreateNextWrittenVersion(), FileArtifactWithAttributes.Create(file2, FileExistence.Temporary), FileArtifactWithAttributes.Create(file2, FileExistence.Temporary).CreateNextWrittenVersion(), FileArtifactWithAttributes.Create(file1, FileExistence.Required).CreateNextWrittenVersion(), FileArtifactWithAttributes.Create(file1, FileExistence.Required).CreateNextWrittenVersion().CreateNextWrittenVersion(), FileArtifactWithAttributes.Create(file1.CreateNextWrittenVersion(), FileExistence.Required) }, eq: (left, right) => left == right, neq: (left, right) => left != right, skipHashCodeForNotEqualValues: true); }