Skip to content

Commit

Permalink
Fix return value on delegate instrumentation
Browse files Browse the repository at this point in the history
Add tests
  • Loading branch information
kevingosse committed Oct 14, 2024
1 parent a721f7b commit f70131c
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="DelegateInstrumentation.cs" company="Datadog">
// <copyright file="DelegateInstrumentation.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>
Expand Down Expand Up @@ -404,7 +404,7 @@ async Task<TInnerReturn> AddContinuation(Task<TInnerReturn>? originalTask, IRetu
}
}

TInnerReturn? continuationResult = default;
TInnerReturn? continuationResult;
try
{
// *
Expand All @@ -415,6 +415,7 @@ async Task<TInnerReturn> AddContinuation(Task<TInnerReturn>? originalTask, IRetu
catch (Exception ex)
{
asyncCallback.OnException(sender, ex);
continuationResult = taskResult;
}

// *
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="FuncInstrumentationTests.cs" company="Datadog">
// <copyright file="FuncInstrumentationTests.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>
Expand Down Expand Up @@ -65,6 +65,31 @@ public void Func0Test()
value.Should().Be(3);
}

[Fact]
public void Func0CallbackFailureTest()
{
var value = 0;
CustomFunc<int> func = () =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc0Callbacks(
target =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func().Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func0Callbacks : IBegin0Callbacks, IReturnCallback
{
public Func0Callbacks()
Expand Down Expand Up @@ -142,6 +167,31 @@ public void Func1Test()
value.Should().Be(3);
}

[Fact]
public void Func1CallbackFailureTest()
{
var value = 0;
CustomFunc<string, int> func = _ =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc1Callbacks(
(target, _) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func(default).Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func1Callbacks : IBegin1Callbacks, IReturnCallback
{
public Func1Callbacks()
Expand Down Expand Up @@ -206,6 +256,31 @@ public void Func2Test()
value.Should().Be(3);
}

[Fact]
public void Func2CallbackFailureTest()
{
var value = 0;
CustomFunc<string, string, int> func = (_, _) =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc2Callbacks(
(target, _, _) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func(default, default).Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func2Callbacks : IBegin2Callbacks, IReturnCallback
{
public Func2Callbacks()
Expand Down Expand Up @@ -272,6 +347,31 @@ public void Func3Test()
value.Should().Be(3);
}

[Fact]
public void Func3CallbackFailureTest()
{
var value = 0;
CustomFunc<string, string, string, int> func = (_, _, _) =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc3Callbacks(
(target, _, _, _) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func(default, default, default).Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func3Callbacks : IBegin3Callbacks, IReturnCallback
{
public Func3Callbacks()
Expand Down Expand Up @@ -340,6 +440,31 @@ public void Func4Test()
value.Should().Be(3);
}

[Fact]
public void Func4CallbackFailureTest()
{
var value = 0;
CustomFunc<string, string, string, string, int> func = (_, _, _, _) =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc4Callbacks(
(target, _, _, _, _) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func(default, default, default, default).Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func4Callbacks : IBegin4Callbacks, IReturnCallback
{
public Func4Callbacks()
Expand Down Expand Up @@ -410,6 +535,31 @@ public void Func5Test()
value.Should().Be(3);
}

[Fact]
public void Func5CallbackFailureTest()
{
var value = 0;
CustomFunc<string, string, string, string, string, int> func = (_, _, _, _, _) =>
{
Interlocked.Increment(ref value);
return 42;
};
func = DelegateInstrumentation.Wrap(func, new DelegateFunc5Callbacks(
(target, _, _, _, _, _) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new InvalidOperationException("Expected");
}));
using var scope = new AssertionScope();
func(default, default, default, default, default).Should().Be(42);
value.Should().Be(3);
}

public readonly struct Func5Callbacks : IBegin5Callbacks, IReturnCallback
{
public Func5Callbacks()
Expand Down Expand Up @@ -473,12 +623,14 @@ public async Task Async1Test()
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value).Should().Be(3);
// 3 or 4 because we can't predict if onDelegateEnd or onDelegateAsyncEnd will be called first
Interlocked.Increment(ref value).Should().BeOneOf(3, 4);
return returnValue;
},
onDelegateAsyncEnd: async (sender, returnValue, exception, state) =>
{
Interlocked.Increment(ref value).Should().Be(4);
// 3 or 4 because we can't predict if onDelegateEnd or onDelegateAsyncEnd will be called first
Interlocked.Increment(ref value).Should().BeOneOf(3, 4);
await Task.Delay(100).ConfigureAwait(false);
return ((int)returnValue) + 1;
}));
Expand All @@ -488,6 +640,40 @@ public async Task Async1Test()
value.Should().Be(4);
}

[Fact]
public async Task Async1CallbackFailureTest()
{
int value = 0;

CustomFunc<string, Task<int>> func = async (arg1) =>
{
Interlocked.Increment(ref value);
await Task.Delay(100).ConfigureAwait(false);
return 42;
};

func = DelegateInstrumentation.Wrap(func, new DelegateFunc1Callbacks(
(target, arg1) =>
{
Interlocked.Increment(ref value);
throw new Exception("Expected");
},
(target, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new Exception("Expected");
},
onDelegateAsyncEnd: (sender, returnValue, exception, state) =>
{
Interlocked.Increment(ref value);
throw new Exception("Expected");
}));
var result = await func("Arg01").ConfigureAwait(false);
using var scope = new AssertionScope();
value.Should().Be(4);
result.Should().Be(42);
}

[Fact]
public async Task Async1WithAsyncExceptionTest()
{
Expand Down

0 comments on commit f70131c

Please sign in to comment.