Moq Timeout Exception C# - c#

I am using the Moq testing framework in C#, and I trying to create a unit test where I have a method which calls out to a service on a remote server over a unreliable network.
In side the method I am trying to unit test I have the following code:
Task.Factory.StartNew(() => this.remoteClient.SomeMethod(userDetails)).Wait(Timespan.FromSeconds(10));
The aim of the unit test is to mock out the timeout where the service failed to respond within 10 seconds.
So far I have the unit test as follows, which does work, but I am feeling that it is not quite right.
mockRemoteClientService.Setup(r =>r.SomeMethod(It.IsAny<string>())).Callback(() => Thread.Sleep(11000));
Can anyone advise me whether the approach I am taking is correct or is there another way to do this?

You can use a cancellation token to setup the actual timeout.
When you want to mock out the service call to simulate a timeout, you can use Throws (or ThrowsAsync in case of an async method) to throw a TaskCancelledException or TimeOutException like so:
mockRemoteClientService.Setup(x => x.SomeMethod(It.IsAny<string>())).Throw(new TaskCancelledException());
Then Assert that you handle the response correctly.

Related

RestSharp Response error: "Only one usage of each socket address (protocol/network address/port) is normally permitted"

I'm using RestSharp to communicate with a .Net Core Web API. Both Client and Server are written by me.
I have a suite of Services all inheriting a Base class which contains an async method to perform the request via a RestClient. Here is the method within the base class that creates the RestClient.
private async Task<ServiceResponse> RequestAsync(ServiceRequest request)
{
try
{
var result = await new RestClient(_digiCore.Config.GetApiBaseUrl()).ExecuteTaskAsync(request.Request, request.CancellationTokenSource.Token);
switch (result.StatusCode)
{
case HttpStatusCode.OK:
case HttpStatusCode.Created:
case HttpStatusCode.NoContent:
return new ServiceResponse
{
Code = ServiceResponseCode.Success,
Content = result.Content
};
// User wasn't authenticated for this one - better luck next time!
case HttpStatusCode.Unauthorized:
Logger.LogError($"Unauthorized {request.Method.ToString()}/{request.Path}");
default:
Logger.LogError($"An error occurred {request.Method.ToString()}/{request.Path}");
}
}
catch (Exception e)
{
Logger.LogError($"A Rest Client error occurred {request.Method.ToString()}/{request.Path}");
}
}
My understanding is that the RestClient (unlike HttpClient) is thread safe and OK to create a new instance each time.
When Load testing my application, one I reach a certain point, I find that I occasionally receive the following response back from the API. Refreshing the page might bring back the correct result, or I might get another error. When the Load Test has finished everything goes back to normal. The numbers of the load test are nothing crazy, so its started to get me worried about real-life performance...
Only one usage of each socket address (protocol/network address/port) is normally permitted
I believe this is down to port exhaustion. Both API and Client are running in Azure as App services.
I have tried making the RestClient part of a singleton service, and checked that it is only created once - but this did not alleviate the issue.
I have also looked into setting the DefaultConnectionLimit in the Startup function of my startup class from the default (2) to 12, but I did not see any improvements here either.
I'm really struggling to see how I can improve this...
Found out the reason for this...
It seems there is currently an issue with RestSharp whereby socket connections are not closed down immediately and instead are left in TIME_WAIT state.
This issue is currently logged with the RestSharp guys here ->
https://github.com/restsharp/RestSharp/issues/1322
I have chosen to switch over to using HttpClient - and running the exact same load test I had zero problems.
Here is an screenshot taken from Azure showing the difference between the two load tests.
Was with my app using RestSharp
Was with my app using Http Client
Hope this helps somebody. It's a shame I had to ditch RestSharp as it was a nice little library - unfortunately with an issue like this it's just too risky to run in a Production environment.

webapi 2 - how to properly invoke long running method async/in new thread, and return response to client

