Example #1
0
            public async Task EventuallyFailsIfBatchPusherNeverSucceeds()
            {
                Config.MaxConcurrentVersionListWriters = 1;
                Changes["PackageA"] = 1;
                Changes["PackageB"] = 2;
                BatchPusher
                .Setup(x => x.TryFinishAsync())
                .ReturnsAsync(new BatchPusherResult(new[] { "PackageB" }));

                var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => Target.ExecuteAsync());

                Assert.Equal("The index operations for the following package IDs failed due to version list concurrency: PackageB", ex.Message);
                VerifyCompletedTelemetry(JobOutcome.Failure);
                VerifyAllIdsAreProcessed(new[] { "PackageA", "PackageB", "PackageB", "PackageB" });
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        "PackageA",
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Once);
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        "PackageB",
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Exactly(3));
                BatchPusher.Verify(
                    x => x.EnqueueIndexActions(It.IsAny <string>(), It.IsAny <IndexActions>()),
                    Times.Exactly(4));
                BatchPusher.Verify(x => x.TryFinishAsync(), Times.Exactly(3));
                BatchPusher.Verify(x => x.TryPushFullBatchesAsync(), Times.Never);
            }
Example #2
0
            public async Task RetriesFailedPackageIds()
            {
                Config.MaxConcurrentVersionListWriters = 1;
                Changes["PackageA"] = 1;
                Changes["PackageB"] = 2;
                BatchPusher
                .SetupSequence(x => x.TryFinishAsync())
                .ReturnsAsync(new BatchPusherResult(new[] { "PackageB" }))
                .ReturnsAsync(new BatchPusherResult());

                await Target.ExecuteAsync();

                VerifyCompletedTelemetry(JobOutcome.Success);
                VerifyAllIdsAreProcessed(new[] { "PackageA", "PackageB", "PackageB" });
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        "PackageA",
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Once);
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        "PackageB",
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Exactly(2));
                BatchPusher.Verify(
                    x => x.EnqueueIndexActions(It.IsAny <string>(), It.IsAny <IndexActions>()),
                    Times.Exactly(3));
                BatchPusher.Verify(x => x.TryFinishAsync(), Times.Exactly(2));
                BatchPusher.Verify(x => x.TryPushFullBatchesAsync(), Times.Never);
            }
 public RebuildSearchCommand(
     NuGetClientFactory clientFactory,
     ICursor cursor,
     IPackageService packages,
     IndexActionBuilder actionBuilder,
     AzureSearchBatchIndexer indexer,
     ILogger <RebuildSearchCommand> logger)
 {
     _clientFactory = clientFactory;
     _cursor        = cursor;
     _packages      = packages;
     _actionBuilder = actionBuilder;
     _indexer       = indexer;
     _logger        = logger;
 }
Example #4
0
            [InlineData(4, 8, 15, 0)] // 4,        8 + 4 = 12 is greater than 10 so 8 is the batch size.
            public async Task RespectsAzureSearchBatchSize(int documentsPerId, int batchSize, int fullPushes, int partialPushes)
            {
                var changeCount    = 30;
                var expectedPushes = fullPushes + partialPushes;

                Config.AzureSearchBatchSize = 10;

                IndexActions = new IndexActions(
                    new List <IndexAction <KeyedDocument> >(
                        Enumerable
                        .Range(0, documentsPerId)
                        .Select(x => IndexAction.Merge(new KeyedDocument()))),
                    new List <IndexAction <KeyedDocument> >(),
                    new ResultAndAccessCondition <VersionListData>(
                        new VersionListData(new Dictionary <string, VersionPropertiesData>()),
                        new Mock <IAccessCondition>().Object));

                AddChanges(changeCount);

                await Target.ExecuteAsync();

                VerifyCompletedTelemetry(JobOutcome.Success);
                VerifyAllIdsAreProcessed(changeCount);
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        It.IsAny <string>(),
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Exactly(changeCount));
                BatchPusher.Verify(
                    x => x.EnqueueIndexActions(It.IsAny <string>(), It.IsAny <IndexActions>()),
                    Times.Exactly(changeCount));
                BatchPusher.Verify(x => x.TryFinishAsync(), Times.Exactly(expectedPushes));
                BatchPusher.Verify(x => x.TryPushFullBatchesAsync(), Times.Never);
                SystemTime.Verify(x => x.Delay(It.IsAny <TimeSpan>()), Times.Exactly(expectedPushes - 1));
                DownloadDataClient.Verify(
                    x => x.ReplaceLatestIndexedAsync(
                        NewDownloadData,
                        It.Is <IAccessCondition>(a => a.IfMatchETag == OldDownloadResult.Metadata.ETag)),
                    Times.Once);

                Assert.Equal(
                    fullPushes,
                    FinishedBatches.Count(b => b.Sum(ia => ia.Search.Count) == batchSize));
                Assert.Equal(
                    partialPushes,
                    FinishedBatches.Count(b => b.Sum(ia => ia.Search.Count) != batchSize));
                Assert.Empty(CurrentBatch);
            }
Example #5
0
 public PackageIndexer(
     IPackageService packages,
     IUrlGenerator url,
     CloudBlobContainer blobContainer,
     RegistrationBuilder registrationBuilder,
     IndexActionBuilder actionBuilder,
     AzureSearchBatchIndexer search,
     ILogger <PackageIndexer> logger)
 {
     _packages            = packages;
     _url                 = url;
     _blobContainer       = blobContainer;
     _registrationBuilder = registrationBuilder;
     _actionBuilder       = actionBuilder;
     _search              = search;
     _logger              = logger;
 }
            public async Task PushesNothingWhenThereAreNoChanges()
            {
                await Target.ExecuteAsync();

                VerifyCompletedTelemetry(JobOutcome.NoOp);
                VerifyAllIdsAreProcessed(changeCount: 0);
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        It.IsAny <string>(),
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Never);
                BatchPusher.Verify(x => x.FinishAsync(), Times.Never);
                BatchPusher.Verify(x => x.PushFullBatchesAsync(), Times.Never);
                DownloadDataClient.Verify(
                    x => x.ReplaceLatestIndexedAsync(It.IsAny <DownloadData>(), It.IsAny <IAccessCondition>()),
                    Times.Never);
            }
Example #7
0
            public async Task CanProcessInParallel()
            {
                var changeCount = 1000;

                Config.AzureSearchBatchSize            = 5;
                Config.MaxConcurrentBatches            = 4;
                Config.MaxConcurrentVersionListWriters = 8;
                AddChanges(changeCount);

                await Target.ExecuteAsync();

                VerifyCompletedTelemetry(JobOutcome.Success);
                VerifyAllIdsAreProcessed(changeCount);
                IndexActionBuilder.Verify(
                    x => x.UpdateAsync(
                        It.IsAny <string>(),
                        It.IsAny <Func <SearchFilters, KeyedDocument> >()),
                    Times.Exactly(changeCount));
                BatchPusher.Verify(
                    x => x.EnqueueIndexActions(It.IsAny <string>(), It.IsAny <IndexActions>()),
                    Times.Exactly(changeCount));
                BatchPusher.Verify(x => x.TryFinishAsync(), Times.AtLeastOnce);
                BatchPusher.Verify(x => x.TryPushFullBatchesAsync(), Times.Never);
            }