Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Commit f9f855d

Browse files
authored
Skipping test packages for scan and sign (#451)
* Skipping test pacakges for scan and sign * Skipping flaky test
1 parent 4472edc commit f9f855d

5 files changed

Lines changed: 204 additions & 2 deletions

File tree

src/NuGet.Services.Validation.Orchestrator/PackageSigning/ScanAndSign/ScanAndSignConfiguration.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using NuGet.Jobs.Configuration;
6+
using NuGet.Services.Validation.Vcs;
67

78
namespace NuGet.Services.Validation.Orchestrator.PackageSigning.ScanAndSign
89
{
@@ -17,5 +18,10 @@ public class ScanAndSignConfiguration
1718
/// The visibility delay to apply to Service Bus messages requesting a new validation.
1819
/// </summary>
1920
public TimeSpan? MessageDelay { get; set; }
21+
22+
/// <summary>
23+
/// The criteria used to determine if a package should be submitted scanning.
24+
/// </summary>
25+
public PackageCriteria PackageCriteria { get; set; } = new PackageCriteria();
2026
}
2127
}

src/NuGet.Services.Validation.Orchestrator/PackageSigning/ScanAndSign/ScanAndSignProcessor.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
using System;
55
using System.Threading.Tasks;
66
using Microsoft.Extensions.Logging;
7+
using Microsoft.Extensions.Options;
78
using NuGet.Jobs.Validation;
89
using NuGet.Jobs.Validation.PackageSigning.Storage;
10+
using NuGet.Services.Validation.Vcs;
11+
using NuGetGallery;
912

1013
namespace NuGet.Services.Validation.Orchestrator.PackageSigning.ScanAndSign
1114
{
@@ -14,15 +17,32 @@ public class ScanAndSignProcessor : IProcessor
1417
{
1518
private readonly IValidatorStateService _validatorStateService;
1619
private readonly IScanAndSignEnqueuer _scanAndSignEnqueuer;
20+
private readonly ICorePackageService _packageService;
21+
private readonly IPackageCriteriaEvaluator _criteriaEvaluator;
22+
private readonly ScanAndSignConfiguration _configuration;
1723
private readonly ILogger<ScanAndSignProcessor> _logger;
1824

1925
public ScanAndSignProcessor(
2026
IValidatorStateService validatorStateService,
2127
IScanAndSignEnqueuer scanAndSignEnqueuer,
28+
ICorePackageService packageService,
29+
IPackageCriteriaEvaluator criteriaEvaluator,
30+
IOptionsSnapshot<ScanAndSignConfiguration> configurationAccessor,
2231
ILogger<ScanAndSignProcessor> logger)
2332
{
2433
_validatorStateService = validatorStateService ?? throw new ArgumentNullException(nameof(validatorStateService));
2534
_scanAndSignEnqueuer = scanAndSignEnqueuer ?? throw new ArgumentNullException(nameof(scanAndSignEnqueuer));
35+
_packageService = packageService ?? throw new ArgumentNullException(nameof(packageService));
36+
_criteriaEvaluator = criteriaEvaluator ?? throw new ArgumentNullException(nameof(criteriaEvaluator));
37+
if (configurationAccessor == null)
38+
{
39+
throw new ArgumentNullException(nameof(configurationAccessor));
40+
}
41+
if (configurationAccessor.Value == null)
42+
{
43+
throw new ArgumentException($"{nameof(configurationAccessor.Value)} property is null", nameof(configurationAccessor));
44+
}
45+
_configuration = configurationAccessor.Value;
2646
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
2747
}
2848

@@ -44,6 +64,11 @@ public async Task<IValidationResult> GetResultAsync(IValidationRequest request)
4464
throw new ArgumentNullException(nameof(request));
4565
}
4666

67+
if (ShouldSkip(request))
68+
{
69+
return ValidationResult.Succeeded;
70+
}
71+
4772
var validatorStatus = await _validatorStateService.GetStatusAsync(request);
4873

4974
return validatorStatus.ToValidationResult();
@@ -56,6 +81,13 @@ public async Task<IValidationResult> StartAsync(IValidationRequest request)
5681
throw new ArgumentNullException(nameof(request));
5782
}
5883

