Skip to content

Commit 8658968

Browse files
committed
more coverage
1 parent 364d41d commit 8658968

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/ConcurrencyIssueTest.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Reflection;
34
using System.Threading.Tasks;
45
using AWS.Lambda.Powertools.Metrics;
56
using Xunit;
@@ -281,6 +282,61 @@ public async Task AddMetric_ConcurrentModificationDuringIteration_ShouldHandleAr
281282
CleanupMetrics();
282283
}
283284

285+
[Fact]
286+
public void GetExistingMetric_ArgumentOutOfRangeException_ShouldReturnNull()
287+
{
288+
// Arrange - Use reflection to test the private GetExistingMetric method directly
289+
var getExistingMetricMethod = typeof(Metrics).GetMethod("GetExistingMetric",
290+
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
291+
292+
Assert.NotNull(getExistingMetricMethod);
293+
294+
// Create a custom list that will throw ArgumentOutOfRangeException
295+
var metricsList = new TestMetricsList();
296+
metricsList.Add(new MetricDefinition("TestMetric", MetricUnit.Count, new List<double> { 1.0 }, MetricResolution.Default));
297+
298+
// Act - Call the private method via reflection, searching for a different key
299+
// This will cause the method to iterate and hit the indexer that throws ArgumentOutOfRangeException
300+
var result = getExistingMetricMethod.Invoke(null, new object[] { metricsList, "NonExistentMetric" });
301+
302+
// Assert - Should return null when ArgumentOutOfRangeException is caught
303+
Assert.Null(result);
304+
}
305+
306+
/// <summary>
307+
/// Custom list that throws ArgumentOutOfRangeException on indexer access
308+
/// to simulate the race condition scenario
309+
/// </summary>
310+
private class TestMetricsList : List<MetricDefinition>
311+
{
312+
private bool _shouldThrow = false;
313+
314+
public new int Count
315+
{
316+
get
317+
{
318+
// Return 1 initially, but set flag to throw on indexer access
319+
_shouldThrow = true;
320+
return base.Count;
321+
}
322+
}
323+
324+
public new MetricDefinition this[int index]
325+
{
326+
get
327+
{
328+
if (_shouldThrow)
329+
{
330+
// Throw ArgumentOutOfRangeException to simulate the race condition
331+
// where collection was modified between Count check and indexer access
332+
throw new ArgumentOutOfRangeException(nameof(index), "Simulated race condition");
333+
}
334+
return base[index];
335+
}
336+
set => base[index] = value;
337+
}
338+
}
339+
284340
/// <summary>
285341
/// Cleanup method to ensure no state leaks between tests
286342
/// </summary>

0 commit comments

Comments
 (0)