Skip to content

Commit 211e3a3

Browse files
test(flagd): Refactor Flagd E2E Tests to reduce duplication (#471)
Signed-off-by: Kyle Julian <[email protected]>
1 parent 415988b commit 211e3a3

20 files changed

+216
-328
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
using Microsoft.Extensions.Configuration;
5+
using Reqnroll;
6+
using Xunit;
7+
8+
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common;
9+
10+
[Binding]
11+
public class BeforeHooks
12+
{
13+
internal static FlagdTestBedContainer Container;
14+
15+
private readonly IConfiguration _configuration;
16+
17+
public BeforeHooks(IConfiguration configuration)
18+
{
19+
this._configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
20+
}
21+
22+
[BeforeTestRun]
23+
public static async Task BeforeTestRunAsync()
24+
{
25+
#if NET8_0_OR_GREATER
26+
var version = await File.ReadAllTextAsync("flagd-testbed-version.txt").ConfigureAwait(false);
27+
#else
28+
var version = File.ReadAllText("flagd-testbed-version.txt");
29+
#endif
30+
var container = new FlagdTestBedContainer(version.Trim());
31+
await container.Container.StartAsync().ConfigureAwait(false);
32+
33+
Container = container;
34+
}
35+
36+
[AfterTestRun]
37+
public static async Task AfterTestRunAsync()
38+
{
39+
await Container.Container.StopAsync().ConfigureAwait(false);
40+
await Container.Container.DisposeAsync().ConfigureAwait(false);
41+
42+
Container = null;
43+
}
44+
45+
[BeforeScenario]
46+
public void BeforeScenario()
47+
{
48+
Skip.If(this._configuration["E2E"] != "true", "Skipping test as E2E tests are disabled, enable them by updating the appsettings.json.");
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
using DotNet.Testcontainers.Builders;
22
using DotNet.Testcontainers.Containers;
33

4-
namespace OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest;
4+
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common;
55

6-
public class FlagdSyncTestBedContainer
6+
public class FlagdTestBedContainer
77
{
88
public IContainer Container { get; }
99

10-
public FlagdSyncTestBedContainer(string version)
10+
public FlagdTestBedContainer(string version)
1111
{
1212
Container = new ContainerBuilder()
1313
.WithImage($"ghcr.io/open-feature/flagd-testbed:v{version}")
1414
.WithPortBinding(8015, true)
15+
.WithPortBinding(8013, true)
1516
.Build();
1617
}
1718
}
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<IsTestProject>false</IsTestProject>
55
<GenerateDocumentationFile>false</GenerateDocumentationFile>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<ProjectReference
10-
Include="..\..\src\OpenFeature.Contrib.Providers.Flagd\OpenFeature.Contrib.Providers.Flagd.csproj" />
9+
<ProjectReference Include="..\..\src\OpenFeature.Contrib.Providers.Flagd\OpenFeature.Contrib.Providers.Flagd.csproj" />
1110
</ItemGroup>
1211

1312
<ItemGroup>
13+
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/version.txt" Link="flagd-testbed-version.txt" DestinationFolder="." CopyToOutputDirectory="PreserveNewest" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
18+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
19+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
20+
<PackageReference Include="Reqnroll.Microsoft.Extensions.DependencyInjection" Version="2.4.1" />
1421
<PackageReference Include="Reqnroll.xUnit" Version="2.4.1" />
22+
<PackageReference Include="Testcontainers" Version="4.4.0" />
1523
</ItemGroup>
1624

1725
</Project>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Microsoft.Extensions.Configuration;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Reqnroll;
4+
using Reqnroll.Microsoft.Extensions.DependencyInjection;
5+
6+
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common;
7+
8+
[Binding]
9+
public class Setup
10+
{
11+
[ScenarioDependencies]
12+
public static IServiceCollection CreateServices()
13+
{
14+
var services = new ServiceCollection();
15+
16+
var configuration = new ConfigurationBuilder()
17+
.AddJsonFile("appsettings.json", optional: true)
18+
.AddEnvironmentVariables()
19+
.Build();
20+
21+
var context = new TestContext();
22+
23+
services.AddSingleton<IConfiguration>(configuration);
24+
services.AddSingleton(context);
25+
26+
return services;
27+
}
28+
}
29+
30+
public class TestContext
31+
{
32+
public ResolverType ProviderResolverType { get; set; }
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common.Steps;
5+
6+
public class BaseSteps
7+
{
8+
protected TestContext Context { get; }
9+
10+
public BaseSteps(TestContext testContext)
11+
{
12+
this.Context = testContext ?? throw new ArgumentNullException(nameof(testContext));
13+
}
14+
15+
protected async Task<FeatureClient> CreateFeatureClientAsync()
16+
{
17+
var api = Api.Instance;
18+
var resolverType = this.Context.ProviderResolverType;
19+
20+
var port = resolverType switch
21+
{
22+
ResolverType.IN_PROCESS => BeforeHooks.Container.Container.GetMappedPublicPort(8015),
23+
ResolverType.RPC => BeforeHooks.Container.Container.GetMappedPublicPort(8013),
24+
_ => throw new ArgumentException($"Unknown resolver type: {resolverType}")
25+
};
26+
27+
var host = BeforeHooks.Container.Container.Hostname;
28+
var flagdProvider = new FlagdProvider(
29+
FlagdConfig.Builder()
30+
.WithHost(host)
31+
.WithPort(port)
32+
.WithResolverType(resolverType)
33+
.Build()
34+
);
35+
36+
await api.SetProviderAsync(flagdProvider);
37+
38+
return api.GetClient("openfeatureclient");
39+
}
40+
}

test/OpenFeature.Contrib.Providers.Flagd.E2e.Common/Steps/EvaluationStepDefinitionBase.cs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
using System.Reflection;
55
using System.Threading.Tasks;
66
using OpenFeature.Constant;
7+
using OpenFeature.Contrib.Providers.Flagd.E2e.Common.Steps;
78
using OpenFeature.Model;
89
using Reqnroll;
910
using Xunit;
1011

1112
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common;
1213

13-
public abstract class EvaluationStepDefinitionsBase
14+
[Binding]
15+
[Scope(Feature = "Flag evaluation")]
16+
public class EvaluationStepDefinitionsBase : BaseSteps
1417
{
15-
private readonly ScenarioContext _scenarioContext;
1618
private FeatureClient client;
1719
private bool booleanFlagValue;
1820
private string stringFlagValue;
@@ -35,22 +37,15 @@ public abstract class EvaluationStepDefinitionsBase
3537
private int typeErrorDefaultValue;
3638
private FlagEvaluationDetails<int> typeErrorDetails;
3739

38-
public EvaluationStepDefinitionsBase(ScenarioContext scenarioContext)
40+
public EvaluationStepDefinitionsBase(TestContext testContext)
41+
: base(testContext)
3942
{
40-
_scenarioContext = scenarioContext;
4143
}
4244

4345
[Given(@"a stable provider")]
44-
public void Givenastableprovider()
45-
{
46-
if (this._scenarioContext.TryGetValue<FeatureClient>("Client", out var client))
47-
{
48-
this.client = client;
49-
}
50-
else
51-
{
52-
throw new InvalidOperationException("Client not found in scenario context. Ensure the BeforeTestRun hook initializes the client.");
53-
}
46+
public async Task Givenastableprovider()
47+
{
48+
this.client = await this.CreateFeatureClientAsync().ConfigureAwait(false);
5449
}
5550

5651
[When(@"a boolean flag with key ""(.*)"" is evaluated with default value ""(.*)""")]

test/OpenFeature.Contrib.Providers.Flagd.E2e.Common/Steps/FlagdStepDefinitionBase.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
using System;
22
using System.Threading.Tasks;
33
using OpenFeature.Constant;
4+
using OpenFeature.Contrib.Providers.Flagd.E2e.Common.Steps;
45
using OpenFeature.Model;
56
using Reqnroll;
67
using Xunit;
78

89
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common;
910

10-
public abstract class FlagdStepDefinitionsBase
11+
[Binding]
12+
[Scope(Feature = "flagd providers")]
13+
[Scope(Feature = "flagd json evaluation")]
14+
public class FlagdStepDefinitionsBase : BaseSteps
1115
{
12-
private readonly ScenarioContext _scenarioContext;
1316
private FeatureClient client;
1417
private bool booleanZeroValue;
1518
private string stringZeroValue;
@@ -23,22 +26,15 @@ public abstract class FlagdStepDefinitionsBase
2326
private bool changeHandlerRan = false;
2427
private EvaluationContext evaluationContext;
2528

26-
public FlagdStepDefinitionsBase(ScenarioContext scenarioContext)
29+
public FlagdStepDefinitionsBase(TestContext testContext)
30+
: base(testContext)
2731
{
28-
_scenarioContext = scenarioContext;
2932
}
3033

3134
[Given(@"a flagd provider is set")]
32-
public void GivenAFlagdProviderIsSet()
35+
public async Task GivenAFlagdProviderIsSet()
3336
{
34-
if (this._scenarioContext.TryGetValue<FeatureClient>("Client", out var client))
35-
{
36-
this.client = client;
37-
}
38-
else
39-
{
40-
throw new InvalidOperationException("Client not found in scenario context. Ensure the BeforeTestRun hook initializes the client.");
41-
}
37+
this.client = await this.CreateFeatureClientAsync().ConfigureAwait(false);
4238
}
4339

4440
[When(@"a PROVIDER_READY handler is added")]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using OpenFeature.Contrib.Providers.Flagd.E2e.Common;
3+
using Reqnroll;
4+
5+
namespace OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest;
6+
7+
[Binding]
8+
public class BeforeHooks
9+
{
10+
private readonly TestContext _context;
11+
12+
public BeforeHooks(TestContext context)
13+
{
14+
this._context = context ?? throw new ArgumentNullException(nameof(context));
15+
}
16+
17+
[BeforeScenario]
18+
public void BeforeScenario()
19+
{
20+
this._context.ProviderResolverType = ResolverType.IN_PROCESS;
21+
}
22+
}

test/OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest/OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
<!-- TODO: add remaining tests -->
88
<ItemGroup>
9-
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/version.txt" Link="flagd-testbed-version.txt" DestinationFolder="." CopyToOutputDirectory="PreserveNewest" />
109
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/flagd.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
1110
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/flagd-json-evaluator.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
1211
</ItemGroup>
@@ -17,11 +16,7 @@
1716
</ItemGroup>
1817

1918
<ItemGroup>
20-
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
21-
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
22-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
2319
<PackageReference Include="Reqnroll.xUnit" Version="2.4.1" />
24-
<PackageReference Include="Testcontainers" Version="4.4.0" />
2520
</ItemGroup>
2621

2722
<ItemGroup>

test/OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest/Steps/EvaluationStepDefinitionsProcess.cs

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)