I am developing a web-api that takes data from client, and saves it for later use. Now i have an external system that needs to know of all events, so i want to setup a notification component in my web-api.
What i do is, after data is saved, i execute a SendNotification(message) method in my new component. Meanwhile i don't want my client to wait or even know that we're sending notifications, so i want to return a 201 Created / 200 OK response as fast as possible to my clients.
Yes this is a fire-and-forget scenario. I want the notification component to handle all exception cases (if notification fails, the client of the api doesn't really care at all).
I have tried using async/await, but this does not work in the web-api, since when the request-thread terminates, the async operation does so aswell.
So i took a look at Task.Run().
My controller looks like so:
public IHttpActionResult PostData([FromBody] Data data) {
_dataService.saveData(data);
//This could fail, and retry strategy takes time.
Task.Run(() => _notificationHandler.SendNotification(new Message(data)));
return CreatedAtRoute<object>(...);
}
And the method in my NotificationHandler
public void SendNotification(Message message) {
//..send stuff to a notification server somewhere, syncronously.
}
I am relatively new in the C# world, and i don't know if there is a more elegant(or proper) way of doing this. Are there any pitfalls with using this method?
It really depends how long. Have you looked into the possibility of QueueBackgroundWorkItem as detailed here. If you want to implement a very fast fire and forget you also might want to consider a queue to pop these messages onto so you can return from the controller immediately. You'd then have to have something which polls the queue and sends out the notifications i.e. Scheduled Task, Windows service etc. IIRC, if IIS recycles during a task, the process is killed whereas with QueueBackgroundWorkItem there is a grace period for which ASP.Net will let the work item finish it's job.
I would take a look on Hangfire. It is fairly easy to setup, it should be able to run within your ASP.NET process and is easy to migrate to a standalone process in case your IIS load suddenly increases.
I experimented with Hangfire a while ago but in standalone mode. It has enough docs and easy to understand API.

Run all tests if one test not fails

I know that all test should be independent and run in the random order.
But here is my situation:
I need to test my library which is working with external web resource. I have one test which checks if the web resource available and I have many tests which check the data I get from this resource.
If the web resource is not available I have all my tests failed and I think it is difficult to interpret this result. Is there any way to run all tests which check the data I get from resource if and only if the first test (which checks resource availability) was not failed?
I think availability of web resource should be a precondition for tests of your library. It should not be a separate test itself.
So, you need to check connection in TestFixtureSetup. If connection fails, all tests from fixture will not run. All tests in this test fixture will be marked as failed (which is true if there is no connection) and you will receive message
TestFixtureSetUp failed in YourLibtraryTests
Unfortunately NUnit will not show additional information if you will fail test with some message
Assert.NotNull(connection, "Cannot establish connection to remote service");
But it will be easy to find the reason if you know that TestFixtureSetUp failed.

Triggering an async operation in from mvc controller

Here is my scenario.
I want to create a web endpoint that will kick off a service that may be long-running, perhaps 20-30 minutes. I'd like to return an HttpResponseResult immediately and trigger the service to run asynchronously, instead of having to wait for the service to complete before returning a response to client.
What is the easiest way to go about doing this? I don't need to return any sort of result from the service, just trigger it.
Just run a task using Task.Run(() => <trigger service call> ) and ignore the return value. The only down side of this is that it will consume a thread from the thread pool. If the service has an asynchronous version of the operation you are calling you can use a TaskCompletionSource
SignalR will be my choice to do this kind of behavior. Tutorial is here.
Basically, a client invokes a server method/action and is 'done' (you can continue and do whatever y you want in the client side). Once the server is done it pushes data/notification to client via RPC.
On the server side you can execute the code anyway you like, synchronously or async.

How to check if a WCF service is available?

Can I use Proxy.Open() as an indication to whether the connection should work or not?
I would like to check if a connection is available first, and then, if its not, i won't make any calls to the service during the run of the application.
Note: I only need to check connectivity, not necessarily and entire client-service round-trip.
I Ended up creating a Ping() methods in the service as suggested.
FYI, using simply Open() just didn't work - Open() doesn't raise any exceptions even if the service is offline!
Given the fact that there are so many variables which influence success of a WCF Service call, I tend to add a dummy void KnockKnock()) method to the services to have a real proof if the connection works.
This method can also serve a double purpose: You can call it async to notify the server that he has to be prepared for incoming requests. (Just the initial start-up of the service may take some time.) By invoking the KnockKnock() method the server can start loading the service and give your clients a better initial response performance.

Categories

Resources