From 34918fc2986b0322d4e60145b2d43150ed62db0e Mon Sep 17 00:00:00 2001 From: Omotola Akeredolu Date: Thu, 28 Sep 2023 12:10:11 -0700 Subject: [PATCH 1/2] pupulated disable detectors list and added unit tests --- .../BcdeModels/ScanResult.cs | 4 +- .../Services/ScanExecutionService.cs | 9 +- .../Services/BcdeScanExecutionServiceTests.cs | 128 ++++++++++++++++++ 3 files changed, 137 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs index c516665c9..75da3ec61 100644 --- a/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs +++ b/src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScanResult.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ComponentDetection.Contracts.BcdeModels; +namespace Microsoft.ComponentDetection.Contracts.BcdeModels; using System.Collections.Generic; using Newtonsoft.Json; @@ -12,6 +12,8 @@ public class ScanResult public IEnumerable DetectorsInScan { get; set; } + public IEnumerable DetectorsNotInScan { get; set; } + public Dictionary ContainerDetailsMap { get; set; } [JsonConverter(typeof(StringEnumConverter))] diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs index 1626b4d0b..e03f7c8d0 100644 --- a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs +++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs @@ -38,14 +38,17 @@ public async Task ExecuteScanAsync(ScanSettings settings) using var scope = this.logger.BeginScope("Executing BCDE scan"); var detectorRestrictions = this.GetDetectorRestrictions(settings); - var detectors = this.detectorRestrictionService.ApplyRestrictions(detectorRestrictions, this.detectors).ToImmutableList(); + var detectors = this.detectors.ToList(); + var restrictedDetectors = this.detectorRestrictionService.ApplyRestrictions(detectorRestrictions, detectors).ToImmutableList(); + detectorRestrictions.DisabledDetectors = detectors.Except(restrictedDetectors).ToList(); this.logger.LogDebug("Finished applying restrictions to detectors."); - var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, detectors, detectorRestrictions); + var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, restrictedDetectors, detectorRestrictions); var scanResult = this.graphTranslationService.GenerateScanResultFromProcessingResult(processingResult, settings); - scanResult.DetectorsInScan = detectors.Select(ConvertToContract).ToList(); + scanResult.DetectorsInScan = restrictedDetectors.Select(ConvertToContract).ToList(); + scanResult.DetectorsNotInScan = detectorRestrictions.DisabledDetectors.Select(ConvertToContract).ToList(); scanResult.ResultCode = processingResult.ResultCode; return scanResult; diff --git a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs index be2ecbb4f..8210ec8f0 100644 --- a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs +++ b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs @@ -592,6 +592,131 @@ public async Task VerifyTranslation_DetectedComponentExist_UpdateFunctionIsAppli results.ComponentsFound.Single(component => component.Component.Id == detectedComponent.Component.Id).IsDevelopmentDependency.Should().BeFalse(); } + [TestMethod] + public async Task VerifyDisabledDetectorsisPopulatedAsync() + { + var componentRecorder = new ComponentRecorder(new Mock().Object); + var singleFileComponentRecorder = componentRecorder.CreateSingleFileComponentRecorder(Path.Join(this.sourceDirectory.FullName, "/some/file/path")); + this.versionedComponentDetector1Mock.SetupGet(x => x.Id).Returns("Detector1"); + this.componentDetector2Mock.SetupGet(x => x.Id).Returns("Detector2"); + this.componentDetector3Mock.SetupGet(x => x.Id).Returns("Detector3"); + + IEnumerable registeredDetectors = new[] + { + this.componentDetector2Mock.Object, this.componentDetector3Mock.Object, + + this.versionedComponentDetector1Mock.Object, + }; + var restrictedDetectors = new[] + { + this.componentDetector2Mock.Object, this.componentDetector3Mock.Object, + }; + + var settings = new ScanSettings + { + SourceDirectory = this.sourceDirectory, + }; + var result = await this.DetectComponentsHappyPathAsync( + settings, + registeredDetectors, + restrictedDetectors, + restrictions => + { + restrictions.AllowedDetectorCategories.Should().BeNull(); + restrictions.AllowedDetectorIds.Should().BeNull(); + }, + new List { componentRecorder }); + + result.DetectorsNotInRun.Should().ContainSingle(); + result.DetectorsNotInRun.Single(x => x.DetectorId == "Detector1"); + } + + [TestMethod] + public async Task VerifyNoDisabledDetectorsisPopulatedAsync() + { + var componentRecorder = new ComponentRecorder(new Mock().Object); + var singleFileComponentRecorder = componentRecorder.CreateSingleFileComponentRecorder(Path.Join(this.sourceDirectory.FullName, "/some/file/path")); + this.versionedComponentDetector1Mock.SetupGet(x => x.Id).Returns("Detector1"); + this.componentDetector2Mock.SetupGet(x => x.Id).Returns("Detector2"); + this.componentDetector3Mock.SetupGet(x => x.Id).Returns("Detector3"); + + IEnumerable registeredDetectors = new[] + { + this.componentDetector2Mock.Object, this.componentDetector3Mock.Object, + }; + var restrictedDetectors = new[] + { + this.componentDetector2Mock.Object, this.componentDetector3Mock.Object, + }; + + var settings = new ScanSettings + { + SourceDirectory = this.sourceDirectory, + }; + var result = await this.DetectComponentsHappyPathAsync( + settings, + registeredDetectors, + restrictedDetectors, + restrictions => + { + restrictions.AllowedDetectorCategories.Should().BeNull(); + restrictions.AllowedDetectorIds.Should().BeNull(); + }, + new List { componentRecorder }); + + result.DetectorsNotInRun.Should().BeEmpty(); + } + + private async Task DetectComponentsHappyPathAsync( + ScanSettings settings, + IEnumerable registeredDetectors, + IComponentDetector[] restrictedDetectors, + Action restrictionAsserter = null, + IEnumerable componentRecorders = null) + { + this.detectorsMock.Setup(x => x.GetEnumerator()) + .Returns(registeredDetectors.GetEnumerator()); + this.detectorRestrictionServiceMock.Setup( + x => x.ApplyRestrictions( + It.IsAny(), + It.Is>(inputDetectors => registeredDetectors.Intersect(inputDetectors).Count() == registeredDetectors.Count()))) + .Returns(restrictedDetectors) + .Callback>( + (restrictions, detectors) => restrictionAsserter?.Invoke(restrictions)); + + // We initialize detected component's DetectedBy here because of a Moq constraint -- certain operations (Adding interfaces) have to happen before .Object + this.detectedComponents[0].DetectedBy = this.componentDetector2Mock.Object; + this.detectedComponents[1].DetectedBy = this.componentDetector3Mock.Object; + + var processingResult = new DetectorProcessingResult + { + ResultCode = ProcessingResultCode.Success, + ContainersDetailsMap = new Dictionary + { + { + this.sampleContainerDetails.Id, this.sampleContainerDetails + }, + }, + ComponentRecorders = componentRecorders.Select(componentRecorder => (this.componentDetector2Mock.Object, componentRecorder)), + }; + + this.detectorProcessingServiceMock.Setup(x => + x.ProcessDetectorsAsync( + settings, + It.Is>(inputDetectors => restrictedDetectors.Intersect(inputDetectors).Count() == restrictedDetectors.Length), + Match.Create(restriction => true))) + .ReturnsAsync(processingResult); + + var result = await this.serviceUnderTest.ExecuteScanAsync(settings); + result.ResultCode.Should().Be(ProcessingResultCode.Success); + result.SourceDirectory.Should().NotBeNull(); + result.SourceDirectory.Should().Be(settings.SourceDirectory.ToString()); + + var testOutput = new TestOutput((DefaultGraphScanResult)result); + + return testOutput; + } + private async Task DetectComponentsHappyPathAsync( ScanSettings settings, Action restrictionAsserter = null, @@ -722,6 +847,7 @@ public TestOutput(DefaultGraphScanResult result) this.Result = result.ResultCode; this.DetectedComponents = result.ComponentsFound; this.DetectorsInRun = result.DetectorsInScan; + this.DetectorsNotInRun = result.DetectorsNotInScan; this.DependencyGraphs = result.DependencyGraphs; this.SourceDirectory = result.SourceDirectory; } @@ -732,6 +858,8 @@ public TestOutput(DefaultGraphScanResult result) internal IEnumerable DetectorsInRun { get; set; } + internal IEnumerable DetectorsNotInRun { get; set; } + internal DependencyGraphCollection DependencyGraphs { get; set; } internal string SourceDirectory { get; set; } From a11076efdfbe57f17430bdc354bcccee5b58c183 Mon Sep 17 00:00:00 2001 From: Omotola Akeredolu Date: Thu, 28 Sep 2023 13:41:43 -0700 Subject: [PATCH 2/2] variable rename --- .../Services/ScanExecutionService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs index e03f7c8d0..94ef6f64b 100644 --- a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs +++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs @@ -39,15 +39,15 @@ public async Task ExecuteScanAsync(ScanSettings settings) var detectorRestrictions = this.GetDetectorRestrictions(settings); var detectors = this.detectors.ToList(); - var restrictedDetectors = this.detectorRestrictionService.ApplyRestrictions(detectorRestrictions, detectors).ToImmutableList(); - detectorRestrictions.DisabledDetectors = detectors.Except(restrictedDetectors).ToList(); + var detectorsWithAppliedRestrictions = this.detectorRestrictionService.ApplyRestrictions(detectorRestrictions, detectors).ToImmutableList(); + detectorRestrictions.DisabledDetectors = detectors.Except(detectorsWithAppliedRestrictions).ToList(); this.logger.LogDebug("Finished applying restrictions to detectors."); - var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, restrictedDetectors, detectorRestrictions); + var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, detectorsWithAppliedRestrictions, detectorRestrictions); var scanResult = this.graphTranslationService.GenerateScanResultFromProcessingResult(processingResult, settings); - scanResult.DetectorsInScan = restrictedDetectors.Select(ConvertToContract).ToList(); + scanResult.DetectorsInScan = detectorsWithAppliedRestrictions.Select(ConvertToContract).ToList(); scanResult.DetectorsNotInScan = detectorRestrictions.DisabledDetectors.Select(ConvertToContract).ToList(); scanResult.ResultCode = processingResult.ResultCode;