diff --git a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs index 126b048df..cfc6e8a4f 100644 --- a/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs +++ b/src/NzbDrone.Common.Test/Http/HttpClientFixture.cs @@ -6,6 +6,7 @@ using System.Net; using System.Net.Http; using System.Threading; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NLog; @@ -119,21 +120,21 @@ public void TearDown() } [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(); } @@ -145,47 +146,47 @@ public void bad_ssl_should_fail_when_remote_validation_enabled(CertificateValida 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 }"; @@ -193,17 +194,17 @@ public void should_execute_post_with_content_type() 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"); @@ -213,11 +214,11 @@ public void should_execute_get_using_gzip() [Test] [Platform(Exclude = "MacOsX", Reason = "Azure agent update prevents brotli on OSX")] - public void should_execute_get_using_brotli() + public async Task should_execute_get_using_brotli() { var request = new HttpRequest($"https://{_httpBinHost}/brotli"); - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.Resource.Headers["Accept-Encoding"].ToString().Should().Contain("br"); @@ -235,7 +236,7 @@ public void should_throw_on_unsuccessful_status_codes(int statusCode) { var request = new HttpRequest($"https://{_httpBinHost}/status/{statusCode}"); - var exception = Assert.Throws(() => Subject.Get(request)); + var exception = Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ((int)exception.Response.StatusCode).Should().Be(statusCode); @@ -248,7 +249,7 @@ public void should_not_throw_on_suppressed_status_codes() var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.NotFound }; - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.IgnoreWarns(); } @@ -259,28 +260,28 @@ public void should_not_log_unsuccessful_status_codes() var request = new HttpRequest($"https://{_httpBinHost}/status/{HttpStatusCode.NotFound}"); request.LogHttpError = false; - Assert.Throws(() => Subject.Get(request)); + Assert.ThrowsAsync(async () => await Subject.GetAsync(request)); ExceptionVerification.ExpectedWarns(0); } [Test] - public void should_not_follow_redirects_when_not_in_production() + public async Task should_not_follow_redirects_when_not_in_production() { var request = new HttpRequest($"https://{_httpBinHost}/redirect/1"); - Subject.Get(request); + await Subject.GetAsync(request); ExceptionVerification.ExpectedErrors(1); } [Test] - public void should_follow_redirects() + public async Task should_follow_redirects() { var request = new HttpRequest($"https://{_httpBinHost}/redirect/1"); request.AllowAutoRedirect = true; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.OK); @@ -288,12 +289,12 @@ public void should_follow_redirects() } [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); @@ -301,14 +302,14 @@ public void should_not_follow_redirects() } [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://radarr.video/") .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("Radarr"); @@ -322,17 +323,17 @@ public void should_throw_on_too_many_redirects() 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"); @@ -342,24 +343,24 @@ public void should_send_user_agent() } [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://radarr.video/img/slider/moviedetails.png"; - Subject.DownloadFile(url, file); + await Subject.DownloadFileAsync(url, file); var fileInfo = new FileInfo(file); fileInfo.Exists.Should().BeTrue(); @@ -367,7 +368,7 @@ public void should_download_file() } [Test] - public void should_download_file_with_redirect() + public async Task should_download_file_with_redirect() { var file = GetTempFilePath(); @@ -375,7 +376,7 @@ public void should_download_file_with_redirect() .AddQueryParam("url", $"https://radarr.video/img/slider/moviedetails.png") .Build(); - Subject.DownloadFile(request.Url.FullUri, file); + await Subject.DownloadFileAsync(request.Url.FullUri, file); ExceptionVerification.ExpectedErrors(0); @@ -389,7 +390,7 @@ public void should_not_download_file_with_error() { 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(); @@ -397,7 +398,7 @@ public void should_not_download_file_with_error() } [Test] - public void should_not_write_redirect_content_to_stream() + public async Task should_not_write_redirect_content_to_stream() { var file = GetTempFilePath(); @@ -407,7 +408,7 @@ public void should_not_write_redirect_content_to_stream() request.AllowAutoRedirect = false; request.ResponseStream = fileStream; - var response = Subject.Get(request); + var response = await Subject.GetAsync(request); response.StatusCode.Should().Be(HttpStatusCode.Moved); } @@ -422,12 +423,12 @@ public void should_not_write_redirect_content_to_stream() } [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"); @@ -436,7 +437,7 @@ public void should_send_cookie() cookie.Should().Contain("my=cookie"); } - public void GivenOldCookie() + public async Task GivenOldCookie() { if (_httpBinHost == _httpBinHost2) { @@ -450,19 +451,19 @@ public void GivenOldCookie() oldClient.Should().NotBeSameAs(Subject); - var oldResponse = oldClient.Get(oldRequest); + var oldResponse = await oldClient.GetAsync(oldRequest); oldResponse.Resource.Headers.Should().ContainKey("Cookie"); } [Test] - public void should_preserve_cookie_during_session() + public async Task should_preserve_cookie_during_session() { - GivenOldCookie(); + await 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"); @@ -472,30 +473,30 @@ public void should_preserve_cookie_during_session() } [Test] - public void should_not_send_cookie_to_other_host() + public async Task should_not_send_cookie_to_other_host() { - GivenOldCookie(); + await 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(); @@ -503,18 +504,18 @@ public void should_not_store_request_cookie() } [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"); @@ -522,7 +523,7 @@ public void should_store_request_cookie() } [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"); @@ -531,13 +532,13 @@ public void should_delete_request_cookie() 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"); @@ -545,7 +546,7 @@ public void should_clear_request_cookie() 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); @@ -553,24 +554,24 @@ public void should_clear_request_cookie() 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(); @@ -578,18 +579,18 @@ public void should_not_store_response_cookie() } [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"); @@ -597,13 +598,13 @@ public void should_store_response_cookie() } [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"); @@ -612,7 +613,7 @@ public void should_temp_store_response_cookie() } [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"); @@ -620,11 +621,11 @@ public void should_overwrite_response_cookie() 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"); @@ -632,7 +633,7 @@ public void should_overwrite_response_cookie() } [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"); @@ -640,13 +641,13 @@ public void should_overwrite_temp_response_cookie() 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"); @@ -654,14 +655,14 @@ public void should_overwrite_temp_response_cookie() } [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"); @@ -670,13 +671,13 @@ public void should_not_delete_response_cookie() 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"); @@ -684,14 +685,14 @@ public void should_not_delete_response_cookie() } [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"); @@ -700,13 +701,13 @@ public void should_delete_response_cookie() 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(); @@ -714,14 +715,14 @@ public void should_delete_response_cookie() } [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"); @@ -729,7 +730,7 @@ public void should_delete_temp_response_cookie() 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(); @@ -747,13 +748,13 @@ public void should_throw_on_http429_too_many_requests() { 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 }); @@ -767,7 +768,7 @@ public void should_call_interceptor() var request = new HttpRequest($"https://{_httpBinHost}/get"); - Subject.Get(request); + await Subject.GetAsync(request); Mocker.GetMock() .Verify(v => v.PreRequest(It.IsAny()), Times.Once()); @@ -778,7 +779,7 @@ public void should_call_interceptor() [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); @@ -794,11 +795,11 @@ public void should_parse_malformed_cloudflare_cookie(string culture) 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"); @@ -816,7 +817,7 @@ public void should_parse_malformed_cloudflare_cookie(string culture) } [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 { @@ -826,11 +827,11 @@ public void should_reject_malformed_domain_cookie(string malformedCookie) 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"); 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 850ec2d63..3640b8bb3 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -43,7 +43,7 @@ public ManagedHttpDispatcher(IHttpProxySettingsProvider proxySettingsProvider, _credentialCache = cacheManager.GetCache(typeof(ManagedHttpDispatcher), "credentialcache"); } - public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) + public async Task GetResponseAsync(HttpRequest request, CookieContainer cookies) { var requestMessage = new HttpRequestMessage(request.Method, (Uri)request.Url) { @@ -102,7 +102,7 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) var httpClient = GetClient(request.Url); - using var responseMessage = httpClient.Send(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); + using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); { byte[] data = null; @@ -110,7 +110,7 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) { 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 2824a8f94..a34f49aa5 100644 --- a/src/NzbDrone.Common/Http/HttpClient.cs +++ b/src/NzbDrone.Common/Http/HttpClient.cs @@ -5,6 +5,7 @@ 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 @@ HttpResponse Get(HttpRequest request) HttpResponse Post(HttpRequest request); HttpResponse Post(HttpRequest request) where T : new(); + + Task ExecuteAsync(HttpRequest request); + Task DownloadFileAsync(string url, string fileName); + Task GetAsync(HttpRequest request); + Task> GetAsync(HttpRequest request) + where T : new(); + Task HeadAsync(HttpRequest request); + Task PostAsync(HttpRequest request); + Task> PostAsync(HttpRequest request) + where T : new(); } public class HttpClient : IHttpClient @@ -52,11 +63,11 @@ public HttpClient(IEnumerable requestInterceptors, _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 @@ public HttpResponse Execute(HttpRequest request) request.ContentSummary = null; } - response = ExecuteRequest(request, cookieContainer); + response = await ExecuteRequestAsync(request, cookieContainer); } while (response.HasHttpRedirect); } @@ -112,6 +123,11 @@ public HttpResponse Execute(HttpRequest request) 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 @@ private static bool RequestRequiresForceGet(HttpStatusCode statusCode, HttpMetho }; } - private HttpResponse ExecuteRequest(HttpRequest request, CookieContainer cookieContainer) + private async Task ExecuteRequestAsync(HttpRequest request, CookieContainer cookieContainer) { foreach (var interceptor in _requestInterceptors) { @@ -131,14 +147,14 @@ private HttpResponse ExecuteRequest(HttpRequest request, CookieContainer cookieC 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 @@ private void AddCookiesToContainer(HttpUri url, string[] cookieHeaders, CookieCo } } - public void DownloadFile(string url, string fileName) + public async Task DownloadFileAsync(string url, string fileName) { var fileNamePart = fileName + ".part"; @@ -261,12 +277,12 @@ public void DownloadFile(string url, string fileName) _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,38 +309,71 @@ public void DownloadFile(string url, string fileName) } } - public HttpResponse Get(HttpRequest request) + public void DownloadFile(string url, string fileName) + { + // https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development#the-thread-pool-hack + Task.Run(() => DownloadFileAsync(url, fileName)).GetAwaiter().GetResult(); + } + + public Task GetAsync(HttpRequest request) { request.Method = HttpMethod.Get; - return Execute(request); + return ExecuteAsync(request); + } + + public HttpResponse Get(HttpRequest request) + { + return Task.Run(() => GetAsync(request)).GetAwaiter().GetResult(); + } + + public async Task> GetAsync(HttpRequest request) + where T : new() + { + var response = await GetAsync(request); + CheckResponseContentType(response); + return new HttpResponse(response); } public HttpResponse Get(HttpRequest request) where T : new() { - var response = Get(request); - CheckResponseContentType(response); - return new HttpResponse(response); + return Task.Run(() => GetAsync(request)).GetAwaiter().GetResult(); + } + + public Task HeadAsync(HttpRequest request) + { + request.Method = HttpMethod.Head; + return ExecuteAsync(request); } public HttpResponse Head(HttpRequest request) { - request.Method = HttpMethod.Head; - return Execute(request); + return Task.Run(() => HeadAsync(request)).GetAwaiter().GetResult(); + } + + public Task PostAsync(HttpRequest request) + { + request.Method = HttpMethod.Post; + return ExecuteAsync(request); } public HttpResponse Post(HttpRequest request) { - request.Method = HttpMethod.Post; - return Execute(request); + return Task.Run(() => PostAsync(request)).GetAwaiter().GetResult(); + } + + public async Task> PostAsync(HttpRequest request) + where T : new() + { + var response = await PostAsync(request); + CheckResponseContentType(response); + return new HttpResponse(response); } public HttpResponse Post(HttpRequest request) where T : new() { - var response = Post(request); - CheckResponseContentType(response); - return new HttpResponse(response); + return Task.Run(() => PostAsync(request)).GetAwaiter().GetResult(); } private void CheckResponseContentType(HttpResponse response) diff --git a/src/NzbDrone.Common/Http/HttpRequest.cs b/src/NzbDrone.Common/Http/HttpRequest.cs index 1232219f6..2d01e1a28 100644 --- a/src/NzbDrone.Common/Http/HttpRequest.cs +++ b/src/NzbDrone.Common/Http/HttpRequest.cs @@ -16,6 +16,7 @@ public HttpRequest(string url, HttpAccept httpAccept = null) Method = HttpMethod.Get; Url = new HttpUri(url); Headers = new HttpHeader(); + ConnectionKeepAlive = true; AllowAutoRedirect = true; StoreRequestCookie = true; IgnorePersistentCookies = false; diff --git a/src/NzbDrone.Common/TPL/RateLimitService.cs b/src/NzbDrone.Common/TPL/RateLimitService.cs index 87b0ff22f..b7cfd2e7c 100644 --- a/src/NzbDrone.Common/TPL/RateLimitService.cs +++ b/src/NzbDrone.Common/TPL/RateLimitService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Threading.Tasks; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; @@ -10,6 +11,8 @@ public interface IRateLimitService { 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 @@ public void WaitAndPulse(string key, TimeSpan interval) 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 @@ public void WaitAndPulse(string key, string subKey, TimeSpan interval) 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 da1d9092f..0a923b91a 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; @@ -71,19 +72,19 @@ private RemoteMovie GetRemoteMovie(QualityModel quality, Movie movie = null, Dow } [Test] - public void should_download_report_if_movie_was_not_already_downloaded() + public async Task should_download_report_if_movie_was_not_already_downloaded() { var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); decisions.Add(new DownloadDecision(remoteMovie)); - Subject.ProcessDecisions(decisions); + await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny()), Times.Once()); } [Test] - public void should_only_download_movie_once() + public async Task should_only_download_movie_once() { var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -91,12 +92,12 @@ public void should_only_download_movie_once() decisions.Add(new DownloadDecision(remoteMovie)); decisions.Add(new DownloadDecision(remoteMovie)); - 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_movie_was_already_downloaded() + public async Task should_not_download_if_any_movie_was_already_downloaded() { var remoteMovie1 = GetRemoteMovie( new QualityModel(Quality.HDTV720p)); @@ -108,23 +109,25 @@ public void should_not_download_if_any_movie_was_already_downloaded() decisions.Add(new DownloadDecision(remoteMovie1)); decisions.Add(new DownloadDecision(remoteMovie2)); - 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 remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); decisions.Add(new DownloadDecision(remoteMovie)); - 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 remoteMovie1 = GetRemoteMovie(new QualityModel(Quality.HDTV720p), GetMovie(1)); @@ -134,11 +137,13 @@ public void should_return_all_downloaded_reports() decisions.Add(new DownloadDecision(remoteMovie1)); decisions.Add(new DownloadDecision(remoteMovie2)); - 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 remoteMovie1 = GetRemoteMovie( new QualityModel(Quality.HDTV720p), @@ -157,11 +162,13 @@ public void should_only_return_downloaded_reports() decisions.Add(new DownloadDecision(remoteMovie2)); decisions.Add(new DownloadDecision(remoteMovie3)); - 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 remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -169,7 +176,11 @@ public void should_not_add_to_downloaded_list_when_download_fails() decisions.Add(new DownloadDecision(remoteMovie)); 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); } @@ -185,19 +196,19 @@ public void should_return_an_empty_list_when_none_are_appproved() } [Test] - public void should_not_grab_if_pending() + public async Task should_not_grab_if_pending() { var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); decisions.Add(new DownloadDecision(remoteMovie, 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_movie_was_grabbed() + public async Task should_not_add_to_pending_if_movie_was_grabbed() { var removeMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -205,12 +216,12 @@ public void should_not_add_to_pending_if_movie_was_grabbed() decisions.Add(new DownloadDecision(removeMovie)); decisions.Add(new DownloadDecision(removeMovie, 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 remoteEpisode = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -218,12 +229,12 @@ public void should_add_to_pending_even_if_already_added_to_pending() decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary))); decisions.Add(new DownloadDecision(remoteEpisode, 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 remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -234,12 +245,12 @@ public void should_add_to_failed_if_already_failed_for_that_protocol() 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 remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Usenet); var remoteMovie2 = GetRemoteMovie(new QualityModel(Quality.HDTV720p), null, DownloadProtocol.Torrent); @@ -251,13 +262,13 @@ public void should_not_add_to_failed_if_failed_for_a_different_protocol() 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 remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); @@ -268,7 +279,7 @@ public void should_add_to_rejected_if_release_unavailable_on_indexer() .Setup(s => s.DownloadReport(It.IsAny())) .Throws(new ReleaseUnavailableException(remoteMovie.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 de5b336ff..50f2f0377 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -66,7 +67,7 @@ public void Setup() protected void GivenFailedDownload() { Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) + .Setup(s => s.GetAsync(It.IsAny())) .Throws(new WebException()); } @@ -144,19 +145,19 @@ public void should_return_category() } [Test] - public void Download_should_download_file_if_it_doesnt_exist() + public async Task Download_should_download_file_if_it_doesnt_exist() { var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_save_magnet_if_enabled() + public async Task Download_should_save_magnet_if_enabled() { GivenMagnetFilePath(); Subject.Definition.Settings.As().SaveMagnetFiles = true; @@ -164,16 +165,16 @@ public void Download_should_save_magnet_if_enabled() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = null; - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_save_magnet_using_specified_extension() + public async Task Download_should_save_magnet_using_specified_extension() { var magnetFileExtension = ".url"; GivenMagnetFilePath(magnetFileExtension); @@ -183,12 +184,12 @@ public void Download_should_save_magnet_using_specified_extension() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = null; - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -197,31 +198,31 @@ public void Download_should_not_save_magnet_if_disabled() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteMovie, CreateIndexer())); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Never()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_prefer_torrent_over_magnet() + public async Task Download_should_prefer_torrent_over_magnet() { Subject.Definition.Settings.As().SaveMagnetFiles = true; var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_magnetFilePath), Times.Never()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_replace_illegal_characters_in_title() + public async Task Download_should_replace_illegal_characters_in_title() { var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]"; var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath)); @@ -229,11 +230,11 @@ public void Download_should_replace_illegal_characters_in_title() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.Title = illegalTitle; - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] @@ -242,7 +243,7 @@ public void Download_should_throw_if_magnet_and_torrent_url_does_not_exist() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = null; - Assert.Throws(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteMovie, CreateIndexer())); } [Test] @@ -312,11 +313,13 @@ public void should_return_status_with_outputdirs() } [Test] - public void should_return_null_hash() + public async Task should_return_null_hash() { var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()).Should().BeNull(); + var result = await Subject.Download(remoteMovie, 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 4777e49ec..09c9f78bd 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/UsenetBlackholeFixture.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using FluentAssertions; using Moq; @@ -115,19 +116,19 @@ public void should_return_category() } [Test] - public void Download_should_download_file_if_it_doesnt_exist() + public async Task Download_should_download_file_if_it_doesnt_exist() { var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(_filePath), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] - public void Download_should_replace_illegal_characters_in_title() + public async Task Download_should_replace_illegal_characters_in_title() { var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]"; var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath)); @@ -135,11 +136,11 @@ public void Download_should_replace_illegal_characters_in_title() var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.Title = illegalTitle; - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); - Mocker.GetMock().Verify(c => c.Get(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); + Mocker.GetMock().Verify(c => c.GetAsync(It.Is(v => v.Url.FullUri == _downloadUrl)), Times.Once()); Mocker.GetMock().Verify(c => c.OpenWriteStream(expectedFilename), Times.Once()); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), It.IsAny()), Times.Never()); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs index 1bf50d37b..89077fec0 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 @@ public void completed_download_should_have_required_properties() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 1518227a1..2de876ec3 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadClientFixtureBase.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NLog; @@ -36,8 +37,8 @@ public void SetupBase() .Returns(() => CreateRemoteMovie()); Mocker.GetMock() - .Setup(s => s.Get(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), Array.Empty())); + .Setup(s => s.GetAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), Array.Empty()))); Mocker.GetMock() .Setup(v => v.RemapRemoteToLocal(It.IsAny(), It.IsAny())) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs index e3ce75b02..e964694c8 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 @@ protected int GivenAllKindOfTasks() } [Test] - public void Download_with_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenSerialNumber(); GivenTvDirectory(); @@ -393,7 +394,7 @@ public void Download_with_TvDirectory_should_force_directory() var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -402,7 +403,7 @@ public void Download_with_TvDirectory_should_force_directory() } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenSerialNumber(); GivenTvCategory(); @@ -410,7 +411,7 @@ public void Download_with_category_should_force_directory() var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -419,14 +420,14 @@ public void Download_with_category_should_force_directory() } [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 remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -505,7 +506,7 @@ public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number() .Setup(s => s.GetSerialNumber(_settings)) .Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException")); - Assert.Throws(Is.InstanceOf(), () => Subject.Download(remoteEpisode, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteEpisode, 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 8354c7c6c..7610fd590 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -267,7 +268,7 @@ protected static string CleanFileName(string name) } [Test] - public void Download_with_TvDirectory_should_force_directory() + public async Task Download_with_TvDirectory_should_force_directory() { GivenSerialNumber(); GivenTvDirectory(); @@ -275,7 +276,7 @@ public void Download_with_TvDirectory_should_force_directory() var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -284,7 +285,7 @@ public void Download_with_TvDirectory_should_force_directory() } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenSerialNumber(); GivenTvCategory(); @@ -292,7 +293,7 @@ public void Download_with_category_should_force_directory() var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -301,14 +302,14 @@ public void Download_with_category_should_force_directory() } [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 remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -387,7 +388,7 @@ public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number() .Setup(s => s.GetSerialNumber(_settings)) .Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException")); - Assert.Throws(Is.InstanceOf(), () => Subject.Download(remoteEpisode, CreateIndexer())); + Assert.ThrowsAsync(Is.InstanceOf(), async () => await Subject.Download(remoteEpisode, CreateIndexer())); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), null, _settings), Times.Never()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/FreeboxDownloadTests/TorrentFreeboxDownloadFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/FreeboxDownloadTests/TorrentFreeboxDownloadFixture.cs index 99cca4a6d..dc10ff4f6 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/FreeboxDownloadTests/TorrentFreeboxDownloadFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/FreeboxDownloadTests/TorrentFreeboxDownloadFixture.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; @@ -146,21 +147,21 @@ protected override RemoteMovie CreateRemoteMovie() } [Test] - public void Download_with_DestinationDirectory_should_force_directory() + public async Task Download_with_DestinationDirectory_should_force_directory() { GivenDestinationDirectory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDestinationDirectory, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_with_Category_should_force_directory() + public async Task Download_with_Category_should_force_directory() { GivenDownloadConfiguration(); GivenCategory(); @@ -168,21 +169,21 @@ public void Download_with_Category_should_force_directory() var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDefaultDestinationAndCategory, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_without_DestinationDirectory_and_Category_should_use_default() + public async Task Download_without_DestinationDirectory_and_Category_should_use_default() { GivenDownloadConfiguration(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), _encodedDefaultDestination, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); @@ -190,7 +191,7 @@ public void Download_without_DestinationDirectory_and_Category_should_use_defaul [TestCase(false, false)] [TestCase(true, true)] - public void Download_should_pause_torrent_as_expected(bool addPausedSetting, bool toBePausedFlag) + public async Task Download_should_pause_torrent_as_expected(bool addPausedSetting, bool toBePausedFlag) { _settings.AddPaused = addPausedSetting; @@ -199,7 +200,7 @@ public void Download_should_pause_torrent_as_expected(bool addPausedSetting, boo var remoteMovie = CreateRemoteMovie(); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), toBePausedFlag, It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); @@ -213,7 +214,7 @@ public void Download_should_pause_torrent_as_expected(bool addPausedSetting, boo [TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.First, false)] [TestCase(22, (int)FreeboxDownloadPriority.First, (int)FreeboxDownloadPriority.Last, true)] [TestCase(22, (int)FreeboxDownloadPriority.Last, (int)FreeboxDownloadPriority.Last, false)] - public void Download_should_queue_torrent_first_as_expected(int ageDay, int olderPriority, int recentPriority, bool toBeQueuedFirstFlag) + public async Task Download_should_queue_torrent_first_as_expected(int ageDay, int olderPriority, int recentPriority, bool toBeQueuedFirstFlag) { _settings.OlderPriority = olderPriority; _settings.RecentPriority = recentPriority; @@ -225,7 +226,7 @@ public void Download_should_queue_torrent_first_as_expected(int ageDay, int olde remoteMovie.Movie.MovieMetadata.Value.PhysicalRelease = DateTime.UtcNow.AddDays(-ageDay); - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), toBeQueuedFirstFlag, It.IsAny(), It.IsAny()), Times.Once()); @@ -233,7 +234,7 @@ public void Download_should_queue_torrent_first_as_expected(int ageDay, int olde [TestCase(0, 0)] [TestCase(1.5, 150)] - public void Download_should_define_seed_ratio_as_expected(double? providerSeedRatio, double? expectedSeedRatio) + public async Task Download_should_define_seed_ratio_as_expected(double? providerSeedRatio, double? expectedSeedRatio) { GivenDownloadConfiguration(); GivenSuccessfulDownload(); @@ -243,7 +244,7 @@ public void Download_should_define_seed_ratio_as_expected(double? providerSeedRa remoteMovie.SeedConfiguration = new TorrentSeedConfiguration(); remoteMovie.SeedConfiguration.Ratio = providerSeedRatio; - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.AddTaskFromUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), expectedSeedRatio, It.IsAny()), Times.Once()); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/HadoukenTests/HadoukenFixture.cs index 0199e0e82..d727521ba 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 @@ protected void GivenFailedDownload() 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 @@ public void completed_download_should_have_required_properties() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -277,7 +278,7 @@ public void GetItems_should_ignore_torrents_with_a_different_category() } [Test] - public void Download_from_magnet_link_should_return_hash_uppercase() + public async Task Download_from_magnet_link_should_return_hash_uppercase() { var remoteMovie = CreateRemoteMovie(); @@ -286,13 +287,13 @@ public void Download_from_magnet_link_should_return_hash_uppercase() Mocker.GetMock() .Setup(v => v.AddTorrentUri(It.IsAny(), It.IsAny())); - var result = Subject.Download(remoteMovie, CreateIndexer()); + var result = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); @@ -300,7 +301,7 @@ public void Download_from_torrent_file_should_return_hash_uppercase() .Setup(v => v.AddTorrentFile(It.IsAny(), It.IsAny())) .Returns("hash"); - var result = Subject.Download(remoteMovie, CreateIndexer()); + var result = await Subject.Download(remoteMovie, 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 4e6213d24..78b3f855d 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 @@ public void should_report_BadlyEncoded_as_failed() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -218,7 +219,7 @@ public void Download_should_throw_if_failed() var remoteMovie = CreateRemoteMovie(); - Assert.Throws(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteMovie, 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 2f8871825..ea7e97767 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 @@ public void should_report_scriptstatus_failure_as_failed() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -357,7 +358,7 @@ public void Download_should_throw_if_failed() var remoteMovie = CreateRemoteMovie(); - Assert.Throws(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteMovie, CreateIndexer())); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/PneumaticProviderFixture.cs index df3253d16..148a38a0b 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 @@ public void Setup() private void WithFailedDownload() { - Mocker.GetMock().Setup(c => c.DownloadFile(It.IsAny(), It.IsAny())).Throws(new WebException()); + Mocker.GetMock().Setup(c => c.DownloadFileAsync(It.IsAny(), It.IsAny())).Throws(new WebException()); } [Test] - public void should_download_file_if_it_doesnt_exist() + public async Task should_download_file_if_it_doesnt_exist() { - Subject.Download(_remoteMovie, _indexer); + await Subject.Download(_remoteMovie, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(_nzbUrl, _nzbPath), Times.Once()); } [Test] @@ -81,7 +82,7 @@ public void should_throw_on_failed_download() { WithFailedDownload(); - Assert.Throws(() => Subject.Download(_remoteMovie, _indexer)); + Assert.ThrowsAsync(async () => await Subject.Download(_remoteMovie, _indexer)); } [Test] @@ -91,15 +92,15 @@ public void should_throw_item_is_removed() } [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"); _remoteMovie.Release.Title = illegalTitle; - Subject.Download(_remoteMovie, _indexer); + await Subject.Download(_remoteMovie, _indexer); - Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), expectedFilename), Times.Once()); + Mocker.GetMock().Verify(c => c.DownloadFileAsync(It.IsAny(), expectedFilename), Times.Once()); } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs index 54b0b17db..2f85b5e2b 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.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -448,26 +449,26 @@ public void api_261_should_use_content_path() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().Be(expectedHash); } @@ -482,7 +483,7 @@ public void Download_should_refuse_magnet_if_no_trackers_provided_and_dht_is_dis var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR"; - Assert.Throws(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.ThrowsAsync(async () => await Subject.Download(remoteMovie, CreateIndexer())); } [Test] @@ -495,28 +496,28 @@ public void Download_should_accept_magnet_if_trackers_provided_and_dht_is_disabl var remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = "magnet:?xt=urn:btih:ZPBPA2P6ROZPKRHK44D5OW6NHXU5Z6KR&tr=udp://abc"; - Assert.DoesNotThrow(() => Subject.Download(remoteMovie, CreateIndexer())); + Assert.DoesNotThrowAsync(async () => await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); Mocker.GetMock() .Verify(v => v.MoveTorrentToTopInQueue(It.IsAny(), It.IsAny()), Times.Once()); } [Test] - public void Download_should_not_fail_if_top_priority_not_available() + public async Task Download_should_not_fail_if_top_priority_not_available() { GivenHighPriority(); GivenSuccessfulDownload(); @@ -527,7 +528,7 @@ public void Download_should_not_fail_if_top_priority_not_available() var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -554,27 +555,27 @@ public void should_return_status_with_outputdirs() } [Test] - public void Download_should_handle_http_redirect_to_magnet() + public async Task Download_should_handle_http_redirect_to_magnet() { GivenRedirectToMagnet(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 f63cd5c40..d29ce6ba8 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/RTorrentTests/RTorrentFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -111,13 +112,13 @@ public void completed_download_should_have_required_properties() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteEpisode = CreateRemoteMovie(); - var id = Subject.Download(remoteEpisode, CreateIndexer()); + var id = await Subject.Download(remoteEpisode, 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 f74237dae..25f8c7874 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; @@ -299,27 +300,27 @@ public void deleted_history_item_should_be_ignored() } [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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.Title = title; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -353,7 +354,7 @@ public void should_report_diskspace_unpack_error_as_warning() [Test] [Ignore("Series")] - 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 @@ public void Download_should_use_sabRecentTvPriority_when_recentEpisode_is_true() .Build() .ToList();*/ - Subject.Download(remoteMovie, CreateIndexer()); + await Subject.Download(remoteMovie, 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 35b888d02..b216da6f2 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 @@ public void magnet_download_should_not_return_the_item() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_MovieDirectory_should_force_directory() + public async Task Download_with_MovieDirectory_should_force_directory() { GivenMovieDirectory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -83,14 +84,14 @@ public void Download_with_MovieDirectory_should_force_directory() } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenMovieCategory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -99,7 +100,7 @@ public void Download_with_category_should_force_directory() } [Test] - public void Download_with_category_should_not_have_double_slashes() + public async Task Download_with_category_should_not_have_double_slashes() { GivenMovieCategory(); GivenSuccessfulDownload(); @@ -108,7 +109,7 @@ public void Download_with_category_should_not_have_double_slashes() var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -117,13 +118,13 @@ public void Download_with_category_should_not_have_double_slashes() } [Test] - public void Download_without_TvDirectory_and_Category_should_use_default() + public async Task Download_without_TvDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -132,14 +133,14 @@ public void Download_without_TvDirectory_and_Category_should_use_default() } [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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 d724bf90b..f1bb18021 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 @@ public void completed_download_should_have_required_properties() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } @@ -252,14 +253,14 @@ public void GetItems_should_ignore_downloads_from_other_categories() // 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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().Be(expectedHash); } @@ -350,27 +351,27 @@ public void should_combine_drive_letter() } [Test] - public void Download_should_handle_http_redirect_to_magnet() + public async Task Download_should_handle_http_redirect_to_magnet() { GivenRedirectToMagnet(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, 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 d6ea954be..d17ccb344 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 @@ public void magnet_download_should_not_return_the_item() } [Test] - public void Download_should_return_unique_id() + public async Task Download_should_return_unique_id() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); } [Test] - public void Download_with_MovieDirectory_should_force_directory() + public async Task Download_with_MovieDirectory_should_force_directory() { GivenMovieDirectory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -91,14 +92,14 @@ public void Download_with_MovieDirectory_should_force_directory() } [Test] - public void Download_with_category_should_force_directory() + public async Task Download_with_category_should_force_directory() { GivenMovieCategory(); GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -107,7 +108,7 @@ public void Download_with_category_should_force_directory() } [Test] - public void Download_with_category_should_not_have_double_slashes() + public async Task Download_with_category_should_not_have_double_slashes() { GivenMovieCategory(); GivenSuccessfulDownload(); @@ -116,7 +117,7 @@ public void Download_with_category_should_not_have_double_slashes() var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -125,13 +126,13 @@ public void Download_with_category_should_not_have_double_slashes() } [Test] - public void Download_without_MovieDirectory_and_Category_should_use_default() + public async Task Download_without_MovieDirectory_and_Category_should_use_default() { GivenSuccessfulDownload(); var remoteMovie = CreateRemoteMovie(); - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().NotBeNullOrEmpty(); @@ -140,14 +141,14 @@ public void Download_without_MovieDirectory_and_Category_should_use_default() } [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 remoteMovie = CreateRemoteMovie(); remoteMovie.Release.DownloadUrl = magnetUrl; - var id = Subject.Download(remoteMovie, CreateIndexer()); + var id = await Subject.Download(remoteMovie, CreateIndexer()); id.Should().Be(expectedHash); } diff --git a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs index e050659cc..256f4ce3c 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadServiceFixture.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading.Tasks; using FizzWare.NBuilder; using Moq; using NUnit.Framework; @@ -70,23 +71,23 @@ private Mock WithTorrentClient() } [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()); } @@ -98,7 +99,7 @@ public void Download_report_should_not_publish_on_failed_grab_event() 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(); } @@ -113,7 +114,7 @@ public void Download_report_should_trigger_indexer_backoff_on_indexer_error() 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()); @@ -133,7 +134,7 @@ public void Download_report_should_trigger_indexer_backoff_on_http429_with_long_ 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()); @@ -153,7 +154,7 @@ public void Download_report_should_trigger_indexer_backoff_on_http429_based_on_d 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(), @@ -167,7 +168,7 @@ public void Download_report_should_not_trigger_indexer_backoff_on_downloadclient 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()); @@ -183,7 +184,7 @@ public void Download_report_should_not_trigger_indexer_backoff_on_indexer_404_er 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()); @@ -192,14 +193,14 @@ public void Download_report_should_not_trigger_indexer_backoff_on_indexer_404_er [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(); @@ -214,7 +215,7 @@ public void should_attempt_download_even_if_client_is_disabled() } }); - 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()); @@ -222,26 +223,26 @@ public void should_attempt_download_even_if_client_is_disabled() } [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/ReleaseSearchServiceFixture.cs b/src/NzbDrone.Core.Test/IndexerSearchTests/ReleaseSearchServiceFixture.cs index 15e6d7687..df6aa4ad6 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; @@ -53,13 +54,13 @@ private List WatchForSearchCriteria() _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_MovieNoTags_IndexerNotIncluded() + public async Task Tags_IndexerTags_MovieNoTags_IndexerNotIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -69,7 +70,7 @@ public void Tags_IndexerTags_MovieNoTags_IndexerNotIncluded() var allCriteria = WatchForSearchCriteria(); - Subject.MovieSearch(_movie, true, false); + await Subject.MovieSearch(_movie, true, false); var criteria = allCriteria.OfType().ToList(); @@ -77,7 +78,7 @@ public void Tags_IndexerTags_MovieNoTags_IndexerNotIncluded() } [Test] - public void Tags_IndexerNoTags_MovieTags_IndexerIncluded() + public async Task Tags_IndexerNoTags_MovieTags_IndexerIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -95,7 +96,7 @@ public void Tags_IndexerNoTags_MovieTags_IndexerIncluded() var allCriteria = WatchForSearchCriteria(); - Subject.MovieSearch(_movie, true, false); + await Subject.MovieSearch(_movie, true, false); var criteria = allCriteria.OfType().ToList(); @@ -103,7 +104,7 @@ public void Tags_IndexerNoTags_MovieTags_IndexerIncluded() } [Test] - public void Tags_IndexerAndMovieTagsMatch_IndexerIncluded() + public async Task Tags_IndexerAndMovieTagsMatch_IndexerIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -122,7 +123,7 @@ public void Tags_IndexerAndMovieTagsMatch_IndexerIncluded() var allCriteria = WatchForSearchCriteria(); - Subject.MovieSearch(_movie, true, false); + await Subject.MovieSearch(_movie, true, false); var criteria = allCriteria.OfType().ToList(); @@ -130,7 +131,7 @@ public void Tags_IndexerAndMovieTagsMatch_IndexerIncluded() } [Test] - public void Tags_IndexerAndMovieTagsMismatch_IndexerNotIncluded() + public async Task Tags_IndexerAndMovieTagsMismatch_IndexerNotIncluded() { _mockIndexer.SetupGet(s => s.Definition).Returns(new IndexerDefinition { @@ -149,7 +150,7 @@ public void Tags_IndexerAndMovieTagsMismatch_IndexerNotIncluded() var allCriteria = WatchForSearchCriteria(); - Subject.MovieSearch(_movie, true, false); + await Subject.MovieSearch(_movie, 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 8b742f47c..8a6e32516 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 @@ public void Setup() } [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(4); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs index 4bea0d2df..ffa53af86 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/HDBitsTests/HDBitsFixture.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net.Http; using System.Text; +using System.Threading.Tasks; using FluentAssertions; using Moq; using NUnit.Framework; @@ -30,15 +31,15 @@ public void Setup() [TestCase("Files/Indexers/HdBits/RecentFeedLongIDs.json")] [TestCase("Files/Indexers/HdBits/RecentFeedStringIDs.json")] - public void should_parse_recent_feed_from_HDBits(string fileName) + public async Task should_parse_recent_feed_from_HDBits(string fileName) { var responseJson = ReadAllText(fileName); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Post))) - .Returns(r => new HttpResponse(r, new HttpHeader(), responseJson)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Post))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), responseJson))); - var torrents = Subject.FetchRecent(); + var torrents = await Subject.FetchRecent(); torrents.Should().HaveCount(2); torrents.First().Should().BeOfType(); @@ -59,15 +60,15 @@ public void should_parse_recent_feed_from_HDBits(string fileName) } [Test] - public void should_warn_on_wrong_passkey() + public async Task should_warn_on_wrong_passkey() { var responseJson = new { status = 5, message = "Invalid authentication credentials" }.ToJson(); Mocker.GetMock() - .Setup(v => v.Execute(It.IsAny())) - .Returns(r => new HttpResponse(r, new HttpHeader(), Encoding.UTF8.GetBytes(responseJson))); + .Setup(v => v.ExecuteAsync(It.IsAny())) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), Encoding.UTF8.GetBytes(responseJson)))); - var torrents = Subject.FetchRecent(); + var torrents = await Subject.FetchRecent(); torrents.Should().BeEmpty(); 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 @@ public void should_not_validate_no_download_format() } [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 d31be4c1a..5841b489d 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.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; @@ -37,15 +38,15 @@ public void Setup() } [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); diff --git a/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/NyaaTests/NyaaFixture.cs index e65e920e2..d440e255d 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; @@ -58,15 +59,15 @@ public void should_parse_recent_feed_from_Nyaa() }*/ [Test] - public void should_parse_2021_recent_feed_from_Nyaa() + public async Task should_parse_2021_recent_feed_from_Nyaa() { var recentFeed = ReadAllText(@"Files/Indexers/Nyaa/Nyaa2021.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(3); releases.First().Should().BeOfType(); diff --git a/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs index 2dd371949..cc9864f06 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/PTPTests/PTPFixture.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; @@ -27,7 +28,7 @@ public void Setup() } [TestCase("Files/Indexers/PTP/imdbsearch.json")] - public void should_parse_feed_from_PTP(string fileName) + public async Task should_parse_feed_from_PTP(string fileName) { var authResponse = new PassThePopcornAuthResponse { Result = "Ok" }; @@ -36,14 +37,14 @@ public void should_parse_feed_from_PTP(string fileName) var responseJson = ReadAllText(fileName); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Post))) - .Returns(r => new HttpResponse(r, new HttpHeader(), authStream.ToString())); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Post))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), authStream.ToString()))); Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, responseJson)); + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, responseJson))); - var torrents = Subject.FetchRecent(); + var torrents = await Subject.FetchRecent(); torrents.Should().HaveCount(293); torrents.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 @@ public List TestPublic() { 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 23131d280..286450114 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 @@ private void GivenRecentFeedResponse(string rssXmlFile) { 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 @@ public void should_parse_recent_feed_from_ImmortalSeed() } [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 @@ public void should_parse_recent_feed_from_Ezrss() } [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 @@ public void should_parse_recent_feed_from_ShowRSS_info() } [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 @@ public void should_parse_recent_feed_from_Doki() } [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 @@ public void should_parse_recent_feed_from_ExtraTorrents() } [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 @@ public void should_parse_recent_feed_from_LimeTorrents() } [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 @@ public void should_parse_recent_feed_from_AnimeTosho_without_size() } [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 @@ public void should_parse_multi_enclosure_from_AnimeTosho() } [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 @@ public void should_parse_recent_feed_from_AlphaRatio() } [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 @@ public void should_parse_recent_feed_from_EveolutionWorld_without_size() } [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/TorznabTests/TorznabFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/TorznabTests/TorznabFixture.cs index f3213e777..c2b27686f 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 @@ public void Setup() } [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 @@ public void should_parse_recent_feed_from_torznab_hdaccess_net() } [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); @@ -103,15 +104,15 @@ public void should_parse_recent_feed_from_torznab_tpb() } [Test] - public void should_parse_recent_feed_from_torznab_animetosho() + public async Task should_parse_recent_feed_from_torznab_animetosho() { var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_animetosho.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(2); @@ -170,8 +171,8 @@ public void jackett_all_url_should_not_validate(string baseUrl) (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(); @@ -185,8 +186,8 @@ public void jackett_all_api_should_not_validate(string apiPath) 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.Test/Radarr.Core.Test.csproj b/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj index 0ebddafeb..870ac34da 100644 --- a/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/Radarr.Core.Test.csproj @@ -20,4 +20,9 @@ PreserveNewest + + + + + diff --git a/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs b/src/NzbDrone.Core/Download/Clients/Pneumatic/Pneumatic.cs index 313f9dcec..003704b08 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; @@ -33,7 +34,7 @@ public Pneumatic(IHttpClient httpClient, public override DownloadProtocol Protocol => DownloadProtocol.Usenet; - public override string Download(RemoteMovie remoteMovie, IIndexer indexer) + public override async Task Download(RemoteMovie remoteMovie, IIndexer indexer) { var url = remoteMovie.Release.DownloadUrl; var title = remoteMovie.Release.Title; @@ -49,7 +50,7 @@ public override string Download(RemoteMovie remoteMovie, IIndexer indexer) 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 a0f2ab3db..b9c5a1de0 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; @@ -62,7 +63,7 @@ public abstract DownloadProtocol Protocol get; } - public abstract string Download(RemoteMovie remoteMovie, IIndexer indexer); + public abstract Task Download(RemoteMovie remoteMovie, 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 bbc622ee7..2fe82cf97 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(RemoteMovie remoteMovie); + Task DownloadReport(RemoteMovie remoteMovie); } public class DownloadService : IDownloadService @@ -49,7 +50,7 @@ public DownloadService(IProvideDownloadClient downloadClientProvider, _logger = logger; } - public void DownloadReport(RemoteMovie remoteMovie) + public async Task DownloadReport(RemoteMovie remoteMovie) { var filterBlockedClients = remoteMovie.Release.PendingReleaseReason == PendingReleaseReason.DownloadClientUnavailable; @@ -57,10 +58,10 @@ public void DownloadReport(RemoteMovie remoteMovie) var downloadClient = _downloadClientProvider.GetDownloadClient(remoteMovie.Release.DownloadProtocol, remoteMovie.Release.IndexerId, filterBlockedClients, tags); - DownloadReport(remoteMovie, downloadClient); + await DownloadReport(remoteMovie, downloadClient); } - public void DownloadReport(RemoteMovie remoteMovie, IDownloadClient downloadClient) + public async Task DownloadReport(RemoteMovie remoteMovie, IDownloadClient downloadClient) { Ensure.That(remoteMovie.Movie, () => remoteMovie.Movie).IsNotNull(); @@ -78,7 +79,7 @@ public void DownloadReport(RemoteMovie remoteMovie, IDownloadClient downloadClie if (remoteMovie.Release.DownloadUrl.IsNotNullOrWhiteSpace() && !remoteMovie.Release.DownloadUrl.StartsWith("magnet:")) { var url = new HttpUri(remoteMovie.Release.DownloadUrl); - _rateLimitService.WaitAndPulse(url.Host, TimeSpan.FromSeconds(2)); + await _rateLimitService.WaitAndPulseAsync(url.Host, TimeSpan.FromSeconds(2)); } IIndexer indexer = null; @@ -91,7 +92,7 @@ public void DownloadReport(RemoteMovie remoteMovie, IDownloadClient downloadClie string downloadClientId; try { - downloadClientId = downloadClient.Download(remoteMovie, indexer); + downloadClientId = await downloadClient.Download(remoteMovie, indexer); _downloadClientStatusService.RecordSuccess(downloadClient.Definition.Id); _indexerStatusService.RecordSuccess(remoteMovie.Release.IndexerId); } diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index 747ba73de..c642fa3f2 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(RemoteMovie remoteMovie, IIndexer indexer); + Task Download(RemoteMovie remoteMovie, 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 5158b019c..890662962 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 @@ public ProcessDownloadDecisions(IDownloadService downloadService, _logger = logger; } - public ProcessedDecisions ProcessDecisions(List decisions) + public async Task ProcessDecisions(List decisions) { var qualifiedReports = GetQualifiedReports(decisions); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisionsForMovies(qualifiedReports); @@ -73,7 +74,7 @@ public ProcessedDecisions ProcessDecisions(List decisions) try { _logger.Trace("Grabbing from Indexer {0} at priority {1}.", remoteMovie.Release.Indexer, remoteMovie.Release.IndexerPriority); - _downloadService.DownloadReport(remoteMovie); + await _downloadService.DownloadReport(remoteMovie); grabbed.Add(report); } catch (ReleaseUnavailableException) diff --git a/src/NzbDrone.Core/Download/TorrentClientBase.cs b/src/NzbDrone.Core/Download/TorrentClientBase.cs index 4fc581fa8..07dccd118 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; @@ -42,7 +43,7 @@ protected TorrentClientBase(ITorrentFileInfoReader torrentFileInfoReader, protected abstract string AddFromMagnetLink(RemoteMovie remoteMovie, string hash, string magnetLink); protected abstract string AddFromTorrentFile(RemoteMovie remoteMovie, string hash, string filename, byte[] fileContent); - public override string Download(RemoteMovie remoteMovie, IIndexer indexer) + public override async Task Download(RemoteMovie remoteMovie, IIndexer indexer) { var torrentInfo = remoteMovie.Release as TorrentInfo; @@ -69,7 +70,7 @@ public override string Download(RemoteMovie remoteMovie, IIndexer indexer) { try { - return DownloadFromWebUrl(remoteMovie, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteMovie, indexer, torrentUrl); } catch (Exception ex) { @@ -115,14 +116,14 @@ public override string Download(RemoteMovie remoteMovie, IIndexer indexer) if (torrentUrl.IsNotNullOrWhiteSpace()) { - return DownloadFromWebUrl(remoteMovie, indexer, torrentUrl); + return await DownloadFromWebUrl(remoteMovie, indexer, torrentUrl); } } return null; } - private string DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, string torrentUrl) + private async Task DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, string torrentUrl) { byte[] torrentFile = null; @@ -133,7 +134,7 @@ private string DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, str 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 || @@ -152,7 +153,7 @@ private string DownloadFromWebUrl(RemoteMovie remoteMovie, IIndexer indexer, str request.Url += new HttpUri(locationHeader); - return DownloadFromWebUrl(remoteMovie, indexer, request.Url.ToString()); + return await DownloadFromWebUrl(remoteMovie, 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 fb721dd9c..25743f2ed 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; @@ -35,7 +36,7 @@ protected UsenetClientBase(IHttpClient httpClient, protected abstract string AddFromNzbFile(RemoteMovie remoteMovie, string filename, byte[] fileContents); - public override string Download(RemoteMovie remoteMovie, IIndexer indexer) + public override async Task Download(RemoteMovie remoteMovie, IIndexer indexer) { var url = remoteMovie.Release.DownloadUrl; var filename = FileNameBuilder.CleanFileName(remoteMovie.Release.Title) + ".nzb"; @@ -46,7 +47,10 @@ public override string Download(RemoteMovie remoteMovie, IIndexer indexer) { var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url); request.RateLimitKey = remoteMovie?.Release?.IndexerId.ToString(); - nzbData = _httpClient.Get(request).ResponseData; + + var response = await _httpClient.GetAsync(request); + + nzbData = response.ResponseData; _logger.Debug("Downloaded nzb for movie '{0}' finished ({1} bytes from {2})", remoteMovie.Release.Title, nzbData.Length, url); } diff --git a/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs b/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs index b9b5cd043..6ddbc95d3 100644 --- a/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/MoviesSearchService.cs @@ -50,8 +50,9 @@ public void Execute(MoviesSearchCommand message) continue; } - var decisions = _releaseSearchService.MovieSearch(movieId, userInvokedSearch, false); - downloadedCount += _processDownloadDecisions.ProcessDecisions(decisions).Grabbed.Count; + var decisions = _releaseSearchService.MovieSearch(movieId, userInvokedSearch, false).GetAwaiter().GetResult(); + var processDecisions = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); + downloadedCount += processDecisions.Grabbed.Count; } _logger.ProgressInfo("Movie search completed. {0} reports downloaded.", downloadedCount); @@ -107,7 +108,7 @@ private void SearchForMissingMovies(List movies, bool userInvokedSearch) try { - decisions = _releaseSearchService.MovieSearch(movieId.Key, userInvokedSearch, false); + decisions = _releaseSearchService.MovieSearch(movieId.Key, userInvokedSearch, false).GetAwaiter().GetResult(); } catch (Exception ex) { @@ -116,9 +117,8 @@ private void SearchForMissingMovies(List movies, bool userInvokedSearch) continue; } - var processed = _processDownloadDecisions.ProcessDecisions(decisions); - - downloadedCount += processed.Grabbed.Count; + var processDecisions = _processDownloadDecisions.ProcessDecisions(decisions).GetAwaiter().GetResult(); + downloadedCount += processDecisions.Grabbed.Count; } _logger.ProgressInfo("Completed missing search for {0} movies. {1} reports downloaded.", movies.Count, downloadedCount); diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs index 1f399aa45..a84badc74 100644 --- a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs +++ b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs @@ -5,7 +5,6 @@ using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Instrumentation.Extensions; -using NzbDrone.Common.TPL; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Indexers; using NzbDrone.Core.IndexerSearch.Definitions; @@ -18,8 +17,8 @@ namespace NzbDrone.Core.IndexerSearch { public interface ISearchForReleases { - List MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch); - List MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch); + Task> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch); + Task> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch); } public class ReleaseSearchService : ISearchForReleases @@ -46,21 +45,21 @@ public ReleaseSearchService(IIndexerFactory indexerFactory, _logger = logger; } - public List MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch) + public async Task> MovieSearch(int movieId, bool userInvokedSearch, bool interactiveSearch) { var movie = _movieService.GetMovie(movieId); movie.MovieMetadata.Value.Translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(movie.MovieMetadataId); - return MovieSearch(movie, userInvokedSearch, interactiveSearch); + return await MovieSearch(movie, userInvokedSearch, interactiveSearch); } - public List MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch) + public async Task> MovieSearch(Movie movie, bool userInvokedSearch, bool interactiveSearch) { var downloadDecisions = new List(); var searchSpec = Get(movie, userInvokedSearch, interactiveSearch); - var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); + var decisions = await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec); downloadDecisions.AddRange(decisions); return DeDupeDecisions(downloadDecisions); @@ -96,7 +95,7 @@ private TSpec Get(Movie movie, bool userInvokedSearch, bool interactiveSe return spec; } - private List Dispatch(Func> searchAction, SearchCriteriaBase criteriaBase) + private async Task> Dispatch(Func>> searchAction, SearchCriteriaBase criteriaBase) { var indexers = criteriaBase.InteractiveSearch ? _indexerFactory.InteractiveSearchEnabled() : @@ -105,42 +104,33 @@ private List Dispatch(Func> // Filter indexers to untagged indexers and indexers with intersecting tags indexers = indexers.Where(i => i.Definition.Tags.Empty() || i.Definition.Tags.Intersect(criteriaBase.Movie.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; + var batch = await Task.WhenAll(tasks); - 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()); - } - - 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 298d7f4fe..8ac004712 100644 --- a/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs +++ b/src/NzbDrone.Core/Indexers/FetchAndParseRssService.cs @@ -3,14 +3,13 @@ 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 @@ -24,54 +23,42 @@ public FetchAndParseRssService(IIndexerFactory indexerFactory, Logger logger) _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(); - - lock (result) - { - _logger.Debug("Found {0} from {1}", indexerReports.Count, indexer.Name); - - result.AddRange(indexerReports); - } - } - catch (Exception e) - { - _logger.Error(e, "Error during RSS Sync"); - } - }).LogExceptions(); - - taskList.Add(task); - } - - Task.WaitAll(taskList.ToArray()); + var result = batch.SelectMany(x => x).ToList(); _logger.Debug("Found {0} reports", result.Count); return result; } + + private async Task> FetchIndexer(IIndexer indexer) + { + try + { + return await indexer.FetchRecent(); + } + catch (Exception ex) + { + _logger.Error(ex, "Error during RSS Sync"); + } + + return Array.Empty(); + } } } diff --git a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs index c473b95b8..ce5fbfff9 100644 --- a/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/HttpIndexerBase.cs @@ -40,21 +40,21 @@ public HttpIndexerBase(IHttpClient httpClient, IIndexerStatusService indexerStat _httpClient = httpClient; } - public override IList FetchRecent() + public override Task> FetchRecent() { if (!SupportsRss) { - return Array.Empty(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetRecentRequests(), true); } - public override IList Fetch(MovieSearchCriteria searchCriteria) + public override Task> Fetch(MovieSearchCriteria searchCriteria) { if (!SupportsSearch) { - return Array.Empty(); + return Task.FromResult>(Array.Empty()); } return FetchReleases(g => g.GetSearchRequests(searchCriteria)); @@ -92,7 +92,7 @@ public override HttpRequest GetDownloadRequest(string link) 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; @@ -128,7 +128,7 @@ protected virtual IList FetchReleases(Func page) 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 { @@ -308,7 +308,7 @@ protected virtual IList FetchPage(IndexerRequest request, IParseInd } } - protected virtual IndexerResponse FetchIndexerResponse(IndexerRequest request) + protected virtual async Task FetchIndexerResponse(IndexerRequest request) { _logger.Debug("Downloading Feed " + request.HttpRequest.ToString(false)); @@ -321,15 +321,17 @@ protected virtual IndexerResponse FetchIndexerResponse(IndexerRequest request) request.HttpRequest.AllowAutoRedirect = true; - 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 { @@ -346,7 +348,7 @@ protected virtual ValidationFailure TestConnection() 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 71ed6e92d..3f4e3ba2d 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,8 +13,8 @@ public interface IIndexer : IProvider bool SupportsSearch { get; } DownloadProtocol Protocol { get; } - IList FetchRecent(); - IList Fetch(MovieSearchCriteria searchCriteria); + Task> FetchRecent(); + Task> Fetch(MovieSearchCriteria searchCriteria); HttpRequest GetDownloadRequest(string link); } } diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs index 7707b1d70..bcfa5b4e0 100644 --- a/src/NzbDrone.Core/Indexers/IndexerBase.cs +++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using System.Threading.Tasks; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; @@ -71,8 +72,8 @@ public virtual object RequestAction(string action, IDictionary q protected TSettings Settings => (TSettings)Definition.Settings; - public abstract IList FetchRecent(); - public abstract IList Fetch(MovieSearchCriteria searchCriteria); + public abstract Task> FetchRecent(); + public abstract Task> Fetch(MovieSearchCriteria searchCriteria); public abstract HttpRequest GetDownloadRequest(string link); protected virtual IList CleanupReleases(IEnumerable releases) @@ -103,7 +104,7 @@ public ValidationResult Test() try { - Test(failures); + Test(failures).GetAwaiter().GetResult(); } catch (Exception ex) { @@ -114,7 +115,7 @@ public ValidationResult Test() 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 0ecf8e070..3c7785079 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; @@ -93,9 +94,10 @@ private NewznabSettings GetSettings(string url, string apiPath = null, int[] cat 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 @@ public RssSyncService(IIndexerStatusService indexerStatusService, _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 @@ private ProcessedDecisions Sync() 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 309ab1bba..75bdd67e5 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; @@ -83,9 +84,10 @@ private TorznabSettings GetSettings(string url, string apiPath = null, int[] cat 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 65bed4473..f2d5da996 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -167,7 +167,7 @@ public static IHostBuilder CreateConsoleHostBuilder(string[] args, StartupContex }); builder.ConfigureKestrel(serverOptions => { - serverOptions.AllowSynchronousIO = true; + serverOptions.AllowSynchronousIO = false; serverOptions.Limits.MaxRequestBodySize = null; }); builder.UseStartup(); diff --git a/src/Radarr.Api.V3/Indexers/ReleaseController.cs b/src/Radarr.Api.V3/Indexers/ReleaseController.cs index 67221471b..990c50562 100644 --- a/src/Radarr.Api.V3/Indexers/ReleaseController.cs +++ b/src/Radarr.Api.V3/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; @@ -96,21 +97,21 @@ public object DownloadRelease(ReleaseResource release) } [HttpGet] - public List GetReleases(int? movieId) + public async Task> GetReleases(int? movieId) { if (movieId.HasValue) { - return GetMovieReleases(movieId.Value); + return await GetMovieReleases(movieId.Value); } - return GetRss(); + return await GetRss(); } - private List GetMovieReleases(int movieId) + private async Task> GetMovieReleases(int movieId) { try { - var decisions = _releaseSearchService.MovieSearch(movieId, true, true); + var decisions = await _releaseSearchService.MovieSearch(movieId, true, true); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisionsForMovies(decisions); return MapDecisions(prioritizedDecisions); @@ -126,9 +127,9 @@ private List GetMovieReleases(int movieId) } } - private List GetRss() + private async Task> GetRss() { - var reports = _rssFetcherAndParser.Fetch(); + var reports = await _rssFetcherAndParser.Fetch(); var decisions = _downloadDecisionMaker.GetRssDecision(reports); var prioritizedDecisions = _prioritizeDownloadDecision.PrioritizeDecisionsForMovies(decisions); diff --git a/src/Radarr.Api.V3/Indexers/ReleasePushController.cs b/src/Radarr.Api.V3/Indexers/ReleasePushController.cs index a940a0871..4f3c43806 100644 --- a/src/Radarr.Api.V3/Indexers/ReleasePushController.cs +++ b/src/Radarr.Api.V3/Indexers/ReleasePushController.cs @@ -61,7 +61,7 @@ public ActionResult> Create(ReleaseResource release) lock (PushLock) { decisions = _downloadDecisionMaker.GetRssDecision(new List { info }); - _downloadDecisionProcessor.ProcessDecisions(decisions); + _downloadDecisionProcessor.ProcessDecisions(decisions).GetAwaiter().GetResult(); } var firstDecision = decisions.FirstOrDefault(); diff --git a/src/Radarr.Api.V3/Queue/QueueActionController.cs b/src/Radarr.Api.V3/Queue/QueueActionController.cs index bc2b1862e..e1c35ec56 100644 --- a/src/Radarr.Api.V3/Queue/QueueActionController.cs +++ b/src/Radarr.Api.V3/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 @@ public QueueActionController(IPendingReleaseService pendingReleaseService, } [HttpPost("grab/{id:int}")] - public object Grab(int id) + public async Task Grab(int id) { var pendingRelease = _pendingReleaseService.FindPendingQueueItem(id); @@ -29,13 +30,14 @@ public object Grab(int id) throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteMovie); + await _downloadService.DownloadReport(pendingRelease.RemoteMovie); 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 @@ public object Grab([FromBody] QueueBulkResource resource) throw new NotFoundException(); } - _downloadService.DownloadReport(pendingRelease.RemoteMovie); + await _downloadService.DownloadReport(pendingRelease.RemoteMovie); } return new { };