84+
// We probably should only try to skip if operation is scan only,
85+
// but currently that's the only implemented option.
86+
if (ShouldSkip(request))
87+
{
88+
return ValidationResult.Succeeded;
89+
}
90+
5991
var validatorStatus = await _validatorStateService.GetStatusAsync(request);
6092

6193
if (validatorStatus.State != ValidationStatus.NotStarted)
@@ -70,12 +102,37 @@ public async Task<IValidationResult> StartAsync(IValidationRequest request)
70102
}
71103

72104
// here we need to determine whether we do scan only or scan and repo sign.
73-
// Right now we only support scan only
105+
// Right now we only support scan only.
74106

75107
await _scanAndSignEnqueuer.EnqueueScanAsync(request);
76108
var result = await _validatorStateService.TryAddValidatorStatusAsync(request, validatorStatus, ValidationStatus.Incomplete);
77109

78110
return result.ToValidationResult();
79111
}
112+
113+
private bool ShouldSkip(IValidationRequest request)
114+
{
115+
var package = _packageService.FindPackageByIdAndVersionStrict(
116+
request.PackageId,
117+
request.PackageVersion);
118+
119+
return ShouldSkip(request, package);
120+
}
121+
122+
private bool ShouldSkip(IValidationRequest request, Package package)
123+
{
124+
if (!_criteriaEvaluator.IsMatch(_configuration.PackageCriteria, package))
125+
{
126+
_logger.LogInformation(
127+
"The scan for {validationId} ({packageId} {packageVersion}) was skipped due to package criteria configuration.",
128+
request.ValidationId,
129+
request.PackageId,
130+
request.PackageVersion);
131+
132+
return true;
133+
}
134+
135+
return false;
136+
}
80137
}
81138
}

src/NuGet.Services.Validation.Orchestrator/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@
7272
"TopicPath": "",
7373
"SubscriptionName": ""
7474
},
75+
"PackageCriteria": {
76+
"ExcludeOwners": [
77+
"NugetTestAccount"
78+
],
79+
"IncludeIdPatterns": [
80+
"E2E.SemVer1Stable.*"
81+
]
82+
},
7583
"MessageDelay": "00:00:05"
7684
},
7785
"RunnerConfiguration": {

tests/Validation.PackageSigning.ProcessSignature.Tests/SignatureValidatorIntegrationTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ public async Task StripsRepositorySignatureWithUnallowedRepositoryUrl()
614614
Assert.NotNull(result.NupkgUri);
615615
}
616616

617-
[Fact]
617+
[Fact(Skip = "Appears to be flaky")]
618618
public async Task StripsRepositorySignatureWithUntrustedSigningCertificate()
619619
{
620620
// Arrange

tests/Validation.PackageSigning.ScanAndSign.Tests/ScanAndSignProcessorFacts.cs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
using System.Collections.Generic;
66
using System.Threading.Tasks;
77
using Microsoft.Extensions.Logging;
8+
using Microsoft.Extensions.Options;
89
using Moq;
910
using NuGet.Jobs.Validation.PackageSigning.Storage;
1011
using NuGet.Services.Validation;
1112
using NuGet.Services.Validation.Orchestrator;
1213
using NuGet.Services.Validation.Orchestrator.PackageSigning.ScanAndSign;
14+
using NuGet.Services.Validation.Vcs;
15+
using NuGetGallery;
1316
using Xunit;
1417

1518
namespace Validation.PackageSigning.ScanAndSign.Tests
@@ -22,6 +25,9 @@ public void ThrowsWhenValidatorStateServiceIsNull()
2225
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
2326
null,
2427
_enqueuerMock.Object,
28+
_packageServiceMock.Object,
29+
_criteriaEvaluatorMock.Object,
30+
_configurationAccessorMock.Object,
2531
_loggerMock.Object));
2632

