Skip to content

Commit

Permalink
Acceptance tests for ThreeMammals#2084 user scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
raman-m committed Jul 16, 2024
1 parent 52051ec commit c1d8624
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder
string primaryConfigFile = null, string globalConfigFile = null, string environmentConfigFile = null, bool? optional = null, bool? reloadOnChange = null) // optional injections
{
var json = GetMergedOcelotJson(folder, env, null, primaryConfigFile, globalConfigFile, environmentConfigFile);
primaryConfigFile ??= Path.Join(folder, PrimaryConfigFile); // if not specified, merge & write back to the same folder
return ApplyMergeOcelotJsonOption(builder, mergeTo, json, primaryConfigFile, optional, reloadOnChange);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,70 +1,117 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.DependencyInjection;
using System.Runtime.CompilerServices;

namespace Ocelot.AcceptanceTests.Configuration;

public sealed class ConfigurationMergeTests : Steps
{
private readonly FileConfiguration _globalConfig;
private readonly FileConfiguration _initialGlobalConfig;
private readonly string _globalConfigFileName;

public ConfigurationMergeTests() : base()
{
_globalConfig = new();
_initialGlobalConfig = new();
_globalConfigFileName = $"{TestID}-{ConfigurationBuilderExtensions.GlobalConfigFile}";
Files.Add(_globalConfigFileName);
}

protected override void DeleteOcelotConfig(params string[] files) => base.DeleteOcelotConfig(_globalConfigFileName);

[Fact]
[Theory]
[Trait("Bug", "1216")]
[Trait("Feat", "1227")]
public void Should_run_with_global_config_merged_to_memory()
[InlineData(MergeOcelotJson.ToFile, true)]
[InlineData(MergeOcelotJson.ToMemory, false)]
public void ShouldRunWithGlobalConfigMerged_WithExplicitGlobalConfigFileParameter(MergeOcelotJson where, bool fileExist)
{
Arrange();

// Act
GivenOcelotIsRunningMergedConfig(MergeOcelotJson.ToMemory);
StartOcelot((context, config) => config
.AddOcelot(_initialGlobalConfig, context.HostingEnvironment, where, _ocelotConfigFileName, _globalConfigFileName, null, false, false));

// Assert
TheOcelotPrimaryConfigFileExists(false);
Assert();
TheOcelotPrimaryConfigFileExists(fileExist);
ThenGlobalConfigurationHasBeenMerged();
}

[Fact]
[Trait("Bug", "1216")]
[Trait("Feat", "1227")]
public void Should_run_with_global_config_merged_to_file()
[Theory]
[Trait("Bug", "2084")]
[InlineData(MergeOcelotJson.ToFile, true)]
[InlineData(MergeOcelotJson.ToMemory, false)]
public void ShouldRunWithGlobalConfigMerged_WithImplicitGlobalConfigFileParameter(MergeOcelotJson where, bool fileExist)
{
Arrange();
var globalConfig = _initialGlobalConfig;
globalConfig.Routes.Clear();
var routeAConfig = GivenConfiguration(GetRoute("A"));
var routeBConfig = GivenConfiguration(GetRoute("B"));
var environmentConfig = GivenConfiguration(GetRoute("Env"));
environmentConfig.GlobalConfiguration = null;
var folder = "GatewayConfiguration-" + TestID;
Folders.Add(Directory.CreateDirectory(folder).FullName);
var globalPath = Path.Combine(folder, ConfigurationBuilderExtensions.GlobalConfigFile);
var routeAPath = Path.Combine(folder, string.Format(ConfigurationBuilderExtensions.EnvironmentConfigFile, "A"));
var routeBPath = Path.Combine(folder, string.Format(ConfigurationBuilderExtensions.EnvironmentConfigFile, "B"));
var environmentPath = Path.Combine(folder, string.Format(ConfigurationBuilderExtensions.EnvironmentConfigFile, "Env"));
GivenThereIsAConfiguration(globalConfig, globalPath);
GivenThereIsAConfiguration(routeAConfig, routeAPath);
GivenThereIsAConfiguration(routeBConfig, routeBPath);
GivenThereIsAConfiguration(environmentConfig, environmentPath);

// Act
GivenOcelotIsRunningMergedConfig(MergeOcelotJson.ToFile);
StartOcelot((context, config) => config
.AddOcelot(folder, context.HostingEnvironment, where) // overloaded version from the user's scenario
.AddJsonFile(environmentPath),
"Env");

// Assert
TheOcelotPrimaryConfigFileExists(true);
Assert();
}
TheOcelotPrimaryConfigFileExists(false);
ThenGlobalConfigurationHasBeenMerged();

private void GivenOcelotIsRunningMergedConfig(MergeOcelotJson mergeTo)
=> StartOcelot((context, config) => config.AddOcelot(_globalConfig, context.HostingEnvironment, mergeTo, _ocelotConfigFileName, _globalConfigFileName, null, false, false));
var actualLocation = Path.Combine(folder, ConfigurationBuilderExtensions.PrimaryConfigFile);
File.Exists(actualLocation).ShouldBe(fileExist);

private void TheOcelotPrimaryConfigFileExists(bool expected)
=> File.Exists(_ocelotConfigFileName).ShouldBe(expected);
var repository = _ocelotServer.Services.GetService<IInternalConfigurationRepository>().ShouldNotBeNull();
var response = repository.Get().ShouldNotBeNull();
response.IsError.ShouldBeFalse();
var internalConfig = response.Data.ShouldNotBeNull();

// Assert Arrange() setup
internalConfig.RequestId.ShouldBe(nameof(ShouldRunWithGlobalConfigMerged_WithImplicitGlobalConfigFileParameter));
internalConfig.ServiceProviderConfiguration.ConfigurationKey.ShouldBe(nameof(ShouldRunWithGlobalConfigMerged_WithImplicitGlobalConfigFileParameter));
}

private void Arrange([CallerMemberName] string testName = null)
{
_globalConfig.GlobalConfiguration.RequestIdKey = testName;
_initialGlobalConfig.GlobalConfiguration.RequestIdKey = testName;
_initialGlobalConfig.GlobalConfiguration.ServiceDiscoveryProvider.ConfigurationKey = testName;
}

private void Assert([CallerMemberName] string testName = null)
private void TheOcelotPrimaryConfigFileExists(bool expected)
=> File.Exists(_ocelotConfigFileName).ShouldBe(expected);

private void ThenGlobalConfigurationHasBeenMerged([CallerMemberName] string testName = null)
{
var config = _ocelotServer.Services.GetService<IConfiguration>();
config.ShouldNotBeNull();
var config = _ocelotServer.Services.GetService<IConfiguration>().ShouldNotBeNull();
var actual = config["GlobalConfiguration:RequestIdKey"];
actual.ShouldNotBeNull().ShouldBe(testName);
actual = config["GlobalConfiguration:ServiceDiscoveryProvider:ConfigurationKey"];
actual.ShouldNotBeNull().ShouldBe(testName);
}

private static FileRoute GetRoute(string suffix, [CallerMemberName] string testName = null) => new()
{
DownstreamScheme = nameof(FileRoute.DownstreamScheme) + suffix,
DownstreamPathTemplate = "/" + suffix,
Key = testName + suffix,
UpstreamPathTemplate = "/" + suffix,
UpstreamHttpMethod = new() { nameof(FileRoute.UpstreamHttpMethod) + suffix },
DownstreamHostAndPorts = new()
{
new(nameof(FileHostAndPort.Host) + suffix, 80),
},
};
}
50 changes: 39 additions & 11 deletions test/Ocelot.AcceptanceTests/Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@ public Steps()
{
_random = new Random();
_testId = Guid.NewGuid();
_ocelotConfigFileName = $"{_testId:N}-{ConfigurationBuilderExtensions.PrimaryConfigFile}";
_ocelotConfigFileName = $"{_testId:N}-{ConfigurationBuilderExtensions.PrimaryConfigFile}";
Files = new() { _ocelotConfigFileName };
Folders = new();
}

