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

Commit 53187a3

Browse files
committed
Don't create validation records for validators with ShouldStart = false (#611)
Address NuGet/NuGetGallery#6619
1 parent 4c14c3a commit 53187a3

2 files changed

Lines changed: 124 additions & 6 deletions

File tree

src/NuGet.Services.Validation.Orchestrator/ValidationSetProvider.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ private PackageValidationSet InitializeValidationSet(PackageValidationMessageDat
152152
ValidatingType = message.ValidatingType
153153
};
154154

155-
foreach (var validation in _validationConfiguration.Validations)
155+
var validationsToStart = _validationConfiguration
156+
.Validations
157+
.Where(v => v.ShouldStart);
158+
159+
foreach (var validation in validationsToStart)
156160
{
157161
var packageValidation = new PackageValidation
158162
{

tests/NuGet.Services.Validation.Orchestrator.Tests/ValidationSetProviderFacts.cs

Lines changed: 119 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ public async Task CopiesToValidationSetContainerBeforeAddingDbRecord()
6969
{
7070
Name = validation1,
7171
TrackAfter = TimeSpan.FromDays(1),
72-
RequiredValidations = new List<string>{}
72+
RequiredValidations = new List<string>(),
73+
ShouldStart = true,
7374
}
7475
};
7576

@@ -172,7 +173,13 @@ public async Task CopiesPackageFromPackagesContainerWhenAvailable()
172173
const string validation1 = "validation1";
173174
Configuration.Validations = new List<ValidationConfigurationItem>
174175
{
175-
new ValidationConfigurationItem(){ Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List<string>{ } }
176+
new ValidationConfigurationItem
177+
{
178+
Name = validation1,
179+
TrackAfter = TimeSpan.FromDays(1),
180+
RequiredValidations = new List<string>(),
181+
ShouldStart = true,
182+
}
176183
};
177184

178185
Package.PackageStatusKey = PackageStatus.Available;
@@ -221,7 +228,13 @@ public async Task CopiesPackageFromValidationContainerWhenNotAvailable(PackageSt
221228
const string validation1 = "validation1";
222229
Configuration.Validations = new List<ValidationConfigurationItem>
223230
{
224-
new ValidationConfigurationItem(){ Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List<string>{ } }
231+
new ValidationConfigurationItem()
232+
{
233+
Name = validation1,
234+
TrackAfter = TimeSpan.FromDays(1),
235+
RequiredValidations = new List<string>(),
236+
ShouldStart = true,
237+
}
225238
};
226239

227240
Package.PackageStatusKey = packageStatus;
@@ -286,8 +299,20 @@ public async Task ProperlyConstructsValidationSet()
286299
const string validation2 = "validation2";
287300
Configuration.Validations = new List<ValidationConfigurationItem>
288301
{
289-
new ValidationConfigurationItem(){ Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List<string>{ validation2 } },
290-
new ValidationConfigurationItem(){ Name = validation2, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List<string>{ } }
302+
new ValidationConfigurationItem()
303+
{
304+
Name = validation1,
305+
TrackAfter = TimeSpan.FromDays(1),
306+
RequiredValidations = new List<string>{ validation2 },
307+
ShouldStart = true,
308+
},
309+
new ValidationConfigurationItem()
310+
{
311+
Name = validation2,
312+
TrackAfter = TimeSpan.FromDays(1),
313+
RequiredValidations = new List<string>(),
314+
ShouldStart = true,
315+
}
291316
};
292317

293318
Guid validationTrackingId = Guid.NewGuid();
@@ -356,6 +381,95 @@ public async Task ProperlyConstructsValidationSet()
356381
Times.Once);
357382
}
358383