2733
Assert.Equal("validatorStateService", ex.ParamName);
@@ -33,6 +39,9 @@ public void ThrowsWhenScanAndSignEnqueuerIsNull()
3339
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
3440
_validatorStateServiceMock.Object,
3541
null,
42+
_packageServiceMock.Object,
43+
_criteriaEvaluatorMock.Object,
44+
_configurationAccessorMock.Object,
3645
_loggerMock.Object));
3746

3847
Assert.Equal("scanAndSignEnqueuer", ex.ParamName);
@@ -44,10 +53,73 @@ public void ThrowsWhenLoggerIsNull()
4453
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
4554
_validatorStateServiceMock.Object,
4655
_enqueuerMock.Object,
56+
_packageServiceMock.Object,
57+
_criteriaEvaluatorMock.Object,
58+
_configurationAccessorMock.Object,
4759
null));
4860

4961
Assert.Equal("logger", ex.ParamName);
5062
}
63+
64+
[Fact]
65+
public void ThrowsWhenPackageServiceIsNull()
66+
{
67+
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
68+
_validatorStateServiceMock.Object,
69+
_enqueuerMock.Object,
70+
null,
71+
_criteriaEvaluatorMock.Object,
72+
_configurationAccessorMock.Object,
73+
_loggerMock.Object));
74+
75+
Assert.Equal("packageService", ex.ParamName);
76+
}
77+
78+
[Fact]
79+
public void ThrowsWhenCriteriaEvaluatorIsNull()
80+
{
81+
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
82+
_validatorStateServiceMock.Object,
83+
_enqueuerMock.Object,
84+
_packageServiceMock.Object,
85+
null,
86+
_configurationAccessorMock.Object,
87+
_loggerMock.Object));
88+
89+
Assert.Equal("criteriaEvaluator", ex.ParamName);
90+
}
91+
92+
[Fact]
93+
public void ThrowsWhenConfigurationAccessorIsNull()
94+
{
95+
var ex = Assert.Throws<ArgumentNullException>(() => new ScanAndSignProcessor(
96+
_validatorStateServiceMock.Object,
97+
_enqueuerMock.Object,
98+
_packageServiceMock.Object,
99+
_criteriaEvaluatorMock.Object,
100+
null,
101+
_loggerMock.Object));
102+
103+
Assert.Equal("configurationAccessor", ex.ParamName);
104+
}
105+
106+
[Fact]
107+
public void ThrowsWhenConfigurationIsNull()
108+
{
109+
_configurationAccessorMock
110+
.SetupGet(ca => ca.Value)
111+
.Returns((ScanAndSignConfiguration)null);
112+
113+
var ex = Assert.Throws<ArgumentException>(() => new ScanAndSignProcessor(
114+
_validatorStateServiceMock.Object,
115+
_enqueuerMock.Object,
116+
_packageServiceMock.Object,
117+
_criteriaEvaluatorMock.Object,
118+
_configurationAccessorMock.Object,
119+
_loggerMock.Object));
120+
121+
Assert.Equal("configurationAccessor", ex.ParamName);
122+
}
51123
}
52124

53125
public class TheCleanUpAsyncMethod : ScanAndSignProcessorFactsBase
@@ -96,6 +168,24 @@ public async Task ForwardsCallToValidatorStateService()
96168
Assert.Equal(status.State, result.Status);
97169
Assert.Equal(status.NupkgUrl, result.NupkgUrl);
98170
}
171+
172+
[Fact]
173+
public async Task SkipsCheckWhenPackageFitsCriteria()
174+
{
175+
var request = new ValidationRequest(Guid.NewGuid(), 42, "somepackage", "somversion", "https://example.com/package.nupkg");
176+
_criteriaEvaluatorMock
177+
.Setup(ce => ce.IsMatch(It.IsAny<IPackageCriteria>(), It.IsAny<Package>()))
178+
.Returns(false);
179+
180+
var result = await _target.GetResultAsync(request);
181+
182+
Assert.Equal(ValidationStatus.Succeeded, result.Status);
183+
184+
_validatorStateServiceMock
185+
.Verify(vss => vss.GetStatusAsync(It.IsAny<ValidationRequest>()), Times.Never);
186+
_validatorStateServiceMock
187+
.Verify(vss => vss.GetStatusAsync(It.IsAny<Guid>()), Times.Never);
188+
}
99189
}
100190

