5
5
6
6
using System . Collections . Generic ;
7
7
using System . Collections . Specialized ;
8
+ using System . Linq ;
8
9
using Datadog . Trace . Configuration ;
10
+ using Datadog . Trace . Configuration . ConfigurationSources . Telemetry ;
9
11
using Datadog . Trace . Configuration . Telemetry ;
10
12
using Datadog . Trace . Telemetry ;
11
13
using FluentAssertions ;
@@ -137,7 +139,7 @@ public void AttemptsToGrabStringFromEverySource(string key)
137
139
{
138
140
var telemetry = new StubTelemetry ( ) ;
139
141
var actual = _source . GetString ( key , telemetry , validator : null , recordValue : true ) ;
140
- telemetry . Accesses [ key ] . Should ( ) . Be ( 1 ) ;
142
+ telemetry . GetInstanceCount ( key ) . Should ( ) . Be ( 1 ) ;
141
143
}
142
144
143
145
[ Theory ]
@@ -160,7 +162,7 @@ public void AttemptsToGrabIntFromEverySource(string key)
160
162
{
161
163
var telemetry = new StubTelemetry ( ) ;
162
164
var actual = _source . GetInt32 ( key , telemetry , validator : null ) ;
163
- telemetry . Accesses [ key ] . Should ( ) . Be ( 1 ) ;
165
+ telemetry . GetInstanceCount ( key ) . Should ( ) . Be ( 1 ) ;
164
166
}
165
167
166
168
[ Theory ]
@@ -183,7 +185,7 @@ public void AttemptsToGrabDoubleFromEverySource(string key)
183
185
{
184
186
var telemetry = new StubTelemetry ( ) ;
185
187
var actual = _source . GetDouble ( key , telemetry , validator : null ) ;
186
- telemetry . Accesses [ key ] . Should ( ) . Be ( 1 ) ;
188
+ telemetry . GetInstanceCount ( key ) . Should ( ) . Be ( 1 ) ;
187
189
}
188
190
189
191
[ Theory ]
@@ -206,7 +208,7 @@ public void AttemptsToGrabBoolFromEverySource(string key)
206
208
{
207
209
var telemetry = new StubTelemetry ( ) ;
208
210
var actual = _source . GetBool ( key , telemetry , validator : null ) ;
209
- telemetry . Accesses [ key ] . Should ( ) . Be ( 1 ) ;
211
+ telemetry . GetInstanceCount ( key ) . Should ( ) . Be ( 1 ) ;
210
212
}
211
213
212
214
[ Theory ]
@@ -229,30 +231,105 @@ public void AttemptsToGrabDictionaryFromEverySource(string key)
229
231
{
230
232
var telemetry = new StubTelemetry ( ) ;
231
233
var actual = _source . GetDictionary ( key , telemetry , validator : null ) ;
232
- telemetry . Accesses [ key ] . Should ( ) . Be ( 1 ) ;
234
+ telemetry . GetInstanceCount ( key ) . Should ( ) . Be ( 1 ) ;
235
+ }
236
+
237
+ [ Fact ]
238
+ public void Telemetry_WhenMissingDoesNotRecordTelemetry ( )
239
+ {
240
+ var telemetry = new StubTelemetry ( ) ;
241
+ const string key = "int_value" ;
242
+ var source = new CompositeConfigurationSource ( )
243
+ {
244
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . Calculated ) ,
245
+ new NameValueConfigurationSource ( new ( ) { { "something_else" , "456" } } , ConfigurationOrigins . EnvVars ) ,
246
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . AppConfig ) ,
247
+ } ;
248
+
249
+ // not present
250
+ var actual = source . GetInt32 ( key , telemetry , validator : null ) ;
251
+ actual . Should ( ) . Be ( ConfigurationResult < int > . NotFound ( ) ) ;
252
+
253
+ // final telemetry value should be the "real" value
254
+ telemetry . Telemetry . Should ( ) . BeEmpty ( ) ;
255
+ }
256
+
257
+ [ Fact ]
258
+ public void Telemetry_WhenErrorRecordsTelemetry ( )
259
+ {
260
+ var telemetry = new StubTelemetry ( ) ;
261
+ const string key = "int_value" ;
262
+ var source = new CompositeConfigurationSource ( )
263
+ {
264
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . Calculated ) ,
265
+ new NameValueConfigurationSource ( new ( ) { { key , "not_an_int" } } , ConfigurationOrigins . DdConfig ) ,
266
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . AppConfig ) ,
267
+ } ;
268
+
269
+ // no valid value
270
+ var actual = source . GetInt32 ( key , telemetry , validator : null ) ;
271
+ actual . Should ( ) . Be ( ConfigurationResult < int > . NotFound ( ) ) ;
272
+
273
+ // only telemetry value should be the error
274
+ telemetry . Telemetry . Should ( )
275
+ . ContainSingle ( )
276
+ . Which . Should ( )
277
+ . BeEquivalentTo ( new ConfigurationTelemetryTests . ConfigDto ( key , "not_an_int" , ConfigurationOrigins . DdConfig , true , TelemetryErrorCode . ParsingInt32Error ) ) ;
278
+ }
279
+
280
+ [ Fact ]
281
+ public void RecordsTelemetry_WhenPresentInMultipleSources ( )
282
+ {
283
+ var telemetry = new StubTelemetry ( ) ;
284
+ const string key = "int_value" ;
285
+ var source = new CompositeConfigurationSource ( )
286
+ {
287
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . Calculated ) ,
288
+ new NameValueConfigurationSource ( new ( ) { { key , "not_an_int" } } , ConfigurationOrigins . DdConfig ) ,
289
+ new NameValueConfigurationSource ( new ( ) { { key , "123" } } , ConfigurationOrigins . Code ) ,
290
+ new NameValueConfigurationSource ( new ( ) , ConfigurationOrigins . AppConfig ) ,
291
+ new NameValueConfigurationSource ( new ( ) { { key , "not_an_int" } } , ConfigurationOrigins . RemoteConfig ) ,
292
+ new NameValueConfigurationSource ( new ( ) { { key , "456" } } , ConfigurationOrigins . EnvVars ) ,
293
+ } ;
294
+
295
+ // first wins
296
+ var expected = 123 ;
297
+ var actual = source . GetInt32 ( key , telemetry , validator : null ) ;
298
+ actual . Should ( ) . Be ( ConfigurationResult < int > . Valid ( expected ) ) ;
299
+
300
+ // final telemetry value should be the "real" value
301
+ telemetry . Telemetry . Last ( ) . Value . Should ( ) . Be ( expected ) ;
302
+
303
+ // telemetry records the first error, and then the successful value
304
+ telemetry . Telemetry . Should ( )
305
+ . BeEquivalentTo (
306
+ [
307
+ new ConfigurationTelemetryTests . ConfigDto ( key , "not_an_int" , ConfigurationOrigins . DdConfig , true , TelemetryErrorCode . ParsingInt32Error ) ,
308
+ new ConfigurationTelemetryTests . ConfigDto ( key , 123 , ConfigurationOrigins . Code , true , null ) ,
309
+ ] ) ;
233
310
}
234
311
235
312
internal class StubTelemetry : IConfigurationTelemetry
236
313
{
237
- public Dictionary < string , int > Accesses { get ; } = new ( ) ;
314
+ public List < ConfigurationTelemetryTests . ConfigDto > Telemetry { get ; } = new ( ) ;
238
315
239
316
public void Record ( string key , string value , bool recordValue , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
240
- => IncrementAccess ( key ) ;
317
+ => Telemetry . Add ( new ( key , value , origin , recordValue , error ) ) ;
241
318
242
319
public void Record ( string key , bool value , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
243
- => IncrementAccess ( key ) ;
320
+ => Telemetry . Add ( new ( key , value , origin , recordValue : true , error ) ) ;
244
321
245
322
public void Record ( string key , double value , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
246
- => IncrementAccess ( key ) ;
323
+ => Telemetry . Add ( new ( key , value , origin , recordValue : true , error ) ) ;
247
324
248
325
public void Record ( string key , int value , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
249
- => IncrementAccess ( key ) ;
326
+ => Telemetry . Add ( new ( key , value , origin , recordValue : true , error ) ) ;
250
327
251
328
public void Record ( string key , double ? value , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
252
- => IncrementAccess ( key ) ;
329
+ => Telemetry . Add ( new ( key , value , origin , recordValue : true , error ) ) ;
253
330
254
331
public void Record ( string key , int ? value , ConfigurationOrigins origin , TelemetryErrorCode ? error = null )
255
- => IncrementAccess ( key ) ;
332
+ => Telemetry . Add ( new ( key , value , origin , recordValue : true , error ) ) ;
256
333
257
334
public ICollection < ConfigurationKeyValue > GetData ( ) => null ;
258
335
@@ -264,16 +341,7 @@ public void SetErrorOnCurrentEntry(string key, TelemetryErrorCode error)
264
341
{
265
342
}
266
343
267
- private void IncrementAccess ( string key )
268
- {
269
- if ( Accesses . TryGetValue ( key , out var i ) )
270
- {
271
- Accesses [ key ] = i + 1 ;
272
- }
273
- else
274
- {
275
- Accesses [ key ] = 1 ;
276
- }
277
- }
344
+ public int GetInstanceCount ( string key )
345
+ => Telemetry . Count ( x => x . Name == key ) ;
278
346
}
279
347
}
0 commit comments