Skip to content

Commit

Permalink
ThreeMammals#893 fix request cancellation, add acceptance test
Browse files Browse the repository at this point in the history
  • Loading branch information
jlukawska authored and raman-m committed May 19, 2023
1 parent bc25f4e commit 027c23c
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Ocelot/Multiplexer/MultiplexingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ private static HttpContext Copy(HttpContext source)
target.Request.RouteValues = source.Request.RouteValues;
target.Connection.RemoteIpAddress = source.Connection.RemoteIpAddress;
target.RequestServices = source.RequestServices;
target.RequestAborted = source.RequestAborted;
return target;
}

Expand Down
133 changes: 133 additions & 0 deletions test/Ocelot.AcceptanceTests/CancelRequestTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;

namespace Ocelot.AcceptanceTests
{
public class CancelRequestTests : IDisposable
{
private const int SERVICE_WORK_TIME = 5_000;
private const int MAX_WAITING_TIME = 60_000;
private readonly Steps _steps;
private readonly ServiceHandler _serviceHandler;
private Notifier _serviceWorkStartedNotifier;
private Notifier _serviceWorkStoppedNotifier;
private bool _cancelExceptionThrown;

public CancelRequestTests()
{
_serviceHandler = new ServiceHandler();
_steps = new Steps();
_serviceWorkStartedNotifier = new Notifier("service work started notifier");
_serviceWorkStoppedNotifier = new Notifier("service work finished notifier");
}

[Fact]
public void should_abort_service_work_when_cancelling_the_request()
{
var port = RandomPortFinder.GetRandomPort();

var configuration = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamPathTemplate = "/",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
},
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
},
},
};

this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayAndDontWait("/"))
.And(x => x.WhenIWaitForNotification(_serviceWorkStartedNotifier))
.And(x => _steps.WhenICancelTheRequest())
.And(x => x.WhenIWaitForNotification(_serviceWorkStoppedNotifier))
.Then(x => x.ThenServiceWorkIsNotFinished())
.BDDfy();
}

private void GivenThereIsAServiceRunningOn(string baseUrl)
{
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, async context =>
{
try
{
var response = string.Empty;
_serviceWorkStartedNotifier.NotificationSent = true;
await Task.Delay(SERVICE_WORK_TIME, context.RequestAborted);
context.Response.StatusCode = (int)HttpStatusCode.OK;
await context.Response.WriteAsync(response);
}
catch (TaskCanceledException)
{
_cancelExceptionThrown = true;
}
finally
{
_serviceWorkStoppedNotifier.NotificationSent = true;
}
});
}

private async Task WhenIWaitForNotification(Notifier notifier)
{
int waitingTime = 0;
while (!notifier.NotificationSent)
{
var waitingInterval = 50;
await Task.Delay(waitingInterval);
waitingTime += waitingInterval;

if (waitingTime > MAX_WAITING_TIME)
{
throw new TimeoutException(notifier.Name + $" did not sent notification within {MAX_WAITING_TIME}s.");
}
}
}

private void ThenServiceWorkIsNotFinished()
{
_cancelExceptionThrown.ShouldBeTrue();
}

public void Dispose()
{
_serviceHandler?.Dispose();
_steps.Dispose();
}

class Notifier
{
public Notifier(string name)
{
Name = name;
}

public bool NotificationSent { get; set; }

public string Name { get; set; }
}
}
}
10 changes: 10 additions & 0 deletions test/Ocelot.AcceptanceTests/Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,16 @@ public void WhenIGetUrlOnTheApiGateway(string url)
_response = _ocelotClient.GetAsync(url).Result;
}

public void WhenIGetUrlOnTheApiGatewayAndDontWait(string url)
{
_ocelotClient.GetAsync(url);
}

public void WhenICancelTheRequest()
{
_ocelotClient.CancelPendingRequests();
}

public void WhenIGetUrlOnTheApiGateway(string url, HttpContent content)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url) { Content = content };
Expand Down

0 comments on commit 027c23c

Please sign in to comment.