384+
[Fact]
385+
public async Task DoesNotCreateValidationsWhenShouldStartFalse()
386+
{
387+
const string validation1 = "validation1";
388+
const string validation2 = "validation2";
389+
Configuration.Validations = new List<ValidationConfigurationItem>
390+
{
391+
new ValidationConfigurationItem()
392+
{
393+
Name = validation1,
394+
TrackAfter = TimeSpan.FromDays(1),
395+
RequiredValidations = new List<string>(),
396+
ShouldStart = true,
397+
},
398+
new ValidationConfigurationItem()
399+
{
400+
Name = validation2,
401+
TrackAfter = TimeSpan.FromDays(1),
402+
RequiredValidations = new List<string>(),
403+
ShouldStart = false,
404+
}
405+
};
406+
407+
Guid validationTrackingId = Guid.NewGuid();
408+
ValidationStorageMock
409+
.Setup(vs => vs.GetValidationSetAsync(validationTrackingId))
410+
.ReturnsAsync((PackageValidationSet)null)
411+
.Verifiable();
412+
413+
ValidationStorageMock
414+
.Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny<IValidatingEntity<Package>>(), It.IsAny<TimeSpan>(), validationTrackingId))
415+
.ReturnsAsync(false);
416+
417+
PackageValidationSet createdSet = null;
418+
ValidationStorageMock
419+
.Setup(vs => vs.CreateValidationSetAsync(It.IsAny<PackageValidationSet>()))
420+
.Returns<PackageValidationSet>(pvs => Task.FromResult(pvs))
421+
.Callback<PackageValidationSet>(pvs => createdSet = pvs)
422+
.Verifiable();
423+
424+
ValidationStorageMock
425+
.Setup(vs => vs.GetValidationSetCountAsync(It.IsAny<IValidatingEntity<Package>>()))
426+
.ReturnsAsync(1);
427+
428+
var provider = new ValidationSetProvider<Package>(
429+
ValidationStorageMock.Object,
430+
PackageFileServiceMock.Object,
431+
ValidatorProvider.Object,
432+
ConfigurationAccessorMock.Object,
433+
TelemetryServiceMock.Object,
434+
LoggerMock.Object);
435+
436+
var packageValidationMessageData = new PackageValidationMessageData(
437+
Package.PackageRegistration.Id,
438+
Package.NormalizedVersion,
439+
validationTrackingId);
440+
var returnedSet = await provider.TryGetOrCreateValidationSetAsync(packageValidationMessageData, PackageValidatingEntity);
441+
var endOfCallTimestamp = DateTime.UtcNow;
442+
443+
ValidationStorageMock
444+
.Verify(vs => vs.CreateValidationSetAsync(It.IsAny<PackageValidationSet>()), Times.Once);
445+
446+
Assert.NotNull(returnedSet);
447+
Assert.NotNull(createdSet);
448+
Assert.Same(createdSet, returnedSet);
449+
Assert.Equal(Package.PackageRegistration.Id, createdSet.PackageId);
450+
Assert.Equal(Package.NormalizedVersion, createdSet.PackageNormalizedVersion);
451+
Assert.Equal(Package.Key, createdSet.PackageKey);
452+
Assert.Equal(validationTrackingId, createdSet.ValidationTrackingId);
453+
Assert.True(createdSet.Created.Kind == DateTimeKind.Utc);
454+
Assert.True(createdSet.Updated.Kind == DateTimeKind.Utc);
455+
456+
var allowedTimeDifference = TimeSpan.FromSeconds(5);
457+
Assert.True(endOfCallTimestamp - createdSet.Created < allowedTimeDifference);
458+
Assert.True(endOfCallTimestamp - createdSet.Updated < allowedTimeDifference);
459+
Assert.All(createdSet.PackageValidations, v => Assert.Same(createdSet, v.PackageValidationSet));
460+
Assert.All(createdSet.PackageValidations, v => Assert.Equal(ValidationStatus.NotStarted, v.ValidationStatus));
461+
Assert.All(createdSet.PackageValidations, v => Assert.True(endOfCallTimestamp - v.ValidationStatusTimestamp < allowedTimeDifference));
462+
Assert.Contains(createdSet.PackageValidations, v => v.Type == validation1);
463+
Assert.DoesNotContain(createdSet.PackageValidations, v => v.Type == validation2);
464+
465+
PackageFileServiceMock.Verify(
466+
x => x.CopyValidationPackageForValidationSetAsync(returnedSet),
467+
Times.Once);
468+
TelemetryServiceMock.Verify(
469+
x => x.TrackDurationToValidationSetCreation(createdSet.Created - Package.Created),
470+
Times.Once);
471+
}
472+
359473
[Fact]
360474
public async Task DoesNotEmitTelemetryIfMultipleValidationSetsExist()
361475
{

0 commit comments

Comments
 (0)