Skip to content

Commit

Permalink
TestJournal with Write intreception and varios failure strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
valdisz committed Aug 9, 2019
1 parent ed02407 commit f640b69
Show file tree
Hide file tree
Showing 17 changed files with 1,112 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/Akka.sln
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpawnBenchmark", "benchmark
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Akka.Persistence.FSharp", "core\Akka.Persistence.FSharp\Akka.Persistence.FSharp.fsproj", "{539C3EB6-FCC8-41FA-9373-364605877EE1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Akka.Persistence.TestKit", "core\Akka.Persistence.TestKit\Akka.Persistence.TestKit.csproj", "{212A2D35-E8D1-46A7-A1D1-418CF9509D77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Persistence.TestKit.Tests", "core\Akka.Persistence.TestKit.Tests\Akka.Persistence.TestKit.Tests.csproj", "{22F6EA86-0079-41A0-9BD3-82D2D6C34638}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -844,6 +848,30 @@ Global
{539C3EB6-FCC8-41FA-9373-364605877EE1}.Release|x64.Build.0 = Release|Any CPU
{539C3EB6-FCC8-41FA-9373-364605877EE1}.Release|x86.ActiveCfg = Release|Any CPU
{539C3EB6-FCC8-41FA-9373-364605877EE1}.Release|x86.Build.0 = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|x64.ActiveCfg = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|x64.Build.0 = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|x86.ActiveCfg = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Debug|x86.Build.0 = Debug|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|Any CPU.Build.0 = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|x64.ActiveCfg = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|x64.Build.0 = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|x86.ActiveCfg = Release|Any CPU
{212A2D35-E8D1-46A7-A1D1-418CF9509D77}.Release|x86.Build.0 = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|x64.ActiveCfg = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|x64.Build.0 = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|x86.ActiveCfg = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Debug|x86.Build.0 = Debug|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|Any CPU.Build.0 = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|x64.ActiveCfg = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|x64.Build.0 = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|x86.ActiveCfg = Release|Any CPU
{22F6EA86-0079-41A0-9BD3-82D2D6C34638}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -929,6 +957,8 @@ Global
{A1D57384-A933-480A-9DF4-FA5E60AB1A67} = {73108242-625A-4D7B-AA09-63375DBAE464}
{9BEAF609-B406-4CCB-9708-6E8DFF764232} = {73108242-625A-4D7B-AA09-63375DBAE464}
{539C3EB6-FCC8-41FA-9373-364605877EE1} = {01167D3C-49C4-4CDE-9787-C176D139ACDD}
{212A2D35-E8D1-46A7-A1D1-418CF9509D77} = {01167D3C-49C4-4CDE-9787-C176D139ACDD}
{22F6EA86-0079-41A0-9BD3-82D2D6C34638} = {01167D3C-49C4-4CDE-9787-C176D139ACDD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {03AD8E21-7507-4E68-A4E9-F4A7E7273164}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />

<PropertyGroup>
<AssemblyTitle>Akka.Persistence.TestKit.Tests</AssemblyTitle>
<TargetFrameworks>$(NetFrameworkTestVersion);$(NetCoreTestVersion)</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="xunit.runner.utility" Version="$(XunitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
<PackageReference Include="TeamCity.ServiceMessages" Version="3.0.8" />
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionsVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Akka.Persistence.TestKit\Akka.Persistence.TestKit.csproj" />
<ProjectReference Include="..\Akka.Tests.Shared.Internals\Akka.Tests.Shared.Internals.csproj" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="test-journal.conf" />
<EmbeddedResource Include="test-journal.conf" />
</ItemGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == '$(NetCoreTestVersion)' ">
<DefineConstants>$(DefineConstants);CORECLR</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>
144 changes: 144 additions & 0 deletions src/core/Akka.Persistence.TestKit.Tests/TestJournalSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
namespace Akka.Persistence.TestKit.Tests
{
<<<<<<< HEAD
=======
using System;
>>>>>>> d16f7c013... foo
using Actor;
using Akka.Persistence.TestKit;
using Akka.TestKit;
using Configuration;
using Xunit;
using Xunit.Abstractions;

public class TestJournalSpec : AkkaSpec
{
<<<<<<< HEAD
ITestJournal journal;

public TestJournalSpec(ITestOutputHelper output = null)
: base(GetConfig().ToString(), output)
{
var ext = Persistence.Instance.Apply(Sys);
var journalRef = ext.JournalFor("akka.persistence.journal.test");
journal = TestJournal.FromRef(journalRef);
}

[Fact]
public void just_usage_samples()
{
// by default journal will not fail
// user is supposed to define journal behavior like that:

// * to fail always
journal.OnWrite.Fail();

// * to fail on specific message type
journal.OnWrite.FailOnType<object>();

// * to fail on predicate
journal.OnWrite.FailIf(x => x.Sender != ActorRefs.Nobody);

// similar way Read from journal would be configured
}

static Config GetConfig()
=> ConfigurationFactory.FromResource<TestJournalSpec>("Akka.Persistence.TestKit.Tests.test-journal.conf");
}
=======
public TestJournalSpec(ITestOutputHelper output = null)
: base(GetConfig().ToString(), output)
{
}

[Fact]
public void must_return_ack_after_new_write_interceptor_is_set()
{
var journalActor = GetJournalRef(Sys);

journalActor.Tell(new TestJournal.UseWriteInterceptor(null), TestActor);

ExpectMsg<TestJournal.Ack>(TimeSpan.FromSeconds(3));
}

[Fact]
public void works_as_memory_journal_by_default()
{
var journal = TestJournal.FromRef(GetJournalRef(Sys));

var actor = Sys.ActorOf<PersistActor>();

// should pass
journal.OnWrite.Pass();
actor.Tell("write", TestActor);
ExpectMsg("ack", TimeSpan.FromSeconds(3));
}

[Fact]
public void when_fail_on_write_is_set_all_writes_to_journal_will_fail()
{
var journal = TestJournal.FromRef(GetJournalRef(Sys));
var actor = Sys.ActorOf<PersistActor>();
Watch(actor);

journal.OnWrite.Fail();
actor.Tell("write", TestActor);

ExpectTerminated(actor, TimeSpan.FromSeconds(3));
}

[Fact]
public void when_reject_on_write_is_set_all_writes_to_journal_will_be_rejected()
{
var journal = TestJournal.FromRef(GetJournalRef(Sys));
var actor = Sys.ActorOf<PersistActor>();
Watch(actor);

journal.OnWrite.Reject();
actor.Tell("write", TestActor);

ExpectMsg("rejected", TimeSpan.FromSeconds(3));
}

static IActorRef GetJournalRef(ActorSystem sys) => Persistence.Instance.Apply(sys).JournalFor(null);

static Config GetConfig()
=> ConfigurationFactory.FromResource<TestJournalSpec>("Akka.Persistence.TestKit.Tests.test-journal.conf");
}

public class PersistActor : UntypedPersistentActor
{
public override string PersistenceId => "foo";

protected override void OnCommand(object message)
{
var sender = Sender;
switch (message as string)
{
case "write":
Persist(message, _ =>
{
sender.Tell("ack");
});

break;

default:
return;
}
}

protected override void OnRecover(object message)
{
// noop
}

protected override void OnPersistRejected(Exception cause, object @event, long sequenceNr)
{
Sender.Tell("rejected");

base.OnPersistRejected(cause, @event, sequenceNr);
}
}
>>>>>>> d16f7c013... foo
}
13 changes: 13 additions & 0 deletions src/core/Akka.Persistence.TestKit.Tests/test-journal.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
akka {
persistence {
journal {
plugin = "akka.persistence.journal.test"
auto-start-journals = ["akka.persistence.journal.test"]

test {
class = "Akka.Persistence.TestKit.TestJournal, Akka.Persistence.TestKit"
plugin-dispatcher = "akka.actor.default-dispatcher"
}
}
}
}
25 changes: 25 additions & 0 deletions src/core/Akka.Persistence.TestKit/Akka.Persistence.TestKit.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />

<PropertyGroup>
<AssemblyTitle>Akka.Persistence.TestKit</AssemblyTitle>
<Description>TestKit for writing tests for Akka.NET Persistance module.</Description>
<TargetFrameworks>$(NetFrameworkLibVersion);$(NetStandardLibVersion)</TargetFrameworks>
<PackageTags>$(AkkaPackageTags);testkit;persistance</PackageTags>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.6' ">1.6.1</NetStandardImplicitPackageVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Akka.Persistence\Akka.Persistence.csproj" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<!-- WORKAROUND: for some reason starting at Akka.NET 1.3.2 this package was determined as "unpackable" by default via DOTNET CLI -->
<IsPackable>true</IsPackable>
</PropertyGroup>
</Project>
23 changes: 23 additions & 0 deletions src/core/Akka.Persistence.TestKit/Delay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Akka.Persistence.TestKit
{
using System;
using System.Threading.Tasks;

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

private readonly TimeSpan _delay;
private readonly IJournalWriteInterceptor _next;

public async Task InterceptAsync(IPersistentRepresentation message)
{
await Task.Delay(_delay);
await _next.InterceptAsync(message);
}
}
}
19 changes: 19 additions & 0 deletions src/core/Akka.Persistence.TestKit/Failure.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//-----------------------------------------------------------------------
// <copyright file="IJournalWriteBehavior.cs" company="Akka.NET Project">
// Copyright (C) 2009-2019 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2019 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

namespace Akka.Persistence.TestKit
{
using System.Threading.Tasks;
using Akka.Persistence;

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

public Task InterceptAsync(IPersistentRepresentation message) => throw new TestJournalWriteException();
}
}
9 changes: 9 additions & 0 deletions src/core/Akka.Persistence.TestKit/IJournalWriteInterceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Akka.Persistence.TestKit
{
using System.Threading.Tasks;

public interface IJournalWriteInterceptor
{
Task InterceptAsync(IPersistentRepresentation message);
}
}
Loading

0 comments on commit f640b69

Please sign in to comment.