diff --git a/build-system/README.md b/build-system/README.md
new file mode 100644
index 0000000..699c2d4
--- /dev/null
+++ b/build-system/README.md
@@ -0,0 +1,8 @@
+# Azure Pipelines Build Files
+These `.yaml` files are used by Windows Azure DevOps Pipelines to help execute the following types of builds:
+
+- Pull request validation on Linux (Mono / .NET Core)
+- Pull request validation on Windows (.NET Framework / .NET Core)
+- NuGet releases with automatic release notes posted to a Github Release repository.
+
+**NOTE**: you will need to change some of the pipeline variables inside the `windows-release.yaml` for your specific project and you will also want to create variable groups with your signing and NuGet push information.
\ No newline at end of file
diff --git a/build-system/azure-pipeline.template.yaml b/build-system/azure-pipeline.template.yaml
new file mode 100644
index 0000000..a3663c3
--- /dev/null
+++ b/build-system/azure-pipeline.template.yaml
@@ -0,0 +1,63 @@
+parameters:
+ name: ''
+ vmImage: ''
+ displayName: ''
+ artifactName: 'akkaBuild'
+ scriptFileName: ''
+ scriptArgs: 'all'
+ outputDirectory: ''
+ timeoutInMinutes: 120
+
+jobs:
+ - job: ${{ parameters.name }}
+ displayName: ${{ parameters.displayName }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+ pool:
+ vmImage: ${{ parameters.vmImage }}
+ steps:
+ - checkout: self # self represents the repo where the initial Pipelines YAML file was found
+ clean: false # whether to fetch clean each time
+ submodules: recursive # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
+ persistCredentials: true
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core Runtime 3.1.10'
+ inputs:
+ packageType: runtime
+ version: 3.1.10
+ # Linux or macOS
+ - task: Bash@3
+ displayName: Linux / OSX Build
+ inputs:
+ filePath: ${{ parameters.scriptFileName }}
+ arguments: ${{ parameters.scriptArgs }}
+ continueOnError: true
+ condition: in( variables['Agent.OS'], 'Linux', 'Darwin' )
+ # Windows test is disabled, could not use redis container in Azure Pipelines
+# - task: BatchScript@1
+# displayName: Windows Build
+# inputs:
+# filename: ${{ parameters.scriptFileName }}
+# arguments: ${{ parameters.scriptArgs }}
+# continueOnError: true
+# condition: eq( variables['Agent.OS'], 'Windows_NT' )
+ - task: PublishTestResults@2
+ inputs:
+ testRunner: VSTest
+ testResultsFiles: '**/*.trx' #TestResults folder usually
+ testRunTitle: ${{ parameters.name }}
+ mergeTestResults: true
+ - task: CopyFiles@2
+ displayName: 'Copy Build Output'
+ inputs:
+ sourceFolder: ${{ parameters.outputDirectory }}
+ contents: '**\*'
+ targetFolder: $(Build.ArtifactStagingDirectory)
+ continueOnError: boolean # 'true' if future steps should run even if this step fails; defaults to 'false'
+ - task: PublishBuildArtifacts@1
+ inputs:
+ pathtoPublish: '$(Build.ArtifactStagingDirectory)'
+ artifactName: ${{ parameters.artifactName }}
+ - script: 'echo 1>&2'
+ failOnStderr: true
+ displayName: 'If above is partially succeeded, then fail'
+ condition: eq(variables['Agent.JobStatus'], 'SucceededWithIssues')
\ No newline at end of file
diff --git a/build-system/pr-validation.yaml b/build-system/pr-validation.yaml
new file mode 100644
index 0000000..87e3618
--- /dev/null
+++ b/build-system/pr-validation.yaml
@@ -0,0 +1,34 @@
+# Pull request validation for Windows against the `dev` and `master` branches
+# See https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema for reference
+trigger:
+ branches:
+ include:
+ - dev
+ - master
+
+pr:
+ autoCancel: true # indicates whether additional pushes to a PR should cancel in-progress runs for the same PR. Defaults to true
+ branches:
+ include: [ dev, master ] # branch names which will trigger a build
+
+name: $(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
+
+jobs:
+ # Windows testing is disabled, Redis linux container can not run in windows docker.
+# - template: azure-pipeline.template.yaml
+# parameters:
+# name: 'windows_pr'
+# displayName: 'Windows PR Validation'
+# vmImage: 'windows-2019'
+# scriptFileName: build.cmd
+# scriptArgs: all
+
+ - template: azure-pipeline.template.yaml
+ parameters:
+ name: 'linux_pr'
+ displayName: 'Linux PR Validation'
+ vmImage: 'ubuntu-16.04'
+ scriptFileName: './build.sh'
+ scriptArgs: RunTestsNetCore
+ outputDirectory: 'TestResults'
+ artifactName: 'net_core_tests-$(Build.BuildId)'
\ No newline at end of file
diff --git a/build-system/windows-release.yaml b/build-system/windows-release.yaml
new file mode 100644
index 0000000..2c707cf
--- /dev/null
+++ b/build-system/windows-release.yaml
@@ -0,0 +1,43 @@
+# Release task for PbLib projects
+# See https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema for reference
+
+pool:
+ vmImage: vs2017-win2016
+ demands: Cmd
+
+trigger:
+ branches:
+ include:
+ - refs/tags/*
+pr: none
+
+variables:
+ - group: signingSecrets #create this group with SECRET variables `signingUsername` and `signingPassword`
+ - group: nugetKeys #create this group with SECRET variables `nugetKey`
+ - name: githubConnectionName
+ value: AkkaDotNet_Releases
+ - name: projectName
+ value: Akka.Persistence.PostgreSql
+ - name: githubRepositoryName
+ value: akkadotnet/Akka.Persistence.PostgreSql
+steps:
+- task: UseDotNet@2
+ displayName: 'Use .NET Core Runtime 3.1.10'
+ inputs:
+ packageType: runtime
+ version: 3.1.10
+- task: BatchScript@1
+ displayName: 'FAKE Build'
+ inputs:
+ filename: build.cmd
+ arguments: 'Nuget SignClientUser=$(signingUsername) SignClientSecret=$(signingPassword) nugetpublishurl=https://www.nuget.org/api/v2/package nugetkey=$(nugetKey)'
+
+- task: GitHubRelease@0
+ displayName: 'GitHub release (create)'
+ inputs:
+ gitHubConnection: $(githubConnectionName)
+ repositoryName: $(githubRepositoryName)
+ title: '$(projectName) v$(Build.SourceBranchName)'
+ releaseNotesFile: 'RELEASE_NOTES.md'
+ assets: |
+ bin\nuget\*.nupkg
diff --git a/build.fsx b/build.fsx
index da1bc70..49ccef6 100644
--- a/build.fsx
+++ b/build.fsx
@@ -7,44 +7,47 @@ open System.Text
open Fake
open Fake.DotNetCli
+open Fake.DocFxHelper
+open Fake.NuGet.Install
-//--------------------------------------------------------------------------------
-// Information about the project for Nuget and Assembly info files
-//--------------------------------------------------------------------------------
-
-let product = "Akka.NET"
-let authors = [ "Akka.NET Team" ]
-let copyright = "Copyright © 2013-2015 Akka.NET Team"
-let company = "Akka.NET Team"
-let description = "Akka.NET is a port of the popular Java/Scala framework Akka to .NET"
-let tags = ["akka";"actors";"actor";"model";"Akka";"concurrency"]
+// Variables
let configuration = "Release"
+let solution = System.IO.Path.GetFullPath(string "./src/Akka.Persistence.PostgreSql.sln")
-//--------------------------------------------------------------------------------
// Directories
-//--------------------------------------------------------------------------------
-
-let slnFile = __SOURCE_DIRECTORY__ @@ "src/Akka.Persistence.PostgreSql.sln"
+let toolsDir = __SOURCE_DIRECTORY__ @@ "tools"
let output = __SOURCE_DIRECTORY__ @@ "bin"
-let outputTests = output @@ "TestResults"
-let outputPerfTests = output @@ "perf"
+let outputTests = __SOURCE_DIRECTORY__ @@ "TestResults"
+let outputPerfTests = __SOURCE_DIRECTORY__ @@ "PerfResults"
let outputBinaries = output @@ "binaries"
let outputNuGet = output @@ "nuget"
-let outputBinariesNet45 = outputBinaries @@ "net45"
-let outputBinariesNetStandard = outputBinaries @@ "netstandard1.6"
+let outputBinariesNet47 = outputBinaries @@ "net471"
+let outputBinariesNetStandard = outputBinaries @@ "netstandard2.0"
// Read release notes and version
let buildNumber = environVarOrDefault "BUILD_NUMBER" "0"
-let preReleaseVersionSuffix = (if (not (buildNumber = "0")) then (buildNumber) else "") + "-beta"
-let versionSuffix =
- match (getBuildParam "nugetprerelease") with
- | "dev" -> preReleaseVersionSuffix
- | _ -> ""
+let preReleaseVersionSuffix = "beta" + (if (not (buildNumber = "0")) then (buildNumber) else DateTime.UtcNow.Ticks.ToString())
let releaseNotes =
- File.ReadLines "./RELEASE_NOTES.md"
+ File.ReadLines (__SOURCE_DIRECTORY__ @@ "RELEASE_NOTES.md")
|> ReleaseNotesHelper.parseReleaseNotes
+let versionFromReleaseNotes =
+ match releaseNotes.SemVer.PreRelease with
+ | Some r -> r.Origin
+ | None -> ""
+
+let versionSuffix =
+ match (getBuildParam "nugetprerelease") with
+ | "dev" -> preReleaseVersionSuffix
+ | "" -> versionFromReleaseNotes
+ | str -> str
+
+// Configuration values for tests
+let testNetFrameworkVersion = "net471"
+let testNetCoreVersion = "netcoreapp3.1"
+let testNetVersion = "net5.0"
+
printfn "Assembly version: %s\nNuget version; %s\n" releaseNotes.AssemblyVersion releaseNotes.NugetVersion
//--------------------------------------------------------------------------------
@@ -52,11 +55,17 @@ printfn "Assembly version: %s\nNuget version; %s\n" releaseNotes.AssemblyVersion
//--------------------------------------------------------------------------------
Target "Clean" (fun _ ->
+ ActivateFinalTarget "KillCreatedProcesses"
+
CleanDir output
CleanDir outputTests
CleanDir outputPerfTests
+ CleanDir outputBinaries
CleanDir outputNuGet
+ CleanDir outputBinariesNet47
+ CleanDir outputBinariesNetStandard
CleanDir "docs/_site"
+
CleanDirs !! "./**/bin"
CleanDirs !! "./**/obj"
)
@@ -69,8 +78,8 @@ Target "RestorePackages" (fun _ ->
DotNetCli.Restore
(fun p ->
{ p with
- Project = slnFile
- NoCache = false })
+ Project = solution
+ NoCache = true })
)
//--------------------------------------------------------------------------------
@@ -106,6 +115,22 @@ Target "Build" (fun _ ->
// Run tests
//--------------------------------------------------------------------------------
+type Runtime =
+ | NetCore
+ | Net
+ | NetFramework
+
+let getTestAssembly runtime project =
+ let assemblyPath = match runtime with
+ | NetCore -> !! ("src" @@ "**" @@ "bin" @@ "Release" @@ testNetCoreVersion @@ fileNameWithoutExt project + ".dll")
+ | NetFramework -> !! ("src" @@ "**" @@ "bin" @@ "Release" @@ testNetFrameworkVersion @@ fileNameWithoutExt project + ".dll")
+ | Net -> !! ("src" @@ "**" @@ "bin" @@ "Release" @@ testNetVersion @@ fileNameWithoutExt project + ".dll")
+
+ if Seq.isEmpty assemblyPath then
+ None
+ else
+ Some (assemblyPath |> Seq.head)
+
module internal ResultHandling =
let (|OK|Failure|) = function
| 0 -> OK
@@ -125,62 +150,55 @@ module internal ResultHandling =
>> Option.iter (failBuildWithMessage errorLevel)
Target "RunTests" <| fun _ ->
- let projects =
- match (isWindows) with
- | true -> !! "./src/**/*.Tests.csproj"
- | _ -> !! "./src/**/*.Tests.csproj" // if you need to filter specs for Linux vs. Windows, do it here
+ let projects =
+ match (isWindows) with
+ | true -> !! "./src/**/*.Tests.*sproj"
+ | _ -> !! "./src/**/*.Tests.*sproj" // if you need to filter specs for Linux vs. Windows, do it here
ensureDirectory outputTests
let runSingleProject project =
+ let arguments =
+ (sprintf "test -c Release --no-build --logger:trx --logger:\"console;verbosity=normal\" --framework %s --results-directory \"%s\" -- -parallel none" testNetFrameworkVersion outputTests)
+
let result = ExecProcess(fun info ->
info.FileName <- "dotnet"
info.WorkingDirectory <- (Directory.GetParent project).FullName
- info.Arguments <- (sprintf "xunit -f net452 -c Release -parallel none -teamcity -xml %s_net452_xunit.xml" (outputTests @@ fileNameWithoutExt project))) (TimeSpan.FromMinutes 30.)
-
- ResultHandling.failBuildIfXUnitReportedError TestRunnerErrorLevel.DontFailBuild result
+ info.Arguments <- arguments) (TimeSpan.FromMinutes 30.0)
- // dotnet process will be killed by ExecProcess (or throw if can't) '
- // but per https://github.com/xunit/xunit/issues/1338 xunit.console may not
- killProcess "xunit.console"
- killProcess "dotnet"
+ ResultHandling.failBuildIfXUnitReportedError TestRunnerErrorLevel.Error result
- projects |> Seq.iter (log)
+ CreateDir outputTests
projects |> Seq.iter (runSingleProject)
Target "RunTestsNetCore" <| fun _ ->
- let projects =
- match (isWindows) with
- | true -> !! "./src/**/*.Tests.csproj"
- | _ -> !! "./src/**/*.Tests.csproj" // if you need to filter specs for Linux vs. Windows, do it here
+ let projects =
+ match (isWindows) with
+ | true -> !! "./src/**/*.Tests.*sproj"
+ | _ -> !! "./src/**/*.Tests.*sproj" // if you need to filter specs for Linux vs. Windows, do it here
ensureDirectory outputTests
let runSingleProject project =
+ let arguments =
+ (sprintf "test -c Release --no-build --logger:trx --logger:\"console;verbosity=normal\" --framework %s --results-directory \"%s\" -- -parallel none" testNetCoreVersion outputTests)
+
let result = ExecProcess(fun info ->
info.FileName <- "dotnet"
info.WorkingDirectory <- (Directory.GetParent project).FullName
- info.Arguments <- (sprintf "xunit -f netcoreapp1.1 -c Release -parallel none -teamcity -xml %s_netcore_xunit.xml" (outputTests @@ fileNameWithoutExt project))) (TimeSpan.FromMinutes 30.)
-
- ResultHandling.failBuildIfXUnitReportedError TestRunnerErrorLevel.DontFailBuild result
+ info.Arguments <- arguments) (TimeSpan.FromMinutes 30.0)
- // dotnet process will be killed by ExecProcess (or throw if can't) '
- // but per https://github.com/xunit/xunit/issues/1338 xunit.console may not
- killProcess "xunit.console"
- killProcess "dotnet"
+ ResultHandling.failBuildIfXUnitReportedError TestRunnerErrorLevel.Error result
- projects |> Seq.iter (log)
+ CreateDir outputTests
projects |> Seq.iter (runSingleProject)
//--------------------------------------------------------------------------------
// Nuget targets
//--------------------------------------------------------------------------------
-let overrideVersionSuffix (project:string) =
- match project with
- | _ -> versionSuffix // add additional matches to publish different versions for different projects in solution
-
Target "CreateNuget" (fun _ ->
+ CreateDir outputNuGet // need this to stop Azure pipelines copy stage from error-ing out
let projects = !! "src/**/*.csproj"
-- "src/**/*Tests.csproj" // Don't publish unit tests
-- "src/**/*Tests*.csproj"
@@ -192,13 +210,14 @@ Target "CreateNuget" (fun _ ->
Project = project
Configuration = configuration
AdditionalArgs = ["--include-symbols"]
- VersionSuffix = overrideVersionSuffix project
- OutputPath = outputNuGet })
+ VersionSuffix = versionSuffix
+ OutputPath = "\"" + outputNuGet + "\"" })
projects |> Seq.iter (runSingleProject)
)
Target "PublishNuget" (fun _ ->
+
let projects = !! "./bin/nuget/*.nupkg" -- "./bin/nuget/*.symbols.nupkg"
let apiKey = getBuildParamOrDefault "nugetkey" ""
let source = getBuildParamOrDefault "nugetpublishurl" ""
@@ -225,6 +244,14 @@ Target "PublishNuget" (fun _ ->
projects |> Seq.iter (runSingleProject)
)
+FinalTarget "KillCreatedProcesses" (fun _ ->
+ log "Shutting down dotnet build-server"
+ let result = ExecProcess(fun info ->
+ info.FileName <- "dotnet"
+ info.WorkingDirectory <- __SOURCE_DIRECTORY__
+ info.Arguments <- "build-server shutdown") (System.TimeSpan.FromMinutes 2.0)
+ if result <> 0 then failwithf "dotnet build-server shutdown failed"
+)
//--------------------------------------------------------------------------------
// Help
@@ -328,22 +355,24 @@ Target "HelpDocs" <| fun _ ->
//--------------------------------------------------------------------------------
Target "BuildRelease" DoNothing
+Target "All" DoNothing
Target "Nuget" DoNothing
// build dependencies
-"Clean" ==> "AssemblyInfo" ==> "RestorePackages" ==> "Build" ==> "BuildRelease"
+"Clean" ==> "AssemblyInfo" ==> "Build"
+"Build" ==> "BuildRelease"
// test dependencies
-"RestorePackages" ==> "RunTests"
-"RestorePackages" ==> "RunTestsNetCore"
+"Build" ==> "RunTests"
+"Build" ==> "RunTestsNetCore"
// nuget dependencies
"BuildRelease" ==> "CreateNuget"
"CreateNuget" ==> "PublishNuget" ==> "Nuget"
-Target "All" DoNothing
"BuildRelease" ==> "All"
"RunTests" ==> "All"
+"RunTestsNetCore" ==> "All"
"Nuget" ==> "All"
RunTargetOrDefault "Help"
diff --git a/build.ps1 b/build.ps1
index 48cd53e..8e20528 100644
--- a/build.ps1
+++ b/build.ps1
@@ -31,9 +31,9 @@ Param(
$FakeVersion = "4.61.2"
$NBenchVersion = "1.0.1"
-$DotNetChannel = "preview";
-$DotNetVersion = "1.0.4";
-$DotNetInstallerUri = "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1";
+$DotNetChannel = "LTS";
+$DotNetVersion = "3.1.100";
+$DotNetInstallerUri = "https://dot.net/v1/dotnet-install.ps1";
$NugetVersion = "4.1.0";
$NugetUrl = "https://dist.nuget.org/win-x86-commandline/v$NugetVersion/nuget.exe"
$ProtobufVersion = "3.2.0"
diff --git a/build.sh b/build.sh
index 5e653dd..d53ef36 100644
--- a/build.sh
+++ b/build.sh
@@ -7,11 +7,13 @@
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TOOLS_DIR=$SCRIPT_DIR/tools
NUGET_EXE=$TOOLS_DIR/nuget.exe
-NUGET_URL=https://dist.nuget.org/win-x86-commandline/v4.0.0/nuget.exe
-FAKE_VERSION=4.61.2
+NUGET_URL=https://dist.nuget.org/win-x86-commandline/v5.8.0/nuget.exe
+FAKE_VERSION=4.63.0
FAKE_EXE=$TOOLS_DIR/FAKE/tools/FAKE.exe
-DOTNET_VERSION=1.0.4
-DOTNET_INSTALLER_URL=https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.sh
+DOTNET_EXE=$SCRIPT_DIR/.dotnet/dotnet
+DOTNETCORE_VERSION=3.1.105
+DOTNET_INSTALLER_URL=https://dot.net/v1/dotnet-install.sh
+DOTNET_CHANNEL=LTS
# Define default arguments.
TARGET="Default"
@@ -38,22 +40,6 @@ if [ ! -d "$TOOLS_DIR" ]; then
mkdir "$TOOLS_DIR"
fi
-###########################################################################
-# INSTALL .NET CORE CLI
-###########################################################################
-
-echo "Installing .NET CLI..."
-if [ ! -d "$SCRIPT_DIR/.dotnet" ]; then
- mkdir "$SCRIPT_DIR/.dotnet"
-fi
-curl -Lsfo "$SCRIPT_DIR/.dotnet/dotnet-install.sh" $DOTNET_INSTALLER_URL
-bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version $DOTNET_VERSION --install-dir .dotnet --no-path
-export PATH="$SCRIPT_DIR/.dotnet":$PATH
-export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
-export DOTNET_CLI_TELEMETRY_OPTOUT=1
-chmod -R 0755 ".dotnet"
-"$SCRIPT_DIR/.dotnet/dotnet" --info
-
###########################################################################
# INSTALL NUGET
###########################################################################
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Akka.Persistence.PostgreSql.Tests.csproj b/src/Akka.Persistence.PostgreSql.Tests/Akka.Persistence.PostgreSql.Tests.csproj
index 5655bf3..f67866a 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Akka.Persistence.PostgreSql.Tests.csproj
+++ b/src/Akka.Persistence.PostgreSql.Tests/Akka.Persistence.PostgreSql.Tests.csproj
@@ -2,30 +2,20 @@
- net452;netcoreapp1.1
+ $(NetFrameworkTestVersion);$(NetCoreTestVersion)
false
-
-
-
-
-
-
+
+
+
-
-
+
-
-
- Always
-
-
-
diff --git a/src/Akka.Persistence.PostgreSql.Tests/DbUtils.cs b/src/Akka.Persistence.PostgreSql.Tests/DbUtils.cs
index e72be35..56b7d07 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/DbUtils.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/DbUtils.cs
@@ -5,23 +5,18 @@
//
//-----------------------------------------------------------------------
-using Microsoft.Extensions.Configuration;
using Npgsql;
using System;
-using System.IO;
namespace Akka.Persistence.PostgreSql.Tests
{
public static class DbUtils
{
- public static IConfigurationRoot Config { get; private set; }
public static string ConnectionString { get; private set; }
- public static void Initialize()
+ public static void Initialize(PostgresFixture fixture)
{
- Config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
- .AddXmlFile("app.xml").Build();
- ConnectionString = Config.GetSection("connectionStrings:add:TestDb")["connectionString"];
+ ConnectionString = fixture.ConnectionString;
var connectionBuilder = new NpgsqlConnectionStringBuilder(ConnectionString);
//connect to postgres database to create a new database
@@ -36,7 +31,7 @@ public static void Initialize()
bool dbExists;
using (var cmd = new NpgsqlCommand())
{
- cmd.CommandText = string.Format(@"SELECT TRUE FROM pg_database WHERE datname='{0}'", databaseName);
+ cmd.CommandText = $@"SELECT TRUE FROM pg_database WHERE datname='{databaseName}'";
cmd.Connection = conn;
var result = cmd.ExecuteScalar();
@@ -56,8 +51,6 @@ public static void Initialize()
public static void Clean()
{
- var connectionBuilder = new NpgsqlConnectionStringBuilder(ConnectionString);
-
using (var conn = new NpgsqlConnection(ConnectionString))
{
conn.Open();
@@ -70,7 +63,7 @@ private static void DoCreate(NpgsqlConnection conn, string databaseName)
{
using (var cmd = new NpgsqlCommand())
{
- cmd.CommandText = string.Format(@"CREATE DATABASE {0}", databaseName);
+ cmd.CommandText = $@"CREATE DATABASE {databaseName}";
cmd.Connection = conn;
cmd.ExecuteNonQuery();
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlJournalJsonSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlJournalJsonSpec.cs
index 4ba96e9..4e17779 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlJournalJsonSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlJournalJsonSpec.cs
@@ -15,15 +15,13 @@ namespace Akka.Persistence.PostgreSql.Tests.Json
[Collection("PostgreSqlSpec")]
public class PostgreSqlJournalJsonSpec : JournalSpec
{
- private static readonly Config SpecConfig;
-
- static PostgreSqlJournalJsonSpec()
+ private static Config Initialize(PostgresFixture fixture)
{
//need to make sure db is created before the tests start
- DbUtils.Initialize();
+ DbUtils.Initialize(fixture);
- var config = @"
- akka.persistence {
+ return ConfigurationFactory.ParseString(@"
+ akka.persistence {
publish-plugin-commands = on
journal {
plugin = ""akka.persistence.journal.postgresql""
@@ -37,13 +35,14 @@ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistenc
stored-as = ""jsonb""
}
}
- }";
-
- SpecConfig = ConfigurationFactory.ParseString(config);
+ }");
}
- public PostgreSqlJournalJsonSpec(ITestOutputHelper output)
- : base(SpecConfig, "PostgreSqlJournalJsonSpec", output: output)
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ protected override bool SupportsSerialization => false;
+
+ public PostgreSqlJournalJsonSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), "PostgreSqlJournalJsonSpec", output: output)
{
Initialize();
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlSnapshotStoreJsonSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlSnapshotStoreJsonSpec.cs
index 265eab1..ab8f9a1 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlSnapshotStoreJsonSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/Json/PostgreSqlSnapshotStoreJsonSpec.cs
@@ -15,15 +15,13 @@ namespace Akka.Persistence.PostgreSql.Tests.Json
[Collection("PostgreSqlSpec")]
public class PostgreSqlSnapshotStoreJsonSpec : SnapshotStoreSpec
{
- private static readonly Config SpecConfig;
-
- static PostgreSqlSnapshotStoreJsonSpec()
+ private static Config Initialize(PostgresFixture fixture)
{
//need to make sure db is created before the tests start
- DbUtils.Initialize();
+ DbUtils.Initialize(fixture);
- var config = @"
- akka.persistence {
+ return ConfigurationFactory.ParseString(@"
+ akka.persistence {
publish-plugin-commands = on
snapshot-store {
plugin = ""akka.persistence.snapshot-store.postgresql""
@@ -37,17 +35,19 @@ class = ""Akka.Persistence.PostgreSql.Snapshot.PostgreSqlSnapshotStore, Akka.Per
stored-as = ""JSONB""
}
}
- }";
-
- SpecConfig = ConfigurationFactory.ParseString(config);
+ }");
}
- public PostgreSqlSnapshotStoreJsonSpec(ITestOutputHelper output)
- : base(SpecConfig, "PostgreSqlSnapshotStoreJsonSpec", output: output)
+
+ public PostgreSqlSnapshotStoreJsonSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), "PostgreSqlSnapshotStoreJsonSpec", output: output)
{
Initialize();
}
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ protected override bool SupportsSerialization => false;
+
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Performance/PostgreSqlJournalPerfSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Performance/PostgreSqlJournalPerfSpec.cs
new file mode 100644
index 0000000..5305561
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Performance/PostgreSqlJournalPerfSpec.cs
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2021 Lightbend Inc.
+// Copyright (C) 2013-2021 .NET Foundation
+//
+//-----------------------------------------------------------------------
+
+using System;
+using Akka.Configuration;
+using Akka.Persistence.TestKit.Performance;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Performance
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlJournalPerfSpec : JournalPerfSpec
+ {
+ public PostgreSqlJournalPerfSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(CreateSpecConfig(fixture), "PostgreSqlJournalPerfSpec", output)
+ {
+ EventsCount = 5 * 1000;
+ ExpectDuration = TimeSpan.FromSeconds(60);
+ }
+
+ private static Config CreateSpecConfig(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString(@"
+ akka.loglevel = INFO
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ auto-initialize = on
+ connection-string = """ + DbUtils.ConnectionString + @"""
+ }
+ akka.test.single-expect-default = 3s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalConnectionFailureSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalConnectionFailureSpec.cs
new file mode 100644
index 0000000..5cf7389
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalConnectionFailureSpec.cs
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Sql.TestKit;
+using Akka.Persistence.TCK.Journal;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlJournalConnectionFailureSpec : SqlJournalConnectionFailureSpec
+ {
+ private static Config Initialize(PostgresFixture fixture, string connectionString)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ var config = @"
+ akka.persistence {
+ publish-plugin-commands = on
+ journal {
+ plugin = ""akka.persistence.journal.postgresql""
+ postgresql {
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ schema-name = public
+ auto-initialize = on
+ connection-string = """ + connectionString + @"""
+ }
+ }
+ }";
+
+ return ConfigurationFactory.ParseString(config);
+ }
+
+ public PostgreSqlJournalConnectionFailureSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture, DefaultInvalidConnectionString), output: output)
+ {
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalSpec.cs
index 4af6baf..bb87fa0 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlJournalSpec.cs
@@ -15,12 +15,10 @@ namespace Akka.Persistence.PostgreSql.Tests
[Collection("PostgreSqlSpec")]
public class PostgreSqlJournalSpec : JournalSpec
{
- private static readonly Config SpecConfig;
-
- static PostgreSqlJournalSpec()
+ private static Config Initialize(PostgresFixture fixture)
{
//need to make sure db is created before the tests start
- DbUtils.Initialize();
+ DbUtils.Initialize(fixture);
var config = @"
akka.persistence {
@@ -38,11 +36,14 @@ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistenc
}
}";
- SpecConfig = ConfigurationFactory.ParseString(config);
+ return ConfigurationFactory.ParseString(config);
}
- public PostgreSqlJournalSpec(ITestOutputHelper output)
- : base(SpecConfig, "PostgreSqlJournalSpec", output: output)
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ protected override bool SupportsSerialization => false;
+
+ public PostgreSqlJournalSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), "PostgreSqlJournalSpec", output: output)
{
Initialize();
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreConnectionFailureSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreConnectionFailureSpec.cs
new file mode 100644
index 0000000..9d991dd
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreConnectionFailureSpec.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Snapshot;
+using Akka.Persistence.Sql.TestKit;
+using Akka.Persistence.TCK.Snapshot;
+using Akka.TestKit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlSnapshotStoreConnectionFailureSpec : SqlSnapshotConnectionFailureSpec
+ {
+ private static Config Initialize(PostgresFixture fixture, string connectionString)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ var config = @"
+ akka.persistence {
+ publish-plugin-commands = on
+ snapshot-store {
+ plugin = ""akka.persistence.snapshot-store.postgresql""
+ postgresql {
+ class = ""Akka.Persistence.PostgreSql.Snapshot.PostgreSqlSnapshotStore, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = snapshot_store
+ schema-name = public
+ auto-initialize = on
+ connection-string = """ + connectionString + @"""
+ }
+ }
+ }";
+
+ return ConfigurationFactory.ParseString(config);
+ }
+
+ public PostgreSqlSnapshotStoreConnectionFailureSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture, DefaultInvalidConnectionString), output: output)
+ {
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreSpec.cs
index 29306aa..93486ec 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/PostgreSqlSnapshotStoreSpec.cs
@@ -16,12 +16,10 @@ namespace Akka.Persistence.PostgreSql.Tests
[Collection("PostgreSqlSpec")]
public class PostgreSqlSnapshotStoreSpec : SnapshotStoreSpec
{
- private static readonly Config SpecConfig;
-
- static PostgreSqlSnapshotStoreSpec()
+ private static Config Initialize(PostgresFixture fixture)
{
//need to make sure db is created before the tests start
- DbUtils.Initialize();
+ DbUtils.Initialize(fixture);
var config = @"
akka.persistence {
@@ -39,11 +37,11 @@ class = ""Akka.Persistence.PostgreSql.Snapshot.PostgreSqlSnapshotStore, Akka.Per
}
}";
- SpecConfig = ConfigurationFactory.ParseString(config);
+ return ConfigurationFactory.ParseString(config);
}
- public PostgreSqlSnapshotStoreSpec(ITestOutputHelper output)
- : base(SpecConfig, "PostgreSqlSnapshotStoreSpec", output: output)
+ public PostgreSqlSnapshotStoreSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), "PostgreSqlSnapshotStoreSpec", output: output)
{
Initialize();
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/PostgresFixture.cs b/src/Akka.Persistence.PostgreSql.Tests/PostgresFixture.cs
new file mode 100644
index 0000000..48158ec
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/PostgresFixture.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Akka.Util;
+using Docker.DotNet;
+using Docker.DotNet.Models;
+using Xunit;
+
+namespace Akka.Persistence.PostgreSql.Tests
+{
+ [CollectionDefinition("PostgreSqlSpec")]
+ public sealed class PostgresSpecsFixture : ICollectionFixture
+ {
+ }
+
+ ///
+ /// Fixture used to run PostgresSQL Server
+ ///
+ public class PostgresFixture : IAsyncLifetime
+ {
+ protected readonly string PostgresContainerName = $"postgresSqlServer-{Guid.NewGuid():N}";
+ protected DockerClient Client;
+
+ public PostgresFixture()
+ {
+ DockerClientConfiguration config;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ config = new DockerClientConfiguration(new Uri("unix://var/run/docker.sock"));
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ config = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"));
+ else
+ throw new NotSupportedException($"Unsupported OS [{RuntimeInformation.OSDescription}]");
+
+ Client = config.CreateClient();
+ }
+
+ protected string ImageName => "postgres";
+ protected string Tag => "latest";
+
+ protected string PostgresImageName => $"{ImageName}:{Tag}";
+
+ public string ConnectionString { get; private set; }
+
+ public async Task InitializeAsync()
+ {
+ var images = await Client.Images.ListImagesAsync(new ImagesListParameters
+ {
+ Filters = new Dictionary>
+ {
+ {
+ "reference",
+ new Dictionary
+ {
+ {PostgresImageName, true}
+ }
+ }
+ }
+ });
+
+ if (images.Count == 0)
+ await Client.Images.CreateImageAsync(
+ new ImagesCreateParameters { FromImage = ImageName, Tag = Tag }, null,
+ new Progress(message =>
+ {
+ Console.WriteLine(!string.IsNullOrEmpty(message.ErrorMessage)
+ ? message.ErrorMessage
+ : $"{message.ID} {message.Status} {message.ProgressMessage}");
+ }));
+
+ var sqlServerHostPort = ThreadLocalRandom.Current.Next(9000, 10000);
+
+ // create the container
+ await Client.Containers.CreateContainerAsync(new CreateContainerParameters
+ {
+ Image = PostgresImageName,
+ Name = PostgresContainerName,
+ Tty = true,
+ ExposedPorts = new Dictionary
+ {
+ {"5432/tcp", new EmptyStruct()}
+ },
+ HostConfig = new HostConfig
+ {
+ PortBindings = new Dictionary>
+ {
+ {
+ "5432/tcp",
+ new List
+ {
+ new PortBinding
+ {
+ HostPort = $"{sqlServerHostPort}"
+ }
+ }
+ }
+ }
+ },
+ Env = new[]
+ {
+ "POSTGRES_PASSWORD=postgres",
+ "POSTGRES_USER=postgres"
+ }
+ });
+
+ // start the container
+ await Client.Containers.StartContainerAsync(PostgresContainerName, new ContainerStartParameters());
+
+ // Provide a 10 second startup delay
+ await Task.Delay(TimeSpan.FromSeconds(10));
+
+ ConnectionString = $"Server=127.0.0.1;Port={sqlServerHostPort};" +
+ "Database=postgres;User Id=postgres;Password=postgres";
+ }
+
+ public async Task DisposeAsync()
+ {
+ if (Client != null)
+ {
+ await Client.Containers.StopContainerAsync(PostgresContainerName, new ContainerStopParameters());
+ await Client.Containers.RemoveContainerAsync(PostgresContainerName,
+ new ContainerRemoveParameters { Force = true });
+ Client.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllEventsSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllEventsSpec.cs
new file mode 100644
index 0000000..ef6b2e1
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllEventsSpec.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Query;
+using Akka.Persistence.Query.Sql;
+using Akka.Persistence.TCK.Query;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Query
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlAllEventsSpec : AllEventsSpec
+ {
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
+ akka.test.single-expect-default = 10s
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {{
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ auto-initialize = on
+ connection-string = ""{DbUtils.ConnectionString}""
+ refresh-interval = 1s
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ public PostgreSqlAllEventsSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlAllEventsSpec), output)
+ {
+ ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentAllEventsSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentAllEventsSpec.cs
new file mode 100644
index 0000000..a7c7102
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentAllEventsSpec.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Query;
+using Akka.Persistence.Query.Sql;
+using Akka.Persistence.TCK.Query;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Query
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlCurrentAllEventsSpec : AllEventsSpec
+ {
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
+ akka.test.single-expect-default = 10s
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {{
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ auto-initialize = on
+ connection-string = ""{DbUtils.ConnectionString}""
+ refresh-interval = 1s
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ public PostgreSqlCurrentAllEventsSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlCurrentAllEventsSpec), output)
+ {
+ ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllPersistenceIdsSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByPersistenceIdSpec.cs
similarity index 61%
rename from src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllPersistenceIdsSpec.cs
rename to src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByPersistenceIdSpec.cs
index cb87f05..b635fe4 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlAllPersistenceIdsSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByPersistenceIdSpec.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-//
+//
// Copyright (C) 2009-2016 Lightbend Inc.
// Copyright (C) 2013-2016 Akka.NET project
//
@@ -15,11 +15,15 @@
namespace Akka.Persistence.PostgreSql.Tests.Query
{
[Collection("PostgreSqlSpec")]
- public class PostgreSqlAllPersistenceIdsSpec : PersistenceIdsSpec
+ public class PostgreSqlCurrentEventsByPersistenceIdSpec : CurrentEventsByPersistenceIdSpec
{
- public static Config SpecConfig => ConfigurationFactory.ParseString($@"
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
akka.loglevel = INFO
- akka.test.single-expect-default = 10s
akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
akka.persistence.journal.postgresql {{
class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
@@ -28,15 +32,15 @@ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistenc
auto-initialize = on
connection-string = """ + DbUtils.ConnectionString + @"""
refresh-interval = 1s
- }}")
- .WithFallback(SqlReadJournal.DefaultConfiguration());
-
- static PostgreSqlAllPersistenceIdsSpec()
- {
- DbUtils.Initialize();
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
}
- public PostgreSqlAllPersistenceIdsSpec(ITestOutputHelper output) : base(SpecConfig, nameof(PostgreSqlAllPersistenceIdsSpec), output)
+ public PostgreSqlCurrentEventsByPersistenceIdSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlCurrentEventsByPersistenceIdSpec), output)
{
ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByTagSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByTagSpec.cs
new file mode 100644
index 0000000..ddede9e
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentEventsByTagSpec.cs
@@ -0,0 +1,63 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Journal;
+using Akka.Persistence.Query;
+using Akka.Persistence.Query.Sql;
+using Akka.Persistence.TCK.Query;
+using System.Collections.Immutable;
+using System.Linq;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Query
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlCurrentEventsByTagSpec : CurrentEventsByTagSpec
+ {
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {{
+ event-adapters {{
+ color-tagger = ""Akka.Persistence.TCK.Query.ColorFruitTagger, Akka.Persistence.TCK""
+ }}
+ event-adapter-bindings = {{
+ ""System.String"" = color-tagger
+ }}
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ auto-initialize = on
+ connection-string = """ + DbUtils.ConnectionString + @"""
+ refresh-interval = 1s
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ public PostgreSqlCurrentEventsByTagSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlCurrentEventsByTagSpec), output)
+ {
+ ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentPersistenceIdsSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentPersistenceIdsSpec.cs
new file mode 100644
index 0000000..7884a9e
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlCurrentPersistenceIdsSpec.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Query;
+using Akka.Persistence.Query.Sql;
+using Akka.Persistence.TCK.Query;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Query
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlCurrentPersistenceIdsSpec : CurrentPersistenceIdsSpec
+ {
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
+ akka.test.single-expect-default = 10s
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {{
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ auto-initialize = on
+ connection-string = ""{DbUtils.ConnectionString}""
+ refresh-interval = 1s
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ public PostgreSqlCurrentPersistenceIdsSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlCurrentPersistenceIdsSpec), output)
+ {
+ ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByPersistenceIdSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByPersistenceIdSpec.cs
index 9ed38be..ed58d4d 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByPersistenceIdSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByPersistenceIdSpec.cs
@@ -17,7 +17,12 @@ namespace Akka.Persistence.PostgreSql.Tests.Query
[Collection("PostgreSqlSpec")]
public class PostgreSqlEventsByPersistenceIdSpec : EventsByPersistenceIdSpec
{
- public static Config SpecConfig => ConfigurationFactory.ParseString($@"
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
akka.loglevel = INFO
akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
akka.persistence.journal.postgresql {{
@@ -28,14 +33,14 @@ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistenc
connection-string = """ + DbUtils.ConnectionString + @"""
refresh-interval = 1s
}}
- akka.test.single-expect-default = 10s");
-
- static PostgreSqlEventsByPersistenceIdSpec()
- {
- DbUtils.Initialize();
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
}
- public PostgreSqlEventsByPersistenceIdSpec(ITestOutputHelper output) : base(SpecConfig, nameof(PostgreSqlEventsByPersistenceIdSpec), output)
+ public PostgreSqlEventsByPersistenceIdSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlEventsByPersistenceIdSpec), output)
{
ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByTagSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByTagSpec.cs
index 65f963a..2750409 100644
--- a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByTagSpec.cs
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlEventsByTagSpec.cs
@@ -6,12 +6,9 @@
//-----------------------------------------------------------------------
using Akka.Configuration;
-using Akka.Persistence.Journal;
using Akka.Persistence.Query;
using Akka.Persistence.Query.Sql;
using Akka.Persistence.TCK.Query;
-using System.Collections.Immutable;
-using System.Linq;
using Xunit;
using Xunit.Abstractions;
@@ -20,12 +17,17 @@ namespace Akka.Persistence.PostgreSql.Tests.Query
[Collection("PostgreSqlSpec")]
public class PostgreSqlEventsByTagSpec : EventsByTagSpec
{
- public static Config SpecConfig => ConfigurationFactory.ParseString($@"
- akka.loglevel = DEBUG
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
akka.persistence.journal.postgresql {{
event-adapters {{
- color-tagger = ""Akka.Persistence.PostgreSql.Tests.Query.ColorTagger, Akka.Persistence.PostgreSql.Tests""
+ color-tagger = ""Akka.Persistence.TCK.Query.ColorFruitTagger, Akka.Persistence.TCK""
}}
event-adapter-bindings = {{
""System.String"" = color-tagger
@@ -37,15 +39,15 @@ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistenc
connection-string = """ + DbUtils.ConnectionString + @"""
refresh-interval = 1s
}}
- akka.test.single-expect-default = 10s");
-
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
- static PostgreSqlEventsByTagSpec()
- {
- DbUtils.Initialize();
}
- public PostgreSqlEventsByTagSpec(ITestOutputHelper output) : base(SpecConfig, nameof(PostgreSqlEventsByTagSpec), output)
+ public PostgreSqlEventsByTagSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlEventsByTagSpec), output)
{
ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
}
@@ -56,24 +58,4 @@ protected override void Dispose(bool disposing)
DbUtils.Clean();
}
}
-
- // This ColorTagger class was previously in Akka.Persistence.Sql.TestKit but has gone
- public class ColorTagger : IWriteEventAdapter
- {
- public static readonly IImmutableSet Colors = ImmutableHashSet.CreateRange(new[] { "green", "black", "blue" });
- public string Manifest(object evt) => string.Empty;
-
- public object ToJournal(object evt)
- {
- var s = evt as string;
- if (s != null)
- {
- var tags = Colors.Aggregate(ImmutableHashSet.Empty, (acc, color) => s.Contains(color) ? acc.Add(color) : acc);
- return tags.IsEmpty
- ? evt
- : new Tagged(evt, tags);
- }
- else return evt;
- }
- }
}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlPersistenceIdsSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlPersistenceIdsSpec.cs
new file mode 100644
index 0000000..e2ddb1d
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Query/PostgreSqlPersistenceIdsSpec.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2016 Lightbend Inc.
+// Copyright (C) 2013-2016 Akka.NET project
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.Query;
+using Akka.Persistence.Query.Sql;
+using Akka.Persistence.TCK.Query;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Query
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlPersistenceIdsSpec : PersistenceIdsSpec
+ {
+ private static Config Initialize(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString($@"
+ akka.loglevel = INFO
+ akka.test.single-expect-default = 10s
+ akka.persistence.journal.plugin = ""akka.persistence.journal.postgresql""
+ akka.persistence.journal.postgresql {{
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ auto-initialize = on
+ connection-string = ""{DbUtils.ConnectionString}""
+ refresh-interval = 1s
+ }}
+ akka.test.single-expect-default = 15s")
+ .WithFallback(PostgreSqlPersistence.DefaultConfiguration())
+ .WithFallback(SqlReadJournal.DefaultConfiguration())
+ .WithFallback(Persistence.DefaultConfig());
+ }
+
+ public PostgreSqlPersistenceIdsSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(Initialize(fixture), nameof(PostgreSqlPersistenceIdsSpec), output)
+ {
+ ReadJournal = Sys.ReadJournalFor(SqlReadJournal.Identifier);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ DbUtils.Clean();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlJournalSerializationSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlJournalSerializationSpec.cs
new file mode 100644
index 0000000..1742f22
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlJournalSerializationSpec.cs
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2021 Lightbend Inc.
+// Copyright (C) 2013-2021 .NET Foundation
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.TCK.Serialization;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Serialization
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlJournalSerializationSpec : JournalSerializationSpec
+ {
+ public PostgreSqlJournalSerializationSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(CreateSpecConfig(fixture), "PostgreSqlJournalSerializationSpec", output)
+ {
+ }
+
+ private static Config CreateSpecConfig(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString(@"
+ akka.persistence {
+ publish-plugin-commands = on
+ journal {
+ plugin = ""akka.persistence.journal.postgresql""
+ postgresql {
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ schema-name = public
+ auto-initialize = on
+ connection-string = """ + DbUtils.ConnectionString + @"""
+ }
+ }
+ }");
+ }
+
+ [Fact(Skip = "Sql plugin does not support EventAdapter.Manifest")]
+ public override void Journal_should_serialize_Persistent_with_EventAdapter_manifest()
+ {
+ }
+ }
+}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlSnapshotStoreSerializationSpec.cs b/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlSnapshotStoreSerializationSpec.cs
new file mode 100644
index 0000000..c69deb8
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/Serialization/PostgreSqlSnapshotStoreSerializationSpec.cs
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2021 Lightbend Inc.
+// Copyright (C) 2013-2021 .NET Foundation
+//
+//-----------------------------------------------------------------------
+
+using Akka.Configuration;
+using Akka.Persistence.TCK.Serialization;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Akka.Persistence.PostgreSql.Tests.Serialization
+{
+ [Collection("PostgreSqlSpec")]
+ public class PostgreSqlSnapshotStoreSerializationSpec : SnapshotStoreSerializationSpec
+ {
+ public PostgreSqlSnapshotStoreSerializationSpec(ITestOutputHelper output, PostgresFixture fixture)
+ : base(CreateSpecConfig(fixture), "PostgreSqlSnapshotStoreSerializationSpec", output)
+ {
+ }
+
+ private static Config CreateSpecConfig(PostgresFixture fixture)
+ {
+ //need to make sure db is created before the tests start
+ DbUtils.Initialize(fixture);
+
+ return ConfigurationFactory.ParseString(@"
+ akka.persistence {
+ publish-plugin-commands = on
+ journal {
+ plugin = ""akka.persistence.journal.postgresql""
+ postgresql {
+ class = ""Akka.Persistence.PostgreSql.Journal.PostgreSqlJournal, Akka.Persistence.PostgreSql""
+ plugin-dispatcher = ""akka.actor.default-dispatcher""
+ table-name = event_journal
+ schema-name = public
+ auto-initialize = on
+ connection-string = """ + DbUtils.ConnectionString + @"""
+ }
+ }
+ }");
+ }
+ }
+}
diff --git a/src/Akka.Persistence.PostgreSql.Tests/app.xml b/src/Akka.Persistence.PostgreSql.Tests/app.xml
deleted file mode 100644
index c7c3fdf..0000000
--- a/src/Akka.Persistence.PostgreSql.Tests/app.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql.Tests/xunit.runner.json b/src/Akka.Persistence.PostgreSql.Tests/xunit.runner.json
new file mode 100644
index 0000000..4a73b1e
--- /dev/null
+++ b/src/Akka.Persistence.PostgreSql.Tests/xunit.runner.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://xunit.github.io/schema/current/xunit.runner.schema.json",
+ "longRunningTestSeconds": 60,
+ "parallelizeAssembly": false,
+ "parallelizeTestCollections": false
+}
\ No newline at end of file
diff --git a/src/Akka.Persistence.PostgreSql/Akka.Persistence.PostgreSql.csproj b/src/Akka.Persistence.PostgreSql/Akka.Persistence.PostgreSql.csproj
index f24b62a..ad093d7 100644
--- a/src/Akka.Persistence.PostgreSql/Akka.Persistence.PostgreSql.csproj
+++ b/src/Akka.Persistence.PostgreSql/Akka.Persistence.PostgreSql.csproj
@@ -4,9 +4,8 @@
Akka.Persistence.PostgreSql
Akka Persistence journal and snapshot store backed by PostgreSql database.
- net45;netstandard1.6
+ $(NetStandardLibVersion)
true
- 1.6.1
@@ -20,8 +19,8 @@
-
-
+
+
diff --git a/src/Akka.Persistence.PostgreSql/Journal/PostgreSqlQueryExecutor.cs b/src/Akka.Persistence.PostgreSql/Journal/PostgreSqlQueryExecutor.cs
index dd030fc..ad2a14e 100644
--- a/src/Akka.Persistence.PostgreSql/Journal/PostgreSqlQueryExecutor.cs
+++ b/src/Akka.Persistence.PostgreSql/Journal/PostgreSqlQueryExecutor.cs
@@ -17,6 +17,7 @@
using System.Data;
using System.Data.Common;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
namespace Akka.Persistence.PostgreSql.Journal
@@ -60,20 +61,28 @@ public PostgreSqlQueryExecutor(PostgreSqlQueryConfiguration configuration, Akka.
case StoredAsType.ByteA:
_serialize = e =>
{
- var serializer = Serialization.FindSerializerFor(e.Payload);
- return new SerializationResult(NpgsqlDbType.Bytea, serializer.ToBinary(e.Payload), serializer);
+ var payloadType = e.Payload.GetType();
+ var serializer = Serialization.FindSerializerForType(payloadType, Configuration.DefaultSerializer);
+
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ var binary = Akka.Serialization.Serialization.WithTransport(Serialization.System, () => serializer.ToBinary(e.Payload));
+
+ return new SerializationResult(NpgsqlDbType.Bytea, binary, serializer);
};
- _deserialize = (type, serialized, manifest, serializerId) =>
+ _deserialize = (type, payload, manifest, serializerId) =>
{
if (serializerId.HasValue)
{
- return Serialization.Deserialize((byte[])serialized, serializerId.Value, manifest);
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ return Serialization.Deserialize((byte[])payload, serializerId.Value, manifest);
}
else
{
// Support old writes that did not set the serializer id
var deserializer = Serialization.FindSerializerForType(type, Configuration.DefaultSerializer);
- return deserializer.FromBinary((byte[])serialized, type);
+
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ return Akka.Serialization.Serialization.WithTransport(Serialization.System, () => deserializer.FromBinary((byte[])payload, type));
}
};
break;
@@ -110,7 +119,7 @@ protected override void WriteEvent(DbCommand command, IPersistentRepresentation
AddParameter(command, "@PersistenceId", DbType.String, e.PersistenceId);
AddParameter(command, "@SequenceNr", DbType.Int64, e.SequenceNr);
- AddParameter(command, "@Timestamp", DbType.Int64, TimestampProvider.GenerateTimestamp(e));
+ AddParameter(command, "@Timestamp", DbType.Int64, e.Timestamp);
AddParameter(command, "@IsDeleted", DbType.Boolean, false);
AddParameter(command, "@Manifest", DbType.String, manifest);
@@ -125,6 +134,15 @@ protected override void WriteEvent(DbCommand command, IPersistentRepresentation
command.Parameters.Add(new NpgsqlParameter("@Payload", serializationResult.DbType) { Value = serializationResult.Payload });
+ if (serializer != null)
+ {
+ AddParameter(command, "@SerializerId", DbType.Int32, serializer.Identifier);
+ }
+ else
+ {
+ AddParameter(command, "@SerializerId", DbType.Int32, DBNull.Value);
+ }
+
if (tags.Count != 0)
{
var tagBuilder = new StringBuilder(";", tags.Sum(x => x.Length) + tags.Count + 1);
@@ -138,17 +156,15 @@ protected override void WriteEvent(DbCommand command, IPersistentRepresentation
else AddParameter(command, "@Tag", DbType.String, DBNull.Value);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static string QualifiedName(IPersistentRepresentation e)
- {
- var type = e.Payload.GetType();
- return type.TypeQualifiedName();
- }
+ => e.Payload.GetType().TypeQualifiedName();
protected override IPersistentRepresentation ReadEvent(DbDataReader reader)
{
var persistenceId = reader.GetString(PersistenceIdIndex);
var sequenceNr = reader.GetInt64(SequenceNrIndex);
- //var timestamp = reader.GetDateTime(TimestampIndex);
+ var timestamp = reader.GetInt64(TimestampIndex);
var isDeleted = reader.GetBoolean(IsDeletedIndex);
var manifest = reader.GetString(ManifestIndex);
var raw = reader[PayloadIndex];
@@ -166,7 +182,7 @@ protected override IPersistentRepresentation ReadEvent(DbDataReader reader)
var deserialized = _deserialize(type, raw, manifest, serializerId);
- return new Persistent(deserialized, sequenceNr, persistenceId, manifest, isDeleted, ActorRefs.NoSender, null);
+ return new Persistent(deserialized, sequenceNr, persistenceId, manifest, isDeleted, ActorRefs.NoSender, null, timestamp);
}
}
diff --git a/src/Akka.Persistence.PostgreSql/Snapshot/PostgreSqlQueryExecutor.cs b/src/Akka.Persistence.PostgreSql/Snapshot/PostgreSqlQueryExecutor.cs
index 3ed4ad9..c0c4018 100644
--- a/src/Akka.Persistence.PostgreSql/Snapshot/PostgreSqlQueryExecutor.cs
+++ b/src/Akka.Persistence.PostgreSql/Snapshot/PostgreSqlQueryExecutor.cs
@@ -68,7 +68,10 @@ WITH upsert AS (
_serialize = ss =>
{
var serializer = Serialization.FindSerializerFor(ss);
- return new SerializationResult(NpgsqlDbType.Bytea, serializer.ToBinary(ss), serializer);
+ // TODO: hack. Replace when https://github.com/akkadotnet/akka.net/issues/3811
+ var binary = Akka.Serialization.Serialization
+ .WithTransport(Serialization.System, () => serializer.ToBinary(ss));
+ return new SerializationResult(NpgsqlDbType.Bytea, binary, serializer);
};
_deserialize = (type, serialized, manifest, serializerId) =>
{
@@ -116,10 +119,10 @@ protected override void SetManifestParameters(object snapshot, DbCommand command
var snapshotType = snapshot.GetType();
var serializer = Serialization.FindSerializerForType(snapshotType, Configuration.DefaultSerializer);
- string manifest = "";
- if (serializer is SerializerWithStringManifest)
+ var manifest = "";
+ if (serializer is SerializerWithStringManifest stringManifest)
{
- manifest = ((SerializerWithStringManifest)serializer).Manifest(snapshot);
+ manifest = stringManifest.Manifest(snapshot);
}
else if (!serializer.IncludeManifest)
{
diff --git a/src/common.props b/src/common.props
index d7d3c88..6b8707f 100644
--- a/src/common.props
+++ b/src/common.props
@@ -12,21 +12,16 @@
$(NoWarn);CS1591
- 2.3.1
+ 2.4.1
+ 2.4.3
+ 1.4.16
+ 5.0.3
+ netstandard2.0
+ net45
+ 16.8.3
+ netcoreapp3.1
+ net471
-
-
-
-
-
- 4.3.0
-
-
-
-
- 4.3.0
-
-
Upgraded for Akka.NET v1.3.9.
Other Fixes and Improvements**