コード例 #1
0
            public async Task TestTimeoutCancelsProcessing()
            {
                var repo            = new WritableRepositoryInformation("owner/test", url: "", stars: 100, description: "", mainBranch: "master");
                var configFileNames = new string[] { "packages.config", "someProjFile.csproj", "someProjFile.props", "someProjFile.targets" };
                var repoFiles       = new List <GitFileInfo>()
                {
                    new GitFileInfo("file1.txt", 1),
                    new GitFileInfo("file2.txt", 1),
                    new GitFileInfo(configFileNames[0], 1),
                    new GitFileInfo(configFileNames[1], 1),
                    new GitFileInfo(configFileNames[2], 1),
                    new GitFileInfo(configFileNames[3], 1)
                };

                var telemetry = new Mock <ITelemetryService>();
                var indexer   = CreateIndexer(
                    repo,
                    repoFiles,
                    telemetry,
                    // This should not be called because the process will be cancelled before it writes.
                    onDisposeHandler: (string serializedValue) => Assert.True(false),
                    shouldTimeOut: true);

                await Assert.ThrowsAsync <OperationCanceledException>(() => indexer.RunAsync());
            }
コード例 #2
0
            public async Task TestNoDependenciesInFiles()
            {
                var repo            = new WritableRepositoryInformation("owner/test", url: "", stars: 100, description: "", mainBranch: "master");
                var configFileNames = new string[] { "packages.config", "someProjFile.csproj", "someProjFile.props", "someProjFile.targets" };
                var repoFiles       = new List <GitFileInfo>()
                {
                    new GitFileInfo("file1.txt", 1),
                    new GitFileInfo("file2.txt", 1),
                    new GitFileInfo(configFileNames[0], 1),
                    new GitFileInfo(configFileNames[1], 1),
                    new GitFileInfo(configFileNames[2], 1),
                    new GitFileInfo(configFileNames[3], 1)
                };

                var telemetry      = new Mock <ITelemetryService>();
                var indexMetric    = new Mock <IDisposable>();
                var listMetric     = new Mock <IDisposable>();
                var checkoutMetric = new Mock <IDisposable>();
                var uploadMetric   = new Mock <IDisposable>();

                telemetry
                .Setup(t => t.TrackIndexRepositoryDuration("owner/test"))
                .Returns(indexMetric.Object);
                telemetry
                .Setup(t => t.TrackListFilesDuration("owner/test"))
                .Returns(listMetric.Object);
                telemetry
                .Setup(t => t.TrackCheckOutFilesDuration("owner/test"))
                .Returns(checkoutMetric.Object);
                telemetry
                .Setup(t => t.TrackUploadGitHubUsageBlobDuration())
                .Returns(uploadMetric.Object);

                var indexer = CreateIndexer(
                    repo,
                    repoFiles,
                    telemetry,
                    // This should not be called since there is no dependencies
                    onDisposeHandler: (string serializedValue) => Assert.True(false));
                await indexer.RunAsync();

                var result = repo.ToRepositoryInformation();

                Assert.Equal(0, result.Dependencies.Count);

                telemetry.Verify(t => t.TrackIndexRepositoryDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackListFilesDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackCheckOutFilesDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackUploadGitHubUsageBlobDuration(), Times.Never);
                telemetry.Verify(
                    t => t.TrackRunDuration(It.IsAny <TimeSpan>(), /* completed: */ true),
                    Times.Once);

                indexMetric.Verify(m => m.Dispose(), Times.Once);
                listMetric.Verify(m => m.Dispose(), Times.Once);
                checkoutMetric.Verify(m => m.Dispose(), Times.Once);
                uploadMetric.Verify(m => m.Dispose(), Times.Never);

                telemetry.Verify(t => t.TrackEmptyGitHubUsageBlob(), Times.Once);
            }
