Last active
August 29, 2015 14:17
-
-
Save plioi/a15a3e9b3b4843195d64 to your computer and use it in GitHub Desktop.
Fixie Convention - Retry on SQL Timeouts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class IntegrationTestConvention : Convention | |
{ | |
public IntegrationTestConvention() | |
{ | |
Classes | |
.NameEndsWith("Tests"); | |
Methods | |
.Where(method => method.IsVoid() || method.IsAsync()); | |
CaseExecution | |
.Wrap<RetryOnSqlTimeout>(); | |
} | |
} | |
public class RetryOnSqlTimeout : CaseBehavior | |
{ | |
public void Execute(Case @case, Action execute) | |
{ | |
execute(); //Run the test for the first time. | |
if (@case.Exceptions.Count == 1) | |
{ | |
var exception = @case.Exceptions.Single(); | |
var sqlException = exception as SqlException; | |
const int timeout = -2; | |
if (sqlException != null && sqlException.Number == timeout) | |
{ | |
@case.ClearExceptions(); | |
execute(); //Run the test for the second time. | |
//You might instead do this check/clear/retry in a loop, | |
//but even then you'd want to bail out after a few | |
//consecutive failures. | |
} | |
} | |
} | |
} | |
public class LongRunningQueryTests | |
{ | |
public void AlwaysPasses() | |
{ | |
Console.WriteLine("AlwaysPasses"); | |
} | |
public void AlwaysFails() | |
{ | |
Console.WriteLine("AlwaysFails"); | |
throw new NotSupportedException(); | |
} | |
static bool hasTimedOutAlready = false; | |
public void TimesOutOnFirstTry() | |
{ | |
Console.WriteLine("TimesOutOnFirstTry"); | |
if (hasTimedOutAlready) | |
return; | |
hasTimedOutAlready = true; | |
throw new SqlException(-2); | |
} | |
} | |
/// <summary> | |
/// The real SqlException class can't be constructed directly. | |
/// For the sake of the example, here we imitate the part that matters. | |
/// SqlException's Number property indicates the specific problem. | |
/// -2 indicates timeout. | |
/// </summary> | |
public class SqlException : Exception | |
{ | |
public int Number { get; private set; } | |
public SqlException(int number) | |
{ | |
Number = number; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment