|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
1 | 3 | using OpenFeature.Contrib.Providers.Flagd.E2e.Common.Utils; |
2 | 4 | using Reqnroll; |
| 5 | +using Xunit; |
3 | 6 |
|
4 | 7 | namespace OpenFeature.Contrib.Providers.Flagd.E2e.Common.Steps; |
5 | 8 |
|
| 9 | +#nullable enable |
| 10 | + |
6 | 11 | [Binding] |
7 | 12 | public class ConfigSteps |
8 | 13 | { |
| 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 | + |
9 | 24 | private readonly State _state; |
10 | 25 |
|
| 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 | + |
11 | 72 | public ConfigSteps(State state) |
12 | 73 | { |
13 | 74 | this._state = state; |
14 | 75 | } |
15 | 76 |
|
| 77 | + [BeforeScenario] |
| 78 | + public void BeforeScenario() |
| 79 | + { |
| 80 | + foreach (var envVar in _environmentVariables) |
| 81 | + { |
| 82 | + Environment.SetEnvironmentVariable(envVar, null); |
| 83 | + } |
| 84 | + } |
| 85 | + |
16 | 86 | [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) |
18 | 88 | { |
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) |
20 | 94 | { |
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; |
22 | 147 | } |
| 148 | + } |
23 | 149 |
|
24 | | - if (option == "cache") |
| 150 | + [When("a config was initialized")] |
| 151 | + public void WhenAConfigWasInitialized() |
| 152 | + { |
| 153 | + try |
25 | 154 | { |
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); |
28 | 159 | } |
29 | | - else if (option == "selector") |
| 160 | + catch (Exception) |
30 | 161 | { |
31 | | - this._state.FlagdConfig = this._state.FlagdConfig.WithSourceSelector(value); |
| 162 | + this._errorOccurred = true; |
32 | 163 | } |
33 | 164 | } |
| 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 | + } |
34 | 243 | } |
0 commit comments