コード例 #3
0
            public async Task OversizedBlobs()
            {
                var repo             = new WritableRepositoryInformation("owner/test", url: "", stars: 100, description: "", mainBranch: "master");
                var configFileNames  = new string[] { "packages.config", "someProjFile.csproj", "someProjFile.props", "someProjFile.targets" };
                var repoDependencies = new string[] { "dependency1", "dependency2", "dependency3", "dependency4" };
                var repoFiles        = new List <GitFileInfo>()
                {
                    new GitFileInfo("file1.txt", 1),
                    new GitFileInfo("file2.txt", 1),
                    new GitFileInfo(configFileNames[0], ReposIndexer.MaxBlobSizeBytes + 1),
                    new GitFileInfo(configFileNames[1], 1),
                    new GitFileInfo(configFileNames[2], 1),
                    new GitFileInfo(configFileNames[3], 1)
                };

                var telemetry      = new Mock <ITelemetryService>();
                var indexMetric    = new Mock <IDisposable>();
                var listMetric     = new Mock <IDisposable>();
                var checkoutMetric = new Mock <IDisposable>();
                var uploadMetric   = new Mock <IDisposable>();

                telemetry
                .Setup(t => t.TrackIndexRepositoryDuration("owner/test"))
                .Returns(indexMetric.Object);
                telemetry
                .Setup(t => t.TrackListFilesDuration("owner/test"))
                .Returns(listMetric.Object);
                telemetry
                .Setup(t => t.TrackCheckOutFilesDuration("owner/test"))
                .Returns(checkoutMetric.Object);
                telemetry
                .Setup(t => t.TrackUploadGitHubUsageBlobDuration())
                .Returns(uploadMetric.Object);

                var writeToBlobCalled = false;
                var indexer           = CreateIndexer(repo, repoFiles, telemetry, configFileParser: (ICheckedOutFile file) =>
                {
                    var idx = Array.FindIndex(configFileNames, x => string.Equals(x, file.Path));

                    // Make sure that the Indexer filters out the non-config files
                    Assert.True(idx != -1);
                    Assert.True(
                        repoFiles[repoFiles.FindIndex(f => string.Equals(f.Path, file.Path))]
                        .BlobSize < ReposIndexer.MaxBlobSizeBytes);
                    return(repoDependencies);
                },
                                                      onDisposeHandler: (string serializedText) =>
                {
                    writeToBlobCalled = true;
                    Assert.Equal(JsonConvert.SerializeObject(new RepositoryInformation[] { repo.ToRepositoryInformation() }), serializedText);
                });
                await indexer.RunAsync();

                var result = repo.ToRepositoryInformation();

                // Make sure the dependencies got read correctly
                Assert.Equal(repoDependencies.Length, result.Dependencies.Count);
                Assert.Equal(repoDependencies, result.Dependencies);

                // Make sure the repo information didn't get changed in the process
                Assert.Equal(repo.Id, result.Id);
                Assert.Equal(repo.Stars, result.Stars);
                Assert.Equal(repo.Url, result.Url);

                // Make sure the blob has been written
                Assert.True(writeToBlobCalled);

                // Verify telemetry
                telemetry.Verify(t => t.TrackIndexRepositoryDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackListFilesDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackCheckOutFilesDuration("owner/test"), Times.Once);
                telemetry.Verify(t => t.TrackUploadGitHubUsageBlobDuration(), Times.Once);
                telemetry.Verify(
                    t => t.TrackRunDuration(It.IsAny <TimeSpan>(), /* completed: */ true),
                    Times.Once);

                indexMetric.Verify(m => m.Dispose(), Times.Once);
                listMetric.Verify(m => m.Dispose(), Times.Once);
                checkoutMetric.Verify(m => m.Dispose(), Times.Once);
                uploadMetric.Verify(m => m.Dispose(), Times.Once);

                telemetry.Verify(t => t.TrackEmptyGitHubUsageBlob(), Times.Never);
            }
