diff --git a/src/Lidarr.Api.V1/Indexers/ReleaseController.cs b/src/Lidarr.Api.V1/Indexers/ReleaseController.cs index 0a6428b08..3ab9ea319 100644 --- a/src/Lidarr.Api.V1/Indexers/ReleaseController.cs +++ b/src/Lidarr.Api.V1/Indexers/ReleaseController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FluentValidation; using Lidarr.Http; using Microsoft.AspNetCore.Mvc; @@ -65,7 +66,7 @@ namespace Lidarr.Api.V1.Indexers } [HttpPost] - public ActionResult Create(ReleaseResource release) + public async Task> DownloadRelease(ReleaseResource release) { ValidateResource(release); @@ -126,7 +127,7 @@ namespace Lidarr.Api.V1.Indexers throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse albums in the release"); } - _downloadService.DownloadReport(remoteAlbum); + await _downloadService.DownloadReport(remoteAlbum); } catch (ReleaseDownloadException ex) { @@ -138,26 +139,26 @@ namespace Lidarr.Api.V1.Indexers } [HttpGet] - public List GetReleases(int? albumId, int? artistId) + public async Task> GetReleases(int? albumId, int? artistId) { if (albumId.HasValue) { - return GetAlbumReleases(int.Parse(Request.Query["albumId"])); + return await GetAlbumReleases(int.Parse(Request.Query["albumId"])); } if (artistId.HasValue) { - return GetArtistReleases(int.Parse(Request.Query["artistId"])); + return await GetArtistReleases(int.Parse(Request.Query["artistId"])); } - return GetRss(); + return await GetRss(); } - private List GetAlbumReleases(int albumId) + private async Task> GetAlbumReleases(int albumId) { try { - var decisions = _releaseSearchService.AlbumSearch(albumId, true, true, true); + var decisions = await _releaseSearchService.AlbumSearch(albumId, true, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); @@ -169,11 +170,11 @@ namespace Lidarr.Api.V1.Indexers } } - private List GetArtistReleases(int artistId) + private async Task> GetArtistReleases(int artistId) { try { - var decisions = _releaseSearchService.ArtistSearch(artistId, false, true, true); + var decisions = await _releaseSearchService.ArtistSearch(artistId, false, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); @@ -185,9 +186,9 @@ namespace Lidarr.Api.V1.Indexers } } - private List GetRss() + private async Task> GetRss() { - var reports = _rssFetcherAndParser.Fetch(); + var reports = await _rssFetcherAndParser.Fetch(); var decisions = _downloadDecisionMaker.GetRssDecision(reports); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); @@ -198,6 +199,7 @@ namespace Lidarr.Api.V1.Indexers { var resource = base.MapDecision(decision, initialWeight); _remoteAlbumCache.Set(GetCacheKey(resource), decision.RemoteAlbum, TimeSpan.FromMinutes(30)); + return resource; } diff --git a/src/Lidarr.Api.V1/Indexers/ReleasePushController.cs b/src/Lidarr.Api.V1/Indexers/ReleasePushController.cs index 1a5e4439b..e87e29101 100644 --- a/src/Lidarr.Api.V1/Indexers/ReleasePushController.cs +++ b/src/Lidarr.Api.V1/Indexers/ReleasePushController.cs @@ -61,7 +61,7 @@ namespace Lidarr.Api.V1.Indexers lock (PushLock) { decisions = _downloadDecisionMaker.GetRssDecision(new List { info }); - _downloadDecisionProcessor.ProcessDecisions(decisions); + _downloadDecisionProcessor.ProcessDecisions(decisions).GetAwaiter().GetResult(); } var firstDecision = decisions.FirstOrDefault(); diff --git a/src/Lidarr.Api.V1/Queue/QueueActionController.cs b/src/Lidarr.Api.V1/Queue/QueueActionController.cs index dd2c52589..d29f7b43f 100644 --- a/src/Lidarr.Api.V1/Queue/QueueActionController.cs +++ b/src/Lidarr.Api.V1/Queue/QueueActionController.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Lidarr.Http; using Lidarr.Http.REST; using Microsoft.AspNetCore.Mvc; @@ -20,7 +21,7 @@ namespace Lidarr.Api.V1.Queue } [HttpPost("grab/{id:int}")] - public object Grab(int id) + public async Task Grab(int id) { var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id); @@ -29,14 +30,14 @@ namespace Lidarr.Api.V1.Queue throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteAlbum); + await _downloadService.DownloadReport(pendingRelease.RemoteAlbum); return new { }; } [HttpPost("grab/bulk")] [Consumes("application/json")] - public object Grab([FromBody] QueueBulkResource resource) + public async Task Grab([FromBody] QueueBulkResource resource) { foreach (var id in resource.Ids) { @@ -47,7 +48,7 @@ namespace Lidarr.Api.V1.Queue throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteAlbum); + await _downloadService.DownloadReport(pendingRelease.RemoteAlbum); } return new { }; diff --git a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs index 057c83cfb..fa02134fd 100644 --- a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Threading; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NLog; @@ -121,21 +122,21 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_execute_simple_get() + public async Task should_execute_simple_get() { var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Execute(request); + var response = await Subject.ExecuteAsync(request); response.Content.Should().NotBeNullOrWhiteSpace(); } [Test] - public void should_execute_https_get() + public async Task should_execute_https_get() { var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Execute(request); + var response = await Subject.ExecuteAsync(request); response.Content.Should().NotBeNullOrWhiteSpace(); } @@ -147,47 +148,47 @@ namespace NzbDrone.Common.Test.Http Mocker.GetMock().SetupGet(x => x.CertificateValidation).Returns(validationType); var request = new HttpRequest($"https://expired.badssl.com"); - Assert.Throws(() => Subject.Execute(request)); + Assert.ThrowsAsync(async () => await Subject.ExecuteAsync(request)); ExceptionVerification.ExpectedErrors(1); } [Test] - public void bad_ssl_should_pass_if_remote_validation_disabled() + public async Task bad_ssl_should_pass_if_remote_validation_disabled() { Mocker.GetMock().SetupGet(x => x.CertificateValidation).Returns(CertificateValidationType.Disabled); var request = new HttpRequest($"https://expired.badssl.com"); - Subject.Execute(request); + await Subject.ExecuteAsync(request); ExceptionVerification.ExpectedErrors(0); } [Test] - public void should_execute_typed_get() + public async Task should_execute_typed_get() { var request = new HttpRequest($"https://{_httpBinHost}/get?test=1"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Url.EndsWith("/get?test=1"); response.Resource.Args.Should().Contain("test", "1"); } [Test] - public void should_execute_simple_post() + public async Task should_execute_simple_post() { var message = "{ my: 1 }"; var request = new HttpRequest($"https://{_httpBinHost}/post"); request.SetContent(message); - var response = Subject.Post(request); + var response = await Subject.PostAsync(request); response.Resource.Data.Should().Be(message); } [Test] - public void should_execute_post_with_content_type() + public async Task should_execute_post_with_content_type() { var message = "{ my: 1 }"; @@ -195,16 +196,16 @@ namespace NzbDrone.Common.Test.Http request.SetContent(message); request.Headers.ContentType = "application/json"; - var response = Subject.Post(request); + var response = await Subject.PostAsync(request); response.Resource.Data.Should().Be(message); } [Test] - public void should_execute_get_using_gzip() + public async Task should_execute_get_using_gzip() { var request = new HttpRequest($"https://{_httpBinHost}/gzip"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers["Accept-Encoding"].ToString().Should().Contain("gzip"); @@ -214,10 +215,10 @@ namespace NzbDrone.Common.Test.Http [Test] [Platform(Exclude = "MacOsX", Reason = "Azure agent update prevents brotli on OSX")] - public void should_execute_get_using_brotli() + public async Task should_execute_get_using_brotli() { var request = new HttpRequest($"https://{_httpBinHost}/brotli"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers["Accept-Encoding"].ToString().Should().Contain("br"); @@ -235,7 +236,7 @@ namespace NzbDrone.Common.Test.Http { var request = new HttpRequest($"https://{_httpBinHost}/status/{statusCode}"); - var exception = Assert.Throws(() => Subject.Get(request)); + var exception = Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ((int)exception.Response.StatusCode).Should().Be(statusCode); @@ -248,7 +249,7 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.NotFound }; - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.IgnoreWarns(); } @@ -258,7 +259,7 @@ namespace NzbDrone.Common.Test.Http { var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); - var exception = Assert.Throws(() => Subject.Get(request)); + var exception = Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.ExpectedWarns(1); } @@ -269,28 +270,28 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.LogHttpError = false; - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.ExpectedWarns(0); } [Test] - public void should_not_follow_redirects_when_not_in_production() + public async Task should_not_follow_redirects_when_not_in_production() { var request = new HttpRequest($"https://{_httpBinHost}/redirect/1"); - Subject.Get(request); + await Subject.GetAsync(request); ExceptionVerification.ExpectedErrors(1); } [Test] - public void should_follow_redirects() + public async Task should_follow_redirects() { var request = new HttpRequest($"https://{_httpBinHost}/redirect/1"); request.AllowAutoRedirect = true; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -298,12 +299,12 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_not_follow_redirects() + public async Task should_not_follow_redirects() { var request = new HttpRequest($"https://{_httpBinHost}/redirect/1"); request.AllowAutoRedirect = false; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.Found); @@ -311,14 +312,14 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_follow_redirects_to_https() + public async Task should_follow_redirects_to_https() { var request = new HttpRequestBuilder($"https://{_httpBinHost}/redirect-to") .AddQueryParam("url", $"https://lidarr.audio/") .Build(); request.AllowAutoRedirect = true; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.OK); response.Content.Should().Contain("Lidarr"); @@ -332,17 +333,17 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/redirect/6"); request.AllowAutoRedirect = true; - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.ExpectedErrors(0); } [Test] - public void should_send_user_agent() + public async Task should_send_user_agent() { var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().ContainKey("User-Agent"); @@ -352,24 +353,24 @@ namespace NzbDrone.Common.Test.Http } [TestCase("Accept", "text/xml, text/rss+xml, application/rss+xml")] - public void should_send_headers(string header, string value) + public async Task should_send_headers(string header, string value) { var request = new HttpRequest($"https://{_httpBinHost}/get"); request.Headers.Add(header, value); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers[header].ToString().Should().Be(value); } [Test] - public void should_download_file() + public async Task should_download_file() { var file = GetTempFilePath(); var url = "https://lidarr.audio/img/slider/artistdetails.png"; - Subject.DownloadFile(url, file); + await Subject.DownloadFileAsync(url, file); File.Exists(file).Should().BeTrue(); File.Exists(file + ".part").Should().BeFalse(); @@ -380,7 +381,7 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_download_file_with_redirect() + public async Task should_download_file_with_redirect() { var file = GetTempFilePath(); @@ -388,7 +389,7 @@ namespace NzbDrone.Common.Test.Http .AddQueryParam("url", $"https://lidarr.audio/img/slider/artistdetails.png") .Build(); - Subject.DownloadFile(request.Url.FullUri, file); + await Subject.DownloadFileAsync(request.Url.FullUri, file); ExceptionVerification.ExpectedErrors(0); @@ -402,7 +403,7 @@ namespace NzbDrone.Common.Test.Http { var file = GetTempFilePath(); - Assert.Throws(() => Subject.DownloadFile("https://download.sonarr.tv/wrongpath", file)); + Assert.ThrowsAsync(async () => await Subject.DownloadFileAsync("https://download.sonarr.tv/wrongpath", file)); File.Exists(file).Should().BeFalse(); File.Exists(file + ".part").Should().BeFalse(); @@ -411,7 +412,7 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_not_write_redirect_content_to_stream() + public async Task should_not_write_redirect_content_to_stream() { var file = GetTempFilePath(); @@ -421,7 +422,7 @@ namespace NzbDrone.Common.Test.Http request.AllowAutoRedirect = false; request.ResponseStream = fileStream; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.Redirect); } @@ -436,12 +437,12 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_send_cookie() + public async Task should_send_cookie() { var request = new HttpRequest($"https://{_httpBinHost}/get"); request.Cookies["my"] = "cookie"; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().ContainKey("Cookie"); @@ -470,13 +471,13 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_preserve_cookie_during_session() + public async Task should_preserve_cookie_during_session() { GivenOldCookie(); var request = new HttpRequest($"https://{_httpBinHost2}/get"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().ContainKey("Cookie"); @@ -486,30 +487,30 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_not_send_cookie_to_other_host() + public async Task should_not_send_cookie_to_other_host() { GivenOldCookie(); var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().NotContainKey("Cookie"); } [Test] - public void should_not_store_request_cookie() + public async Task should_not_store_request_cookie() { var requestGet = new HttpRequest($"https://{_httpBinHost}/get"); requestGet.Cookies.Add("my", "cookie"); requestGet.AllowAutoRedirect = false; requestGet.StoreRequestCookie = false; requestGet.StoreResponseCookie = false; - var responseGet = Subject.Get(requestGet); + var responseGet = await Subject.GetAsync(requestGet); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.AllowAutoRedirect = false; - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().BeEmpty(); @@ -517,18 +518,18 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_store_request_cookie() + public async Task should_store_request_cookie() { var requestGet = new HttpRequest($"https://{_httpBinHost}/get"); requestGet.Cookies.Add("my", "cookie"); requestGet.AllowAutoRedirect = false; requestGet.StoreRequestCookie.Should().BeTrue(); requestGet.StoreResponseCookie = false; - var responseGet = Subject.Get(requestGet); + var responseGet = await Subject.GetAsync(requestGet); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.AllowAutoRedirect = false; - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -536,7 +537,7 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_delete_request_cookie() + public async Task should_delete_request_cookie() { var requestDelete = new HttpRequest($"https://{_httpBinHost}/cookies/delete?my"); requestDelete.Cookies.Add("my", "cookie"); @@ -545,13 +546,13 @@ namespace NzbDrone.Common.Test.Http requestDelete.StoreResponseCookie = false; // Delete and redirect since that's the only way to check the internal temporary cookie container - var responseCookies = Subject.Get(requestDelete); + var responseCookies = await Subject.GetAsync(requestDelete); responseCookies.Resource.Cookies.Should().BeEmpty(); } [Test] - public void should_clear_request_cookie() + public async Task should_clear_request_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies"); requestSet.Cookies.Add("my", "cookie"); @@ -559,7 +560,7 @@ namespace NzbDrone.Common.Test.Http requestSet.StoreRequestCookie = true; requestSet.StoreResponseCookie = false; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var requestClear = new HttpRequest($"https://{_httpBinHost}/cookies"); requestClear.Cookies.Add("my", null); @@ -567,24 +568,24 @@ namespace NzbDrone.Common.Test.Http requestClear.StoreRequestCookie = true; requestClear.StoreResponseCookie = false; - var responseClear = Subject.Get(requestClear); + var responseClear = await Subject.GetAsync(requestClear); responseClear.Resource.Cookies.Should().BeEmpty(); } [Test] - public void should_not_store_response_cookie() + public async Task should_not_store_response_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie"); requestSet.AllowAutoRedirect = false; requestSet.StoreRequestCookie = false; requestSet.StoreResponseCookie.Should().BeFalse(); - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().BeEmpty(); @@ -592,18 +593,18 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_store_response_cookie() + public async Task should_store_response_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie"); requestSet.AllowAutoRedirect = false; requestSet.StoreRequestCookie = false; requestSet.StoreResponseCookie = true; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -611,13 +612,13 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_temp_store_response_cookie() + public async Task should_temp_store_response_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie"); requestSet.AllowAutoRedirect = true; requestSet.StoreRequestCookie = false; requestSet.StoreResponseCookie.Should().BeFalse(); - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); // Set and redirect since that's the only way to check the internal temporary cookie container responseSet.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -626,7 +627,7 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_overwrite_response_cookie() + public async Task should_overwrite_response_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie"); requestSet.Cookies.Add("my", "oldcookie"); @@ -634,11 +635,11 @@ namespace NzbDrone.Common.Test.Http requestSet.StoreRequestCookie = false; requestSet.StoreResponseCookie = true; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -646,7 +647,7 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_overwrite_temp_response_cookie() + public async Task should_overwrite_temp_response_cookie() { var requestSet = new HttpRequest($"https://{_httpBinHost}/cookies/set?my=cookie"); requestSet.Cookies.Add("my", "oldcookie"); @@ -654,13 +655,13 @@ namespace NzbDrone.Common.Test.Http requestSet.StoreRequestCookie = true; requestSet.StoreResponseCookie = false; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); responseSet.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "oldcookie"); @@ -668,14 +669,14 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_not_delete_response_cookie() + public async Task should_not_delete_response_cookie() { var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.Cookies.Add("my", "cookie"); requestCookies.AllowAutoRedirect = false; requestCookies.StoreRequestCookie = true; requestCookies.StoreResponseCookie = false; - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -684,13 +685,13 @@ namespace NzbDrone.Common.Test.Http requestDelete.StoreRequestCookie = false; requestDelete.StoreResponseCookie = false; - var responseDelete = Subject.Get(requestDelete); + var responseDelete = await Subject.GetAsync(requestDelete); requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.StoreRequestCookie = false; requestCookies.StoreResponseCookie = false; - responseCookies = Subject.Get(requestCookies); + responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -698,14 +699,14 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_delete_response_cookie() + public async Task should_delete_response_cookie() { var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.Cookies.Add("my", "cookie"); requestCookies.AllowAutoRedirect = false; requestCookies.StoreRequestCookie = true; requestCookies.StoreResponseCookie = false; - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -714,13 +715,13 @@ namespace NzbDrone.Common.Test.Http requestDelete.StoreRequestCookie = false; requestDelete.StoreResponseCookie = true; - var responseDelete = Subject.Get(requestDelete); + var responseDelete = await Subject.GetAsync(requestDelete); requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.StoreRequestCookie = false; requestCookies.StoreResponseCookie = false; - responseCookies = Subject.Get(requestCookies); + responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().BeEmpty(); @@ -728,14 +729,14 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_delete_temp_response_cookie() + public async Task should_delete_temp_response_cookie() { var requestCookies = new HttpRequest($"https://{_httpBinHost}/cookies"); requestCookies.Cookies.Add("my", "cookie"); requestCookies.AllowAutoRedirect = false; requestCookies.StoreRequestCookie = true; requestCookies.StoreResponseCookie = false; - var responseCookies = Subject.Get(requestCookies); + var responseCookies = await Subject.GetAsync(requestCookies); responseCookies.Resource.Cookies.Should().HaveCount(1).And.Contain("my", "cookie"); @@ -743,7 +744,7 @@ namespace NzbDrone.Common.Test.Http requestDelete.AllowAutoRedirect = true; requestDelete.StoreRequestCookie = false; requestDelete.StoreResponseCookie = false; - var responseDelete = Subject.Get(requestDelete); + var responseDelete = await Subject.GetAsync(requestDelete); responseDelete.Resource.Cookies.Should().BeEmpty(); @@ -761,13 +762,13 @@ namespace NzbDrone.Common.Test.Http { var request = new HttpRequest($"https://{_httpBinHost}/status/429"); - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.IgnoreWarns(); } [Test] - public void should_call_interceptor() + public async Task should_call_interceptor() { Mocker.SetConstant>(new[] { Mocker.GetMock().Object }); @@ -781,7 +782,7 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/get"); - Subject.Get(request); + await Subject.GetAsync(request); Mocker.GetMock() .Verify(v => v.PreRequest(It.IsAny()), Times.Once()); @@ -792,7 +793,7 @@ namespace NzbDrone.Common.Test.Http [TestCase("en-US")] [TestCase("es-ES")] - public void should_parse_malformed_cloudflare_cookie(string culture) + public async Task should_parse_malformed_cloudflare_cookie(string culture) { var origCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture); @@ -808,11 +809,11 @@ namespace NzbDrone.Common.Test.Http requestSet.AllowAutoRedirect = false; requestSet.StoreResponseCookie = true; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().ContainKey("Cookie"); @@ -830,7 +831,7 @@ namespace NzbDrone.Common.Test.Http } [TestCase("lang_code=en; expires=Wed, 23-Dec-2026 18:09:14 GMT; Max-Age=31536000; path=/; domain=.abc.com")] - public void should_reject_malformed_domain_cookie(string malformedCookie) + public async Task should_reject_malformed_domain_cookie(string malformedCookie) { try { @@ -840,11 +841,11 @@ namespace NzbDrone.Common.Test.Http requestSet.AllowAutoRedirect = false; requestSet.StoreResponseCookie = true; - var responseSet = Subject.Get(requestSet); + var responseSet = await Subject.GetAsync(requestSet); var request = new HttpRequest($"https://{_httpBinHost}/get"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers.Should().NotContainKey("Cookie"); @@ -856,12 +857,12 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_correctly_use_basic_auth() + public async Task should_correctly_use_basic_auth() { var request = new HttpRequest($"https://{_httpBinHost}/basic-auth/username/password"); request.Credentials = new BasicNetworkCredential("username", "password"); - var response = Subject.Execute(request); + var response = await Subject.ExecuteAsync(request); response.StatusCode.Should().Be(HttpStatusCode.OK); } diff --git a/src/NzbDrone.Common/Http/Dispatchers/IHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/IHttpDispatcher.cs index 8e665ceed..a5565f26b 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/IHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/IHttpDispatcher.cs @@ -1,9 +1,10 @@ using System.Net; +using System.Threading.Tasks; namespace NzbDrone.Common.Http.Dispatchers { public interface IHttpDispatcher { - HttpResponse GetResponse(HttpRequest request, CookieContainer cookies); + Task GetResponseAsync(HttpRequest request, CookieContainer cookies); } } diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 9eb61b315..732c4fbe4 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -43,7 +43,7 @@ namespace NzbDrone.Common.Http.Dispatchers _credentialCache = cacheManager.GetCache(typeof(ManagedHttpDispatcher), "credentialcache"); } - public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) + public async Task GetResponseAsync(HttpRequest request, CookieContainer cookies) { var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url) { @@ -102,7 +102,7 @@ namespace NzbDrone.Common.Http.Dispatchers var httpClient = GetClient(request.Url); - using var responseMessage = httpClient.Send(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); + using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); { byte[] data = null; @@ -110,7 +110,7 @@ namespace NzbDrone.Common.Http.Dispatchers { if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK) { - responseMessage.Content.CopyTo(request.ResponseStream, null, cts.Token); + await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token); } else { diff --git a/src/NzbDrone.Common/Http/HttpClient.cs b/src/NzbDrone.Common/Http/HttpClient.cs index 1e67641a9..0039ad9ba 100644 --- a/src/NzbDrone.Common/Http/HttpClient.cs +++ b/src/NzbDrone.Common/Http/HttpClient.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.EnvironmentInfo; @@ -25,6 +26,16 @@ namespace NzbDrone.Common.Http HttpResponse Post(HttpRequest request); HttpResponse Post(HttpRequest request) where T : new(); + + Task ExecuteAsync(HttpRequest request); + Task DownloadFileAsync(string url, string fileName); + Task GetAsync(HttpRequest request); + Task> GetAsync(HttpRequest request) + where T : new(); + Task HeadAsync(HttpRequest request); + Task PostAsync(HttpRequest request); + Task> PostAsync(HttpRequest request) + where T : new(); } public class HttpClient : IHttpClient @@ -52,11 +63,11 @@ namespace NzbDrone.Common.Http _cookieContainerCache = cacheManager.GetCache(typeof(HttpClient)); } - public HttpResponse Execute(HttpRequest request) + public virtual async Task ExecuteAsync(HttpRequest request) { var cookieContainer = InitializeRequestCookies(request); - var response = ExecuteRequest(request, cookieContainer); + var response = await ExecuteRequestAsync(request, cookieContainer); if (request.AllowAutoRedirect && response.HasHttpRedirect) { @@ -82,7 +93,7 @@ namespace NzbDrone.Common.Http request.ContentSummary = null; } - response = ExecuteRequest(request, cookieContainer); + response = await ExecuteRequestAsync(request, cookieContainer); } while (response.HasHttpRedirect); } @@ -112,6 +123,11 @@ namespace NzbDrone.Common.Http return response; } + public HttpResponse Execute(HttpRequest request) + { + return ExecuteAsync(request).GetAwaiter().GetResult(); + } + private static bool RequestRequiresForceGet(HttpStatusCode statusCode, HttpMethod requestMethod) { return statusCode switch @@ -122,7 +138,7 @@ namespace NzbDrone.Common.Http }; } - private HttpResponse ExecuteRequest(HttpRequest request, CookieContainer cookieContainer) + private async Task ExecuteRequestAsync(HttpRequest request, CookieContainer cookieContainer) { foreach (var interceptor in _requestInterceptors) { @@ -131,14 +147,14 @@ namespace NzbDrone.Common.Http if (request.RateLimit != TimeSpan.Zero) { - _rateLimitService.WaitAndPulse(request.Url.Host, request.RateLimitKey, request.RateLimit); + await _rateLimitService.WaitAndPulseAsync(request.Url.Host, request.RateLimitKey, request.RateLimit); } _logger.Trace(request); var stopWatch = Stopwatch.StartNew(); - var response = _httpDispatcher.GetResponse(request, cookieContainer); + var response = await _httpDispatcher.GetResponseAsync(request, cookieContainer); HandleResponseCookies(response, cookieContainer); @@ -246,7 +262,7 @@ namespace NzbDrone.Common.Http } } - public void DownloadFile(string url, string fileName) + public async Task DownloadFileAsync(string url, string fileName) { var fileNamePart = fileName + ".part"; @@ -261,12 +277,12 @@ namespace NzbDrone.Common.Http _logger.Debug("Downloading [{0}] to [{1}]", url, fileName); var stopWatch = Stopwatch.StartNew(); - using (var fileStream = new FileStream(fileNamePart, FileMode.Create, FileAccess.ReadWrite)) + await using (var fileStream = new FileStream(fileNamePart, FileMode.Create, FileAccess.ReadWrite)) { var request = new HttpRequest(url); request.AllowAutoRedirect = true; request.ResponseStream = fileStream; - var response = Get(request); + var response = await GetAsync(request); if (response.Headers.ContentType != null && response.Headers.ContentType.Contains("text/html")) { @@ -275,6 +291,7 @@ namespace NzbDrone.Common.Http } stopWatch.Stop(); + if (File.Exists(fileName)) { File.Delete(fileName); @@ -292,40 +309,73 @@ namespace NzbDrone.Common.Http } } - public HttpResponse Get(HttpRequest request) + public void DownloadFile(string url, string fileName) + { + // https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development#the-thread-pool-hack + Task.Run(() => DownloadFileAsync(url, fileName)).GetAwaiter().GetResult(); + } + + public Task GetAsync(HttpRequest request) { request.Method = HttpMethod.Get; - return Execute(request); + return ExecuteAsync(request); } - public HttpResponse Get(HttpRequest request) + public HttpResponse Get(HttpRequest request) + { + return Task.Run(() => GetAsync(request)).GetAwaiter().GetResult(); + } + + public async Task> GetAsync(HttpRequest request) where T : new() { - var response = Get(request); + var response = await GetAsync(request); CheckResponseContentType(response); return new HttpResponse(response); } - public HttpResponse Head(HttpRequest request) + public HttpResponse Get(HttpRequest request) + where T : new() + { + return Task.Run(() => GetAsync(request)).GetAwaiter().GetResult(); + } + + public Task HeadAsync(HttpRequest request) { request.Method = HttpMethod.Head; - return Execute(request); + return ExecuteAsync(request); } - public HttpResponse Post(HttpRequest request) + public HttpResponse Head(HttpRequest request) + { + return Task.Run(() => HeadAsync(request)).GetAwaiter().GetResult(); + } + + public Task PostAsync(HttpRequest request) { request.Method = HttpMethod.Post; - return Execute(request); + return ExecuteAsync(request); } - public HttpResponse Post(HttpRequest request) + public HttpResponse Post(HttpRequest request) + { + return Task.Run(() => PostAsync(request)).GetAwaiter().GetResult(); + } + + public async Task> PostAsync(HttpRequest request) where T : new() { - var response = Post(request); + var response = await PostAsync(request); CheckResponseContentType(response); return new HttpResponse(response); } + public HttpResponse Post(HttpRequest request) + where T : new() + { + return Task.Run(() => PostAsync(request)).GetAwaiter().GetResult(); + } + private void CheckResponseContentType(HttpResponse response) { if (response.Headers.ContentType != null && response.Headers.ContentType.Contains("text/html")) diff --git a/src/NzbDrone.Common/Http/HttpRequest.cs b/src/NzbDrone.Common/Http/HttpRequest.cs index c9ef99f62..b3ce190d4 100644 --- a/src/NzbDrone.Common/Http/HttpRequest.cs +++ b/src/NzbDrone.Common/Http/HttpRequest.cs @@ -16,6 +16,7 @@ namespace NzbDrone.Common.Http Method = HttpMethod.Get; Url = new HttpUri(url); Headers = new HttpHeader(); + ConnectionKeepAlive = true; AllowAutoRedirect = true; StoreRequestCookie = true; LogHttpError = true; diff --git a/src/NzbDrone.Common/TPL/RateLimitService.cs b/src/NzbDrone.Common/TPL/RateLimitService.cs index 87b0ff22f..b7cfd2e7c 100644 --- a/src/NzbDrone.Common/TPL/RateLimitService.cs +++ b/src/NzbDrone.Common/TPL/RateLimitService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; @@ -10,6 +11,8 @@ namespace NzbDrone.Common.TPL { void WaitAndPulse(string key, TimeSpan interval); void WaitAndPulse(string key, string subKey, TimeSpan interval); + Task WaitAndPulseAsync(string key, TimeSpan interval); + Task WaitAndPulseAsync(string key, string subKey, TimeSpan interval); } public class RateLimitService : IRateLimitService @@ -28,7 +31,34 @@ namespace NzbDrone.Common.TPL WaitAndPulse(key, null, interval); } + public async Task WaitAndPulseAsync(string key, TimeSpan interval) + { + await WaitAndPulseAsync(key, null, interval); + } + public void WaitAndPulse(string key, string subKey, TimeSpan interval) + { + var delay = GetDelay(key, subKey, interval); + + if (delay.TotalSeconds > 0.0) + { + _logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds); + System.Threading.Thread.Sleep(delay); + } + } + + public async Task WaitAndPulseAsync(string key, string subKey, TimeSpan interval) + { + var delay = GetDelay(key, subKey, interval); + + if (delay.TotalSeconds > 0.0) + { + _logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds); + await Task.Delay(delay); + } + } + + private TimeSpan GetDelay(string key, string subKey, TimeSpan interval) { var waitUntil = DateTime.UtcNow.Add(interval); @@ -59,13 +89,7 @@ namespace NzbDrone.Common.TPL waitUntil -= interval; - var delay = waitUntil - DateTime.UtcNow; - - if (delay.TotalSeconds > 0.0) - { - _logger.Trace("Rate Limit triggered, delaying '{0}' for {1:0.000} sec", key, delay.TotalSeconds); - System.Threading.Thread.Sleep(delay); - } + return waitUntil - DateTime.UtcNow; } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs index 8d774ec36..7e00b0680 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -58,7 +59,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests } [Test] - public void should_download_report_if_album_was_not_already_downloaded() + public async Task should_download_report_if_album_was_not_already_downloaded() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -66,12 +67,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteAlbum)); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_only_download_album_once() + public async Task should_only_download_album_once() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -80,12 +81,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum)); decisions.Add(new DownloadDecision(remoteAlbum)); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_not_download_if_any_album_was_already_downloaded() + public async Task should_not_download_if_any_album_was_already_downloaded() { var remoteAlbum1 = GetRemoteAlbum( new List { GetAlbum(1) }, @@ -99,12 +100,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum1)); decisions.Add(new DownloadDecision(remoteAlbum2)); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_return_downloaded_reports() + public async Task should_return_downloaded_reports() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -112,11 +113,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteAlbum)); - Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(1); + var result = await Subject.ProcessDecisions(decisions); + + result.Grabbed.Should().HaveCount(1); } [Test] - public void should_return_all_downloaded_reports() + public async Task should_return_all_downloaded_reports() { var remoteAlbum1 = GetRemoteAlbum( new List { GetAlbum(1) }, @@ -130,11 +133,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum1)); decisions.Add(new DownloadDecision(remoteAlbum2)); - Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2); + var result = await Subject.ProcessDecisions(decisions); + + result.Grabbed.Should().HaveCount(2); } [Test] - public void should_only_return_downloaded_reports() + public async Task should_only_return_downloaded_reports() { var remoteAlbum1 = GetRemoteAlbum( new List { GetAlbum(1) }, @@ -153,11 +158,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum2)); decisions.Add(new DownloadDecision(remoteAlbum3)); - Subject.ProcessDecisions(decisions).Grabbed.Should().HaveCount(2); + var result = await Subject.ProcessDecisions(decisions); + + result.Grabbed.Should().HaveCount(2); } [Test] - public void should_not_add_to_downloaded_list_when_download_fails() + public async Task should_not_add_to_downloaded_list_when_download_fails() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -166,7 +173,11 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum)); Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny())).Throws(new Exception()); - Subject.ProcessDecisions(decisions).Grabbed.Should().BeEmpty(); + + var result = await Subject.ProcessDecisions(decisions); + + result.Grabbed.Should().BeEmpty(); + ExceptionVerification.ExpectedWarns(1); } @@ -181,7 +192,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests } [Test] - public void should_not_grab_if_pending() + public async Task should_not_grab_if_pending() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -189,12 +200,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteAlbum, new Rejection("Failure!", RejectionType.Temporary))); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Never()); } [Test] - public void should_not_add_to_pending_if_album_was_grabbed() + public async Task should_not_add_to_pending_if_album_was_grabbed() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -203,12 +214,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum)); decisions.Add(new DownloadDecision(remoteAlbum, new Rejection("Failure!", RejectionType.Temporary))); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.AddMany(It.IsAny>>()), Times.Never()); } [Test] - public void should_add_to_pending_even_if_already_added_to_pending() + public async Task should_add_to_pending_even_if_already_added_to_pending() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_192)); @@ -217,12 +228,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteAlbum, new Rejection("Failure!", RejectionType.Temporary))); decisions.Add(new DownloadDecision(remoteAlbum, new Rejection("Failure!", RejectionType.Temporary))); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.AddMany(It.IsAny>>()), Times.Once()); } [Test] - public void should_add_to_failed_if_already_failed_for_that_protocol() + public async Task should_add_to_failed_if_already_failed_for_that_protocol() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_320)); @@ -234,12 +245,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests Mocker.GetMock().Setup(s => s.DownloadReport(It.IsAny())) .Throws(new DownloadClientUnavailableException("Download client failed")); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_not_add_to_failed_if_failed_for_a_different_protocol() + public async Task should_not_add_to_failed_if_failed_for_a_different_protocol() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_320), DownloadProtocol.Usenet); @@ -252,13 +263,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests Mocker.GetMock().Setup(s => s.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet))) .Throws(new DownloadClientUnavailableException("Download client failed")); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Usenet)), Times.Once()); Mocker.GetMock().Verify(v => v.DownloadReport(It.Is(r => r.Release.DownloadProtocol == DownloadProtocol.Torrent)), Times.Once()); } [Test] - public void should_add_to_rejected_if_release_unavailable_on_indexer() + public async Task should_add_to_rejected_if_release_unavailable_on_indexer() { var albums = new List { GetAlbum(1) }; var remoteAlbum = GetRemoteAlbum(albums, new QualityModel(Quality.MP3_320)); @@ -270,7 +281,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests .Setup(s => s.DownloadReport(It.IsAny())) .Throws(new ReleaseUnavailableException(remoteAlbum.Release, "That 404 Error is not just a Quirk")); - var result = Subject.ProcessDecisions(decisions); + var result = await Subject.ProcessDecisions(decisions); result.Grabbed.Should().BeEmpty(); result.Rejected.Should().NotBeEmpty(); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs index f8e3a56fa..6b09201cf 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Abstractions; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -70,7 +71,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole protected void GivenFailedDownload() { Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) + .Setup(s => s.GetAsync(It.IsAny())) .Throws(new WebException()); } @@ -148,19 +149,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole } [Test] - public void Download_should_download_file_if_it_doesnt_exist() + public async Task Download_should_download_file_if_it_doesnt_exist() { var remoteAlbum = CreateRemoteAlbum(); - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_save_magnet_if_enabled() + public async Task Download_should_save_magnet_if_enabled() { GivenMagnetFilePath(); Subject.Definition.Settings.As().SaveMagnetFiles = true; @@ -168,16 +169,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = null; - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_save_magnet_using_specified_extension() + public async Task Download_should_save_magnet_using_specified_extension() { var magnetFileExtension = ".url"; GivenMagnetFilePath(magnetFileExtension); @@ -188,12 +189,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = null; - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -203,31 +204,31 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_prefer_torrent_over_magnet() + public async Task Download_should_prefer_torrent_over_magnet() { Subject.Definition.Settings.As().SaveMagnetFiles = true; var remoteAlbum = CreateRemoteAlbum(); - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_replace_illegal_characters_in_title() + public async Task Download_should_replace_illegal_characters_in_title() { var illegalTitle = "Radiohead - Scotch Mist [2008/FLAC/Lossless]"; var expectedFilename = Path.Combine(_blackholeFolder, "Radiohead - Scotch Mist [2008+FLAC+Lossless]" + Path.GetExtension(_filePath)); @@ -235,11 +236,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.Title = illegalTitle; - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -248,7 +249,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); } [Test] @@ -318,11 +319,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole } [Test] - public void should_return_null_hash() + public async Task should_return_null_hash() { var remoteAlbum = CreateRemoteAlbum(); - Subject.Download(remoteAlbum, CreateIndexer()).Should().BeNull(); + var result = await Subject.Download(remoteAlbum, CreateIndexer()); + + result.Should().BeNull(); } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs index 6c2003976..3d79e5bd9 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Abstractions; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -119,19 +120,19 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole } [Test] - public void Download_should_download_file_if_it_doesnt_exist() + public async Task Download_should_download_file_if_it_doesnt_exist() { var remoteAlbum = CreateRemoteAlbum(); - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_replace_illegal_characters_in_title() + public async Task Download_should_replace_illegal_characters_in_title() { var illegalTitle = "Radiohead - Scotch Mist [2008/FLAC/Lossless]"; var expectedFilename = Path.Combine(_blackholeFolder, "Radiohead - Scotch Mist [2008+FLAC+Lossless]" + Path.GetExtension(_filePath)); @@ -139,11 +140,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.Title = illegalTitle; - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs index 538dea40d..58a37472d 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -200,26 +201,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")] - public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) + public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().Be(expectedHash); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs index 6f518e4b0..92ea1cb78 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NLog; @@ -36,8 +37,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests .Returns(() => CreateRemoteAlbum()); Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), Array.Empty())); + .Setup(s => s.GetAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), Array.Empty()))); Mocker.GetMock() .Setup(v => v.RemapRemoteToLocal(It.IsAny(), It.IsAny())) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs index b6f6c2025..ada9120eb 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -385,7 +386,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_with_MusicDirectory_should_force_directory() + public async Task Download_with_MusicDirectory_should_force_directory() { GivenSerialNumber(); GivenMusicDirectory(); @@ -393,7 +394,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -402,7 +403,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenSerialNumber(); GivenMusicCategory(); @@ -410,7 +411,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -419,14 +420,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_without_MusicDirectory_and_Category_should_use_default() + public async Task Download_without_MusicDirectory_and_Category_should_use_default() { GivenSerialNumber(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -505,7 +506,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests .Setup(s => s.GetSerialNumber(_settings)) .Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException")); - Assert.Throws(Is.InstanceOf(), () => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteAlbum, CreateIndexer())); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), null, _settings), Times.Never()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs index e733a7f29..ff46fabae 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -267,7 +268,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_with_MusicDirectory_should_force_directory() + public async Task Download_with_MusicDirectory_should_force_directory() { GivenSerialNumber(); GivenMusicDirectory(); @@ -275,7 +276,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -284,7 +285,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenSerialNumber(); GivenMusicCategory(); @@ -292,7 +293,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -301,14 +302,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_without_MusicDirectory_and_Category_should_use_default() + public async Task Download_without_MusicDirectory_and_Category_should_use_default() { GivenSerialNumber(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -387,7 +388,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests .Setup(s => s.GetSerialNumber(_settings)) .Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException")); - Assert.Throws(Is.InstanceOf(), () => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteAlbum, CreateIndexer())); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), null, _settings), Times.Never()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs index 03fbf1540..f23b3125b 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -103,8 +104,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests protected void GivenSuccessfulDownload() { Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), new byte[1000])); + .Setup(s => s.GetAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), new byte[1000]))); Mocker.GetMock() .Setup(s => s.AddTorrentUri(It.IsAny(), It.IsAny())) @@ -196,13 +197,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -277,7 +278,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests } [Test] - public void Download_from_magnet_link_should_return_hash_uppercase() + public async Task Download_from_magnet_link_should_return_hash_uppercase() { var remoteAlbum = CreateRemoteAlbum(); @@ -286,13 +287,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests Mocker.GetMock() .Setup(v => v.AddTorrentUri(It.IsAny(), It.IsAny())); - var result = Subject.Download(remoteAlbum, CreateIndexer()); + var result = await Subject.Download(remoteAlbum, CreateIndexer()); Assert.IsFalse(result.Any(c => char.IsLower(c))); } [Test] - public void Download_from_torrent_file_should_return_hash_uppercase() + public async Task Download_from_torrent_file_should_return_hash_uppercase() { var remoteAlbum = CreateRemoteAlbum(); @@ -300,7 +301,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests .Setup(v => v.AddTorrentFile(It.IsAny(), It.IsAny())) .Returns("hash"); - var result = Subject.Download(remoteAlbum, CreateIndexer()); + var result = await Subject.Download(remoteAlbum, CreateIndexer()); Assert.IsFalse(result.Any(c => char.IsLower(c))); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbVortexTests/NzbVortexFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbVortexTests/NzbVortexFixture.cs index ccabbbb06..a11b557a7 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbVortexTests/NzbVortexFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbVortexTests/NzbVortexFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -200,13 +201,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -218,7 +219,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests var remoteAlbum = CreateRemoteAlbum(); - Assert.Throws(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs index 80c8e3b46..be7f06d81 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/NzbgetTests/NzbgetFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -339,13 +340,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -357,7 +358,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests var remoteAlbum = CreateRemoteAlbum(); - Assert.Throws(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs index cb335d528..bc849ad89 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using Moq; using NLog; @@ -65,15 +66,15 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests private void WithFailedDownload() { - Mocker.GetMock().Setup(c => c.DownloadFile(It.IsAny(), It.IsAny())).Throws(new WebException()); + Mocker.GetMock().Setup(c => c.DownloadFileAsync(It.IsAny(), It.IsAny())).Throws(new WebException()); } [Test] - public void should_download_file_if_it_doesnt_exist() + public async Task should_download_file_if_it_doesnt_exist() { - Subject.Download(_remoteAlbum, _indexer); + await Subject.Download(_remoteAlbum, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(_nzbUrl, _nzbPath), Times.Once()); } [Test] @@ -81,7 +82,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests { WithFailedDownload(); - Assert.Throws(() => Subject.Download(_remoteAlbum, _indexer)); + Assert.ThrowsAsync(async () => await Subject.Download(_remoteAlbum, _indexer)); } [Test] @@ -90,7 +91,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests _remoteAlbum.Release.Title = "Alien Ant Farm - Discography"; _remoteAlbum.ParsedAlbumInfo.Discography = true; - Assert.Throws(() => Subject.Download(_remoteAlbum, _indexer)); + Assert.ThrowsAsync(async () => await Subject.Download(_remoteAlbum, _indexer)); } [Test] @@ -100,15 +101,15 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests } [Test] - public void should_replace_illegal_characters_in_title() + public async Task should_replace_illegal_characters_in_title() { var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]"; var expectedFilename = Path.Combine(_pneumaticFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV].nzb"); _remoteAlbum.Release.Title = illegalTitle; - Subject.Download(_remoteAlbum, _indexer); + await Subject.Download(_remoteAlbum, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), expectedFilename), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), expectedFilename), Times.Once()); } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs index 56e5d1492..76ecd4c57 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -448,26 +449,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")] - public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) + public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().Be(expectedHash); } @@ -482,7 +483,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR"; - Assert.Throws(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); } [Test] @@ -495,28 +496,28 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp://abc"; - Assert.DoesNotThrow(() => Subject.Download(remoteAlbum, CreateIndexer())); + Assert.DoesNotThrowAsync(async () => await Subject.Download(remoteAlbum, CreateIndexer())); Mocker.GetMock() .Verify(s => s.AddTorrentFromUrl(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_should_set_top_priority() + public async Task Download_should_set_top_priority() { GivenHighPriority(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); Mocker.GetMock() .Verify(v => v.MoveTorrentToTopInQueue(It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_should_not_fail_if_top_priority_not_available() + public async Task Download_should_not_fail_if_top_priority_not_available() { GivenHighPriority(); GivenSuccessfulDownload(); @@ -527,7 +528,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -554,27 +555,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests } [Test] - public void Download_should_handle_http_redirect_to_magnet() + public async Task Download_should_handle_http_redirect_to_magnet() { GivenRedirectToMagnet(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_should_handle_http_redirect_to_torrent() + public async Task Download_should_handle_http_redirect_to_torrent() { GivenRedirectToTorrent(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs index 13e77846b..200c8a2bd 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -111,13 +112,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs index 5d814a7cb..811ee6444 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -300,27 +301,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests } [TestCase("[ TOWN ]-[ http://www.town.ag ]-[ ANIME ]-[Usenet Provider >> http://www.ssl- <<] - [Commie] Aldnoah Zero 18 [234C8FC7]", "[ TOWN ]-[ http-++www.town.ag ]-[ ANIME ]-[Usenet Provider http-++www.ssl- ] - [Commie] Aldnoah Zero 18 [234C8FC7].nzb")] - public void Download_should_use_clean_title(string title, string filename) + public async Task Download_should_use_clean_title(string title, string filename) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.Title = title; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); Mocker.GetMock() .Verify(v => v.DownloadNzb(It.IsAny(), filename, It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -353,7 +354,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests } [Test] - public void Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true() + public async Task Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true() { Mocker.GetMock() .Setup(s => s.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny())) @@ -366,7 +367,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests .Build() .ToList(); - Subject.Download(remoteAlbum, CreateIndexer()); + await Subject.Download(remoteAlbum, CreateIndexer()); Mocker.GetMock() .Verify(v => v.DownloadNzb(It.IsAny(), It.IsAny(), It.IsAny(), (int)SabnzbdPriority.High, It.IsAny()), Times.Once()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs index 6e46b345d..f9ae85b30 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -55,26 +56,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_MusicDirectory_should_force_directory() + public async Task Download_with_MusicDirectory_should_force_directory() { GivenMusicDirectory(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -83,14 +84,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenMusicCategory(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -99,7 +100,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [Test] - public void Download_with_category_should_not_have_double_slashes() + public async Task Download_with_category_should_not_have_double_slashes() { GivenMusicCategory(); GivenSuccessfulDownload(); @@ -108,7 +109,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -117,13 +118,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [Test] - public void Download_without_MusicDirectory_and_Category_should_use_default() + public async Task Download_without_MusicDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -132,14 +133,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")] - public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) + public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().Be(expectedHash); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/UTorrentTests/UTorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/UTorrentTests/UTorrentFixture.cs index 3cf7b0326..6b45ed90f 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/UTorrentTests/UTorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/UTorrentTests/UTorrentFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -228,13 +229,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -252,14 +253,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests // Proxy.GetTorrents does not return original url. So item has to be found via magnet url. [TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")] - public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) + public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().Be(expectedHash); } @@ -350,27 +351,27 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests } [Test] - public void Download_should_handle_http_redirect_to_magnet() + public async Task Download_should_handle_http_redirect_to_magnet() { GivenRedirectToMagnet(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_should_handle_http_redirect_to_torrent() + public async Task Download_should_handle_http_redirect_to_torrent() { GivenRedirectToTorrent(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/VuzeTests/VuzeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/VuzeTests/VuzeFixture.cs index 91ed4538a..8d9556b30 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/VuzeTests/VuzeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/VuzeTests/VuzeFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -63,26 +64,26 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_MusicDirectory_should_force_directory() + public async Task Download_with_MusicDirectory_should_force_directory() { GivenMusicDirectory(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -91,14 +92,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenMusicCategory(); GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -107,7 +108,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [Test] - public void Download_with_category_should_not_have_double_slashes() + public async Task Download_with_category_should_not_have_double_slashes() { GivenMusicCategory(); GivenSuccessfulDownload(); @@ -116,7 +117,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -125,13 +126,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [Test] - public void Download_without_MusicDirectory_and_Category_should_use_default() + public async Task Download_without_MusicDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -140,14 +141,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [TestCase("magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp", "CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951")] - public void Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) + public async Task Download_should_get_hash_from_magnet_url(string magnetUrl, string expectedHash) { GivenSuccessfulDownload(); var remoteAlbum = CreateRemoteAlbum(); remoteAlbum.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteAlbum, CreateIndexer()); + var id = await Subject.Download(remoteAlbum, CreateIndexer()); id.Should().Be(expectedHash); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index dc142d478..27cae1e9a 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using Moq; using NUnit.Framework; @@ -77,23 +78,23 @@ namespace NzbDrone.Core.Test.Download } [Test] - public void Download_report_should_publish_on_grab_event() + public async Task Download_report_should_publish_on_grab_event() { var mock = WithUsenetClient(); mock.Setup(s => s.Download(It.IsAny(), It.IsAny())); - Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult); VerifyEventPublished(); } [Test] - public void Download_report_should_grab_using_client() + public async Task Download_report_should_grab_using_client() { var mock = WithUsenetClient(); mock.Setup(s => s.Download(It.IsAny(), It.IsAny())); - Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult); mock.Verify(s => s.Download(It.IsAny(), It.IsAny()), Times.Once()); } @@ -105,7 +106,7 @@ namespace NzbDrone.Core.Test.Download mock.Setup(s => s.Download(It.IsAny(), It.IsAny())) .Throws(new WebException()); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); VerifyEventNotPublished(); } @@ -120,7 +121,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new WebException()); }); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Once()); @@ -140,7 +141,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response)); }); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), TimeSpan.FromMinutes(5.0)), Times.Once()); @@ -160,7 +161,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseDownloadException(v.Release, "Error", new TooManyRequestsException(request, response)); }); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), @@ -174,7 +175,7 @@ namespace NzbDrone.Core.Test.Download mock.Setup(s => s.Download(It.IsAny(), It.IsAny())) .Throws(new DownloadClientException("Some Error")); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Never()); @@ -190,7 +191,7 @@ namespace NzbDrone.Core.Test.Download throw new ReleaseUnavailableException(v.Release, "Error", new WebException()); }); - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), It.IsAny()), Times.Never()); @@ -199,14 +200,14 @@ namespace NzbDrone.Core.Test.Download [Test] public void should_not_attempt_download_if_client_isnt_configured() { - Assert.Throws(() => Subject.DownloadReport(_parseResult)); + Assert.ThrowsAsync(async () => await Subject.DownloadReport(_parseResult)); Mocker.GetMock().Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); VerifyEventNotPublished(); } [Test] - public void should_attempt_download_even_if_client_is_disabled() + public async Task should_attempt_download_even_if_client_is_disabled() { var mockUsenet = WithUsenetClient(); @@ -221,7 +222,7 @@ namespace NzbDrone.Core.Test.Download } }); - Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult); Mocker.GetMock().Verify(c => c.GetBlockedProviders(), Times.Never()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); @@ -229,26 +230,26 @@ namespace NzbDrone.Core.Test.Download } [Test] - public void should_send_download_to_correct_usenet_client() + public async Task should_send_download_to_correct_usenet_client() { var mockTorrent = WithTorrentClient(); var mockUsenet = WithUsenetClient(); - Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult); mockTorrent.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void should_send_download_to_correct_torrent_client() + public async Task should_send_download_to_correct_torrent_client() { var mockTorrent = WithTorrentClient(); var mockUsenet = WithUsenetClient(); _parseResult.Release.DownloadProtocol = DownloadProtocol.Torrent; - Subject.DownloadReport(_parseResult); + await Subject.DownloadReport(_parseResult); mockTorrent.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Once()); mockUsenet.Verify(c => c.Download(It.IsAny(), It.IsAny()), Times.Never()); diff --git a/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs index edbb71f42..27a1db77e 100644 --- a/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerSearchTests/ArtistSearchServiceFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Moq; using NUnit.Framework; using NzbDrone.Core.DecisionEngine; @@ -27,11 +28,11 @@ namespace NzbDrone.Core.Test.IndexerSearchTests Mocker.GetMock() .Setup(s => s.ArtistSearch(_artist.Id, false, true, false)) - .Returns(new List()); + .Returns(Task.FromResult(new List())); Mocker.GetMock() .Setup(s => s.ProcessDecisions(It.IsAny>())) - .Returns(new ProcessedDecisions(new List(), new List(), new List())); + .Returns(Task.FromResult(new ProcessedDecisions(new List(), new List(), new List()))); } [Test] diff --git a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs index 732825188..995332eca 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/FileListTests/FileListFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -26,15 +27,15 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests } [Test] - public void should_parse_recent_feed_from_FileList() + public async Task should_parse_recent_feed_from_FileList() { var recentFeed = ReadAllText(@"Files/Indexers/FileList/RecentFeed.json"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(2); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs index d9a7242a5..018590181 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -30,24 +31,24 @@ namespace NzbDrone.Core.Test.IndexerTests.GazelleTests } [Test] - public void should_parse_recent_feed_from_gazelle() + public async Task should_parse_recent_feed_from_gazelle() { var recentFeed = ReadAllText(@"Files/Indexers/Gazelle/Gazelle.json"); var indexFeed = ReadAllText(@"Files/Indexers/Gazelle/GazelleIndex.json"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get && v.Url.FullUri.Contains("ajax.php?action=browse")))) - .Returns(r => new HttpResponse(r, new HttpHeader { ContentType = "application/json" }, recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get && v.Url.FullUri.Contains("ajax.php?action=browse")))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = "application/json" }, recentFeed))); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Post && v.Url.FullUri.Contains("ajax.php?action=index")))) - .Returns(r => new HttpResponse(r, new HttpHeader(), indexFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Post && v.Url.FullUri.Contains("ajax.php?action=index")))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), indexFeed))); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Post && v.Url.FullUri.Contains("login.php")))) - .Returns(r => new HttpResponse(r, new HttpHeader(), indexFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Post && v.Url.FullUri.Contains("login.php")))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), indexFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(4); diff --git a/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleRequestGeneratorFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleRequestGeneratorFixture.cs index 947d6aebd..b8f0a5fae 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleRequestGeneratorFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleRequestGeneratorFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NLog; @@ -10,7 +11,7 @@ using NzbDrone.Core.Indexers.Gazelle; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Test.Framework; -namespace NzbDrone.Core.Test.IndexerTests.NewznabTests +namespace NzbDrone.Core.Test.IndexerTests.GazelleTests { public class GazelleRequestGeneratorFixture : CoreTest { @@ -40,8 +41,8 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests }; Mocker.GetMock() - .Setup(v => v.Execute(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), "{ \"status\": \"success\", \"response\": { \"authkey\": \"key\", \"passkey\": \"key\" } }")); + .Setup(v => v.ExecuteAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), "{ \"status\": \"success\", \"response\": { \"authkey\": \"key\", \"passkey\": \"key\" } }"))); Mocker.GetMock>>() .Setup(v => v.Find(It.IsAny())) diff --git a/src/NzbDrone.Core.Test/IndexerTests/HeadphonesTests/HeadphonesFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/HeadphonesTests/HeadphonesFixture.cs index a2e4aef56..08d7b44b1 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/HeadphonesTests/HeadphonesFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/HeadphonesTests/HeadphonesFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -38,15 +39,15 @@ namespace NzbDrone.Core.Test.IndexerTests.HeadphonesTests } [Test] - public void should_parse_recent_feed_from_headphones() + public async Task should_parse_recent_feed_from_headphones() { var recentFeed = ReadAllText(@"Files/Indexers/Headphones/Headphones.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(16); diff --git a/src/NzbDrone.Core.Test/IndexerTests/IPTorrentsTests/IPTorrentsFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/IPTorrentsTests/IPTorrentsFixture.cs index 14238d93f..890acf429 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/IPTorrentsTests/IPTorrentsFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/IPTorrentsTests/IPTorrentsFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -84,15 +85,15 @@ namespace NzbDrone.Core.Test.IndexerTests.IPTorrentsTests } [Test] - public void should_parse_recent_feed_from_IPTorrents() + public async Task should_parse_recent_feed_from_IPTorrents() { var recentFeed = ReadAllText(@"Files/Indexers/IPTorrents/IPTorrents.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs index 68c78043b..40eca431d 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Net; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -39,15 +40,15 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests } [Test] - public void should_parse_recent_feed_from_newznab_nzb_su() + public async Task should_parse_recent_feed_from_newznab_nzb_su() { var recentFeed = ReadAllText(@"Files/Indexers/Newznab/newznab_nzb_su.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(100); @@ -83,7 +84,7 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests } [Test] - public void should_record_indexer_failure_if_caps_throw() + public async Task should_record_indexer_failure_if_caps_throw() { var request = new HttpRequest("http://my.indexer.com"); var response = new HttpResponse(request, new HttpHeader(), Array.Empty(), (HttpStatusCode)429); @@ -96,7 +97,9 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests _caps.MaxPageSize = 30; _caps.DefaultPageSize = 25; - Subject.FetchRecent().Should().BeEmpty(); + var releases = await Subject.FetchRecent(); + + releases.Should().BeEmpty(); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), TimeSpan.FromMinutes(5.0)), Times.Once()); diff --git a/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs index 14e926ce2..c98c9126d 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -26,15 +27,15 @@ namespace NzbDrone.Core.Test.IndexerTests.NyaaTests } [Test] - public void should_parse_recent_feed_from_Nyaa() + public async Task should_parse_recent_feed_from_Nyaa() { var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(4); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs index c5afaead9..06b462283 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -28,17 +29,17 @@ namespace NzbDrone.Core.Test.IndexerTests.RedactedTests } [Test] - public void should_parse_recent_feed_from_redacted() + public async Task should_parse_recent_feed_from_redacted() { var recentFeed = ReadAllText(@"Files/Indexers/Gazelle/Gazelle.json"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get && + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get && v.Url.FullUri.Contains("ajax.php?action=browse") && v.Headers.Get("Authorization") == ((RedactedSettings)Subject.Definition.Settings).ApiKey))) - .Returns(r => new HttpResponse(r, new HttpHeader { ContentType = "application/json" }, recentFeed)); + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = "application/json" }, recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(4); diff --git a/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TestTorrentRssIndexer.cs b/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TestTorrentRssIndexer.cs index 110db4ec2..d969c5653 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TestTorrentRssIndexer.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TestTorrentRssIndexer.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests { var result = new List(); SetupNLog(); // Enable this to enable trace logging with nlog for debugging purposes - Test(result); + Test(result).GetAwaiter().GetResult(); return result; } diff --git a/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TorrentRssIndexerFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TorrentRssIndexerFixture.cs index 506e8ad18..e25421379 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TorrentRssIndexerFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/TorrentRssIndexerTests/TorrentRssIndexerFixture.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -34,17 +35,21 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests { var recentFeed = ReadAllText(@"Files/Indexers/" + rssXmlFile); + Mocker.GetMock() + .Setup(o => o.ExecuteAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); + Mocker.GetMock() .Setup(o => o.Execute(It.IsAny())) .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); } [Test] - public void should_parse_recent_feed_from_ImmortalSeed() + public async Task should_parse_recent_feed_from_ImmortalSeed() { GivenRecentFeedResponse("TorrentRss/ImmortalSeed.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(50); releases.First().Should().BeOfType(); @@ -66,11 +71,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_Ezrss() + public async Task should_parse_recent_feed_from_Ezrss() { GivenRecentFeedResponse("TorrentRss/Ezrss.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(3); releases.First().Should().BeOfType(); @@ -92,13 +97,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_ShowRSS_info() + public async Task should_parse_recent_feed_from_ShowRSS_info() { Subject.Definition.Settings.As().AllowZeroSize = true; GivenRecentFeedResponse("TorrentRss/ShowRSS.info.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); @@ -120,13 +125,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_Doki() + public async Task should_parse_recent_feed_from_Doki() { Subject.Definition.Settings.As().AllowZeroSize = true; GivenRecentFeedResponse("TorrentRss/Doki.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); @@ -148,11 +153,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_ExtraTorrents() + public async Task should_parse_recent_feed_from_ExtraTorrents() { GivenRecentFeedResponse("TorrentRss/ExtraTorrents.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); @@ -174,11 +179,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_LimeTorrents() + public async Task should_parse_recent_feed_from_LimeTorrents() { GivenRecentFeedResponse("TorrentRss/LimeTorrents.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); @@ -200,11 +205,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_AnimeTosho_without_size() + public async Task should_parse_recent_feed_from_AnimeTosho_without_size() { GivenRecentFeedResponse("TorrentRss/AnimeTosho_NoSize.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(2); releases.First().Should().BeOfType(); @@ -226,11 +231,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_multi_enclosure_from_AnimeTosho() + public async Task should_parse_multi_enclosure_from_AnimeTosho() { GivenRecentFeedResponse("TorrentRss/AnimeTosho_NoSize.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(2); releases.Last().Should().BeOfType(); @@ -243,11 +248,11 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_AlphaRatio() + public async Task should_parse_recent_feed_from_AlphaRatio() { GivenRecentFeedResponse("TorrentRss/AlphaRatio.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(2); releases.Last().Should().BeOfType(); @@ -260,12 +265,12 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_parse_recent_feed_from_EveolutionWorld_without_size() + public async Task should_parse_recent_feed_from_EveolutionWorld_without_size() { Subject.Definition.Settings.As().AllowZeroSize = true; GivenRecentFeedResponse("TorrentRss/EvolutionWorld.xml"); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(2); releases.First().Should().BeOfType(); @@ -287,11 +292,13 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests } [Test] - public void should_record_indexer_failure_if_unsupported_feed() + public async Task should_record_indexer_failure_if_unsupported_feed() { GivenRecentFeedResponse("TorrentRss/invalid/TorrentDay_NoPubDate.xml"); - Subject.FetchRecent().Should().BeEmpty(); + var releases = await Subject.FetchRecent(); + + releases.Should().BeEmpty(); Mocker.GetMock() .Verify(v => v.RecordFailure(It.IsAny(), TimeSpan.Zero), Times.Once()); diff --git a/src/NzbDrone.Core.Test/IndexerTests/TorrentleechTests/TorrentleechFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/TorrentleechTests/TorrentleechFixture.cs index 59a284276..a40b246d2 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/TorrentleechTests/TorrentleechFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/TorrentleechTests/TorrentleechFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -26,15 +27,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentleechTests } [Test] - public void should_parse_recent_feed_from_Torrentleech() + public async Task should_parse_recent_feed_from_Torrentleech() { var recentFeed = ReadAllText(@"Files/Indexers/Torrentleech/Torrentleech.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/TorznabTests/TorznabFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/TorznabTests/TorznabFixture.cs index 91b5c38ad..7098d758f 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/TorznabTests/TorznabFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/TorznabTests/TorznabFixture.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -44,15 +45,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests } [Test] - public void should_parse_recent_feed_from_torznab_hdaccess_net() + public async Task should_parse_recent_feed_from_torznab_hdaccess_net() { var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_hdaccess_net.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); @@ -73,15 +74,15 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests } [Test] - public void should_parse_recent_feed_from_torznab_tpb() + public async Task should_parse_recent_feed_from_torznab_tpb() { var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_tpb.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); - var releases = Subject.FetchRecent(); + var releases = await Subject.FetchRecent(); releases.Should().HaveCount(5); @@ -140,8 +141,8 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests (Subject.Definition.Settings as TorznabSettings).BaseUrl = baseUrl; Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); var result = new NzbDroneValidationResult(Subject.Test()); result.IsValid.Should().BeTrue(); @@ -155,8 +156,8 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_tpb.xml"); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), recentFeed))); (Subject.Definition.Settings as TorznabSettings).ApiPath = apiPath; diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs index 7e9102d52..df47e136d 100644 --- a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs +++ b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; @@ -32,7 +33,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic public override DownloadProtocol Protocol => DownloadProtocol.Usenet; - public override string Download(RemoteAlbum remoteAlbum, IIndexer indexer) + public override async Task Download(RemoteAlbum remoteAlbum, IIndexer indexer) { var url = remoteAlbum.Release.DownloadUrl; var title = remoteAlbum.Release.Title; @@ -48,7 +49,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic var nzbFile = Path.Combine(Settings.NzbFolder, title + ".nzb"); _logger.Debug("Downloading NZB from: {0} to: {1}", url, nzbFile); - _httpClient.DownloadFile(url, nzbFile); + await _httpClient.DownloadFileAsync(url, nzbFile); _logger.Debug("NZB Download succeeded, saved to: {0}", nzbFile); diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs index c1233df84..668d17011 100644 --- a/src/NzbDrone.Core/Download/DownloadClientBase.cs +++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; @@ -58,7 +59,7 @@ namespace NzbDrone.Core.Download get; } - public abstract string Download(RemoteAlbum remoteAlbum, IIndexer indexer); + public abstract Task Download(RemoteAlbum remoteAlbum, IIndexer indexer); public abstract IEnumerable GetItems(); public virtual DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt) diff --git a/src/NzbDrone.Core/Download/DownloadService.cs b/src/NzbDrone.Core/Download/DownloadService.cs index 439d63d82..8fab26e6c 100644 --- a/src/NzbDrone.Core/Download/DownloadService.cs +++ b/src/NzbDrone.Core/Download/DownloadService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.EnsureThat; using NzbDrone.Common.Extensions; @@ -16,7 +17,7 @@ namespace NzbDrone.Core.Download { public interface IDownloadService { - void DownloadReport(RemoteAlbum remoteAlbum); + Task DownloadReport(RemoteAlbum remoteAlbum); } public class DownloadService : IDownloadService @@ -49,7 +50,7 @@ namespace NzbDrone.Core.Download _logger = logger; } - public void DownloadReport(RemoteAlbum remoteAlbum) + public async Task DownloadReport(RemoteAlbum remoteAlbum) { var filterBlockedClients = remoteAlbum.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; @@ -57,10 +58,10 @@ namespace NzbDrone.Core.Download var downloadClient = _downloadClientProvider.GetDownloadClient(remoteAlbum.Release.DownloadProtocol, remoteAlbum.Release.IndexerId, filterBlockedClients, tags); - DownloadReport(remoteAlbum, downloadClient); + await DownloadReport(remoteAlbum, downloadClient); } - private void DownloadReport(RemoteAlbum remoteAlbum, IDownloadClient downloadClient) + private async Task DownloadReport(RemoteAlbum remoteAlbum, IDownloadClient downloadClient) { Ensure.That(remoteAlbum.Artist, () => remoteAlbum.Artist).IsNotNull(); Ensure.That(remoteAlbum.Albums, () => remoteAlbum.Albums).HasItems(); @@ -79,7 +80,7 @@ namespace NzbDrone.Core.Download if (remoteAlbum.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteAlbum.Release.DownloadUrl.StartsWith("magnet:")) { var url = new HttpUri(remoteAlbum.Release.DownloadUrl); - _rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2)); + await _rateLimitService.WaitAndPulseAsync(url.Host, TimeSpan.FromSeconds(2)); } IIndexer indexer = null; @@ -92,7 +93,7 @@ namespace NzbDrone.Core.Download string downloadClientId; try { - downloadClientId = downloadClient.Download(remoteAlbum, indexer); + downloadClientId = await downloadClient.Download(remoteAlbum, indexer); _downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id); _indexerStatusService.RecordSuccess(remoteAlbum.Release.IndexerId); } diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index 68bb5743f..de69027e3 100644 --- a/src/NzbDrone.Core/Download/IDownloadClient.cs +++ b/src/NzbDrone.Core/Download/IDownloadClient.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using NzbDrone.Core.Indexers; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.ThingiProvider; @@ -8,8 +9,7 @@ namespace NzbDrone.Core.Download public interface IDownloadClient : IProvider { DownloadProtocol Protocol { get; } - - string Download(RemoteAlbum remoteAlbum, IIndexer indexer); + Task Download(RemoteAlbum remoteAlbum, IIndexer indexer); IEnumerable GetItems(); DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt); void RemoveItem(DownloadClientItem item, bool deleteData); diff --git a/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs b/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs index ab7c67f3d..5dd85b2ff 100644 --- a/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs +++ b/src/NzbDrone.Core/Download/ProcessDownloadDecisions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using NLog; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download.Clients; @@ -12,7 +13,7 @@ namespace NzbDrone.Core.Download { public interface IProcessDownloadDecisions { - ProcessedDecisions ProcessDecisions(List decisions); + Task ProcessDecisions(List decisions); } public class ProcessDownloadDecisions : IProcessDownloadDecisions @@ -33,7 +34,7 @@ namespace NzbDrone.Core.Download _logger = logger; } - public ProcessedDecisions ProcessDecisions(List decisions) + public async Task ProcessDecisions(List decisions) { var qualifiedReports = GetQualifiedReports(decisions); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(qualifiedReports); @@ -75,7 +76,7 @@ namespace NzbDrone.Core.Download try { _logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteAlbum.Release.Indexer, remoteAlbum.Release.IndexerPriority); - _downloadService.DownloadReport(remoteAlbum); + await _downloadService.DownloadReport(remoteAlbum); grabbed.Add(report); } catch (ReleaseUnavailableException) diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index 939aa7f04..09e8ac551 100644 --- a/src/NzbDrone.Core/Download/TorrentClientBase.cs +++ b/src/NzbDrone.Core/Download/TorrentClientBase.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading.Tasks; using MonoTorrent; using NLog; using NzbDrone.Common.Disk; @@ -41,7 +42,7 @@ namespace NzbDrone.Core.Download protected abstract string AddFromMagnetLink(RemoteAlbum remoteAlbum, string hash, string magnetLink); protected abstract string AddFromTorrentFile(RemoteAlbum remoteAlbum, string hash, string filename, byte[] fileContent); - public override string Download(RemoteAlbum remoteAlbum, IIndexer indexer) + public override async Task Download(RemoteAlbum remoteAlbum, IIndexer indexer) { var torrentInfo = remoteAlbum.Release as TorrentInfo; @@ -68,7 +69,7 @@ namespace NzbDrone.Core.Download { try { - return DownloadFromWebUrl(remoteAlbum, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteAlbum, indexer, torrentUrl); } catch (Exception ex) { @@ -114,14 +115,14 @@ namespace NzbDrone.Core.Download if (torrentUrl.IsNotNullOrWhiteSpace()) { - return DownloadFromWebUrl(remoteAlbum, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteAlbum, indexer, torrentUrl); } } return null; } - private string DownloadFromWebUrl(RemoteAlbum remoteAlbum, IIndexer indexer, string torrentUrl) + private async Task DownloadFromWebUrl(RemoteAlbum remoteAlbum, IIndexer indexer, string torrentUrl) { byte[] torrentFile = null; @@ -132,7 +133,7 @@ namespace NzbDrone.Core.Download request.Headers.Accept = "application/x-bittorrent"; request.AllowAutoRedirect = false; - var response = _httpClient.Get(request); + var response = await _httpClient.GetAsync(request); if (response.StatusCode == HttpStatusCode.MovedPermanently || response.StatusCode == HttpStatusCode.Found || @@ -151,7 +152,7 @@ namespace NzbDrone.Core.Download request.Url += new HttpUri(locationHeader); - return DownloadFromWebUrl(remoteAlbum, indexer, request.Url.ToString()); + return await DownloadFromWebUrl(remoteAlbum, indexer, request.Url.ToString()); } throw new WebException("Remote website tried to redirect without providing a location."); diff --git a/src/NzbDrone.Core/Download/UsenetClientBase.cs b/src/NzbDrone.Core/Download/UsenetClientBase.cs index b49dfd3a8..945739026 100644 --- a/src/NzbDrone.Core/Download/UsenetClientBase.cs +++ b/src/NzbDrone.Core/Download/UsenetClientBase.cs @@ -1,4 +1,5 @@ using System.Net; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Http; @@ -34,7 +35,7 @@ namespace NzbDrone.Core.Download protected abstract string AddFromNzbFile(RemoteAlbum remoteAlbum, string filename, byte[] fileContent); - public override string Download(RemoteAlbum remoteAlbum, IIndexer indexer) + public override async Task Download(RemoteAlbum remoteAlbum, IIndexer indexer) { var url = remoteAlbum.Release.DownloadUrl; var filename = FileNameBuilder.CleanFileName(remoteAlbum.Release.Title) + ".nzb"; @@ -46,7 +47,9 @@ namespace NzbDrone.Core.Download var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url); request.RateLimitKey = remoteAlbum?.Release?.IndexerId.ToString(); - nzbData = _httpClient.Get(request).ResponseData; + var response = await _httpClient.GetAsync(request); + + nzbData = response.ResponseData; _logger.Debug("Downloaded nzb for release '{0}' finished ({1} bytes from {2})", remoteAlbum.Release.Title, nzbData.Length, url); } diff --git a/src/NzbDrone.Core/IndexerSearch/AlbumSearchService.cs b/src/NzbDrone.Core/IndexerSearch/AlbumSearchService.cs index 3759c0e04..1b2dbc649 100644 --- a/src/NzbDrone.Core/IndexerSearch/AlbumSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/AlbumSearchService.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.Datastore; @@ -39,7 +40,7 @@ namespace NzbDrone.Core.IndexerSearch _logger = logger; } - private void SearchForMissingAlbums(List albums, bool userInvokedSearch) + private async Task SearchForMissingAlbums(List albums, bool userInvokedSearch) { _logger.ProgressInfo("Performing missing search for {0} albums", albums.Count); var downloadedCount = 0; @@ -47,8 +48,8 @@ namespace NzbDrone.Core.IndexerSearch foreach (var album in albums) { List decisions; - decisions = _releaseSearchService.AlbumSearch(album.Id, false, userInvokedSearch, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + decisions = await _releaseSearchService.AlbumSearch(album.Id, false, userInvokedSearch, false); + var processed = await _processDownloadDecisions.ProcessDecisions(decisions); downloadedCount += processed.Grabbed.Count; } @@ -60,9 +61,8 @@ namespace NzbDrone.Core.IndexerSearch { foreach (var albumId in message.AlbumIds) { - var decisions = - _releaseSearchService.AlbumSearch(albumId, false, message.Trigger == CommandTrigger.Manual, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var decisions = _releaseSearchService.AlbumSearch(albumId, false, message.Trigger == CommandTrigger.Manual, false).GetAwaiter().GetResult(); + var processed = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); _logger.ProgressInfo("Album search completed. {0} reports downloaded.", processed.Grabbed.Count); } @@ -106,7 +106,7 @@ namespace NzbDrone.Core.IndexerSearch var queue = _queueService.GetQueue().Where(q => q.Album != null).Select(q => q.Album.Id); var missing = albums.Where(e => !queue.Contains(e.Id)).ToList(); - SearchForMissingAlbums(missing, message.Trigger == CommandTrigger.Manual); + SearchForMissingAlbums(missing, message.Trigger == CommandTrigger.Manual).GetAwaiter().GetResult(); } public void Execute(CutoffUnmetAlbumSearchCommand message) @@ -132,7 +132,7 @@ namespace NzbDrone.Core.IndexerSearch var queue = _queueService.GetQueue().Where(q => q.Album != null).Select(q => q.Album.Id); var missing = albums.Where(e => !queue.Contains(e.Id)).ToList(); - SearchForMissingAlbums(missing, message.Trigger == CommandTrigger.Manual); + SearchForMissingAlbums(missing, message.Trigger == CommandTrigger.Manual).GetAwaiter().GetResult(); } } } diff --git a/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs index c4cb6a5ec..e0a618d28 100644 --- a/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/ArtistSearchService.cs @@ -22,8 +22,8 @@ namespace NzbDrone.Core.IndexerSearch public void Execute(ArtistSearchCommand message) { - var decisions = _releaseSearchService.ArtistSearch(message.ArtistId, false, message.Trigger == CommandTrigger.Manual, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var decisions = _releaseSearchService.ArtistSearch(message.ArtistId, false, message.Trigger == CommandTrigger.Manual, false).GetAwaiter().GetResult(); + var processed = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); _logger.ProgressInfo("Artist search completed. {0} reports downloaded.", processed.Grabbed.Count); } diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs index 5205c0e3e..cc6fad685 100644 --- a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Instrumentation.Extensions; -using NzbDrone.Common.TPL; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Indexers; using NzbDrone.Core.IndexerSearch.Definitions; @@ -16,8 +15,8 @@ namespace NzbDrone.Core.IndexerSearch { public interface ISearchForReleases { - List AlbumSearch(int albumId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); - List ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + Task> AlbumSearch(int albumId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + Task> ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); } public class ReleaseSearchService : ISearchForReleases @@ -41,19 +40,21 @@ namespace NzbDrone.Core.IndexerSearch _logger = logger; } - public List AlbumSearch(int albumId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> AlbumSearch(int albumId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var album = _albumService.GetAlbum(albumId); - return AlbumSearch(album, missingOnly, userInvokedSearch, interactiveSearch); + + return await AlbumSearch(album, missingOnly, userInvokedSearch, interactiveSearch); } - public List ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> ArtistSearch(int artistId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var artist = _artistService.GetArtist(artistId); - return ArtistSearch(artist, missingOnly, userInvokedSearch, interactiveSearch); + + return await ArtistSearch(artist, missingOnly, userInvokedSearch, interactiveSearch); } - public List ArtistSearch(Artist artist, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> ArtistSearch(Artist artist, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var downloadDecisions = new List(); @@ -64,13 +65,13 @@ namespace NzbDrone.Core.IndexerSearch searchSpec.Albums = albums; - var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + var decisions = await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); downloadDecisions.AddRange(decisions); return DeDupeDecisions(downloadDecisions); } - public List AlbumSearch(Album album, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> AlbumSearch(Album album, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var downloadDecisions = new List(); @@ -89,7 +90,7 @@ namespace NzbDrone.Core.IndexerSearch searchSpec.Disambiguation = album.Disambiguation; } - var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + var decisions = await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); downloadDecisions.AddRange(decisions); return DeDupeDecisions(downloadDecisions); @@ -119,7 +120,7 @@ namespace NzbDrone.Core.IndexerSearch return spec; } - private List Dispatch(Func> searchAction, SearchCriteriaBase criteriaBase) + private async Task> Dispatch(Func>> searchAction, SearchCriteriaBase criteriaBase) { var indexers = criteriaBase.InteractiveSearch ? _indexerFactory.InteractiveSearchEnabled() : @@ -128,42 +129,33 @@ namespace NzbDrone.Core.IndexerSearch // Filter indexers to untagged indexers and indexers with intersecting tags indexers = indexers.Where(i => i.Definition.Tags.Empty() || i.Definition.Tags.Intersect(criteriaBase.Artist.Tags).Any()).ToList(); - var reports = new List(); - _logger.ProgressInfo("Searching indexers for {0}. {1} active indexers", criteriaBase, indexers.Count); - var taskList = new List(); - var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); + var tasks = indexers.Select(indexer => DispatchIndexer(searchAction, indexer, criteriaBase)); - foreach (var indexer in indexers) - { - var indexerLocal = indexer; - - taskList.Add(taskFactory.StartNew(() => - { - try - { - var indexerReports = searchAction(indexerLocal); - - lock (reports) - { - reports.AddRange(indexerReports); - } - } - catch (Exception e) - { - _logger.Error(e, "Error while searching for {0}", criteriaBase); - } - }).LogExceptions()); - } + var batch = await Task.WhenAll(tasks); - Task.WaitAll(taskList.ToArray()); + var reports = batch.SelectMany(x => x).ToList(); _logger.Debug("Total of {0} reports were found for {1} from {2} indexers", reports.Count, criteriaBase, indexers.Count); return _makeDownloadDecision.GetSearchDecision(reports, criteriaBase).ToList(); } + private async Task> DispatchIndexer(Func>> searchAction, IIndexer indexer, SearchCriteriaBase criteriaBase) + { + try + { + return await searchAction(indexer); + } + catch (Exception ex) + { + _logger.Error(ex, "Error while searching for {0}", criteriaBase); + } + + return Array.Empty(); + } + private List DeDupeDecisions(List decisions) { // De-dupe reports by guid so duplicate results aren't returned. Pick the one with the least rejections and higher indexer priority. diff --git a/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs b/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs index 460f63e13..373e6998a 100644 --- a/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs +++ b/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using NLog; -using NzbDrone.Common.TPL; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Indexers { public interface IFetchAndParseRss { - List Fetch(); + Task> Fetch(); } public class FetchAndParseRssService : IFetchAndParseRss @@ -23,54 +22,42 @@ namespace NzbDrone.Core.Indexers _logger = logger; } - public List Fetch() + public async Task> Fetch() { - var result = new List(); - var indexers = _indexerFactory.RssEnabled(); if (!indexers.Any()) { _logger.Warn("No available indexers. check your configuration."); - return result; + + return new List(); } _logger.Debug("Available indexers {0}", indexers.Count); - var taskList = new List(); - var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); + var tasks = indexers.Select(FetchIndexer); - foreach (var indexer in indexers) - { - var indexerLocal = indexer; + var batch = await Task.WhenAll(tasks); - var task = taskFactory.StartNew(() => - { - try - { - var indexerReports = indexerLocal.FetchRecent(); + var result = batch.SelectMany(x => x).ToList(); - lock (result) - { - _logger.Debug("Found {0} from {1}", indexerReports.Count, indexer.Name); + _logger.Debug("Found {0} reports", result.Count); - result.AddRange(indexerReports); - } - } - catch (Exception e) - { - _logger.Error(e, "Error during RSS Sync"); - } - }).LogExceptions(); + return result; + } - taskList.Add(task); + private async Task> FetchIndexer(IIndexer indexer) + { + try + { + return await indexer.FetchRecent(); + } + catch (Exception ex) + { + _logger.Error(ex, "Error during RSS Sync"); } - Task.WaitAll(taskList.ToArray()); - - _logger.Debug("Found {0} reports", result.Count); - - return result; + return Array.Empty(); } } } diff --git a/src/NzbDrone.Core/Indexers/Gazelle/Gazelle.cs b/src/NzbDrone.Core/Indexers/Gazelle/Gazelle.cs index c30a7edfe..fc52e6ad3 100644 --- a/src/NzbDrone.Core/Indexers/Gazelle/Gazelle.cs +++ b/src/NzbDrone.Core/Indexers/Gazelle/Gazelle.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Cache; @@ -78,11 +79,12 @@ namespace NzbDrone.Core.Indexers.Gazelle return settings; } - protected override void Test(List failures) + protected override async Task Test(List failures) { // Remove previous cookies when testing incase user or pwd change _authCookieCache.Remove(Settings.BaseUrl.Trim().TrimEnd('/')); - base.Test(failures); + + await base.Test(failures); } } } diff --git a/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs index 750ed5914..ee3b553ef 100644 --- a/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net.Http; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; @@ -52,17 +53,14 @@ namespace NzbDrone.Core.Indexers.Gazelle private IEnumerable GetRequest(string searchParameters) { - Authenticate(); + Authenticate().GetAwaiter().GetResult(); var filter = ""; if (searchParameters == null) { } - var request = - new IndexerRequest( - $"{Settings.BaseUrl.Trim().TrimEnd('/')}/ajax.php?action=browse&searchstr={searchParameters}{filter}", - HttpAccept.Json); + var request = new IndexerRequest($"{Settings.BaseUrl.Trim().TrimEnd('/')}/ajax.php?action=browse&searchstr={searchParameters}{filter}", HttpAccept.Json); var cookies = AuthCookieCache.Find(Settings.BaseUrl.Trim().TrimEnd('/')); foreach (var cookie in cookies) @@ -73,36 +71,36 @@ namespace NzbDrone.Core.Indexers.Gazelle yield return request; } - private GazelleAuthResponse GetIndex(Dictionary cookies) + private async Task GetIndex(Dictionary cookies) { var indexRequestBuilder = new HttpRequestBuilder($"{Settings.BaseUrl.Trim().TrimEnd('/')}") { - LogResponseContent = true + LogResponseContent = true, + Method = HttpMethod.Post }; indexRequestBuilder.SetCookies(cookies); - indexRequestBuilder.Method = HttpMethod.Post; indexRequestBuilder.Resource("ajax.php?action=index"); var authIndexRequest = indexRequestBuilder .Accept(HttpAccept.Json) .Build(); - var indexResponse = HttpClient.Execute(authIndexRequest); + var indexResponse = await HttpClient.ExecuteAsync(authIndexRequest); var result = Json.Deserialize(indexResponse.Content); return result; } - private void Authenticate() + private async Task Authenticate() { var requestBuilder = new HttpRequestBuilder($"{Settings.BaseUrl.Trim().TrimEnd('/')}") { - LogResponseContent = true + LogResponseContent = true, + Method = HttpMethod.Post }; - requestBuilder.Method = HttpMethod.Post; requestBuilder.Resource("login.php"); requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15); @@ -120,19 +118,20 @@ namespace NzbDrone.Core.Indexers.Gazelle .Accept(HttpAccept.Json) .Build(); - var response = HttpClient.Execute(authLoginRequest); + var response = await HttpClient.ExecuteAsync(authLoginRequest); cookies = response.GetCookies(); AuthCookieCache.Set(authKey, cookies); } - var index = GetIndex(cookies); + var index = await GetIndex(cookies); if (index == null || index.Status.IsNullOrWhiteSpace() || index.Status != "success") { Logger.Debug("Gazelle authentication failed."); AuthCookieCache.Remove(authKey); + throw new Exception("Failed to authenticate with Gazelle."); } diff --git a/src/NzbDrone.Core/Indexers/Headphones/Headphones.cs b/src/NzbDrone.Core/Indexers/Headphones/Headphones.cs index 0e70cef3d..b315b371e 100644 --- a/src/NzbDrone.Core/Indexers/Headphones/Headphones.cs +++ b/src/NzbDrone.Core/Indexers/Headphones/Headphones.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; @@ -51,9 +52,9 @@ namespace NzbDrone.Core.Indexers.Headphones return request; } - protected override void Test(List failures) + protected override async Task Test(List failures) { - base.Test(failures); + await base.Test(failures); if (failures.Any()) { diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 0ef9a81e8..365a6af5a 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -40,31 +40,31 @@ namespace NzbDrone.Core.Indexers _httpClient = httpClient; } - public override IList FetchRecent() + public override Task> FetchRecent() { if (!SupportsRss) { - return Array.Empty(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetRecentRequests(), true); } - public override IList Fetch(AlbumSearchCriteria searchCriteria) + public override Task> Fetch(AlbumSearchCriteria searchCriteria) { if (!SupportsSearch) { - return Array.Empty(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetSearchRequests(searchCriteria)); } - public override IList Fetch(ArtistSearchCriteria searchCriteria) + public override Task> Fetch(ArtistSearchCriteria searchCriteria) { if (!SupportsSearch) { - return Array.Empty(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetSearchRequests(searchCriteria)); @@ -75,7 +75,7 @@ namespace NzbDrone.Core.Indexers return new HttpRequest(link); } - protected virtual IList FetchReleases(Func pageableRequestChainSelector, bool isRecent = false) + protected virtual async Task> FetchReleases(Func pageableRequestChainSelector, bool isRecent = false) { var releases = new List(); var url = string.Empty; @@ -107,7 +107,7 @@ namespace NzbDrone.Core.Indexers { url = request.Url.FullUri; - var page = FetchPage(request, parser); + var page = await FetchPage(request, parser); pagedReleases.AddRange(page); @@ -271,9 +271,9 @@ namespace NzbDrone.Core.Indexers return PageSize != 0 && page.Count >= PageSize; } - protected virtual IList FetchPage(IndexerRequest request, IParseIndexerResponse parser) + protected virtual async Task> FetchPage(IndexerRequest request, IParseIndexerResponse parser) { - var response = FetchIndexerResponse(request); + var response = await FetchIndexerResponse(request); try { @@ -287,7 +287,7 @@ namespace NzbDrone.Core.Indexers } } - protected virtual IndexerResponse FetchIndexerResponse(IndexerRequest request) + protected virtual async Task FetchIndexerResponse(IndexerRequest request) { _logger.Debug("Downloading Feed " + request.HttpRequest.ToString(false)); @@ -298,15 +298,17 @@ namespace NzbDrone.Core.Indexers request.HttpRequest.RateLimitKey = Definition.Id.ToString(); - return new IndexerResponse(request, _httpClient.Execute(request.HttpRequest)); + var response = await _httpClient.ExecuteAsync(request.HttpRequest); + + return new IndexerResponse(request, response); } - protected override void Test(List failures) + protected override async Task Test(List failures) { - failures.AddIfNotNull(TestConnection()); + failures.AddIfNotNull(await TestConnection()); } - protected virtual ValidationFailure TestConnection() + protected virtual async Task TestConnection() { try { @@ -319,7 +321,7 @@ namespace NzbDrone.Core.Indexers return new ValidationFailure(string.Empty, "No rss feed query available. This may be an issue with the indexer or your indexer category settings."); } - var releases = FetchPage(firstRequest, parser); + var releases = await FetchPage(firstRequest, parser); if (releases.Empty()) { diff --git a/src/NzbDrone.Core/Indexers/IIndexer.cs b/src/NzbDrone.Core/Indexers/IIndexer.cs index 791f49dd0..fef7a6284 100644 --- a/src/NzbDrone.Core/Indexers/IIndexer.cs +++ b/src/NzbDrone.Core/Indexers/IIndexer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using NzbDrone.Common.Http; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser.Model; @@ -12,9 +13,9 @@ namespace NzbDrone.Core.Indexers bool SupportsSearch { get; } DownloadProtocol Protocol { get; } - IList FetchRecent(); - IList Fetch(AlbumSearchCriteria searchCriteria); - IList Fetch(ArtistSearchCriteria searchCriteria); + Task> FetchRecent(); + Task> Fetch(AlbumSearchCriteria searchCriteria); + Task> Fetch(ArtistSearchCriteria searchCriteria); HttpRequest GetDownloadRequest(string link); } } diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index 3ba0c676a..9d33a96cd 100644 --- a/src/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Http; @@ -66,16 +67,14 @@ namespace NzbDrone.Core.Indexers protected TSettings Settings => (TSettings)Definition.Settings; - public abstract IList FetchRecent(); - - public abstract IList Fetch(AlbumSearchCriteria searchCriteria); - public abstract IList Fetch(ArtistSearchCriteria searchCriteria); + public abstract Task> FetchRecent(); + public abstract Task> Fetch(AlbumSearchCriteria searchCriteria); + public abstract Task> Fetch(ArtistSearchCriteria searchCriteria); public abstract HttpRequest GetDownloadRequest(string link); protected virtual IList CleanupReleases(IEnumerable releases) { var result = releases.DistinctBy(v => v.Guid).ToList(); - var settings = Definition.Settings as IIndexerSettings; result.ForEach(c => { @@ -95,7 +94,7 @@ namespace NzbDrone.Core.Indexers try { - Test(failures); + Test(failures).GetAwaiter().GetResult(); } catch (Exception ex) { @@ -106,7 +105,7 @@ namespace NzbDrone.Core.Indexers return new ValidationResult(failures); } - protected abstract void Test(List failures); + protected abstract Task Test(List failures); public override string ToString() { diff --git a/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs b/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs index 3d65d68d4..31420c6d3 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/Newznab.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; @@ -92,9 +93,10 @@ namespace NzbDrone.Core.Indexers.Newznab return settings; } - protected override void Test(List failures) + protected override async Task Test(List failures) { - base.Test(failures); + await base.Test(failures); + if (failures.HasErrors()) { return; diff --git a/src/NzbDrone.Core/Indexers/RssSyncService.cs b/src/NzbDrone.Core/Indexers/RssSyncService.cs index 8f4a07a04..46e0c0707 100644 --- a/src/NzbDrone.Core/Indexers/RssSyncService.cs +++ b/src/NzbDrone.Core/Indexers/RssSyncService.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.DecisionEngine; @@ -39,16 +40,16 @@ namespace NzbDrone.Core.Indexers _logger = logger; } - private ProcessedDecisions Sync() + private async Task Sync() { _logger.ProgressInfo("Starting RSS Sync"); - var rssReleases = _rssFetcherAndParser.Fetch(); + var rssReleases = await _rssFetcherAndParser.Fetch(); var pendingReleases = _pendingReleaseService.GetPending(); var reports = rssReleases.Concat(pendingReleases).ToList(); var decisions = _downloadDecisionMaker.GetRssDecision(reports); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var processed = await _processDownloadDecisions.ProcessDecisions(decisions); var message = string.Format("RSS Sync Completed. Reports found: {0}, Reports grabbed: {1}", reports.Count, processed.Grabbed.Count); @@ -64,7 +65,7 @@ namespace NzbDrone.Core.Indexers public void Execute(RssSyncCommand message) { - var processed = Sync(); + var processed = Sync().GetAwaiter().GetResult(); var grabbedOrPending = processed.Grabbed.Concat(processed.Pending).ToList(); _eventAggregator.PublishEvent(new RssSyncCompleteEvent(processed)); diff --git a/src/NzbDrone.Core/Indexers/Torznab/Torznab.cs b/src/NzbDrone.Core/Indexers/Torznab/Torznab.cs index b09e25627..0b21765cb 100644 --- a/src/NzbDrone.Core/Indexers/Torznab/Torznab.cs +++ b/src/NzbDrone.Core/Indexers/Torznab/Torznab.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; @@ -69,9 +70,10 @@ namespace NzbDrone.Core.Indexers.Torznab return settings; } - protected override void Test(List failures) + protected override async Task Test(List failures) { - base.Test(failures); + await base.Test(failures); + if (failures.HasErrors()) { return; diff --git a/src/NzbDrone.Host/Bootstrap.cs b/src/NzbDrone.Host/Bootstrap.cs index 83f6974b0..38828dc72 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -171,7 +171,7 @@ namespace NzbDrone.Host }); builder.ConfigureKestrel(serverOptions => { - serverOptions.AllowSynchronousIO = true; + serverOptions.AllowSynchronousIO = false; serverOptions.Limits.MaxRequestBodySize = null; }); builder.UseStartup();