diff --git a/SIL.Core.Tests/Code/RetryUtilityTests.cs b/SIL.Core.Tests/Code/RetryUtilityTests.cs
index 5c7c70ba3..32eb6837a 100644
--- a/SIL.Core.Tests/Code/RetryUtilityTests.cs
+++ b/SIL.Core.Tests/Code/RetryUtilityTests.cs
@@ -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
{
- ///
- /// This is a work in progress. At this point it only has a test for one recently-added bit of functionality.
- ///
public class RetryUtilityTests
{
[Test]
@@ -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 (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 (new[] { typeof(Exception) })), Throws.Exception.TypeOf());
+ 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());
+ 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());
+ 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 (new[] { typeof(ApplicationException) })),
+ Throws.Exception.TypeOf());
+ Assert.That(n, Is.EqualTo(1));
+ }
}
}
diff --git a/SIL.Core/Code/RetryUtility.cs b/SIL.Core/Code/RetryUtility.cs
index 07523c81f..bdedf4806 100644
--- a/SIL.Core/Code/RetryUtility.cs
+++ b/SIL.Core/Code/RetryUtility.cs
@@ -31,6 +31,21 @@ public static void Retry(Action action, int maxRetryAttempts = kDefaultMaxRetryA
}, maxRetryAttempts, retryDelay, exceptionTypesToRetry, memo);
}
+ ///
+ /// Retry up to times if it
+ /// throws one of the exceptions in or a subclassed
+ /// exception. The default value for is null which
+ /// will catch IOExceptions.
+ ///
+ /// The action to run
+ /// Number of attempts to run
+ /// Delay in milliseconds between attempts
+ /// Exceptions to catch and retry. Not listed exceptions
+ /// are thrown.
+ /// Text to append to the debug message in case of
+ /// throwing an exception.
+ /// Type that returns
+ /// Return value of
public static T Retry(Func action, int maxRetryAttempts = kDefaultMaxRetryAttempts, int retryDelay = kDefaultRetryDelay, ISet exceptionTypesToRetry = null, string memo = "")
{
if (exceptionTypesToRetry == null)