Upstream App-vNext/Polly state of the touched files before 65d060c90f

This commit is contained in:
upstream committed 2026-09-02 11:43:55 +02:00
commit 7121d2323f
2 files changed
+133

No files matched your search

@@ -0,0 +1,83 @@
using System.ComponentModel;
using Polly.Simmy.Utils;
namespace Polly.Simmy.Fault;
#pragma warning disable CA2225 // Operator overloads have named alternates
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
/// <summary>
/// A generator for creating faults (exceptions) using registered delegate functions.
/// </summary>
/// <remarks>
/// An instance of this class can be assigned to the <see cref="ChaosFaultStrategyOptions.FaultGenerator"/> property.
/// </remarks>
public sealed class FaultGenerator
{
private const int DefaultWeight = 100;
private readonly GeneratorHelper<VoidResult> _helper;
/// <summary>
/// Initializes a new instance of the <see cref="FaultGenerator"/> class.
/// </summary>
public FaultGenerator() => _helper = new(RandomUtil.Next);
/// <summary>
/// Registers an exception generator delegate.
/// </summary>
/// <param name="generator">The delegate that generates the exception.</param>
/// <param name="weight">The weight assigned to this generator. Defaults to <c>100</c>.</param>
/// <returns>The current instance of <see cref="FaultGenerator"/>.</returns>
public FaultGenerator AddException(Func<Exception> generator, int weight = DefaultWeight)
{
Guard.NotNull(generator);
_helper.AddOutcome(_ => Outcome.FromException<VoidResult>(generator()), weight);
return this;
}
/// <summary>
/// Registers an exception generator delegate that accepts a <see cref="ResilienceContext"/>.
/// </summary>
/// <param name="generator">The delegate that generates the exception, accepting a <see cref="ResilienceContext"/>.</param>
/// <param name="weight">The weight assigned to this generator. Defaults to <c>100</c>.</param>
/// <returns>The current instance of <see cref="FaultGenerator"/>.</returns>
public FaultGenerator AddException(Func<ResilienceContext, Exception> generator, int weight = DefaultWeight)
{
Guard.NotNull(generator);
_helper.AddOutcome(context => Outcome.FromException<VoidResult>(generator(context)), weight);
return this;
}
/// <summary>
/// Registers an exception generator for a specific exception type, using the default constructor of that exception.
/// </summary>
/// <typeparam name="TException">The type of the exception to generate.</typeparam>
/// <param name="weight">The weight assigned to this generator. Defaults to <c>100</c>.</param>
/// <returns>The current instance of <see cref="FaultGenerator"/>.</returns>
public FaultGenerator AddException<TException>(int weight = DefaultWeight)
where TException : Exception, new()
{
_helper.AddOutcome(_ => Outcome.FromException<VoidResult>(new TException()), weight);
return this;
}
/// <summary>
/// Provides an implicit conversion from <see cref="FaultGenerator"/> to a delegate compatible with <see cref="ChaosFaultStrategyOptions.FaultGenerator"/>.
/// </summary>
/// <param name="generator">The instance of <see cref="FaultGenerator"/>.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public static implicit operator Func<FaultGeneratorArguments, ValueTask<Exception?>>(FaultGenerator generator)
{
Guard.NotNull(generator);
var generatorDelegate = generator._helper.CreateGenerator();
return args => new ValueTask<Exception?>(generatorDelegate(args.Context)!.Value.Exception);
}
}
@@ -0,0 +1,50 @@
using Polly.Simmy.Fault;
namespace Polly.Core.Tests.Simmy.Fault;
public class FaultGeneratorTests
{
[Fact]
public void AddException_Generic_Ok()
{
var generator = new FaultGenerator();
generator.AddException<InvalidOperationException>();
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
[Fact]
public void AddException_Factory_Ok()
{
var generator = new FaultGenerator();
generator.AddException(() => new InvalidOperationException());
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
[Fact]
public void AddException_FactoryWithResilienceContext_Ok()
{
var generator = new FaultGenerator();
generator.AddException(context =>
{
context.ShouldNotBeNull();
return new InvalidOperationException();
});
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
private static Exception? Generate(FaultGenerator generator)
{
Func<FaultGeneratorArguments, ValueTask<Exception?>> func = generator;
return func(
new FaultGeneratorArguments(
ResilienceContextPool.Shared.Get(TestCancellation.Token))).AsTask().Result;
}
}