public void AllContainedDirectoriesMustBeSharedOpaques() { var sodDir1 = @"\\dummyPath\SharedOpaqueDir1"; var sourceSealDir2 = @"\\dummyPath\SourceSeal"; var root = @"\\dummyPath"; using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath1 = env.Paths.CreateAbsolutePath(sodDir1); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath1, SealDirectoryKind.SharedOpaque); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(sodPath1, out var sharedOpaqueDirectory1); var sourceSealDirectory = env.PipConstructionHelper.SealDirectoryPartial( env.Paths.CreateAbsolutePath(sourceSealDir2), new FileArtifact[0]); var result = env.PipConstructionHelper.TryComposeSharedOpaqueDirectory( env.Paths.CreateAbsolutePath(root), new[] { sharedOpaqueDirectory1.Root, sourceSealDirectory }, description: null, tags: new string[] { }, out var composedSharedOpaque); XAssert.IsFalse(result); AssertErrorEventLogged(LogEventId.ScheduleFailAddPipInvalidComposedSealDirectoryIsNotSharedOpaque); } }
public void SubdirectoryMustBeNestedWithinOriginalDirectory() { var sodDir1 = @"\\dummyPath\SharedOpaqueDir1"; var root = @"\\dummyPath"; using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath1 = env.Paths.CreateAbsolutePath(sodDir1); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath1, SealDirectoryKind.SharedOpaque); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(sodPath1, out var sharedOpaqueDirectory1); var result = env.PipConstructionHelper.TryComposeSharedOpaqueDirectory( env.Paths.CreateAbsolutePath(root), new[] { sharedOpaqueDirectory1.Root }, actionKind: SealDirectoryCompositionActionKind.NarrowDirectoryCone, contentFilter: null, description: null, tags: new string[] { }, out var composedSharedOpaque); XAssert.IsFalse(result); AssertErrorEventLogged(LogEventId.ScheduleFailAddPipInvalidComposedSealDirectoryDoesNotContainRoot); IgnoreWarnings(); } }
public void OpaqueAndSharedOpaqueShouldNotOverlap(string pod, string od) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath = env.Paths.CreateAbsolutePath(pod); AbsolutePath odPath = env.Paths.CreateAbsolutePath(od); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(odPath); pip1.AddOutputDirectory(sodPath, SealDirectoryKind.SharedOpaque); if (sodPath.IsWithin(env.PathTable, odPath)) { // If the shared opaque is in the cone of an opaque, we will discover that when adding the pip var success = env.PipConstructionHelper.TryAddProcess(pip1); Assert.False(success, "Finish should fail, since overlapping opaque and shared opaque directories is not allowed."); } else { // Otherwise, when building the graph env.PipConstructionHelper.AddProcess(pip1); AssertFailedGraphBuilding(env); } } }
public void PartialSealedDirectoriesAreAllowedUnderSharedOpaqueDirectories(string sharedOpaqueRoot, string partialSealDirectoryRoot) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { // Pip2 writes a dummy output under partialSealDirectoryRoot var partialSealDirectoryPath = env.Paths.CreateAbsolutePath(partialSealDirectoryRoot); var pip2 = CreatePipBuilderWithTag(env, "test"); pip2.AddOutputFile(partialSealDirectoryPath.Combine(env.PathTable, "dummy.txt")); var outputs2 = env.PipConstructionHelper.AddProcess(pip2); var partialSeal = env.PipConstructionHelper.SealDirectoryPartial( partialSealDirectoryPath, new [] { outputs2.GetOutputFiles().First() }); // Pip1 declares a shared opaque and a dependency on the partial seal (which is nested to the shared opaque) var sodPath = env.Paths.CreateAbsolutePath(sharedOpaqueRoot); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath, SealDirectoryKind.SharedOpaque); pip1.AddInputDirectory(partialSeal); env.PipConstructionHelper.AddProcess(pip1); AssertSuccessGraphBuilding(env); } }
public void TestFailedWritesToPartiallySealedDirectoryInsideFullySealedDirectory() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath outerPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "outer"); AbsolutePath innerPath = env.Paths.CreateAbsolutePath(outerPath, "inner"); FileArtifact partiallySealedFile = ScheduleWriteOutputFileUnderDirectory(env, innerPath, "existing"); ScheduleSealPartialDirectory(env, innerPath, partiallySealedFile); FileArtifact nextFile = ScheduleWriteOutputFileUnderDirectory(env, innerPath, "newer"); // Can't write partiallySealedFile AssertCannotScheduleRewrite(env, nextFile, partiallySealedFile); AssertErrorEventLogged(LogEventId.InvalidOutputSinceFileHasBeenPartiallySealed); // But can do the reverse (haven't sealed the sibling) FileArtifact rewrittenNextFile = ScheduleRewrite(env, partiallySealedFile, nextFile); AssertCannotScheduleSealDirectory(env, outerPath, partiallySealedFile, nextFile); AssertErrorEventLogged(LogEventId.InvalidInputSinceInputIsRewritten); ScheduleSealDirectory(env, outerPath, partiallySealedFile, rewrittenNextFile); // Now both are sealed, and no new files can be added. AssertCannotScheduleRewrite(env, partiallySealedFile, rewrittenNextFile); AssertErrorEventLogged(LogEventId.InvalidOutputSinceDirectoryHasBeenSealed); // What would be a double-write normally is now a seal-related error. AssertCannotScheduleWriteOutputFileUnderDirectory(env, innerPath, "newer"); AssertErrorEventLogged(LogEventId.InvalidOutputSinceDirectoryHasBeenSealed); AssertCannotScheduleWriteOutputFileUnderDirectory(env, innerPath, "newest"); AssertErrorEventLogged(LogEventId.InvalidOutputSinceDirectoryHasBeenSealed); } }
private ContentFingerprint CreateFingerprintForCompositeSharedOpaque( string composedSharedOpaqueRoot, string[] sharedOpaqueMembers, SealDirectoryContentFilter?contentFilter) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { var sharedOpaqueDirectoryArtifactMembers = new DirectoryArtifact[sharedOpaqueMembers.Length]; for (int i = 0; i < sharedOpaqueMembers.Length; i++) { sharedOpaqueDirectoryArtifactMembers[i] = CreateSharedOpaque(env, env.Paths.CreateAbsolutePath(sharedOpaqueMembers[i])); } var success = env.PipConstructionHelper.TryComposeSharedOpaqueDirectory( env.Paths.CreateAbsolutePath(composedSharedOpaqueRoot), sharedOpaqueDirectoryArtifactMembers, actionKind: SealDirectoryCompositionActionKind.WidenDirectoryCone, contentFilter: contentFilter, description: null, tags: new string[0], out var sharedOpaqueDirectory); XAssert.IsTrue(success); var graph = AssertSuccessGraphBuilding(env); var fingerprint = CreateFingerprintForSharedOpaque(sharedOpaqueDirectory, graph); return(fingerprint); } }
public void OpaqueAndSharedOpaqueShouldNotOverlapOnDifferentPips(string pod, string od, bool failOnFinish) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath = env.Paths.CreateAbsolutePath(pod); AbsolutePath odPath = env.Paths.CreateAbsolutePath(od); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(odPath); env.PipConstructionHelper.AddProcess(pip1); var pip2 = CreatePipBuilderWithTag(env, "test"); pip2.AddOutputDirectory(sodPath, SealDirectoryKind.SharedOpaque); if (failOnFinish) { var success = env.PipConstructionHelper.TryAddProcess(pip2); Assert.False(success, "Finish should fail, since overlapping opaque and shared opaque directories is not allowed."); } else { env.PipConstructionHelper.AddProcess(pip2); AssertFailedGraphBuilding(env); } } }
public virtual void SimpleDirectoryProduceConsume(AddDirectory addDirectory) { // Create a relationship where pip2 depends on a shared opaque directory of pip1 using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath path = env.Paths.CreateAbsolutePath(@"\\dummyPath\Dir1"); var pip1 = CreatePipBuilderWithTag(env, "test"); addDirectory(pip1, path); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(path, out var pip1OutputDirectory); var pip2 = CreatePipBuilderWithTag(env, "test"); // Pip2 is consuming the directory produced by pip1. pip2.AddInputDirectory(pip1OutputDirectory.Root); // process has to produce something, adding a dummy output. AbsolutePath dummyOut = env.Paths.CreateAbsolutePath(@"\\dummyPath\output.dll"); pip2.AddOutputFile(dummyOut); env.PipConstructionHelper.AddProcess(pip2); AssertSuccessGraphBuilding(env); } }
public void TestOutputDirectoriesCannotBeCreatedUnderANonWritableMount(AddDirectory addDirectory, string nonWritableMountRoot, string directory) { var pathTable = new PathTable(); var nonWritableMount = new Mount { Name = PathAtom.Create(pathTable.StringTable, "NonWritableRoot"), Path = AbsolutePath.Create(pathTable, nonWritableMountRoot), IsReadable = true, IsWritable = false, TrackSourceFileChanges = true, Location = default(LocationData) }; using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler(mounts: new List <IMount> { nonWritableMount }, pathTable: pathTable)) { var directoryPath = AbsolutePath.Create(pathTable, directory); var pip1 = CreatePipBuilderWithTag(env, "test"); addDirectory(pip1, directoryPath); var result = env.PipConstructionHelper.TryAddProcess(pip1); Assert.False(result, "Should fail"); } }
public void TestOpaqueDirectorySemistableHashUniqueness(AddDirectory addDirectory) { // Create a relationship where pip2 uses the output of pip1 using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath path1 = env.Paths.CreateAbsolutePath(@"\\dummyPath\Dir1"); AbsolutePath path2 = env.Paths.CreateAbsolutePath(@"\\dummyPath\Dir2"); var pip1 = CreatePipBuilderWithTag(env, "test"); addDirectory(pip1, path1); addDirectory(pip1, path2); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(path1, out var pip1OutputDir1); outputs1.TryGetOutputDirectory(path2, out var pip1OutputDir2); var pipGraph = AssertSuccessGraphBuilding(env); var pip1SemistableHash = pipGraph.PipTable.GetPipSemiStableHash(pipGraph.GetProducer(pip1OutputDir1.Root)); var od1SemistableHash = pipGraph.PipTable.GetPipSemiStableHash(pipGraph.GetSealedDirectoryNode(pip1OutputDir1.Root).ToPipId()); var od2SemistableHash = pipGraph.PipTable.GetPipSemiStableHash(pipGraph.GetSealedDirectoryNode(pip1OutputDir2.Root).ToPipId()); Assert.NotEqual(pip1SemistableHash, od1SemistableHash); Assert.NotEqual(pip1SemistableHash, od2SemistableHash); Assert.NotEqual(od1SemistableHash, od2SemistableHash); } }
private ContentFingerprint CreateFingerprintForPartialSealWithMember(string fileName) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath root = env.Paths.CreateAbsolutePath(@"\\dummyPath\Root"); FileArtifact member = FileArtifact.CreateSourceFile(root.Combine(env.PathTable, fileName)); var staticDirectory = env.PipConstructionHelper.SealDirectoryPartial( root, new[] { member }); var pipBuilder = CreatePipBuilderWithTag(env, nameof(TestPartialSealDirectoryMembersAffectFingerprints)); var outputPath = env.Paths.CreateAbsolutePath(@"\\dummyPath\out"); pipBuilder.AddOutputFile(outputPath); pipBuilder.AddInputDirectory(staticDirectory); env.PipConstructionHelper.AddProcess(pipBuilder); var graph = AssertSuccessGraphBuilding(env); var producerId = graph.TryGetProducer(FileArtifact.CreateOutputFile(outputPath)); XAssert.IsTrue(producerId.IsValid); XAssert.IsTrue(graph.TryGetPipFingerprint(producerId, out ContentFingerprint fingerprint)); return(fingerprint); } }
public void TrustedAccessesAreBlockedIfPipDependsOnSourceSeal() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { var sourceSealedDirectory = new SealDirectory( env.SourceRoot, CollectionUtilities.EmptySortedReadOnlyArray <FileArtifact, OrdinalFileArtifactComparer>(OrdinalFileArtifactComparer.Instance), outputDirectoryContents: CollectionUtilities.EmptySortedReadOnlyArray <DirectoryArtifact, OrdinalDirectoryArtifactComparer>(OrdinalDirectoryArtifactComparer.Instance), kind: SealDirectoryKind.SourceAllDirectories, provenance: env.CreatePipProvenance(StringId.Invalid), tags: ReadOnlyArray <StringId> .Empty, patterns: ReadOnlyArray <StringId> .Empty); DirectoryArtifact artifact = env.PipGraph.AddSealDirectory(sourceSealedDirectory, PipId.Invalid); Assert.True(artifact.IsValid); var pip = CreatePipBuilderWithTag(env, "test"); pip.AddInputDirectory(artifact); pip.Options |= Process.Options.TrustStaticallyDeclaredAccesses; var success = env.PipConstructionHelper.TryAddProcess(pip); Assert.False(success, "Finish should fail, a process depending on a source sealed directory is not allowed to trust declared accesses"); } }
public void TestNoExplicitInputsAreAllowedInOpaqueDirectory() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath odPath = env.Paths.CreateAbsolutePath(@"\\dummyPath\OpaqueDir1"); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(odPath, SealDirectoryKind.Opaque); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(odPath, out var pip1OutputOd); var pip2 = CreatePipBuilderWithTag(env, "test"); // Pip2 is consuming OD produced by pip1. pip2.AddInputDirectory(pip1OutputOd.Root); AbsolutePath artifactInOdPath = env.Paths.CreateAbsolutePath(@"\\dummyPath\OpaqueDir1\in1.dll"); XAssert.IsTrue(artifactInOdPath.IsWithin(env.PathTable, odPath)); // and trying to add input, defined in OD. this is not allowed. pip2.AddInputFile(artifactInOdPath); // process has to produce something, adding a dummy output. AbsolutePath dummyOut = env.Paths.CreateAbsolutePath(@"\\dummyPath\output.dll"); pip2.AddOutputFile(dummyOut); var success = env.PipConstructionHelper.TryAddProcess(pip2); Assert.False(success, "Finish should fail, since no explicit inputs are allowed in opaque directory path."); } }
public void AllContainedDirectoriesMustBeUnderACommonRoot() { var sodDir1 = @"\\dummyPath\SharedOpaqueDir1"; var sodDir2 = @"\\outOfRoot\SharedOpaqueDir2"; var root = @"\\dummyPath"; using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath1 = env.Paths.CreateAbsolutePath(sodDir1); AbsolutePath sodPath2 = env.Paths.CreateAbsolutePath(sodDir2); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath1, SealDirectoryKind.SharedOpaque); var outputs1 = env.PipConstructionHelper.AddProcess(pip1); outputs1.TryGetOutputDirectory(sodPath1, out var sharedOpaqueDirectory1); var pip2 = CreatePipBuilderWithTag(env, "test"); pip2.AddOutputDirectory(sodPath2, SealDirectoryKind.SharedOpaque); var outputs2 = env.PipConstructionHelper.AddProcess(pip2); outputs2.TryGetOutputDirectory(sodPath2, out var sharedOpaqueDirectory2); var result = env.PipConstructionHelper.TryComposeSharedOpaqueDirectory( env.Paths.CreateAbsolutePath(root), new[] { sharedOpaqueDirectory1.Root, sharedOpaqueDirectory2.Root }, description: null, tags: new string[] { }, out var composedSharedOpaque); XAssert.IsFalse(result); AssertErrorEventLogged(EventId.ScheduleFailAddPipInvalidComposedSealDirectoryNotUnderRoot); } }
public void TestSealDirectoryWithCorrectSourceContents() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.SourceRoot, "seal"); FileArtifact a = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "a")); FileArtifact b = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "subdir", "b")); ScheduleSealDirectory(env, directoryPath, a, b); } }
public void TestSealDirectoryWithCorrectOutputContents() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact a = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "a"); FileArtifact b = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, @"subdir\b"); ScheduleSealDirectory(env, directoryPath, a, b); } }
public void TestWritesToPartiallySealedDirectory() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact existing = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "existing"); ScheduleSealPartialDirectory(env, directoryPath, existing); ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "other"); } }
public void TestCallingSetDirectoryArtifactMultipleTimesWithSameDirectoryArtifactShouldBeAllowed() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { SealedDirectoryTable table = new SealedDirectoryTable(env.PathTable); AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact a = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "a")); var partialSeal = CreatePartialSeal(env, directoryPath, a); var directoryArtifact = DirectoryArtifact.CreateDirectoryArtifactForTesting(directoryPath, 1); partialSeal.SetDirectoryArtifact(directoryArtifact); partialSeal.SetDirectoryArtifact(directoryArtifact); // setting the same directory artifact multiple times should be fine } }
public void TestAllDirectoriesSourceSealDirectoryContainingOutputFile() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler(nameof(TestAllDirectoriesSourceSealDirectoryContainingOutputFile))) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "ssd"); ScheduleWriteOutputFileUnderDirectory(env, directoryPath, @"a\b\f.txt"); ScheduleSourceSealDirectory(env, directoryPath, allDirectories: true); XAssert.IsNull(env.PipGraph.Build()); AssertErrorEventLogged(LogEventId.InvalidGraphSinceSourceSealedDirectoryContainsOutputFile); } }
public void TestFailedWritesToFileInPartiallySealedDirectory() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact a = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "a"); FileArtifact b = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "b"); ScheduleSealPartialDirectory(env, directoryPath, a, b); AssertCannotScheduleRewrite(env, a, b); AssertErrorEventLogged(LogEventId.InvalidOutputSinceFileHasBeenPartiallySealed); } }
public void TestSealDirectoryFailureDueToUnrelatedFile() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.SourceRoot, "seal"); FileArtifact a = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "a")); FileArtifact elsewhere = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(env.SourceRoot, "elsewhere")); AssertCannotScheduleSealDirectory(env, directoryPath, a, elsewhere); AssertErrorEventLogged(LogEventId.InvalidSealDirectoryContentSinceNotUnderRoot); ScheduleSealDirectory(env, directoryPath, a); } }
public void TestSealDirectoryWithUnderspecifiedSourceContents() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler(nameof(TestSealDirectoryWithUnderspecifiedSourceContents))) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.SourceRoot, "seal"); FileArtifact a = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "a")); FileArtifact b = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "subdir", "b")); ScheduleConsumeSourceFile(env, directoryPath, "unspecified"); ScheduleSealDirectory(env, directoryPath, a, b); XAssert.IsNotNull(env.PipGraph.Build()); // Expect to succesfully pass } }
public void TestSealDirectoryWithUnderspecifiedRewriteContentsOutputContents() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler(nameof(TestSealDirectoryWithUnderspecifiedRewriteContentsOutputContents))) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact a1 = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "a"); FileArtifact b = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "b"); FileArtifact a2 = ScheduleRewrite(env, b, a1); ScheduleSealDirectory(env, directoryPath, a2); XAssert.IsNull(env.PipGraph.Build()); AssertErrorEventLogged(LogEventId.InvalidGraphSinceFullySealedDirectoryIncomplete); } }
public void TestFailedWritesToSealedDirectory() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact existing = ScheduleWriteOutputFileUnderDirectory(env, directoryPath, "existing"); ScheduleSealDirectory(env, directoryPath, existing); AssertCannotScheduleWriteOutputFileUnderDirectory(env, directoryPath, "existing"); AssertErrorEventLogged(LogEventId.InvalidOutputSinceDirectoryHasBeenSealed); AssertCannotScheduleWriteOutputFileUnderDirectory(env, directoryPath, "new"); AssertErrorEventLogged(LogEventId.InvalidOutputSinceDirectoryHasBeenSealed); } }
public void TestAddInitializedSealDirectoryWhilePatching() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { SealedDirectoryTable table = new SealedDirectoryTable(env.PathTable); AbsolutePath directoryPath = env.Paths.CreateAbsolutePath(env.ObjectRoot, "seal"); FileArtifact a = FileArtifact.CreateSourceFile(env.Paths.CreateAbsolutePath(directoryPath, "a")); var partialSeal = CreatePartialSeal(env, directoryPath, a); var directoryArtifact = DirectoryArtifact.CreateDirectoryArtifactForTesting(directoryPath, 1); partialSeal.SetDirectoryArtifact(directoryArtifact); table.StartPatching(); // if not in IsPatching state, 'ReserveAndAddSeal' would fail ReserveAndAddSeal(table, partialSeal); table.FinishPatching(); } }
public void TestOpaqueDirectoryCannotCoincideWithOutputFile2() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath path = env.Paths.CreateAbsolutePath(@"\\dummyPath\Dir1"); var pip2 = CreatePipBuilderWithTag(env, "test"); pip2.AddOutputDirectory(path, SealDirectoryKind.Opaque); env.PipConstructionHelper.AddProcess(pip2); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputFile(path); XAssert.IsFalse(env.PipConstructionHelper.TryAddProcess(pip1)); } }
public void SharedOpaqueDirectoriesCannotOverlapInSamePip() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath1 = env.Paths.CreateAbsolutePath(@"\\dummyPath\SharedOpaqueDir1"); AbsolutePath sodPath2 = sodPath1.Combine(env.PathTable, "SharedOpaqueDir2"); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath1, SealDirectoryKind.SharedOpaque); pip1.AddOutputDirectory(sodPath2, SealDirectoryKind.SharedOpaque); var success = env.PipConstructionHelper.TryAddProcess(pip1); Assert.False(success, "Finish should fail, since overlapping shared opaques in the same pip is not allowed."); } }
[InlineData(@"\\dummyPath\OpaqueDir1\OpaqueDir2", @"\\dummyPath\OpaqueDir1")] // nesting another way round. public void TestNoOpaqueDirectoryAreAllowedInAnotherOpaqueDirectory(string od1, string od2) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath odPath = env.Paths.CreateAbsolutePath(od1); AbsolutePath anotherOd = env.Paths.CreateAbsolutePath(od2); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(odPath, SealDirectoryKind.Opaque); pip1.AddOutputDirectory(anotherOd, SealDirectoryKind.Opaque); var success = env.PipConstructionHelper.TryAddProcess(pip1); Assert.False(success, "Finish should fail, since opaque directories nesting is not allowed."); } }
public void WarnWhenPreservedOutputsAreRewritten(bool pip1PreserveOutput, bool pip2PreserveOutput, bool inPlaceRewriteForPip2) { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath input = env.Paths.CreateAbsolutePath(@"\\dummyPath\input"); AbsolutePath output = env.Paths.CreateAbsolutePath(@"\\dummyPath\output"); var pip1 = CreatePipBuilder(env); pip1.AddInputFile(FileArtifact.CreateSourceFile(input)); pip1.AddOutputFile(output); if (pip1PreserveOutput) { pip1.Options |= Process.Options.AllowPreserveOutputs; } var outputs1 = env.PipConstructionHelper.AddProcess(pip1); var pip2 = CreatePipBuilder(env); outputs1.TryGetOutputFile(output, out var outputFile); if (inPlaceRewriteForPip2) { pip2.AddRewrittenFileInPlace(outputFile); } else { pip2.AddInputFile(FileArtifact.CreateSourceFile(input)); pip2.AddOutputFile(outputFile, FileExistence.Required); } if (pip2PreserveOutput) { pip2.Options |= Process.Options.AllowPreserveOutputs; } bool hasPreserveOutput = pip1PreserveOutput || pip2PreserveOutput; env.PipConstructionHelper.AddProcess(pip2); AssertSuccessGraphBuilding(env); if (hasPreserveOutput) { AssertVerboseEventLogged(LogEventId.RewritingPreservedOutput, count: 1); } IgnoreWarnings(); } }
public void SharedOpaqueDirectoriesCanOverlapInSamePip() { using (TestEnv env = TestEnv.CreateTestEnvWithPausedScheduler()) { AbsolutePath sodPath1 = env.Paths.CreateAbsolutePath(@"\\dummyPath\SharedOpaqueDir1"); AbsolutePath sodPath2 = sodPath1.Combine(env.PathTable, "SharedOpaqueDir2"); var pip1 = CreatePipBuilderWithTag(env, "test"); pip1.AddOutputDirectory(sodPath1, SealDirectoryKind.SharedOpaque); pip1.AddOutputDirectory(sodPath2, SealDirectoryKind.SharedOpaque); var success = env.PipConstructionHelper.TryAddProcess(pip1); Assert.True(success, "TryAddProcess should succeed, since the nested shared opaques are allowed."); AssertSuccessGraphBuilding(env); } }