Exemple #1
0
        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);
        }
Exemple #3
0
 private static void AssertShimmedIf(string output, bool shimmedCondition)
 {
     if (shimmedCondition)
     {
         XAssert.Contains(output, ShimOutput);
     }
     else
     {
         XAssert.ContainsNot(output, ShimOutput);
     }
 }
Exemple #4
0
        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");
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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());
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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();
        }