public async Task TestDynamicallyLoadedLibrariesReportedOnLinux() { if (!OperatingSystemHelper.IsLinuxOS) { return; } var proc = ToProcess(Operation.Echo("hi")); var info = ToProcessInfo(proc, nameof(TestDynamicallyLoadedLibrariesReportedOnLinux)); info.FileAccessManifest.ReportFileAccesses = true; info.FileAccessManifest.FailUnexpectedFileAccesses = false; using ISandboxedProcess process = await StartProcessAsync(info); var result = await process.GetResultAsync(); XAssert.AreEqual(0, result.ExitCode); var accesses = result.FileAccesses .Select(fa => fa.GetPath(Context.PathTable)) .Where(p => p.EndsWith(".so")) .Select(p => Path.GetFileName(p)) .Select(n => n.Contains('-') ? n.Substring(0, n.IndexOf('-')) + ".so" : n) .Distinct() .ToHashSet(); XAssert.Contains(accesses, new[] { "libhostfxr.so", "libhostpolicy.so", "libclrjit.so", "libcoreclr.so" }); XAssert.ContainsNot(accesses, new[] { "libDetours.so" }); }
public void RunSingleProcessWithSharedOpaqueOutputLogging() { var sharedOpaqueDir = Path.Combine(ObjectRoot, "partialDir"); var sharedOpaqueDirPath = AbsolutePath.Create(Context.PathTable, sharedOpaqueDir); var sharedOpaqueDirectoryArtifact = DirectoryArtifact.CreateWithZeroPartialSealId(sharedOpaqueDirPath); var outputInSharedOpaque = CreateOutputFileArtifact(sharedOpaqueDir); var source = CreateSourceFile(); var builder = CreatePipBuilder(new[] { Operation.WriteFile(outputInSharedOpaque, content: "sod-out", doNotInfer: true) }); builder.AddOutputDirectory(sharedOpaqueDirectoryArtifact, SealDirectoryKind.SharedOpaque); builder.Options |= Process.Options.RequiresAdmin; var pip = SchedulePipBuilder(builder); // run once and assert success var result = RunScheduler().AssertSuccess(); // check that shared opaque outputs have been logged in the sideband file var writesInSidebandFile = GetJournaledWritesForProcess(result, pip.Process); XAssert.Contains(writesInSidebandFile, outputInSharedOpaque); XAssert.ContainsNot(writesInSidebandFile, pip.ProcessOutputs.GetOutputFiles().Select(f => f.Path).ToArray()); // run again and assert cache hit RunScheduler().AssertCacheHit(pip.Process.PipId); // assert sideband files were used for scrubbing AssertInformationalEventLogged(EventId.DeletingOutputsFromSharedOpaqueSidebandFilesStarted, count: 1); AssertInformationalEventLogged(EventId.DeletingSharedOpaqueSidebandFilesStarted, count: 1); }
private static void AssertShimmedIf(string output, bool shimmedCondition) { if (shimmedCondition) { XAssert.Contains(output, ShimOutput); } else { XAssert.ContainsNot(output, ShimOutput); } }
public void IncorrectSwitchDoesNotFailLogger() { var result = RunMSBuild($"Win32ManifestFile='does/not/exist'", out string standardOutput); // The run should fail XAssert.AreNotEqual(0, result); // The reason should be because an unexpected task attribute (MSB4064), but not because of a logger failure XAssert.ContainsNot(standardOutput, "InvalidOperationException"); XAssert.Contains(standardOutput, "MSB4064"); }
public void ValidateStringMatch() { var aBuild = CreateJavaScriptProject("project-A", "build"); var aTest = CreateJavaScriptProject("project-A", "test"); var bBuild = CreateJavaScriptProject("project-B", "build"); var selector = new JavaScriptProjectSelector(new[] { aBuild, aTest, bBuild }); var result = selector.GetMatches("project-A"); XAssert.Contains(result, aBuild, aTest); XAssert.ContainsNot(result, bBuild); }
public void MaskedReportAugmentedAccessIsNotReported(bool reportFileAccesses) { var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = reportFileAccesses }; var basePath = TestBinRootPath.Combine(Context.PathTable, "foo"); var output1 = CreateOutputFileArtifact(basePath); var output2 = CreateOutputFileArtifact(basePath); // We mask reporting accesses for output1 and enable it for output2 fam.AddScope(output1.Path, ~FileAccessPolicy.ReportAccess, FileAccessPolicy.AllowAll); fam.AddScope(output2.Path, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess); var collector = new FileAccessCollector(Context.PathTable); var info = ToProcessInfo( ToProcess( Operation.AugmentedWrite(output1), Operation.AugmentedWrite(output2)), fileAccessManifest: fam, detoursListener: collector); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); // We should get a single explicit access with output2, since output1 shouldn't be reported var accessPath = result.ExplicitlyReportedFileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).ManifestPath; XAssert.AreEqual(output2.Path, accessPath); // We should get both accesses as part of the (optional) FileAccess on request if (reportFileAccesses) { var allTrustedAcceses = result.FileAccesses.Where(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).Select(rfa => rfa.ManifestPath); XAssert.Contains(allTrustedAcceses, output1.Path, output2.Path); } else { // Make sure the access related to output1 is not actually reported, and the only one the listener got is output2 XAssert.Contains(collector.FileAccessPaths, output2.Path); XAssert.ContainsNot(collector.FileAccessPaths, output1.Path); } }
public void BreakawayProcessIsNotDetoured() { // TODO: doesn't currently work on Linux if (OperatingSystemHelper.IsLinuxOS) { return; } var fam = new FileAccessManifest( Context.PathTable, childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName }) { FailUnexpectedFileAccesses = false, ReportUnexpectedFileAccesses = true, ReportFileAccesses = true }; var srcFile1 = CreateSourceFile(); var srcFile2 = CreateSourceFile(); var info = ToProcessInfo( ToProcess( Operation.ReadFile(srcFile1), Operation.Spawn( Context.PathTable, true, Operation.ReadFile(srcFile2))), fileAccessManifest: fam); var result = RunProcess(info).GetAwaiter().GetResult(); XAssert.AreEqual(0, result.ExitCode); var observedAccesses = result.FileAccesses .Select(reportedAccess => AbsolutePath.TryCreate(Context.PathTable, reportedAccess.GetPath(Context.PathTable), out AbsolutePath result) ? result : AbsolutePath.Invalid) .ToArray(); // We should see the access that happens on the main test process XAssert.Contains(observedAccesses, srcFile1.Path); // We shouldn't see the access that happens on the spawned process XAssert.ContainsNot(observedAccesses, srcFile2.Path); // Only a single process should be reported: the parent one var testProcess = ExcludeInjectedOnes(result.Processes).Single(); XAssert.AreEqual(TestProcessToolName.ToLowerInvariant(), Path.GetFileName(testProcess.Path).ToLowerInvariant()); }
public void DirectoryMembershipExistenceTest() { CacheMissData cacheMiss; DirectoryArtifact dir = DirectoryArtifact.CreateWithZeroPartialSealId(CreateUniqueDirectory(ReadonlyRoot)); Directory.CreateDirectory(ArtifactToString(dir)); Process pip = CreateAndSchedulePipBuilder(new Operation[] { Operation.EnumerateDir(dir), Operation.WriteFile(CreateOutputFileArtifact()) }).Process; Configuration.Sandbox.UnsafeSandboxConfigurationMutable.IgnorePreloadedDlls = true; FileArtifact srcFile1 = CreateSourceFile(dir); File.WriteAllText(ArtifactToString(srcFile1), "member1"); RunScheduler().AssertCacheMiss(pip.PipId); ScheduleRunResult buildA = RunScheduler().AssertCacheHit(pip.PipId); FileArtifact srcFile2 = CreateSourceFile(dir); File.WriteAllText(ArtifactToString(srcFile2), "member2"); ScheduleRunResult buildB = RunScheduler(m_testHooks).AssertCacheMiss(pip.PipId); XAssert.IsTrue(m_testHooks.FingerprintStoreTestHooks.TryGetCacheMiss(pip.PipId, out cacheMiss)); XAssert.Contains(cacheMiss.DetailAndResult.Detail.Info.ToString(), srcFile2.Path.GetName(Context.PathTable).ToString(Context.PathTable.StringTable)); Configuration.Sandbox.UnsafeSandboxConfigurationMutable.IgnorePreloadedDlls = false; ScheduleRunResult buildC = RunScheduler(m_testHooks).AssertCacheMiss(pip.PipId); XAssert.IsTrue(m_testHooks.FingerprintStoreTestHooks.TryGetCacheMiss(pip.PipId, out cacheMiss)); XAssert.Contains(cacheMiss.DetailAndResult.Detail.Info.ToString(), ObservedPathSet.Labels.UnsafeOptions); FileArtifact srcFile3 = CreateSourceFile(dir); File.WriteAllText(ArtifactToString(srcFile3), "member3"); ScheduleRunResult buildD = RunScheduler(m_testHooks).AssertCacheMiss(pip.PipId); XAssert.IsTrue(m_testHooks.FingerprintStoreTestHooks.TryGetCacheMiss(pip.PipId, out cacheMiss)); XAssert.Contains(cacheMiss.DetailAndResult.Detail.Info.ToString(), srcFile3.Path.GetName(Context.PathTable).ToString(Context.PathTable.StringTable)); XAssert.ContainsNot(cacheMiss.DetailAndResult.Detail.Info.ToString(), RepeatedStrings.MissingDirectoryMembershipFingerprint); }
public void BreakawayProcessesAreUntracked() { var outerSourceFile = CreateSourceFileWithPrefix(SourceRoot, prefix: $"{nameof(BreakawayProcessesAreUntracked)}-outer-src"); var innerSourceFile = CreateSourceFileWithPrefix(SourceRoot, prefix: $"{nameof(BreakawayProcessesAreUntracked)}-inner-src"); var outerOutputFile = CreateOutputFileArtifact(ObjectRoot, prefix: $"{nameof(BreakawayProcessesAreUntracked)}-outer-out"); var innerOutputFile = CreateOutputFileArtifact(ObjectRoot, prefix: $"{nameof(BreakawayProcessesAreUntracked)}-inner-out"); var builder = CreatePipBuilder(new Operation[] { Operation.ReadFile(outerSourceFile), Operation.WriteFile(outerOutputFile), Operation.Spawn(Context.PathTable, waitToFinish: true, Operation.WriteFile(innerOutputFile, doNotInfer: true), Operation.ReadFile(innerSourceFile, doNotInfer: true)) }); // Configure the test process itself to escape the sandbox builder.ChildProcessesToBreakawayFromSandbox = ReadOnlyArray <PathAtom> .FromWithoutCopy(new[] { PathAtom.Create(Context.StringTable, TestProcessToolName) }); var pip = SchedulePipBuilder(builder); // 1st run: success + cache miss var result = RunScheduler().AssertSuccess().AssertCacheMiss(pip.Process.PipId); // there should be a single "produced output" message and it should be for the outer output file var producedOutputLogMessage = EventListener.GetLogMessagesForEventId((int)LogEventId.PipOutputProduced).Single().ToCanonicalizedPath(); XAssert.Contains(producedOutputLogMessage, ToString(outerOutputFile).ToCanonicalizedPath()); XAssert.ContainsNot(producedOutputLogMessage, ToString(innerOutputFile).ToCanonicalizedPath()); // 2nd run (no changes): success + up to date RunScheduler().AssertSuccess().AssertCacheHit(pip.Process.PipId); // 3nd run (change inner source file): success + cache hit (because inner source is untracked) File.WriteAllText(ToString(innerSourceFile), contents: Guid.NewGuid().ToString()); RunScheduler().AssertSuccess().AssertCacheHit(pip.Process.PipId); // 4th run (change outer source file): success + cache miss File.WriteAllText(ToString(outerSourceFile), contents: Guid.NewGuid().ToString()); RunScheduler().AssertSuccess().AssertCacheMiss(pip.Process.PipId); }
public void BatchingProcessTest() { EventListener.NestedLoggerHandler += eventData => { if (eventData.EventId == (int)SharedLogEventId.CacheMissAnalysisBatchResults) { m_cacheMissAnalysisBatchList.Add(eventData.Payload.ToArray()[0].ToString()); } }; m_cacheMissAnalysisBatchList = new List <string>(); var lenUnit = 100; var string1 = new string('a', lenUnit); var string2 = new string('b', 2 * lenUnit); var string3 = new string('c', 3 * lenUnit); var string4 = new string('d', 4 * lenUnit); var string5 = new string('e', 3 * lenUnit); var string6 = new string('f', 2 * lenUnit); var string7 = new string('g', lenUnit); var results = new List <JProperty>(); JProperty result1 = new JProperty("p1", new JObject(new JProperty("Result", string1))); JProperty result2 = new JProperty("P2", new JObject(new JProperty("Result", string2))); JProperty result3 = new JProperty("P3", new JObject(new JProperty("Result", string3))); JProperty result4 = new JProperty("P4", new JObject(new JProperty("Result", string4))); JProperty result5 = new JProperty("P5", new JObject(new JProperty("Result", string5))); JProperty result6 = new JProperty("P6", new JObject(new JProperty("Result", string6))); JProperty result7 = new JProperty("P7", new JObject(new JProperty("Result", string7))); results.Add(result1); results.Add(result2); results.Add(result3); results.Add(result4); results.Add(result5); results.Add(result6); results.Add(result7); var result1Len = result1.Name.Length + result1.Value.ToString().Length; var result2Len = result2.Name.Length + result2.Value.ToString().Length; var result3Len = result3.Name.Length + result3.Value.ToString().Length; var result4Len = result4.Name.Length + result4.Value.ToString().Length; var result5Len = result5.Name.Length + result5.Value.ToString().Length; var result6Len = result6.Name.Length + result6.Value.ToString().Length; var result7Len = result7.Name.Length + result7.Value.ToString().Length; var timer = new Timer(o => { XAssert.IsTrue(false, "Process Timeout."); }, null, 10000, 10000); // 1 batch per process RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result1Len + result2Len + result3Len + result4Len + result5Len + result6Len + result7Len + 1; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 1, "Should have 1 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1, string2, string3, string4, string5, string6, string7); m_cacheMissAnalysisBatchList.Clear(); // 2 batch per process RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result1Len + result2Len + result3Len + result4Len + 1; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 2, "Should have 2 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1, string2, string3, string4); XAssert.Contains(m_cacheMissAnalysisBatchList[1], string5, string6, string7); m_cacheMissAnalysisBatchList.Clear(); // batch - single - batch in a process RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result1Len + result2Len + result3Len + 20; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 3, "Should have 3 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1, string2, string3); XAssert.Contains(m_cacheMissAnalysisBatchList[1], string4); XAssert.Contains(m_cacheMissAnalysisBatchList[2], string5, string6, string7); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[2], string4); // Make sure there no previous result in it m_cacheMissAnalysisBatchList.Clear(); // batch - single - single - single - batch in a process RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result1Len + result2Len + 1; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 5, "Should have 5 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1, string2); XAssert.Contains(m_cacheMissAnalysisBatchList[1], string3); XAssert.Contains(m_cacheMissAnalysisBatchList[2], string4.Substring(string4.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[2], string4); XAssert.Contains(m_cacheMissAnalysisBatchList[2], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[3], string5); XAssert.Contains(m_cacheMissAnalysisBatchList[4], string6, string7); m_cacheMissAnalysisBatchList.Clear(); // all single in a process RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result1Len + 1; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 7, "Should have 7 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1); XAssert.Contains(m_cacheMissAnalysisBatchList[1], string2.Substring(string2.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[1], string2); XAssert.Contains(m_cacheMissAnalysisBatchList[1], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[2], string3.Substring(string3.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[2], string3); XAssert.Contains(m_cacheMissAnalysisBatchList[2], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[3], string4.Substring(string4.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[3], string4); XAssert.Contains(m_cacheMissAnalysisBatchList[3], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[4], string5.Substring(string5.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[4], string5); XAssert.Contains(m_cacheMissAnalysisBatchList[4], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[5], string6.Substring(string6.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[5], string6); XAssert.Contains(m_cacheMissAnalysisBatchList[5], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[6], string7); m_cacheMissAnalysisBatchList.Clear(); // all single in a process, test a result's len == maxLogLen RuntimeCacheMissAnalyzer.s_numberOfBatchesLogged = 0; Configuration.Logging.AriaIndividualMessageSizeLimitBytes = result3Len; RuntimeCacheMissAnalyzer.ProcessResults(results.ToArray(), Configuration, LoggingContext); XAssert.AreEqual(m_cacheMissAnalysisBatchList.Count, 7, "Should have 7 batch logging."); XAssert.Contains(m_cacheMissAnalysisBatchList[0], string1); XAssert.Contains(m_cacheMissAnalysisBatchList[1], string2); XAssert.Contains(m_cacheMissAnalysisBatchList[2], string3.Substring(string4.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20));// Result has exact length as maxLogLen XAssert.ContainsNot(m_cacheMissAnalysisBatchList[2], string3); XAssert.Contains(m_cacheMissAnalysisBatchList[2], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[3], string4.Substring(string4.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20)); XAssert.ContainsNot(m_cacheMissAnalysisBatchList[3], string4); XAssert.Contains(m_cacheMissAnalysisBatchList[3], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[4], string5.Substring(string4.Length - Configuration.Logging.AriaIndividualMessageSizeLimitBytes / 2 + 20));// Result has exact length as maxLogLen XAssert.ContainsNot(m_cacheMissAnalysisBatchList[4], string5); XAssert.Contains(m_cacheMissAnalysisBatchList[4], "[...]"); XAssert.Contains(m_cacheMissAnalysisBatchList[5], string6); XAssert.Contains(m_cacheMissAnalysisBatchList[6], string7); m_cacheMissAnalysisBatchList.Clear(); timer.Dispose(); }