Skip to content

Commit fa49fec

Browse files
committed
fix(ffe): replace refreshed remote config
1 parent f33ee47 commit fa49fec

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

tracer/src/Datadog.Trace/FeatureFlags/Rcm/FfeProduct.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,18 @@ public ApplyDetails[] UpdateFromRcm(Dictionary<string, List<RemoteConfiguration>
5151
var serverConfigFile = new NamedRawFile(ffeConfig.Path, ffeConfig.Contents).Deserialize<ServerConfiguration>();
5252
if (serverConfigFile.TypedFile is not null)
5353
{
54-
_serverConfigurations.Add(new KeyValuePair<string, ServerConfiguration>(ffeConfig.Path.Path, serverConfigFile.TypedFile));
54+
var path = ffeConfig.Path.Path;
55+
var updatedConfig = new KeyValuePair<string, ServerConfiguration>(path, serverConfigFile.TypedFile);
56+
var existingIndex = _serverConfigurations.FindIndex(config => config.Key == path);
57+
if (existingIndex >= 0)
58+
{
59+
_serverConfigurations[existingIndex] = updatedConfig;
60+
}
61+
else
62+
{
63+
_serverConfigurations.Add(updatedConfig);
64+
}
65+
5566
res.Add(ApplyDetails.FromOk(ffeConfig.Path.Path));
5667
apply = true;
5768
}

tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,46 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo
7575
result.Reason.Should().Be(EvaluationReason.Error);
7676
}
7777

78+
[Fact]
79+
public void UpdateRemoteConfig_WithExistingPath_ReplacesPreviousConfiguration()
80+
{
81+
var rcmManager = new MockRcmSubscriptionManager();
82+
var module = new FeatureFlagsModule(CreateSettings(), rcmManager);
83+
var configPath = RemoteConfigurationPath.FromPath($"datadog/2/{RcmProducts.FfeFlags}/test-config/config");
84+
85+
rcmManager.LastSubscription!.Invoke(
86+
new Dictionary<string, List<RemoteConfiguration>>
87+
{
88+
[RcmProducts.FfeFlags] = [CreateRemoteConfiguration(configPath, "old-flag")]
89+
},
90+
null);
91+
92+
module.Evaluate("old-flag", FeatureFlagsValueType.Boolean, false, "user-1", null).Error.Should().BeNull();
93+
94+
rcmManager.LastSubscription.Invoke(
95+
new Dictionary<string, List<RemoteConfiguration>>
96+
{
97+
[RcmProducts.FfeFlags] = [CreateRemoteConfiguration(configPath, "new-flag")]
98+
},
99+
null);
100+
101+
module.Evaluate("old-flag", FeatureFlagsValueType.Boolean, false, "user-1", null).Error.Should().Be("FLAG_NOT_FOUND");
102+
module.Evaluate("new-flag", FeatureFlagsValueType.Boolean, false, "user-1", null).Error.Should().BeNull();
103+
}
104+
105+
private static RemoteConfiguration CreateRemoteConfiguration(RemoteConfigurationPath configPath, string flagKey)
106+
{
107+
var configJson = JsonConvert.SerializeObject(new ServerConfiguration
108+
{
109+
Flags = new FlagCollection
110+
{
111+
[flagKey] = new Flag { Key = flagKey, Enabled = true, VariationType = FeatureFlagsValueType.Boolean }
112+
}
113+
});
114+
var configBytes = System.Text.Encoding.UTF8.GetBytes(configJson);
115+
return new RemoteConfiguration(configPath, configBytes, configBytes.Length, new Dictionary<string, string> { { "sha256", "dummy" } }, 1);
116+
}
117+
78118
private static TracerSettings CreateSettings()
79119
{
80120
var collection = new NameValueCollection

0 commit comments

Comments
 (0)