diff --git a/Snyk.Code.Library.Tests/SnykCode/AnalysisServiceTest.cs b/Snyk.Code.Library.Tests/SnykCode/AnalysisServiceTest.cs index d25b816b0..3ae202f01 100644 --- a/Snyk.Code.Library.Tests/SnykCode/AnalysisServiceTest.cs +++ b/Snyk.Code.Library.Tests/SnykCode/AnalysisServiceTest.cs @@ -37,7 +37,7 @@ public void AnalysisService_FailedStatusProvided_GetAnalysisThrowException() .Setup(codeClient => codeClient.GetAnalysisAsync(dummyBundleId, It.IsAny())) .ReturnsAsync(dummyAnalysisResultDto); - _ = Assert.ThrowsAsync(() => analysisService.GetAnalysisAsync(dummyBundleId, scanCodeProgressUpdate)); + _ = Assert.ThrowsAsync(() => analysisService.GetAnalysisAsync(dummyBundleId, this.scanCodeProgressUpdate)); codeClientMock .Verify(codeClient => codeClient.GetAnalysisAsync(dummyBundleId, It.IsAny()), Times.Exactly(1)); @@ -83,34 +83,6 @@ public async Task AnalysisService_WaitingStatusProvided_GetAnalysisSuccessInTwoA .Verify(codeClient => codeClient.GetAnalysisAsync(dummyBundleId, It.IsAny()), Times.Exactly(24)); } - [Fact] - public async Task AnalysisService_InfiniteWaitingStatusProvided_GetAnalysisReturnFailedStatusAsync() - { - var codeClientMock = new Mock(); - - var analysisService = new AnalysisService(codeClientMock.Object); - - var analysisResultsDto = new AnalysisResultsDto(); - - string dummyBundleId = "dummyId"; - - var dummyAnalysisResultDto = new AnalysisResultDto - { - Status = AnalysisStatus.Waiting, - }; - - codeClientMock - .Setup(codeClient => codeClient.GetAnalysisAsync(dummyBundleId, It.IsAny())) - .ReturnsAsync(dummyAnalysisResultDto); - - var analysisResult = await analysisService.GetAnalysisAsync(dummyBundleId, this.scanCodeProgressUpdate, requestAttempts: 5); - - Assert.NotNull(analysisResult); - Assert.Equal(AnalysisStatus.Failed, analysisResult.Status); - - codeClientMock - .Verify(codeClient => codeClient.GetAnalysisAsync(dummyBundleId, It.IsAny()), Times.Exactly(5)); - } [Fact] public async Task AnalysisService_TwoFilesWithIssuesProvided_GetAnalysisSuccessAsync() diff --git a/Snyk.Code.Library.Tests/SnykCode/SnykCodeServiceTest.cs b/Snyk.Code.Library.Tests/SnykCode/SnykCodeServiceTest.cs index c186f1306..ddc126708 100644 --- a/Snyk.Code.Library.Tests/SnykCode/SnykCodeServiceTest.cs +++ b/Snyk.Code.Library.Tests/SnykCode/SnykCodeServiceTest.cs @@ -153,7 +153,6 @@ public async Task SnykCodeService_CodeCacheAndFileChangesExists_UpdatePreviousSc .Setup(analysisService => analysisService.GetAnalysisAsync( extendedBundle.Id, It.IsAny(), - It.IsAny(), It.IsAny())) .ReturnsAsync(analysisResults); @@ -208,7 +207,7 @@ public async Task SnykCodeService_CodeCacheExists_ReturnWithoutRemoteQueryAsync( Assert.NotNull(analysisResult); this.analysisServiceMock - .Verify(analysisService => analysisService.GetAnalysisAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(0)); + .Verify(analysisService => analysisService.GetAnalysisAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(0)); this.codeCacheServiceMock .Verify(codeCacheService => codeCacheService.GetCachedAnalysisResult(), Times.Exactly(1)); @@ -285,7 +284,7 @@ public async Task SnykCodeService_TwoFilesWithIssuesProvided_ScanSuccessAsync() .ReturnsAsync(bundle); this.analysisServiceMock - .Setup(analysisService => analysisService.GetAnalysisAsync(bundleId, It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(analysisService => analysisService.GetAnalysisAsync(bundleId, It.IsAny(), It.IsAny())) .ReturnsAsync(analysisResults); this.codeCacheServiceMock @@ -315,7 +314,7 @@ public async Task SnykCodeService_TwoFilesWithIssuesProvided_ScanSuccessAsync() .Verify(bundleService => bundleService.UploadMissingFilesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(1)); this.analysisServiceMock - .Verify(analysisService => analysisService.GetAnalysisAsync(bundleId, It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(1)); + .Verify(analysisService => analysisService.GetAnalysisAsync(bundleId, It.IsAny(), It.IsAny()), Times.Exactly(1)); } [Fact] diff --git a/Snyk.Code.Library/Service/AnalysisService.cs b/Snyk.Code.Library/Service/AnalysisService.cs index bc37f1443..bc60a3b5b 100644 --- a/Snyk.Code.Library/Service/AnalysisService.cs +++ b/Snyk.Code.Library/Service/AnalysisService.cs @@ -16,9 +16,8 @@ /// public class AnalysisService : IAnalysisService { - public const int RequestAttempts = 900; - - private const int RequestTimeout = 1000; + private static readonly TimeSpan MaxScanDuration = TimeSpan.FromHours(3); + private static readonly TimeSpan WaitBetweenRequest = TimeSpan.FromSeconds(1); private static readonly ILogger Logger = LogManager.ForContext(); @@ -27,10 +26,8 @@ public class AnalysisService : IAnalysisService public AnalysisService(ISnykCodeClient codeClient) => this.codeClient = codeClient; /// - public async Task GetAnalysisAsync( - string bundleHash, + public async Task GetAnalysisAsync(string bundleHash, FireScanCodeProgressUpdate scanCodeProgressUpdate, - int requestAttempts = RequestAttempts, CancellationToken cancellationToken = default) { if (string.IsNullOrEmpty(bundleHash)) @@ -40,7 +37,7 @@ public async Task GetAnalysisAsync( cancellationToken.ThrowIfCancellationRequested(); - var analysisResultDto = await this.TryGetAnalysisDtoAsync(bundleHash, scanCodeProgressUpdate, requestAttempts, cancellationToken); + var analysisResultDto = await this.TryGetAnalysisDtoAsync(bundleHash, scanCodeProgressUpdate, cancellationToken); return this.MapDtoAnalysisResultToDomain(analysisResultDto); } @@ -49,18 +46,17 @@ public async Task GetAnalysisAsync( /// Try get analysis DTO 'RequestAttempts' attempts. /// /// Source bundle id. + /// + /// /// object. - private async Task TryGetAnalysisDtoAsync( - string bundleHash, + private async Task TryGetAnalysisDtoAsync(string bundleHash, FireScanCodeProgressUpdate scanCodeProgressUpdate, - int requestAttempts, CancellationToken cancellationToken = default) { - Logger.Debug("Try get analysis DTO object {RequestAttempts} times.", requestAttempts); - cancellationToken.ThrowIfCancellationRequested(); - for (int counter = 0; counter < requestAttempts; counter++) + var startTime = DateTime.Now; + while(DateTime.Now - startTime < MaxScanDuration) { cancellationToken.ThrowIfCancellationRequested(); @@ -83,8 +79,6 @@ private async Task TryGetAnalysisDtoAsync( }; } - Logger.Debug($"Request analysis status {analysisResultDto.Status}"); - int progress = (int)analysisResultDto.Progress * 100; scanCodeProgressUpdate(SnykCodeScanState.Analysing, progress); @@ -97,18 +91,17 @@ private async Task TryGetAnalysisDtoAsync( return analysisResultDto; case AnalysisStatus.Failed: - throw new SnykCodeException("SnykCode Analysis failed."); + throw new SnykCodeException("SnykCode Analysis failed with status code " + analysisResultDto.Status); case AnalysisStatus.Waiting: default: Logger.Information("SnykCode service return {Status} status. Sleep for 1 second timeout.", analysisResultDto.Status); - - Thread.Sleep(RequestTimeout); + await Task.Delay(WaitBetweenRequest, cancellationToken); break; } } - Logger.Warning("Can't Get analysis after {requestAttempts} attepts. Return AnalysisResultDto with Failed status.", requestAttempts); + Logger.Warning("Snyk Code scan timed out on the client side."); return new AnalysisResultDto { Status = AnalysisStatus.Failed, }; } diff --git a/Snyk.Code.Library/Service/IAnalysisService.cs b/Snyk.Code.Library/Service/IAnalysisService.cs index f10044a5a..b49ce87b4 100644 --- a/Snyk.Code.Library/Service/IAnalysisService.cs +++ b/Snyk.Code.Library/Service/IAnalysisService.cs @@ -25,13 +25,10 @@ public interface IAnalysisService /// /// Source bundle id to analysy. /// Scan code progress update delegate. - /// Request attempts. /// token to cancel request. /// Analysis results with suggestions and the relative positions. - Task GetAnalysisAsync( - string bundleId, + Task GetAnalysisAsync(string bundleId, FireScanCodeProgressUpdate scanCodeProgressUpdate, - int requestAttempts = AnalysisService.RequestAttempts, CancellationToken cancellationToken = default); } }