Skip to content

Commit

Permalink
Add some tests for RetryUtility (#1296)
Browse files Browse the repository at this point in the history
* Add some tests for RetryUtility
* Add another test and method documentation
  • Loading branch information
ermshiperete authored Oct 18, 2023
1 parent 0a5bdea commit 1d5a6bd
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 6 deletions.
79 changes: 73 additions & 6 deletions SIL.Core.Tests/Code/RetryUtilityTests.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using SIL.Code;

namespace SIL.Tests.Code
{
/// <summary>
/// This is a work in progress. At this point it only has a test for one recently-added bit of functionality.
/// </summary>
public class RetryUtilityTests
{
[Test]
Expand All @@ -23,5 +17,78 @@ public void TypesIncludes_MainClassAndSubclasses_ButNotSuperclass()
Assert.That(RetryUtility.TypesIncludes(types, typeof(FileNotFoundException)), Is.True);
Assert.That(RetryUtility.TypesIncludes(types, typeof(SystemException)), Is.False);
}

[Test]
public void Retry_WorksOnFirstAttempt()
{
var n = 0;
RetryUtility.Retry(() => { n++; }, 3, 1);
Assert.That(n, Is.EqualTo(1));
}

[Test]
public void Retry_WorksOnSecondAttempt()
{
var n = 0;
RetryUtility.Retry(() => {
n++;
if (n == 1)
throw new ApplicationException();
}, 3, 1, new HashSet<Type> (new[] { typeof(Exception) }));
Assert.That(n, Is.EqualTo(2));
}

[Test]
public void Retry_StopsAfter3Attempts()
{
var n = 0;
Assert.That(() => RetryUtility.Retry(() => {
n++;
throw new ApplicationException();
}, 3, 1, new HashSet<Type> (new[] { typeof(Exception) })), Throws.Exception.TypeOf<ApplicationException>());
Assert.That(n, Is.EqualTo(3));
}

[Test]
public void Retry_NoWorkFor0Attempts()
{
var n = 0;
RetryUtility.Retry(() => { n++; }, 0, 1);
Assert.That(n, Is.EqualTo(0));
}

[Test]
public void Retry_NoRetriesWithoutExceptionType()
{
var n = 0;
Assert.That(() => RetryUtility.Retry(() => {
n++;
throw new ApplicationException();
}, 3, 1, null), Throws.Exception.TypeOf<ApplicationException>());
Assert.That(n, Is.EqualTo(1));
}

[Test]
public void Retry_DefaultsToIOException()
{
var n = 0;
Assert.That(() => RetryUtility.Retry(() => {
n++;
throw new IOException();
}, 3, 1, null), Throws.Exception.TypeOf<IOException>());
Assert.That(n, Is.EqualTo(3));
}

[Test]
public void Retry_CatchesSpecifiedExceptionsOnly()
{
var n = 0;
Assert.That(() => RetryUtility.Retry(() => {
n++;
throw new Exception();
}, 3, 1, new HashSet<Type> (new[] { typeof(ApplicationException) })),
Throws.Exception.TypeOf<Exception>());
Assert.That(n, Is.EqualTo(1));
}
}
}
15 changes: 15 additions & 0 deletions SIL.Core/Code/RetryUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ public static void Retry(Action action, int maxRetryAttempts = kDefaultMaxRetryA
}, maxRetryAttempts, retryDelay, exceptionTypesToRetry, memo);
}

/// <summary>
/// Retry <paramref name="action"/> up to <paramref name="maxRetryAttempts"/> times if it
/// throws one of the exceptions in <paramref name="exceptionTypesToRetry"/> or a subclassed
/// exception. The default value for <paramref name="exceptionTypesToRetry"/> is null which
/// will catch <c>IOException</c>s.
/// </summary>
/// <param name="action">The action to run</param>
/// <param name="maxRetryAttempts">Number of attempts to run <paramref name="action"/></param>
/// <param name="retryDelay">Delay in milliseconds between attempts</param>
/// <param name="exceptionTypesToRetry">Exceptions to catch and retry. Not listed exceptions
/// are thrown.</param>
/// <param name="memo">Text to append to the debug message in case of
/// <paramref name="action"/> throwing an exception.</param>
/// <typeparam name="T">Type that <paramref name="action"/> returns</typeparam>
/// <returns>Return value of <paramref name="action"/></returns>
public static T Retry<T>(Func<T> action, int maxRetryAttempts = kDefaultMaxRetryAttempts, int retryDelay = kDefaultRetryDelay, ISet<Type> exceptionTypesToRetry = null, string memo = "")
{
if (exceptionTypesToRetry == null)
Expand Down

0 comments on commit 1d5a6bd

Please sign in to comment.