diff --git a/appveyor.yml b/appveyor.yml
index 5be803477..b80b67225 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,6 +15,7 @@ version: 2.0.0-preview7.{build}
services:
- mongodb
+ - postgresql101
init:
- cmd: git config --global core.autocrlf true
@@ -89,6 +90,16 @@ build_script:
dotnet build
+before_test:
+ - cmd: >-
+ SET PGUSER=postgres
+
+ SET PGPASSWORD=Password12!
+
+ PATH=C:\Program Files\PostgreSQL\10\bin\;%PATH%
+
+ createdb "elsa-yessql"
+
test_script:
- ps: dotnet test --collect:"XPlat Code Coverage" --logger:xunit -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
diff --git a/src/persistence/Elsa.Persistence.YesSql/Elsa.Persistence.YesSql.csproj b/src/persistence/Elsa.Persistence.YesSql/Elsa.Persistence.YesSql.csproj
index 55a58b7bb..b37f2e08c 100644
--- a/src/persistence/Elsa.Persistence.YesSql/Elsa.Persistence.YesSql.csproj
+++ b/src/persistence/Elsa.Persistence.YesSql/Elsa.Persistence.YesSql.csproj
@@ -15,14 +15,8 @@
+
-
-
-
-
-
-
-
diff --git a/src/persistence/Elsa.Persistence.YesSql/Migrations.cs b/src/persistence/Elsa.Persistence.YesSql/Migrations.cs
index 0777c3046..6d2fa2aa5 100644
--- a/src/persistence/Elsa.Persistence.YesSql/Migrations.cs
+++ b/src/persistence/Elsa.Persistence.YesSql/Migrations.cs
@@ -30,7 +30,7 @@ namespace Elsa.Persistence.YesSql
.Column(nameof(WorkflowInstanceIndex.ContextId))
.Column(nameof(WorkflowInstanceIndex.ContextType))
.Column(nameof(WorkflowInstanceIndex.Name))
- .Column(nameof(WorkflowInstanceIndex.WorkflowStatus))
+ .Column(nameof(WorkflowInstanceIndex.WorkflowStatus))
.Column(nameof(WorkflowInstanceIndex.CreatedAt))
.Column(nameof(WorkflowInstanceIndex.LastExecutedAt))
.Column(nameof(WorkflowInstanceIndex.FinishedAt))
diff --git a/src/persistence/Elsa.Persistence.YesSql/Services/DataMigrationManager.cs b/src/persistence/Elsa.Persistence.YesSql/Services/DataMigrationManager.cs
index 4c75b28c2..bcd714e9d 100644
--- a/src/persistence/Elsa.Persistence.YesSql/Services/DataMigrationManager.cs
+++ b/src/persistence/Elsa.Persistence.YesSql/Services/DataMigrationManager.cs
@@ -53,6 +53,25 @@ namespace Elsa.Persistence.YesSql.Services
_logger.LogError(ex, "Could not run migrations automatically on '{FeatureName}'", migration);
}
}
+
+ try
+ {
+ var commitTask = _session.CurrentTransaction?.CommitAsync() ?? Task.CompletedTask;
+ await commitTask;
+ }
+ catch(InvalidOperationException)
+ {
+ // TODO: Improve on this ugly hack/workaround!
+ //
+ // The commit can throw this exception because it's already been committed. But if
+ // we don't explicitly commit here then it never gets committed and it's as if the
+ // migrations never took place!
+ //
+ // I suspect that either this method is being called more than once, or perhaps (IMO
+ // more likely) an async operation (somewhere) isn't being awaited. That could mean
+ // that the connection is closed/killed-off before the commit actually completes,
+ // with the effect that it doesn't happen.
+ }
}
public async Task> GetMigrationsThatNeedUpdateAsync()
diff --git a/src/persistence/Elsa.Persistence.YesSql/Services/DatabaseInitializer.cs b/src/persistence/Elsa.Persistence.YesSql/Services/DatabaseInitializer.cs
index 5040fd305..0f334bc72 100644
--- a/src/persistence/Elsa.Persistence.YesSql/Services/DatabaseInitializer.cs
+++ b/src/persistence/Elsa.Persistence.YesSql/Services/DatabaseInitializer.cs
@@ -22,6 +22,7 @@ namespace Elsa.Persistence.YesSql.Services
await _store.InitializeCollectionAsync(CollectionNames.WorkflowDefinitions);
await _store.InitializeCollectionAsync(CollectionNames.WorkflowInstances);
await _store.InitializeCollectionAsync(CollectionNames.WorkflowExecutionLog);
+ await _store.InitializeCollectionAsync(CollectionNames.Bookmarks);
}
}
}
diff --git a/test/integration/Elsa.Core.IntegrationTests/Autofixture/WithPostgresYesSqlAttribute.cs b/test/integration/Elsa.Core.IntegrationTests/Autofixture/WithPostgresYesSqlAttribute.cs
new file mode 100644
index 000000000..a19bce55e
--- /dev/null
+++ b/test/integration/Elsa.Core.IntegrationTests/Autofixture/WithPostgresYesSqlAttribute.cs
@@ -0,0 +1,35 @@
+using System;
+using Elsa.Persistence.YesSql;
+using Elsa.Testing.Shared.AutoFixture.Attributes;
+using Elsa.Testing.Shared.Helpers;
+using YesSql;
+using YesSql.Provider.PostgreSql;
+
+namespace Elsa.Core.IntegrationTests.Autofixture
+{
+ public class WithPostgresYesSqlAttribute : ElsaHostBuilderBuilderCustomizeAttributeBase
+ {
+ ///
+ /// This password matches the password which is used by AppVeyor: https://www.appveyor.com/docs/services-databases/#postgresql
+ ///
+ ///
+ ///
+ /// We could do something more sophisticated with the password than keep it in a constant, but since
+ /// this is (so far) the only place where we configure Postgres. There aren't any plans to do anything
+ /// with it in the foreseeable future either, so we can defer that until then.
+ ///
+ ///
+ internal const string PostgresPassword = "Password12!";
+
+ public override Action GetBuilderCustomizer()
+ {
+ return builder => {
+ builder.ElsaCallbacks.Add(elsa => {
+ elsa.UseYesSqlPersistence((IServiceProvider services, IConfiguration config) => {
+ config.UsePostgreSql($"Host=localhost;Database=elsa-yessql;User ID=postgres;Password={PostgresPassword}");
+ });
+ });
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/integration/Elsa.Core.IntegrationTests/Elsa.Core.IntegrationTests.csproj b/test/integration/Elsa.Core.IntegrationTests/Elsa.Core.IntegrationTests.csproj
index 76ca1d91f..35090820c 100644
--- a/test/integration/Elsa.Core.IntegrationTests/Elsa.Core.IntegrationTests.csproj
+++ b/test/integration/Elsa.Core.IntegrationTests/Elsa.Core.IntegrationTests.csproj
@@ -25,6 +25,7 @@
+
diff --git a/test/integration/Elsa.Core.IntegrationTests/Persistence/YesSql/PostgresSqlYesSqlIntegrationTests.cs b/test/integration/Elsa.Core.IntegrationTests/Persistence/YesSql/PostgresSqlYesSqlIntegrationTests.cs
new file mode 100644
index 000000000..e4748cfda
--- /dev/null
+++ b/test/integration/Elsa.Core.IntegrationTests/Persistence/YesSql/PostgresSqlYesSqlIntegrationTests.cs
@@ -0,0 +1,47 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.Core.IntegrationTests.Autofixture;
+using Elsa.Core.IntegrationTests.Workflows;
+using Elsa.Persistence;
+using Elsa.Services;
+using Elsa.Testing.Shared;
+using Elsa.Testing.Shared.Helpers;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Xunit;
+
+namespace Elsa.Core.IntegrationTests.Persistence.YesSql
+{
+ public class PostgresSqlYesSqlIntegrationTests
+ {
+ [Theory(DisplayName = "A persistable workflow instance with default persistence behaviour should be persisted-to and readable-from a YesSQL/PostgreSql store after being run"), AutoMoqData]
+ public async Task APersistableWorkflowInstanceWithDefaultPersistanceBehaviourShouldBeRoundTrippable([WithPersistableWorkflow,WithPostgresYesSql] ElsaHostBuilderBuilder hostBuilderBuilder)
+ {
+ var hostBuilder = hostBuilderBuilder.GetHostBuilder();
+ hostBuilder.ConfigureServices((ctx, services) => services.AddHostedService());
+ var host = await hostBuilder.StartAsync();
+ }
+
+ class HostedWorkflowRunner : IHostedService
+ {
+ readonly IBuildsAndStartsWorkflow _workflowRunner;
+ readonly IWorkflowInstanceStore _instanceStore;
+
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ var instance = await _workflowRunner.BuildAndStartWorkflowAsync(cancellationToken: cancellationToken);
+ var retrievedInstance = await _instanceStore.FindByIdAsync(instance.Id, cancellationToken);
+
+ Assert.NotNull(retrievedInstance);
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+
+ public HostedWorkflowRunner(IBuildsAndStartsWorkflow workflowRunner, IWorkflowInstanceStore instanceStore)
+ {
+ _workflowRunner = workflowRunner ?? throw new System.ArgumentNullException(nameof(workflowRunner));
+ _instanceStore = instanceStore ?? throw new System.ArgumentNullException(nameof(instanceStore));
+ }
+ }
+ }
+}
\ No newline at end of file