Skip to content

Commit

Permalink
Add env var that allows customers to skip pip report (#1166)
Browse files Browse the repository at this point in the history
* add env var to skip pip report

* fixed log messages
  • Loading branch information
pauld-msft authored Jun 10, 2024
1 parent 5e496e3 commit e8c72a1
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Microsoft.ComponentDetection.Common.Telemetry.Records;

public class PipReportSkipTelemetryRecord : BaseDetectionTelemetryRecord
{
public override string RecordName => "PipReportSkip";

public string SkipReason { get; set; }

public string DetectorId { get; set; }

public int DetectorVersion { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace Microsoft.ComponentDetection.Detectors.Pip;

public class PipReportComponentDetector : FileComponentDetector, IExperimentalDetector
{
private const string DisablePipReportScanEnvVar = "DisablePipReportScan";

/// <summary>
/// The maximum version of the report specification that this detector can handle.
/// </summary>
Expand All @@ -26,16 +28,19 @@ public class PipReportComponentDetector : FileComponentDetector, IExperimentalDe
private static readonly Version MinimumPipVersion = new(22, 2, 0);

private readonly IPipCommandService pipCommandService;
private readonly IEnvironmentVariableService envVarService;

public PipReportComponentDetector(
IComponentStreamEnumerableFactory componentStreamEnumerableFactory,
IObservableDirectoryWalkerFactory walkerFactory,
IPipCommandService pipCommandService,
IEnvironmentVariableService envVarService,
ILogger<PipReportComponentDetector> logger)
{
this.ComponentStreamEnumerableFactory = componentStreamEnumerableFactory;
this.Scanner = walkerFactory;
this.pipCommandService = pipCommandService;
this.envVarService = envVarService;
this.Logger = logger;
}

Expand All @@ -47,7 +52,7 @@ public PipReportComponentDetector(

public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.Pip };

public override int Version { get; } = 1;
public override int Version { get; } = 2;

protected override async Task<IObservable<ProcessRequest>> OnPrepareDetectionAsync(IObservable<ProcessRequest> processRequests, IDictionary<string, string> detectorArgs)
{
Expand Down Expand Up @@ -81,6 +86,19 @@ protected override async Task OnFileFoundAsync(ProcessRequest processRequest, ID
FileInfo reportFile = null;
try
{
if (this.IsPipReportManuallyDisabled())
{
this.Logger.LogWarning("PipReport: Found {DisablePipReportScanEnvVar} environment variable equal to true. Skipping pip report.", DisablePipReportScanEnvVar);
using var skipReportRecord = new PipReportSkipTelemetryRecord
{
SkipReason = $"PipReport: Found {DisablePipReportScanEnvVar} environment variable equal to true. Skipping pip report.",
DetectorId = this.Id,
DetectorVersion = this.Version,
};

return;
}

var stopwatch = Stopwatch.StartNew();
this.Logger.LogInformation("PipReport: Generating pip installation report for {File}", file.Location);

Expand Down Expand Up @@ -259,4 +277,7 @@ private void RecordComponents(
}
}
}

private bool IsPipReportManuallyDisabled()
=> this.envVarService.IsEnvironmentVariableValueTrue(DisablePipReportScanEnvVar);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
public class PipReportComponentDetectorTests : BaseDetectorTest<PipReportComponentDetector>
{
private readonly Mock<IPipCommandService> pipCommandService;
private readonly Mock<IEnvironmentVariableService> mockEnvVarService;
private readonly Mock<ILogger<PipReportComponentDetector>> mockLogger;

private readonly PipInstallationReport singlePackageReport;
Expand All @@ -36,6 +37,9 @@ public PipReportComponentDetectorTests()
this.mockLogger = new Mock<ILogger<PipReportComponentDetector>>();
this.DetectorTestUtility.AddServiceMock(this.mockLogger);

this.mockEnvVarService = new Mock<IEnvironmentVariableService>();
this.DetectorTestUtility.AddServiceMock(this.mockEnvVarService);

this.pipCommandService.Setup(x => x.PipExistsAsync(It.IsAny<string>())).ReturnsAsync(true);
this.pipCommandService.Setup(x => x.GetPipVersionAsync(It.IsAny<string>()))
.ReturnsAsync(new Version(23, 0, 0));
Expand Down Expand Up @@ -234,6 +238,31 @@ public async Task TestPipReportDetector_SimpleExtrasAsync()
requestsComponent.Version.Should().Be("2.32.3");
}

[TestMethod]
public async Task TestPipReportDetector_SkipAsync()
{
this.mockEnvVarService.Setup(x => x.IsEnvironmentVariableValueTrue("DisablePipReportScan")).Returns(true);

this.pipCommandService.Setup(x => x.GenerateInstallationReportAsync(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync((this.simpleExtrasReport, null));

var (result, componentRecorder) = await this.DetectorTestUtility
.WithFile("requirements.txt", string.Empty)
.ExecuteDetectorAsync();

result.ResultCode.Should().Be(ProcessingResultCode.Success);

this.mockLogger.Verify(x => x.Log(
LogLevel.Warning,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => o.ToString().StartsWith("PipReport: Found DisablePipReportScan environment variable equal to true")),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()));

var detectedComponents = componentRecorder.GetDetectedComponents();
detectedComponents.Should().BeEmpty();
}

[TestMethod]
public async Task TestPipReportDetector_MultiComponentAsync()
{
Expand Down

0 comments on commit e8c72a1

Please sign in to comment.