You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ocelot/test/Ocelot.AcceptanceTests/ClientRateLimitTests.cs

219 lines
9.5 KiB
C#

namespace Ocelot.AcceptanceTests
{
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;
public class ClientRateLimitTests : IDisposable
{
private readonly Steps _steps;
private int _counterOne;
private readonly ServiceHandler _serviceHandler;
public ClientRateLimitTests()
{
_serviceHandler = new ServiceHandler();
_steps = new Steps();
}
[Fact]
public void should_call_withratelimiting()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/api/ClientRateLimit",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51876,
}
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/api/ClientRateLimit",
UpstreamHttpMethod = new List<string> { "Get" },
RequestIdKey = _steps.RequestIdKey,
RateLimitOptions = new FileRateLimitRule()
{
EnableRateLimiting = true,
ClientWhitelist = new List<string>(),
Limit = 3,
Period = "1s",
PeriodTimespan = 1000
}
}
},
GlobalConfiguration = new FileGlobalConfiguration()
{
RateLimitOptions = new FileRateLimitOptions()
{
ClientIdHeader = "ClientId",
DisableRateLimitHeaders = false,
QuotaExceededMessage = "",
RateLimitCounterPrefix = "",
HttpStatusCode = 428
},
RequestIdKey ="oceclientrequest"
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 2))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(428))
.BDDfy();
}
[Fact]
public void should_wait_for_period_timespan_to_elapse_before_making_next_request()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/api/ClientRateLimit",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51926,
}
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/api/ClientRateLimit",
UpstreamHttpMethod = new List<string> { "Get" },
RequestIdKey = _steps.RequestIdKey,
RateLimitOptions = new FileRateLimitRule()
{
EnableRateLimiting = true,
ClientWhitelist = new List<string>(),
Limit = 3,
Period = "1s",
PeriodTimespan = 2
}
}
},
GlobalConfiguration = new FileGlobalConfiguration()
{
RateLimitOptions = new FileRateLimitOptions()
{
ClientIdHeader = "ClientId",
DisableRateLimitHeaders = false,
QuotaExceededMessage = "",
RateLimitCounterPrefix = "",
HttpStatusCode = 428
},
RequestIdKey ="oceclientrequest"
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51926", "/api/ClientRateLimit"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 2))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(428))
.And(x => _steps.GivenIWait(1000))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(428))
.And(x => _steps.GivenIWait(1000))
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.BDDfy();
}
[Fact]
public void should_call_middleware_withWhitelistClient()
{
int port = 61876;
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/api/ClientRateLimit",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = port,
}
},
DownstreamScheme = "http",
UpstreamPathTemplate = "/api/ClientRateLimit",
UpstreamHttpMethod = new List<string> { "Get" },
RequestIdKey = _steps.RequestIdKey,
RateLimitOptions = new FileRateLimitRule()
{
EnableRateLimiting = true,
ClientWhitelist = new List<string>() { "ocelotclient1"},
Limit = 3,
Period = "1s",
PeriodTimespan = 100
}
}
},
GlobalConfiguration = new FileGlobalConfiguration()
{
RateLimitOptions = new FileRateLimitOptions()
{
ClientIdHeader = "ClientId",
DisableRateLimitHeaders = false,
QuotaExceededMessage = "",
RateLimitCounterPrefix = ""
},
RequestIdKey = "oceclientrequest"
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/ClientRateLimit"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
.Then(x => _steps.ThenTheStatusCodeShouldBe(200))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath)
{
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, context =>
{
_counterOne++;
context.Response.StatusCode = 200;
context.Response.WriteAsync(_counterOne.ToString());
return Task.CompletedTask;
});
}
public void Dispose()
{
_steps.Dispose();
}
}
}