protected List<string> Files { get; }
protected List<string> Folders { get; }
protected string TestID { get => _testId.ToString("N"); }

protected static string DownstreamUrl(int port) => $"{Uri.UriSchemeHttp}://localhost:{port}";
Expand Down Expand Up @@ -167,16 +171,20 @@ public async Task StartFakeOcelotWithWebSocketsWithConsul()
await _ocelotHost.StartAsync();
}

public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
{
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
File.WriteAllText(_ocelotConfigFileName, jsonConfiguration);
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
=> GivenThereIsAConfiguration(fileConfiguration, _ocelotConfigFileName);

public void GivenThereIsAConfiguration(FileConfiguration from, string toFile)
{
toFile ??= _ocelotConfigFileName;
var jsonConfiguration = JsonConvert.SerializeObject(from, Formatting.Indented);
File.WriteAllText(toFile, jsonConfiguration);
Files.Add(toFile); // register for disposing
}

protected virtual void DeleteOcelotConfig(params string[] files)
protected virtual void DeleteFiles()
{
var allFiles = files.Append(_ocelotConfigFileName);
foreach (var file in allFiles)
foreach (var file in Files)
{
if (!File.Exists(file))
{
Expand All @@ -193,6 +201,25 @@ protected virtual void DeleteOcelotConfig(params string[] files)
}
}
}

protected virtual void DeleteFolders()
{
foreach (var folder in Folders)
{
try
{
var f = new DirectoryInfo(folder);
if (f.Exists && f.FullName != AppContext.BaseDirectory)
{
f.Delete(true);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}

public void ThenTheResponseBodyHeaderIs(string key, string value)
{
Expand All @@ -218,7 +245,7 @@ public void GivenOcelotIsRunning()
StartOcelot((_, config) => config.AddJsonFile(_ocelotConfigFileName, false, false));
}

protected void StartOcelot(Action<WebHostBuilderContext, IConfigurationBuilder> configureAddOcelot)
protected void StartOcelot(Action<WebHostBuilderContext, IConfigurationBuilder> configureAddOcelot, string environmentName = null)
{
_webHostBuilder = new WebHostBuilder();

Expand All @@ -234,7 +261,7 @@ protected void StartOcelot(Action<WebHostBuilderContext, IConfigurationBuilder>
})
.ConfigureServices(WithAddOcelot)
.Configure(WithUseOcelot)
.UseEnvironment(nameof(AcceptanceTests));
.UseEnvironment(environmentName ?? nameof(AcceptanceTests));

_ocelotServer = new TestServer(_webHostBuilder);
_ocelotClient = _ocelotServer.CreateClient();
Expand Down Expand Up @@ -1166,7 +1193,8 @@ protected virtual void Dispose(bool disposing)
_ocelotClient?.Dispose();
_ocelotServer?.Dispose();
_ocelotHost?.Dispose();
DeleteOcelotConfig();
DeleteFiles();
DeleteFolders();
}

_disposedValue = true;
Expand Down

0 comments on commit c1d8624

Please sign in to comment.