diff --git a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs index 2613c7e63..9438b4f89 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; @@ -114,21 +115,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(); } @@ -140,47 +141,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 }"; @@ -188,17 +189,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"); @@ -208,11 +208,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"); @@ -230,7 +229,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); @@ -243,7 +242,7 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.NotFound }; - var exception = Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.IgnoreWarns(); } @@ -253,7 +252,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); } @@ -264,28 +263,28 @@ namespace NzbDrone.Common.Test.Http var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.LogHttpError = false; - var exception = 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); @@ -293,12 +292,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); @@ -306,14 +305,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://readarr.com/") .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("Readarr"); @@ -327,17 +326,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"); @@ -347,24 +346,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://readarr.com/img/slider/artistdetails.png"; - Subject.DownloadFile(url, file); + await Subject.DownloadFileAsync(url, file); var fileInfo = new FileInfo(file); fileInfo.Exists.Should().BeTrue(); @@ -372,7 +371,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(); @@ -380,7 +379,7 @@ namespace NzbDrone.Common.Test.Http .AddQueryParam("url", $"https://readarr.com/img/slider/artistdetails.png") .Build(); - Subject.DownloadFile(request.Url.FullUri, file); + await Subject.DownloadFileAsync(request.Url.FullUri, file); ExceptionVerification.ExpectedErrors(0); @@ -394,7 +393,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(); @@ -402,7 +401,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(); @@ -412,7 +411,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.Moved); } @@ -427,12 +426,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"); @@ -461,13 +460,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"); @@ -477,30 +476,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(); @@ -508,18 +507,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"); @@ -527,7 +526,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"); @@ -536,13 +535,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"); @@ -550,7 +549,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); @@ -558,24 +557,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(); @@ -583,18 +582,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"); @@ -602,13 +601,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"); @@ -617,7 +616,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"); @@ -625,11 +624,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"); @@ -637,7 +636,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"); @@ -645,13 +644,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"); @@ -659,14 +658,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"); @@ -675,13 +674,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"); @@ -689,14 +688,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"); @@ -705,13 +704,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(); @@ -719,14 +718,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"); @@ -734,7 +733,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(); @@ -752,13 +751,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 }); @@ -772,7 +771,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()); @@ -783,7 +782,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); @@ -799,11 +798,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"); @@ -821,7 +820,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 { @@ -831,11 +830,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"); @@ -847,12 +846,12 @@ namespace NzbDrone.Common.Test.Http } [Test] - public void should_correctly_use_basic_auth_with_basic_network_credential() + 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 ad8cac315..812b85456 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -44,7 +44,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) { @@ -103,7 +103,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; @@ -111,7 +111,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 d65e1eba2..5b638ad3d 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, string userAgent = null); + 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, string userAgent = null) + public async Task DownloadFileAsync(string url, string fileName, string userAgent = null) { 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")) { @@ -293,40 +309,73 @@ namespace NzbDrone.Common.Http } } - public HttpResponse Get(HttpRequest request) + public void DownloadFile(string url, string fileName, string userAgent = null) + { + // 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, userAgent)).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 f006c378d..48de5db2e 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 e78ed6038..588e65c0f 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_book_was_not_already_downloaded() + public async Task should_download_report_if_book_was_not_already_downloaded() { var books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -66,12 +67,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteBook)); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_only_download_book_once() + public async Task should_only_download_book_once() { var books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -80,12 +81,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); decisions.Add(new DownloadDecision(remoteBook)); - 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_book_was_already_downloaded() + public async Task should_not_download_if_any_book_was_already_downloaded() { var remoteBook1 = GetRemoteBook( new List { GetBook(1) }, @@ -99,12 +100,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook1)); decisions.Add(new DownloadDecision(remoteBook2)); - 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -112,11 +113,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteBook)); - 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 remoteBook1 = GetRemoteBook( new List { GetBook(1) }, @@ -130,11 +133,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook1)); decisions.Add(new DownloadDecision(remoteBook2)); - 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 remoteBook1 = GetRemoteBook( new List { GetBook(1) }, @@ -153,11 +158,13 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook2)); decisions.Add(new DownloadDecision(remoteBook3)); - 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -166,7 +173,11 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -189,12 +200,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests var decisions = new List(); decisions.Add(new DownloadDecision(remoteBook, 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_book_was_grabbed() + public async Task should_not_add_to_pending_if_book_was_grabbed() { var books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -203,12 +214,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook)); decisions.Add(new DownloadDecision(remoteBook, 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -217,12 +228,12 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests decisions.Add(new DownloadDecision(remoteBook, new Rejection("Failure!", RejectionType.Temporary))); decisions.Add(new DownloadDecision(remoteBook, 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3), 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 books = new List { GetBook(1) }; var remoteBook = GetRemoteBook(books, new QualityModel(Quality.MP3)); @@ -270,7 +281,7 @@ namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests .Setup(s => s.DownloadReport(It.IsAny())) .Throws(new ReleaseUnavailableException(remoteBook.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 dc3db5e55..6a396c0bf 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; @@ -69,7 +70,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()); } @@ -147,19 +148,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 remoteBook = CreateRemoteBook(); - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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; @@ -167,16 +168,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = null; - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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); @@ -187,12 +188,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = null; - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -202,31 +203,31 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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 remoteBook = CreateRemoteBook(); - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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)); @@ -234,11 +235,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteBook = CreateRemoteBook(); remoteBook.Release.Title = illegalTitle; - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -247,7 +248,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteBook, CreateIndexer())); } [Test] @@ -317,11 +318,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole } [Test] - public void should_return_null_hash() + public async Task should_return_null_hash() { var remoteBook = CreateRemoteBook(); - Subject.Download(remoteBook, CreateIndexer()).Should().BeNull(); + var result = await Subject.Download(remoteBook, 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 f51cbe221..c2c202d59 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 remoteBook = CreateRemoteBook(); - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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 remoteBook = CreateRemoteBook(); remoteBook.Release.Title = illegalTitle; - Subject.Download(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), 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 2462ce677..086ed2dde 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 14aeb8c4b..f2960c0d5 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(() => CreateRemoteBook()); Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), new byte[0])); + .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 2a770587f..d39fda2b8 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_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenSerialNumber(); GivenTvDirectory(); @@ -393,7 +394,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -419,14 +420,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_without_TvDirectory_and_Category_should_use_default() + public async Task Download_without_TvDirectory_and_Category_should_use_default() { GivenSerialNumber(); GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteBook, 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 eeb90c490..328021733 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; @@ -262,7 +263,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_with_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenSerialNumber(); GivenTvDirectory(); @@ -270,7 +271,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -279,7 +280,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(); @@ -287,7 +288,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -296,14 +297,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests } [Test] - public void Download_without_TvDirectory_and_Category_should_use_default() + public async Task Download_without_TvDirectory_and_Category_should_use_default() { GivenSerialNumber(); GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -382,7 +383,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(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteBook, 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 d7495059e..f012575ce 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); @@ -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(remoteBook, CreateIndexer()); + var result = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); @@ -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(remoteBook, CreateIndexer()); + var result = await Subject.Download(remoteBook, 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 971c947b2..a0c46e382 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -218,7 +219,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests var remoteBook = CreateRemoteBook(); - Assert.Throws(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteBook, 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 1e7115f63..ea4c100ff 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -357,7 +358,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests var remoteBook = CreateRemoteBook(); - Assert.Throws(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteBook, CreateIndexer())); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs index 74dfdae29..6202f4a85 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(), It.IsAny())).Throws(new WebException()); + Mocker.GetMock().Setup(c => c.DownloadFileAsync(It.IsAny(), 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(_remoteBook, _indexer); + await Subject.Download(_remoteBook, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath, null), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(_nzbUrl, _nzbPath, null), Times.Once()); } [Test] @@ -81,7 +82,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests { WithFailedDownload(); - Assert.Throws(() => Subject.Download(_remoteBook, _indexer)); + Assert.ThrowsAsync(async () => await Subject.Download(_remoteBook, _indexer)); } [Test] @@ -90,7 +91,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests _remoteBook.Release.Title = "Alien Ant Farm - Discography"; _remoteBook.ParsedBookInfo.Discography = true; - Assert.Throws(() => Subject.Download(_remoteBook, _indexer)); + Assert.ThrowsAsync(async () => await Subject.Download(_remoteBook, _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"); _remoteBook.Release.Title = illegalTitle; - Subject.Download(_remoteBook, _indexer); + await Subject.Download(_remoteBook, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), expectedFilename, null), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), expectedFilename, null), 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 2c123b173..17a7518e2 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; @@ -449,26 +450,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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().Be(expectedHash); } @@ -483,7 +484,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR"; - Assert.Throws(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteBook, CreateIndexer())); } [Test] @@ -496,28 +497,28 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp://abc"; - Assert.DoesNotThrow(() => Subject.Download(remoteBook, CreateIndexer())); + Assert.DoesNotThrowAsync(async () => await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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(); @@ -528,7 +529,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -555,27 +556,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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 4a3d12efe..fd2481150 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.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; @@ -121,13 +122,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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 2927eddef..bbd803034 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 remoteBook = CreateRemoteBook(); remoteBook.Release.Title = title; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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(remoteBook, CreateIndexer()); + await Subject.Download(remoteBook, 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 52eed5614..1d66ff7f3 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenTvDirectory(); GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -117,13 +118,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests } [Test] - public void Download_without_TvDirectory_and_Category_should_use_default() + public async Task Download_without_TvDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 8aced935a..23384b78e 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 9a507ae34..1229c72ff 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenTvDirectory(); GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -125,13 +126,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests } [Test] - public void Download_without_TvDirectory_and_Category_should_use_default() + public async Task Download_without_TvDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteBook = CreateRemoteBook(); - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, 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 remoteBook = CreateRemoteBook(); remoteBook.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteBook, CreateIndexer()); + var id = await Subject.Download(remoteBook, CreateIndexer()); id.Should().Be(expectedHash); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index 0ea296c9f..39af065f1 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/AuthorSearchServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerSearchTests/AuthorSearchServiceFixture.cs index 73f01a6af..1f524fcf8 100644 --- a/src/NzbDrone.Core.Test/IndexerSearchTests/AuthorSearchServiceFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerSearchTests/AuthorSearchServiceFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Moq; using NUnit.Framework; using NzbDrone.Core.Books; @@ -27,11 +28,11 @@ namespace NzbDrone.Core.Test.IndexerSearchTests Mocker.GetMock() .Setup(s => s.AuthorSearch(_author.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/IndexerSearchTests/ReleaseSearchServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerSearchTests/ReleaseSearchServiceFixture.cs index 5fc1569f3..b798347b5 100644 --- a/src/NzbDrone.Core.Test/IndexerSearchTests/ReleaseSearchServiceFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerSearchTests/ReleaseSearchServiceFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -60,13 +61,13 @@ namespace NzbDrone.Core.Test.IndexerSearchTests _mockIndexer.Setup(v => v.Fetch(It.IsAny())) .Callback(s => result.Add(s)) - .Returns(new List()); + .Returns(Task.FromResult>(new List())); return result; } [Test] - public void Tags_IndexerTags_AuthorNoTags_IndexerNotIncluded() + public async Task Tags_IndexerTags_AuthorNoTags_IndexerNotIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -76,7 +77,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests var allCriteria = WatchForSearchCriteria(); - Subject.BookSearch(_firstBook, false, true, false); + await Subject.BookSearch(_firstBook, false, true, false); var criteria = allCriteria.OfType().ToList(); @@ -84,7 +85,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests } [Test] - public void Tags_IndexerNoTags_AuthorTags_IndexerIncluded() + public async Task Tags_IndexerNoTags_AuthorTags_IndexerIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -102,7 +103,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests var allCriteria = WatchForSearchCriteria(); - Subject.BookSearch(_firstBook, false, true, false); + await Subject.BookSearch(_firstBook, false, true, false); var criteria = allCriteria.OfType().ToList(); @@ -110,7 +111,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests } [Test] - public void Tags_IndexerAndAuthorTagsMatch_IndexerIncluded() + public async Task Tags_IndexerAndAuthorTagsMatch_IndexerIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -129,7 +130,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests var allCriteria = WatchForSearchCriteria(); - Subject.BookSearch(_firstBook, false, true, false); + await Subject.BookSearch(_firstBook, false, true, false); var criteria = allCriteria.OfType().ToList(); @@ -137,7 +138,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests } [Test] - public void Tags_IndexerAndAuthorTagsMismatch_IndexerNotIncluded() + public async Task Tags_IndexerAndAuthorTagsMismatch_IndexerNotIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -156,7 +157,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests var allCriteria = WatchForSearchCriteria(); - Subject.BookSearch(_firstBook, false, true, false); + await Subject.BookSearch(_firstBook, false, true, false); var criteria = allCriteria.OfType().ToList(); 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 76a1325ba..deaec8edc 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/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 8dfa3fccb..005e2dabc 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(), new byte[0], (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 2d2d957d3..14755d2b2 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/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 61e4838b6..3e080732b 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(RemoteBook remoteBook, IIndexer indexer) + public override async Task Download(RemoteBook remoteBook, IIndexer indexer) { var url = remoteBook.Release.DownloadUrl; var title = remoteBook.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 dfe997919..193759191 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(RemoteBook remoteBook, IIndexer indexer); + public abstract Task Download(RemoteBook remoteBook, 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 349599b9b..924581da4 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(RemoteBook remoteBook); + Task DownloadReport(RemoteBook remoteBook); } public class DownloadService : IDownloadService @@ -49,15 +50,23 @@ namespace NzbDrone.Core.Download _logger = logger; } - public void DownloadReport(RemoteBook remoteBook) + public async Task DownloadReport(RemoteBook remoteBook) + { + var filterBlockedClients = remoteBook.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; + + var tags = remoteBook.Author?.Tags; + + var downloadClient = _downloadClientProvider.GetDownloadClient(remoteBook.Release.DownloadProtocol, remoteBook.Release.IndexerId, filterBlockedClients, tags); + + await DownloadReport(remoteBook, downloadClient); + } + + private async Task DownloadReport(RemoteBook remoteBook, IDownloadClient downloadClient) { Ensure.That(remoteBook.Author, () => remoteBook.Author).IsNotNull(); Ensure.That(remoteBook.Books, () => remoteBook.Books).HasItems(); var downloadTitle = remoteBook.Release.Title; - var filterBlockedClients = remoteBook.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; - var tags = remoteBook.Author?.Tags; - var downloadClient = _downloadClientProvider.GetDownloadClient(remoteBook.Release.DownloadProtocol, remoteBook.Release.IndexerId, filterBlockedClients, tags); if (downloadClient == null) { @@ -71,7 +80,7 @@ namespace NzbDrone.Core.Download if (remoteBook.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteBook.Release.DownloadUrl.StartsWith("magnet:")) { var url = new HttpUri(remoteBook.Release.DownloadUrl); - _rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2)); + await _rateLimitService.WaitAndPulseAsync(url.Host, TimeSpan.FromSeconds(2)); } IIndexer indexer = null; @@ -84,7 +93,7 @@ namespace NzbDrone.Core.Download string downloadClientId; try { - downloadClientId = downloadClient.Download(remoteBook, indexer); + downloadClientId = await downloadClient.Download(remoteBook, indexer); _downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id); _indexerStatusService.RecordSuccess(remoteBook.Release.IndexerId); } @@ -100,8 +109,7 @@ namespace NzbDrone.Core.Download } catch (ReleaseDownloadException ex) { - var http429 = ex.InnerException as TooManyRequestsException; - if (http429 != null) + if (ex.InnerException is TooManyRequestsException http429) { _indexerStatusService.RecordFailure(remoteBook.Release.IndexerId, http429.RetryAfter); } diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index 711c10209..2cecd5589 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,7 +9,7 @@ namespace NzbDrone.Core.Download public interface IDownloadClient : IProvider { DownloadProtocol Protocol { get; } - string Download(RemoteBook remoteBook, IIndexer indexer); + Task Download(RemoteBook remoteBook, 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 aa7ab3f70..24228a357 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}.", remoteBook.Release.Indexer, remoteBook.Release.IndexerPriority); - _downloadService.DownloadReport(remoteBook); + await _downloadService.DownloadReport(remoteBook); grabbed.Add(report); } catch (ReleaseUnavailableException) diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index bf398a898..a5ffd4b5e 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(RemoteBook remoteBook, string hash, string magnetLink); protected abstract string AddFromTorrentFile(RemoteBook remoteBook, string hash, string filename, byte[] fileContent); - public override string Download(RemoteBook remoteBook, IIndexer indexer) + public override async Task Download(RemoteBook remoteBook, IIndexer indexer) { var torrentInfo = remoteBook.Release as TorrentInfo; @@ -68,7 +69,7 @@ namespace NzbDrone.Core.Download { try { - return DownloadFromWebUrl(remoteBook, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteBook, indexer, torrentUrl); } catch (Exception ex) { @@ -114,14 +115,14 @@ namespace NzbDrone.Core.Download if (torrentUrl.IsNotNullOrWhiteSpace()) { - return DownloadFromWebUrl(remoteBook, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteBook, indexer, torrentUrl); } } return null; } - private string DownloadFromWebUrl(RemoteBook remoteBook, IIndexer indexer, string torrentUrl) + private async Task DownloadFromWebUrl(RemoteBook remoteBook, 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(remoteBook, indexer, request.Url.ToString()); + return await DownloadFromWebUrl(remoteBook, 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 2bd9b2d23..b4bca217a 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(RemoteBook remoteBook, string filename, byte[] fileContent); - public override string Download(RemoteBook remoteBook, IIndexer indexer) + public override async Task Download(RemoteBook remoteBook, IIndexer indexer) { var url = remoteBook.Release.DownloadUrl; var filename = FileNameBuilder.CleanFileName(remoteBook.Release.Title) + ".nzb"; @@ -46,7 +47,9 @@ namespace NzbDrone.Core.Download var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url); request.RateLimitKey = remoteBook?.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})", remoteBook.Release.Title, nzbData.Length, url); } diff --git a/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs b/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs index 376239d2b..1e01ba913 100644 --- a/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/AuthorSearchService.cs @@ -22,8 +22,8 @@ namespace NzbDrone.Core.IndexerSearch public void Execute(AuthorSearchCommand message) { - var decisions = _releaseSearchService.AuthorSearch(message.AuthorId, false, message.Trigger == CommandTrigger.Manual, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var decisions = _releaseSearchService.AuthorSearch(message.AuthorId, false, message.Trigger == CommandTrigger.Manual, false).GetAwaiter().GetResult(); + var processed = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); _logger.ProgressInfo("Author search completed. {0} reports downloaded.", processed.Grabbed.Count); } diff --git a/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs b/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs index 04bdf55be..f983602ad 100644 --- a/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/BookSearchService.cs @@ -2,11 +2,11 @@ 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.Books; using NzbDrone.Core.Datastore; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Queue; @@ -39,16 +39,15 @@ namespace NzbDrone.Core.IndexerSearch _logger = logger; } - private void SearchForMissingBooks(List books, bool userInvokedSearch) + private async Task SearchForMissingBooks(List books, bool userInvokedSearch) { _logger.ProgressInfo("Performing missing search for {0} books", books.Count); var downloadedCount = 0; foreach (var book in books) { - List decisions; - decisions = _releaseSearchService.BookSearch(book.Id, false, userInvokedSearch, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var decisions = await _releaseSearchService.BookSearch(book.Id, false, userInvokedSearch, false); + var processed = await _processDownloadDecisions.ProcessDecisions(decisions); downloadedCount += processed.Grabbed.Count; } @@ -60,9 +59,8 @@ namespace NzbDrone.Core.IndexerSearch { foreach (var bookId in message.BookIds) { - var decisions = - _releaseSearchService.BookSearch(bookId, false, message.Trigger == CommandTrigger.Manual, false); - var processed = _processDownloadDecisions.ProcessDecisions(decisions); + var decisions = _releaseSearchService.BookSearch(bookId, false, message.Trigger == CommandTrigger.Manual, false).GetAwaiter().GetResult(); + var processed = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); _logger.ProgressInfo("Book search completed. {0} reports downloaded.", processed.Grabbed.Count); } @@ -106,7 +104,7 @@ namespace NzbDrone.Core.IndexerSearch var queue = _queueService.GetQueue().Where(q => q.Book != null).Select(q => q.Book.Id); var missing = books.Where(e => !queue.Contains(e.Id)).ToList(); - SearchForMissingBooks(missing, message.Trigger == CommandTrigger.Manual); + SearchForMissingBooks(missing, message.Trigger == CommandTrigger.Manual).GetAwaiter().GetResult(); } public void Execute(CutoffUnmetBookSearchCommand message) @@ -132,7 +130,7 @@ namespace NzbDrone.Core.IndexerSearch var queue = _queueService.GetQueue().Where(q => q.Book != null).Select(q => q.Book.Id); var missing = books.Where(e => !queue.Contains(e.Id)).ToList(); - SearchForMissingBooks(missing, message.Trigger == CommandTrigger.Manual); + SearchForMissingBooks(missing, message.Trigger == CommandTrigger.Manual).GetAwaiter().GetResult(); } } } diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs index 62d89ee47..dc4844bb9 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.Books; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Indexers; @@ -16,8 +15,8 @@ namespace NzbDrone.Core.IndexerSearch { public interface ISearchForReleases { - List BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); - List AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + Task> BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); + Task> AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch); } public class ReleaseSearchService : ISearchForReleases @@ -41,31 +40,31 @@ namespace NzbDrone.Core.IndexerSearch _logger = logger; } - public List BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var downloadDecisions = new List(); var book = _bookService.GetBook(bookId); - var decisions = BookSearch(book, missingOnly, userInvokedSearch, interactiveSearch); + var decisions = await BookSearch(book, missingOnly, userInvokedSearch, interactiveSearch); downloadDecisions.AddRange(decisions); return DeDupeDecisions(downloadDecisions); } - public List AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var downloadDecisions = new List(); var author = _authorService.GetAuthor(authorId); - var decisions = AuthorSearch(author, missingOnly, userInvokedSearch, interactiveSearch); + var decisions = await AuthorSearch(author, missingOnly, userInvokedSearch, interactiveSearch); downloadDecisions.AddRange(decisions); return DeDupeDecisions(downloadDecisions); } - public List AuthorSearch(Author author, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> AuthorSearch(Author author, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var searchSpec = Get(author, userInvokedSearch, interactiveSearch); var books = _bookService.GetBooksByAuthor(author.Id); @@ -74,10 +73,10 @@ namespace NzbDrone.Core.IndexerSearch searchSpec.Books = books; - return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + return await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); } - public List BookSearch(Book book, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) + public async Task> BookSearch(Book book, bool missingOnly, bool userInvokedSearch, bool interactiveSearch) { var author = _authorService.GetAuthor(book.AuthorId); @@ -91,7 +90,7 @@ namespace NzbDrone.Core.IndexerSearch searchSpec.BookYear = book.ReleaseDate.Value.Year; } - return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + return await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); } private TSpec Get(Author author, List books, bool userInvokedSearch, bool interactiveSearch) @@ -118,7 +117,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() : @@ -127,42 +126,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.Author.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 0f2f2df30..3e05a3818 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; @@ -68,11 +69,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 a64fa6643..0285a414c 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; @@ -43,17 +44,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) @@ -64,36 +62,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); @@ -111,19 +109,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/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index 7a05071f5..b0cffd4fb 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 new List(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetRecentRequests(), true); } - public override IList Fetch(BookSearchCriteria searchCriteria) + public override Task> Fetch(BookSearchCriteria searchCriteria) { if (!SupportsSearch) { - return new List(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetSearchRequests(searchCriteria)); } - public override IList Fetch(AuthorSearchCriteria searchCriteria) + public override Task> Fetch(AuthorSearchCriteria searchCriteria) { if (!SupportsSearch) { - return new List(); + 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 57fcc72b3..f2be5626f 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(BookSearchCriteria searchCriteria); - IList Fetch(AuthorSearchCriteria searchCriteria); + Task> FetchRecent(); + Task> Fetch(BookSearchCriteria searchCriteria); + Task> Fetch(AuthorSearchCriteria searchCriteria); HttpRequest GetDownloadRequest(string link); } } diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index 53e921337..66ba9312b 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(BookSearchCriteria searchCriteria); - public abstract IList Fetch(AuthorSearchCriteria searchCriteria); + public abstract Task> FetchRecent(); + public abstract Task> Fetch(BookSearchCriteria searchCriteria); + public abstract Task> Fetch(AuthorSearchCriteria 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 => { @@ -94,7 +93,7 @@ namespace NzbDrone.Core.Indexers try { - Test(failures); + Test(failures).GetAwaiter().GetResult(); } catch (Exception ex) { @@ -105,7 +104,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 3a58b1efd..43d194976 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 b0fc15d02..e81ef6b82 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 f3a5b97e6..99b2174a1 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -176,7 +176,7 @@ namespace NzbDrone.Host }); builder.ConfigureKestrel(serverOptions => { - serverOptions.AllowSynchronousIO = true; + serverOptions.AllowSynchronousIO = false; serverOptions.Limits.MaxRequestBodySize = null; }); builder.UseStartup(); diff --git a/src/Readarr.Api.V1/Indexers/ReleaseController.cs b/src/Readarr.Api.V1/Indexers/ReleaseController.cs index f8e8cee67..0671b0ef8 100644 --- a/src/Readarr.Api.V1/Indexers/ReleaseController.cs +++ b/src/Readarr.Api.V1/Indexers/ReleaseController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using FluentValidation; using Microsoft.AspNetCore.Mvc; using NLog; @@ -62,7 +63,7 @@ namespace Readarr.Api.V1.Indexers } [HttpPost] - public ActionResult Create(ReleaseResource release) + public async Task> DownloadRelease(ReleaseResource release) { ValidateResource(release); @@ -123,7 +124,7 @@ namespace Readarr.Api.V1.Indexers throw new NzbDroneClientException(HttpStatusCode.NotFound, "Unable to parse books in the release"); } - _downloadService.DownloadReport(remoteBook); + await _downloadService.DownloadReport(remoteBook); } catch (ReleaseDownloadException ex) { @@ -135,26 +136,26 @@ namespace Readarr.Api.V1.Indexers } [HttpGet] - public List GetReleases(int? bookId, int? authorId) + public async Task> GetReleases(int? bookId, int? authorId) { if (bookId.HasValue) { - return GetBookReleases(int.Parse(Request.Query["bookId"])); + return await GetBookReleases(int.Parse(Request.Query["bookId"])); } if (authorId.HasValue) { - return GetAuthorReleases(int.Parse(Request.Query["authorId"])); + return await GetAuthorReleases(int.Parse(Request.Query["authorId"])); } - return GetRss(); + return await GetRss(); } - private List GetBookReleases(int bookId) + private async Task> GetBookReleases(int bookId) { try { - var decisions = _releaseSearchService.BookSearch(bookId, true, true, true); + var decisions = await _releaseSearchService.BookSearch(bookId, true, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); @@ -166,11 +167,11 @@ namespace Readarr.Api.V1.Indexers } } - private List GetAuthorReleases(int authorId) + private async Task> GetAuthorReleases(int authorId) { try { - var decisions = _releaseSearchService.AuthorSearch(authorId, false, true, true); + var decisions = await _releaseSearchService.AuthorSearch(authorId, false, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisions(decisions); return MapDecisions(prioritizedDecisions); @@ -182,9 +183,9 @@ namespace Readarr.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); @@ -195,6 +196,7 @@ namespace Readarr.Api.V1.Indexers { var resource = base.MapDecision(decision, initialWeight); _remoteBookCache.Set(GetCacheKey(resource), decision.RemoteBook, TimeSpan.FromMinutes(30)); + return resource; } diff --git a/src/Readarr.Api.V1/Indexers/ReleasePushController.cs b/src/Readarr.Api.V1/Indexers/ReleasePushController.cs index 1e3ceb9d7..3c8158fc4 100644 --- a/src/Readarr.Api.V1/Indexers/ReleasePushController.cs +++ b/src/Readarr.Api.V1/Indexers/ReleasePushController.cs @@ -58,7 +58,7 @@ namespace Readarr.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/Readarr.Api.V1/Queue/QueueActionController.cs b/src/Readarr.Api.V1/Queue/QueueActionController.cs index df7edf62a..52bcdcd11 100644 --- a/src/Readarr.Api.V1/Queue/QueueActionController.cs +++ b/src/Readarr.Api.V1/Queue/QueueActionController.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Download; using NzbDrone.Core.Download.Pending; @@ -20,7 +21,7 @@ namespace Readarr.Api.V1.Queue } [HttpPost("grab/{id:int}")] - public object Grab(int id) + public async Task Grab(int id) { var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id); @@ -29,13 +30,14 @@ namespace Readarr.Api.V1.Queue throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteBook); + await _downloadService.DownloadReport(pendingRelease.RemoteBook); return new { }; } [HttpPost("grab/bulk")] - public object Grab([FromBody] QueueBulkResource resource) + [Consumes("application/json")] + public async Task Grab([FromBody] QueueBulkResource resource) { foreach (var id in resource.Ids) { @@ -46,7 +48,7 @@ namespace Readarr.Api.V1.Queue throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteBook); + await _downloadService.DownloadReport(pendingRelease.RemoteBook); } return new { };