elsa-core/test/unit/Elsa.Persistence.EFCore.UnitTests/DbExceptionClassifierTests.cs
2026-09-14 02:51:34 +02:00

72 lines
2.5 KiB
C#

using Microsoft.EntityFrameworkCore;
namespace Elsa.Persistence.EFCore.UnitTests;
public sealed class DbExceptionClassifierTests
{
[Theory]
[InlineData(19, 1555, true)]
[InlineData(19, 2067, true)]
[InlineData(19, 19, false)]
[InlineData(19, 0, false)]
public void IsDuplicateKey_WhenSqliteExtendedCodeExists_UsesOnlyExtendedDuplicateCodes(int baseCode, int extendedCode, bool expected)
{
var exception = new SqliteExceptionWithExtendedCode(baseCode, extendedCode);
Assert.Equal(expected, DbExceptionClassifier.IsDuplicateKey(exception));
}
[Theory]
[InlineData(19, true)]
[InlineData(1, false)]
public void IsDuplicateKey_WhenSqliteExtendedCodeIsUnavailable_FallsBackToBaseCode(int baseCode, bool expected)
{
var exception = new SqliteExceptionWithoutExtendedCode(baseCode);
Assert.Equal(expected, DbExceptionClassifier.IsDuplicateKey(exception));
}
[Theory]
[InlineData(1205, true)]
[InlineData(1213, true)]
[InlineData(1062, false)]
public void IsTransient_WhenMySqlProviderUsesInnoDbLockErrorCodes(int number, bool expected)
{
var exception = new MySqlConnector.MySqlException(number);
Assert.Equal(expected, DbExceptionClassifier.IsTransient("Pomelo.EntityFrameworkCore.MySql", exception));
}
[Fact]
public void IsTransient_WhenMySqlProviderExceptionOnlyHasAnUnrelatedNumberProperty_ReturnsFalse()
{
var exception = new UnrelatedNumberException(1213);
Assert.False(DbExceptionClassifier.IsTransient("Pomelo.EntityFrameworkCore.MySql", exception));
}
[Fact]
public void IsTransient_WhenMySqlDeadlockIsWrappedByDbUpdateException_ReturnsTrue()
{
var exception = new DbUpdateException("Write failed", new MySqlConnector.MySqlException(1213));
Assert.True(DbExceptionClassifier.IsTransient("Pomelo.EntityFrameworkCore.MySql", exception));
}
private sealed class SqliteExceptionWithExtendedCode(int sqliteErrorCode, int sqliteExtendedErrorCode) : Exception
{
public int SqliteErrorCode { get; } = sqliteErrorCode;
public int SqliteExtendedErrorCode { get; } = sqliteExtendedErrorCode;
}
private sealed class SqliteExceptionWithoutExtendedCode(int sqliteErrorCode) : Exception
{
public int SqliteErrorCode { get; } = sqliteErrorCode;
}
private sealed class UnrelatedNumberException(int number) : Exception
{
public int Number { get; } = number;
}
}