using System; using Xunit; using System.Diagnostics.Metrics; using System.IO; using System.Linq; using StellaOps.Scanner.Analyzers.Lang.Go; using StellaOps.Scanner.Analyzers.Lang.Tests.Harness; using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities; namespace StellaOps.Scanner.Analyzers.Lang.Go.Tests; public sealed class GoLanguageAnalyzerTests { [Fact] public async Task BuildInfoFixtureProducesDeterministicOutputAsync() { var cancellationToken = TestContext.Current.CancellationToken; var fixturePath = TestPaths.ResolveFixture("lang", "go", "basic"); var goldenPath = Path.Combine(fixturePath, "expected.json"); var analyzers = new ILanguageAnalyzer[] { new GoLanguageAnalyzer(), }; await LanguageAnalyzerTestHarness.AssertDeterministicAsync( fixturePath, goldenPath, analyzers, cancellationToken); } [Fact] public async Task DwarfOnlyFixtureFallsBackToMetadataAsync() { var cancellationToken = TestContext.Current.CancellationToken; var fixturePath = TestPaths.ResolveFixture("lang", "go", "dwarf-only"); var goldenPath = Path.Combine(fixturePath, "expected.json"); var analyzers = new ILanguageAnalyzer[] { new GoLanguageAnalyzer(), }; await LanguageAnalyzerTestHarness.AssertDeterministicAsync( fixturePath, goldenPath, analyzers, cancellationToken); } [Fact] public async Task StrippedBinaryFallsBackToHeuristicBinHashAsync() { var cancellationToken = TestContext.Current.CancellationToken; var fixturePath = TestPaths.ResolveFixture("lang", "go", "stripped"); var goldenPath = Path.Combine(fixturePath, "expected.json"); var analyzers = new ILanguageAnalyzer[] { new GoLanguageAnalyzer(), }; await LanguageAnalyzerTestHarness.AssertDeterministicAsync( fixturePath, goldenPath, analyzers, cancellationToken); } [Fact] public async Task ParallelRunsRemainDeterministicAsync() { var cancellationToken = TestContext.Current.CancellationToken; var fixturePath = TestPaths.ResolveFixture("lang", "go", "basic"); var goldenPath = Path.Combine(fixturePath, "expected.json"); var analyzers = new ILanguageAnalyzer[] { new GoLanguageAnalyzer(), }; var tasks = Enumerable .Range(0, Environment.ProcessorCount) .Select(_ => LanguageAnalyzerTestHarness.AssertDeterministicAsync( fixturePath, goldenPath, analyzers, cancellationToken)); await Task.WhenAll(tasks); } [Fact] public async Task HeuristicMetricCounterIncrementsAsync() { var cancellationToken = TestContext.Current.CancellationToken; var fixturePath = TestPaths.ResolveFixture("lang", "go", "stripped"); var analyzers = new ILanguageAnalyzer[] { new GoLanguageAnalyzer(), }; var total = 0L; using var listener = new MeterListener { InstrumentPublished = (instrument, meterListener) => { if (instrument.Meter.Name == "StellaOps.Scanner.Analyzers.Lang.Go" && instrument.Name == "scanner_analyzer_golang_heuristic_total") { meterListener.EnableMeasurementEvents(instrument); } } }; listener.SetMeasurementEventCallback((_, measurement, _, _) => { Interlocked.Add(ref total, measurement); }); listener.Start(); await LanguageAnalyzerTestHarness.RunToJsonAsync( fixturePath, analyzers, cancellationToken: cancellationToken); listener.Dispose(); Assert.Equal(1, Interlocked.Read(ref total)); } }