Skip to content

Commit 789c186

Browse files
kylejuliandevaskpttoddbaert
authored
test(flagd): Add step definition for config.feature tests (#576)
Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com> Signed-off-by: André Silva <2493377+askpt@users.noreply.github.com> Signed-off-by: Todd Baert <todd.baert@dynatrace.com> Co-authored-by: André Silva <2493377+askpt@users.noreply.github.com> Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
1 parent 16f40dc commit 789c186

File tree

4 files changed

+220
-8
lines changed

4 files changed

+220
-8
lines changed
Lines changed: 217 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,243 @@
1+
using System;
2+
using System.Collections.Generic;
13
using OpenFeature.Contrib.Providers.Flagd.E2e.Common.Utils;
24
using Reqnroll;
5+
using Xunit;
36

47
namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common.Steps;
58

9+
#nullable enable
10+
611
[Binding]
712
public class ConfigSteps
813
{
14+
private const string HostKey = "host";
15+
private const string PortKey = "port";
16+
private const string TlsKey = "tls";
17+
private const string CertPathKey = "certPath";
18+
private const string SocketPathKey = "socketPath";
19+
private const string CacheKey = "cache";
20+
private const string MaxCacheSizeKey = "maxCacheSize";
21+
private const string SelectorKey = "selector";
22+
private const string ResolverKey = "resolver";
23+
924
private readonly State _state;
1025

26+
private FlagdConfig? _config;
27+
private bool _errorOccurred;
28+
29+
private static readonly HashSet<string> _environmentVariables =
30+
[
31+
"FLAGD_RESOLVER",
32+
"FLAGD_HOST",
33+
"FLAGD_PORT",
34+
"FLAGD_TARGET_URI",
35+
"FLAGD_TLS",
36+
"FLAGD_SOCKET_PATH",
37+
"FLAGD_SERVER_CERT_PATH",
38+
"FLAGD_DEADLINE_MS",
39+
"FLAGD_STREAM_DEADLINE_MS",
40+
"FLAGD_RETRY_BACKOFF_MS",
41+
"FLAGD_RETRY_BACKOFF_MAX_MS",
42+
"FLAGD_RETRY_GRACE_PERIOD",
43+
"FLAGD_KEEP_ALIVE_TIME_MS",
44+
"FLAGD_CACHE",
45+
"FLAGD_MAX_CACHE_SIZE",
46+
"FLAGD_SOURCE_SELECTOR",
47+
"FLAGD_OFFLINE_FLAG_SOURCE_PATH",
48+
"FLAGD_OFFLINE_POLL_MS",
49+
"FLAGD_FATAL_STATUS_CODES"
50+
];
51+
52+
private static readonly HashSet<string> _unsupportedEnvironmentVariables =
53+
[
54+
"FLAGD_PROVIDER_ID"
55+
];
56+
57+
private static readonly HashSet<string> _unsupportedConfigOptions =
58+
[
59+
"deadlineMs",
60+
"fatalStatusCodes",
61+
"targetUri",
62+
"providerId",
63+
"offlineFlagSourcePath",
64+
"offlinePollIntervalMs",
65+
"streamDeadlineMs",
66+
"keepAliveTime",
67+
"retryBackoffMs",
68+
"retryBackoffMaxMs",
69+
"retryGracePeriod"
70+
];
71+
1172
public ConfigSteps(State state)
1273
{
1374
this._state = state;
1475
}
1576

77+
[BeforeScenario]
78+
public void BeforeScenario()
79+
{
80+
foreach (var envVar in _environmentVariables)
81+
{
82+
Environment.SetEnvironmentVariable(envVar, null);
83+
}
84+
}
85+
1686
[Given("an option {string} of type {string} with value {string}")]
17-
public void GivenAnOptionOfTypeWithValue(string option, string type, string value)
87+
public void GivenAnOptionOfTypeWithValue(string option, string _, string value)
1888
{
19-
if (this._state.FlagdConfig == null)
89+
Skip.If(_unsupportedConfigOptions.Contains(option), "Config option is not supported");
90+
91+
this._state.FlagdConfig ??= FlagdConfig.Builder();
92+
93+
switch (option)
2094
{
21-
this._state.FlagdConfig = FlagdConfig.Builder();
95+
case HostKey:
96+
{
97+
this._state.FlagdConfig = this._state.FlagdConfig.WithHost(value);
98+
break;
99+
}
100+
case PortKey:
101+
{
102+
var port = int.Parse(value);
103+
this._state.FlagdConfig = this._state.FlagdConfig.WithPort(port);
104+
break;
105+
}
106+
case TlsKey:
107+
{
108+
var useTls = bool.Parse(value);
109+
this._state.FlagdConfig = this._state.FlagdConfig.WithTls(useTls);
110+
break;
111+
}
112+
case CertPathKey:
113+
{
114+
this._state.FlagdConfig = this._state.FlagdConfig.WithCertificatePath(value);
115+
break;
116+
}
117+
case SocketPathKey:
118+
{
119+
this._state.FlagdConfig = this._state.FlagdConfig.WithSocketPath(value);
120+
break;
121+
}
122+
case CacheKey:
123+
{
124+
var enabled = value == "enabled";
125+
this._state.FlagdConfig = this._state.FlagdConfig.WithCache(enabled);
126+
break;
127+
}
128+
case MaxCacheSizeKey:
129+
{
130+
var maxCacheSize = int.Parse(value);
131+
this._state.FlagdConfig = this._state.FlagdConfig.WithMaxCacheSize(maxCacheSize);
132+
break;
133+
}
134+
case SelectorKey:
135+
{
136+
this._state.FlagdConfig = this._state.FlagdConfig.WithSourceSelector(value);
137+
break;
138+
}
139+
case ResolverKey:
140+
{
141+
var resolverType = value == "rpc" ? ResolverType.RPC : ResolverType.IN_PROCESS;
142+
this._state.FlagdConfig = this._state.FlagdConfig.WithResolverType(resolverType);
143+
break;
144+
}
145+
default:
146+
break;
22147
}
148+
}
23149

24-
if (option == "cache")
150+
[When("a config was initialized")]
151+
public void WhenAConfigWasInitialized()
152+
{
153+
try
25154
{
26-
var enabled = value == "enabled";
27-
this._state.FlagdConfig = this._state.FlagdConfig.WithCache(enabled);
155+
var flagdConfigBuilder = this._state.FlagdConfig ?? FlagdConfig.Builder();
156+
this._config = flagdConfigBuilder.Build();
157+
158+
Assert.NotNull(this._config);
28159
}
29-
else if (option == "selector")
160+
catch (Exception)
30161
{
31-
this._state.FlagdConfig = this._state.FlagdConfig.WithSourceSelector(value);
162+
this._errorOccurred = true;
32163
}
33164
}
165+
166+
[Then("the option {string} of type {string} should have the value {string}")]
167+
public void ThenTheOptionOfTypeShouldHaveTheValue(string option, string _, string value)
168+
{
169+
Skip.If(_unsupportedConfigOptions.Contains(option), "Config option is not supported");
170+
171+
switch (option)
172+
{
173+
case ResolverKey:
174+
{
175+
var expected = value.ToLower();
176+
var actual = this._config!.ResolverType == ResolverType.RPC ? "rpc" : "in-process";
177+
Assert.Equal(expected, actual);
178+
break;
179+
}
180+
case HostKey:
181+
{
182+
var expected = value;
183+
var actual = this._config!.Host;
184+
Assert.Equal(expected, actual);
185+
break;
186+
}
187+
case PortKey:
188+
{
189+
var expected = int.Parse(value);
190+
var actual = this._config!.Port;
191+
Assert.Equal(expected, actual);
192+
break;
193+
}
194+
case TlsKey:
195+
{
196+
var expected = bool.Parse(value);
197+
var actual = this._config!.UseTls;
198+
Assert.Equal(expected, actual);
199+
break;
200+
}
201+
case CertPathKey:
202+
{
203+
var expected = value == "null" ? string.Empty : value;
204+
var actual = this._config!.CertificatePath;
205+
Assert.Equal(expected, actual);
206+
break;
207+
}
208+
case SocketPathKey:
209+
{
210+
var expected = value == "null" ? string.Empty : value;
211+
var actual = this._config!.SocketPath;
212+
Assert.Equal(expected, actual);
213+
break;
214+
}
215+
case SelectorKey:
216+
{
217+
var expected = value == "null" ? string.Empty : value;
218+
var actual = this._config!.SourceSelector;
219+
Assert.Equal(expected, actual);
220+
break;
221+
}
222+
223+
default:
224+
break;
225+
}
226+
}
227+
228+
[Then("we should have an error")]
229+
public void ThenWeShouldHaveAnError()
230+
{
231+
Assert.True(this._errorOccurred);
232+
}
233+
234+
[Given("an environment variable {string} with value {string}")]
235+
public void GivenAnEnvironmentVariableWithValue(string env, string value)
236+
{
237+
Skip.If(_unsupportedEnvironmentVariables.Contains(env), "Environment variable is not supported");
238+
239+
Assert.Contains(_environmentVariables, e => e == env); // Ensure only known env vars are set
240+
241+
Environment.SetEnvironmentVariable(env, value);
242+
}
34243
}

test/OpenFeature.Contrib.Providers.Flagd.E2e.ProcessTest/BeforeHooks.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public void BeforeScenario(ScenarioInfo scenarioInfo, FeatureInfo featureInfo)
2424
var scenarioTags = scenarioInfo.Tags;
2525
var featureTags = featureInfo.Tags;
2626
var tags = new HashSet<string>(scenarioTags.Concat(featureTags));
27+
Skip.If(tags.Contains("sync-port"), "Skipping sync-port as it is not supported.");
2728
Skip.If(!tags.Contains("in-process"), "Skipping scenario because it does not have required tag.");
2829
Skip.If(tags.Contains("fractional-v1"), "Skipping legacy fractional bucketing test; v2 algorithm is implemented.");
2930
Skip.If(tags.Contains("operator-errors"), "Skipping operator-errors test; flagd server does not yet fall back to default on operator errors.");

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/selector.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
88
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/metadata.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
99
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/contextEnrichment.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
10+
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/config.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
1011
</ItemGroup>
1112

1213
<ItemGroup>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/targeting.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
77
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/metadata.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
88
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/contextEnrichment.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
9+
<None Include="../../src/OpenFeature.Contrib.Providers.Flagd/flagd-testbed/gherkin/config.feature" Link="../../../Features/%(Filename)%(Extension)" DestinationFolder="../../../Features/" CopyToOutputDirectory="PreserveNewest" />
910
</ItemGroup>
1011

1112
<ItemGroup>

0 commit comments

Comments
 (0)