コード例 #4
0
        private static ReposIndexer CreateIndexer(
            WritableRepositoryInformation searchResult,
            IReadOnlyList <GitFileInfo> repoFiles,
            Mock <ITelemetryService> mockTelemetry,
            Action <string> onDisposeHandler,
            Func <ICheckedOutFile, IReadOnlyList <string> > configFileParser = null,
            bool shouldTimeOut = false)
        {
            var mockConfig = new Mock <IOptionsSnapshot <GitHubIndexerConfiguration> >();
            var config     = new GitHubIndexerConfiguration();

            if (shouldTimeOut)
            {
                config.RepoIndexingTimeout = TimeSpan.Zero;
            }

            mockConfig
            .SetupGet(x => x.Value)
            .Returns(config);

            var mockSearcher = new Mock <IGitRepoSearcher>();

            mockSearcher
            .Setup(x => x.GetPopularRepositories())
            .Returns(Task.FromResult(new List <WritableRepositoryInformation>()
            {
                searchResult
            } as IReadOnlyList <WritableRepositoryInformation> ?? new List <WritableRepositoryInformation>()));

            var mockRepoCache = new Mock <IRepositoriesCache>();
            RepositoryInformation mockVal;

            mockRepoCache
            .Setup(x => x.TryGetCachedVersion(It.IsAny <WritableRepositoryInformation>(), out mockVal))
            .Callback(() => {
                if (shouldTimeOut)
                {
                    // A minute should be long enough to cancel the task.
                    // If the task isn't canceled, the test runtime will only be minorly affected.
                    Thread.Sleep(60 * 1000);
                }
            })
            .Returns(false);     // Simulate no cache
            mockRepoCache
            .Setup(x => x.Persist(It.IsAny <RepositoryInformation>()));

            var mockConfigFileParser = new Mock <IConfigFileParser>();

            mockConfigFileParser
            .Setup(x => x.Parse(It.IsAny <ICheckedOutFile>()))
            .Returns(configFileParser ?? ((ICheckedOutFile file) => new List <string>()));

            var mockFetchedRepo = new Mock <IFetchedRepo>();

            mockFetchedRepo
            .Setup(x => x.GetFileInfos())
            .Returns(repoFiles);
            mockFetchedRepo
            .Setup(x => x.CheckoutFiles(It.IsAny <IReadOnlyCollection <string> >()))
            .Returns((IReadOnlyCollection <string> paths) =>
                     paths.Select(x => new CheckedOutFile(filePath: x, repoId: searchResult.Id) as ICheckedOutFile).ToList());

            var mockRepoFetcher = new Mock <IRepoFetcher>();

            mockRepoFetcher
            .Setup(x => x.FetchRepo(It.IsAny <WritableRepositoryInformation>()))
            .Returns(mockFetchedRepo.Object);

            var mockBlobClient    = new Mock <ICloudBlobClient>();
            var mockBlobContainer = new Mock <ICloudBlobContainer>();
            var mockBlob          = new Mock <ISimpleCloudBlob>();

            mockBlobClient
            .Setup(x => x.GetContainerReference(It.IsAny <string>()))
            .Returns(() => mockBlobContainer.Object);
            mockBlobContainer
            .Setup(x => x.GetBlobReference(It.IsAny <string>()))
            .Returns(() => mockBlob.Object);
            mockBlob
            .Setup(x => x.ETag)
            .Returns("\"some-etag\"");
            mockBlob
            .Setup(x => x.Properties)
            .Returns(new CloudBlockBlob(new Uri("https://example/blob")).Properties);
            mockBlob
            .Setup(x => x.OpenWriteAsync(It.IsAny <AccessCondition>()))
            .ReturnsAsync(() => new RecordingStream(bytes =>
            {
                onDisposeHandler?.Invoke(Encoding.UTF8.GetString(bytes));
            }));

            return(new ReposIndexer(
                       mockSearcher.Object,
                       Mock.Of <ILogger <ReposIndexer> >(),
                       mockRepoCache.Object,
                       mockConfigFileParser.Object,
                       mockRepoFetcher.Object,
                       mockBlobClient.Object,
                       mockConfig.Object,
                       mockTelemetry.Object));
        }