Skip to content

Commit

Permalink
Add custom persistence test kit (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
Arkatufus authored Jul 17, 2024
1 parent f520052 commit 2858467
Show file tree
Hide file tree
Showing 36 changed files with 3,386 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Akka.Persistence" Version="1.5.26" />
<PackageReference Include="Akka.TestKit" Version="1.5.26" />
<PackageReference Include="Akka.TestKit.Xunit2" Version="1.5.26" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="config.conf" />
</ItemGroup>

</Project>
109 changes: 109 additions & 0 deletions Akka.HealthCheck.Persistence.TestKit/ConnectionInterceptors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// -----------------------------------------------------------------------
// <copyright file="ConnectionInterceptors.cs" company="Petabridge, LLC">
// Copyright (C) 2015 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Threading;
using System.Threading.Tasks;
using Akka.HealthCheck.Persistence.TestKit.Journal;

namespace Akka.HealthCheck.Persistence.TestKit;

public class ConnectionInterceptors
{
public class Noop : IConnectionInterceptor
{
public static readonly IConnectionInterceptor Instance = new Noop();

public Task InterceptAsync() => Task.FromResult(true);
}

public class Failure : IConnectionInterceptor
{
public static readonly IConnectionInterceptor Instance = new Failure();

public Task InterceptAsync() => throw new TestConnectionException();
}

public class Delay : IConnectionInterceptor
{
public Delay(TimeSpan delay, IConnectionInterceptor next)
{
_delay = delay;
_next = next;
}

private readonly TimeSpan _delay;
private readonly IConnectionInterceptor _next;

public async Task InterceptAsync()
{
await Task.Delay(_delay);
await _next.InterceptAsync();
}
}

public sealed class OnCondition : IConnectionInterceptor
{
public OnCondition(Func<Task<bool>> predicate, IConnectionInterceptor next, bool negate = false)
{
_predicate = predicate;
_next = next;
_negate = negate;
}

public OnCondition(Func<bool> predicate, IConnectionInterceptor next, bool negate = false)
{
_predicate = () => Task.FromResult(predicate());
_next = next;
_negate = negate;
}

private readonly Func<Task<bool>> _predicate;
private readonly IConnectionInterceptor _next;
private readonly bool _negate;

public async Task InterceptAsync()
{
var result = await _predicate();
if ((_negate && !result) || (!_negate && result))
{
await _next.InterceptAsync();
}
}
}

public class CancelableDelay: IConnectionInterceptor
{
public CancelableDelay(TimeSpan delay, IConnectionInterceptor next, CancellationToken cancellationToken)
{
_delay = delay;
_next = next;
_cancellationToken = cancellationToken;
}

private readonly TimeSpan _delay;
private readonly IConnectionInterceptor _next;
private readonly CancellationToken _cancellationToken;

public async Task InterceptAsync()
{
try
{
await Task.Delay(_delay, _cancellationToken);
}
catch (OperationCanceledException)
{
// no-op
}
catch (TimeoutException)
{
// no-op
}
await _next.InterceptAsync();
}
}

}
14 changes: 14 additions & 0 deletions Akka.HealthCheck.Persistence.TestKit/IConnectionInterceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// -----------------------------------------------------------------------
// <copyright file="IConnectionInterceptor.cs" company="Petabridge, LLC">
// Copyright (C) 2015 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

using System.Threading.Tasks;

namespace Akka.HealthCheck.Persistence.TestKit;

public interface IConnectionInterceptor
{
Task InterceptAsync();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//-----------------------------------------------------------------------
// <copyright file="IJournalBehaviorSetter.cs" company="Akka.NET Project">
// Copyright (C) 2009-2023 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System.Threading.Tasks;

namespace Akka.HealthCheck.Persistence.TestKit.Journal;

public interface IJournalBehaviorSetter
{
Task SetInterceptorAsync(IJournalInterceptor interceptor);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// -----------------------------------------------------------------------
// <copyright file="IConnectionBehaviorSetter.cs" company="Petabridge, LLC">
// Copyright (C) 2015 - 2024 Petabridge, LLC <https://petabridge.com>
// </copyright>
// -----------------------------------------------------------------------

using System.Threading.Tasks;

namespace Akka.HealthCheck.Persistence.TestKit.Journal;

public interface IJournalConnectionBehaviorSetter
{
Task SetInterceptorAsync(IConnectionInterceptor interceptor);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//-----------------------------------------------------------------------
// <copyright file="IJournalInterceptor.cs" company="Akka.NET Project">
// Copyright (C) 2009-2023 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System.Threading.Tasks;
using Akka.Persistence;

namespace Akka.HealthCheck.Persistence.TestKit.Journal;

/// <summary>
/// Interface to object which will intercept written and recovered messages in <see cref="TestJournal"/>.
/// </summary>
public interface IJournalInterceptor
{
/// <summary>
/// Method will be called for each individual message before it is written or recovered.
/// </summary>
/// <param name="message">Written or recovered message.</param>
Task InterceptAsync(IPersistentRepresentation message);
}
26 changes: 26 additions & 0 deletions Akka.HealthCheck.Persistence.TestKit/Journal/ITestJournal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//-----------------------------------------------------------------------
// <copyright file="ITestJournal.cs" company="Akka.NET Project">
// Copyright (C) 2009-2023 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

namespace Akka.HealthCheck.Persistence.TestKit.Journal;

/// <summary>
/// <see cref="TestJournal"/> proxy object interface. Used to simplify communication with <see cref="TestJournal"/> actor instance.
/// </summary>
public interface ITestJournal
{
/// <summary>
/// List of interceptors to alter write behavior of proxied journal.
/// </summary>
JournalWriteBehavior OnWrite { get; }

/// <summary>
/// List of interceptors to alter recovery behavior of proxied journal.
/// </summary>
JournalRecoveryBehavior OnRecovery { get; }

JournalConnectionBehavior OnConnect { get; }
}
Loading

0 comments on commit 2858467

Please sign in to comment.