public async Task SetExceptionHandler_ThrowsForNullHandlerAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                var exception = Assert.Throws <ArgumentNullException>(
                    () => test.Downloader.SetExceptionHandler(handleExceptionAsync: null));

                Assert.Equal("handleExceptionAsync", exception.ParamName);
            }
        }
 public async Task CopyNupkgFileToAsync_ThrowsIfCancelledAsync()
 {
     using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
     {
         await Assert.ThrowsAsync <OperationCanceledException>(
             () => test.Downloader.CopyNupkgFileToAsync(
                 destinationFilePath: "a",
                 cancellationToken: new CancellationToken(canceled: true)));
     }
 }
 public async Task GetPackageHashAsync_ThrowsIfCancelledAsync()
 {
     using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
     {
         await Assert.ThrowsAsync <OperationCanceledException>(
             () => test.Downloader.GetPackageHashAsync(
                 hashAlgorithm: "a",
                 cancellationToken: new CancellationToken(canceled: true)));
     }
 }
        public async Task CoreReader_ThrowsIfDisposedAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Downloader.Dispose();

                var exception = Assert.Throws <ObjectDisposedException>(() => test.Downloader.CoreReader);

                Assert.Equal(nameof(RemotePackageArchiveDownloader), exception.ObjectName);
            }
        }
        public async Task GetPackageHashAsync_ThrowsForNullOrEmptyHashAlgorithmAsync(string hashAlgorithm)
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                var exception = await Assert.ThrowsAsync <ArgumentException>(
                    () => test.Downloader.GetPackageHashAsync(
                        hashAlgorithm,
                        CancellationToken.None));

                Assert.Equal("hashAlgorithm", exception.ParamName);
            }
        }
        public async Task CopyNupkgFileToAsync_ThrowsForNullOrEmptyDestinationFilePathAsync(string destinationFilePath)
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                var exception = await Assert.ThrowsAsync <ArgumentException>(
                    () => test.Downloader.CopyNupkgFileToAsync(
                        destinationFilePath,
                        CancellationToken.None));

                Assert.Equal("destinationFilePath", exception.ParamName);
            }
        }
        public async Task GetPackageHashAsync_ThrowsIfDisposedAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Downloader.Dispose();

                var exception = await Assert.ThrowsAsync <ObjectDisposedException>(
                    () => test.Downloader.GetPackageHashAsync(
                        hashAlgorithm: "SHA512",
                        cancellationToken: CancellationToken.None));

                Assert.Equal(nameof(RemotePackageArchiveDownloader), exception.ObjectName);
            }
        }
        public async Task CopyNupkgFileToAsync_ThrowsIfDisposedAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Downloader.Dispose();

                var exception = await Assert.ThrowsAsync <ObjectDisposedException>(
                    () => test.Downloader.CopyNupkgFileToAsync(
                        destinationFilePath: "a",
                        cancellationToken: CancellationToken.None));

                Assert.Equal(nameof(RemotePackageArchiveDownloader), exception.ObjectName);
            }
        }
        public async Task Constructor_InitializesPropertiesAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Resource.Setup(x => x.CopyNupkgToStreamAsync(
                                        It.IsNotNull <string>(),
                                        It.IsNotNull <NuGetVersion>(),
                                        It.IsNotNull <Stream>(),
                                        It.IsNotNull <SourceCacheContext>(),
                                        It.IsNotNull <ILogger>(),
                                        It.IsAny <CancellationToken>()))
                .Callback <string, NuGetVersion, Stream, SourceCacheContext, ILogger, CancellationToken>(async
                                                                                                             (id, version, stream, cacheContext, logger, cancellationToken) =>
                {
                    var remoteDirectoryPath = Path.Combine(test.TestDirectory.Path, "remote");

                    Directory.CreateDirectory(remoteDirectoryPath);

                    var packageContext = new SimpleTestPackageContext()
                    {
                        Id      = test.PackageIdentity.Id,
                        Version = test.PackageIdentity.Version.ToNormalizedString()
                    };

                    packageContext.AddFile($"lib/net45/{test.PackageIdentity.Id}.dll");

                    await SimpleTestPackageUtility.CreatePackagesAsync(remoteDirectoryPath, packageContext);

                    var sourcePackageFilePath = Path.Combine(
                        remoteDirectoryPath,
                        $"{test.PackageIdentity.Id}.{test.PackageIdentity.Version.ToNormalizedString()}.nupkg");

                    using (var remoteStream = File.OpenRead(sourcePackageFilePath))
                    {
                        remoteStream.CopyTo(stream);
                    }
                })
                .ReturnsAsync(true);

                var destinationFilePath = Path.Combine(test.TestDirectory.Path, "a");

                await test.Downloader.CopyNupkgFileToAsync(
                    destinationFilePath,
                    CancellationToken.None);

                Assert.IsType <PackageArchiveReader>(test.Downloader.ContentReader);
                Assert.IsType <PackageArchiveReader>(test.Downloader.CoreReader);
            }
        }
        public async Task CopyNupkgFileToAsync_RespectsThrottleAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
                using (var throttle = new SemaphoreSlim(initialCount: 0, maxCount: 1))
                    using (var copyEvent = new ManualResetEventSlim())
                    {
                        test.Resource.Setup(x => x.CopyNupkgToStreamAsync(
                                                It.IsNotNull <string>(),
                                                It.IsNotNull <NuGetVersion>(),
                                                It.IsNotNull <Stream>(),
                                                It.IsNotNull <SourceCacheContext>(),
                                                It.IsNotNull <ILogger>(),
                                                It.IsAny <CancellationToken>()))
                        .Callback <string, NuGetVersion, Stream, SourceCacheContext, ILogger, CancellationToken>(
                            (id, version, destination, sourceCacheContext, logger, cancellationToken) =>
                        {
                            copyEvent.Set();
                        })
                        .ReturnsAsync(true);

                        var destinationFilePath = Path.Combine(test.TestDirectory.Path, "a");

                        test.Downloader.SetThrottle(throttle);

                        var wasCopied = false;

                        var copyTask = Task.Run(async() =>
                        {
                            wasCopied = await test.Downloader.CopyNupkgFileToAsync(
                                destinationFilePath,
                                CancellationToken.None);
                        });

                        await Task.Delay(100);

                        Assert.False(copyEvent.IsSet);

                        throttle.Release();

                        await copyTask;

                        Assert.True(copyEvent.IsSet);
                        Assert.True(wasCopied);
                    }
        }
        public async Task CopyNupkgFileToAsync_ReturnsResultFromFindPackageByIdResourceAsync(bool expectedResult)
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Resource.Setup(x => x.CopyNupkgToStreamAsync(
                                        It.IsNotNull <string>(),
                                        It.IsNotNull <NuGetVersion>(),
                                        It.IsNotNull <Stream>(),
                                        It.IsNotNull <SourceCacheContext>(),
                                        It.IsNotNull <ILogger>(),
                                        It.IsAny <CancellationToken>()))
                .ReturnsAsync(expectedResult);

                var destinationFilePath = Path.Combine(test.TestDirectory.Path, "a");

                var actualResult = await test.Downloader.CopyNupkgFileToAsync(
                    destinationFilePath,
                    CancellationToken.None);

                Assert.Equal(expectedResult, actualResult);
            }
        }
        public async Task CopyNupkgFileToAsync_ReleasesThrottleOnExceptionAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
                using (var throttle = new SemaphoreSlim(initialCount: 1, maxCount: 1))
                {
                    test.Resource.Setup(x => x.CopyNupkgToStreamAsync(
                                            It.IsNotNull <string>(),
                                            It.IsNotNull <NuGetVersion>(),
                                            It.IsNotNull <Stream>(),
                                            It.IsNotNull <SourceCacheContext>(),
                                            It.IsNotNull <ILogger>(),
                                            It.IsAny <CancellationToken>()))
                    .ThrowsAsync(new FatalProtocolException("simulated failure"));

                    var destinationFilePath = Path.Combine(test.TestDirectory.Path, "a");

                    test.Downloader.SetThrottle(throttle);

                    var copyTask = Task.Run(async() =>
                    {
                        try
                        {
                            await test.Downloader.CopyNupkgFileToAsync(
                                destinationFilePath,
                                CancellationToken.None);
                        }
                        catch (Exception)
                        {
                        }
                    });

                    await copyTask;

                    Assert.Equal(1, throttle.CurrentCount);
                }
        }
        public async Task CopyNupkgFileToAsync_ReturnsFalseIfExceptionHandledAsync()
        {
            using (var test = await RemotePackageArchiveDownloaderTest.CreateAsync())
            {
                test.Resource.Setup(x => x.CopyNupkgToStreamAsync(
                                        It.IsNotNull <string>(),
                                        It.IsNotNull <NuGetVersion>(),
                                        It.IsNotNull <Stream>(),
                                        It.IsNotNull <SourceCacheContext>(),
                                        It.IsNotNull <ILogger>(),
                                        It.IsAny <CancellationToken>()))
                .ThrowsAsync(new FatalProtocolException("simulated failure"));

                var destinationFilePath = Path.Combine(test.TestDirectory.Path, "a");

                test.Downloader.SetExceptionHandler(exception => Task.FromResult(true));

                var wasCopied = await test.Downloader.CopyNupkgFileToAsync(
                    destinationFilePath,
                    CancellationToken.None);

                Assert.False(wasCopied);
            }
        }