101191
public class TheStartAsyncMethod : ScanAndSignProcessorFactsBase
@@ -148,6 +238,27 @@ public async Task EnqueuesNewOperations()
148238
.Verify(vss => vss.TryAddValidatorStatusAsync(It.IsAny<IValidationRequest>(), It.IsAny<ValidatorStatus>(), It.IsAny<ValidationStatus>()), Times.Once);
149239
}
150240

241+
[Fact]
242+
public async Task SkipsCheckWhenPackageFitsCriteria()
243+
{
244+
_criteriaEvaluatorMock
245+
.Setup(ce => ce.IsMatch(It.IsAny<IPackageCriteria>(), It.IsAny<Package>()))
246+
.Returns(false);
247+
248+
var result = await _target.StartAsync(_request);
249+
250+
Assert.Equal(ValidationStatus.Succeeded, result.Status);
251+
252+
_validatorStateServiceMock
253+
.Verify(vss => vss.GetStatusAsync(It.IsAny<ValidationRequest>()), Times.Never);
254+
_validatorStateServiceMock
255+
.Verify(vss => vss.GetStatusAsync(It.IsAny<Guid>()), Times.Never);
256+
_enqueuerMock
257+
.Verify(e => e.EnqueueScanAsync(It.IsAny<IValidationRequest>()), Times.Never);
258+
_validatorStateServiceMock
259+
.Verify(vss => vss.TryAddValidatorStatusAsync(It.IsAny<IValidationRequest>(), It.IsAny<ValidatorStatus>(), It.IsAny<ValidationStatus>()), Times.Never);
260+
}
261+
151262
private ValidationRequest _request;
152263
private ValidatorStatus _status;
153264

@@ -174,18 +285,38 @@ public class ScanAndSignProcessorFactsBase
174285
{
175286
protected Mock<IValidatorStateService> _validatorStateServiceMock;
176287
protected Mock<IScanAndSignEnqueuer> _enqueuerMock;
288+
protected Mock<ICorePackageService> _packageServiceMock;
289+
protected Mock<IPackageCriteriaEvaluator> _criteriaEvaluatorMock;
290+
protected Mock<IOptionsSnapshot<ScanAndSignConfiguration>> _configurationAccessorMock;
177291
protected Mock<ILogger<ScanAndSignProcessor>> _loggerMock;
178292
protected ScanAndSignProcessor _target;
293+
protected ScanAndSignConfiguration _configuration;
179294

180295
public ScanAndSignProcessorFactsBase()
181296
{
182297
_validatorStateServiceMock = new Mock<IValidatorStateService>();
183298
_enqueuerMock = new Mock<IScanAndSignEnqueuer>();
299+
_packageServiceMock = new Mock<ICorePackageService>();
300+
_criteriaEvaluatorMock = new Mock<IPackageCriteriaEvaluator>();
301+
_configurationAccessorMock = new Mock<IOptionsSnapshot<ScanAndSignConfiguration>>();
184302
_loggerMock = new Mock<ILogger<ScanAndSignProcessor>>();
185303

304+
_configuration = new ScanAndSignConfiguration();
305+
306+
_configurationAccessorMock
307+
.SetupGet(ca => ca.Value)
308+
.Returns(_configuration);
309+
310+
_criteriaEvaluatorMock
311+
.Setup(ce => ce.IsMatch(It.IsAny<IPackageCriteria>(), It.IsAny<Package>()))
312+
.Returns(true);
313+
186314
_target = new ScanAndSignProcessor(
187315
_validatorStateServiceMock.Object,
188316
_enqueuerMock.Object,
317+
_packageServiceMock.Object,
318+
_criteriaEvaluatorMock.Object,
319+
_configurationAccessorMock.Object,
189320
_loggerMock.Object);
190321
}
191322
}

0 commit comments

Comments
 (0)