-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
eqxShipping: Memory store tests (#70)
- Loading branch information
Showing
18 changed files
with
360 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Shipping.Domain.Tests.ContainerTests | ||
|
||
open Shipping.Domain.Container | ||
|
||
open FsCheck.Xunit | ||
open Swensen.Unquote | ||
|
||
let [<Property>] ``events roundtrip`` (x : Events.Event) = | ||
let ee = Events.codec.Encode(None, x) | ||
let e = FsCodec.Core.TimelineEvent.Create(0L, ee.EventType, ee.Data) | ||
let des = Events.codec.TryDecode e | ||
test <@ des = Some x @> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
<WarningLevel>5</WarningLevel> | ||
<IsPackable>false</IsPackable> | ||
<GenerateProgramFile>false</GenerateProgramFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="Infrastructure.fs" /> | ||
<Compile Include="Fixtures.fs" /> | ||
<Compile Include="ContainerTests.fs" /> | ||
<Compile Include="ShipmentTests.fs" /> | ||
<Compile Include="FinalizationTransactionTests.fs" /> | ||
<Compile Include="FinalizationProcessManagerTests.fs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> | ||
|
||
<PackageReference Include="Equinox.MemoryStore" Version="2.1.0" /> | ||
<PackageReference Include="Unquote" Version="5.0.0" /> | ||
<PackageReference Include="FsCheck.Xunit" Version="2.14.2" /> | ||
<PackageReference Include="xunit" Version="2.4.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Domain\Domain.fsproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
43 changes: 43 additions & 0 deletions
43
equinox-shipping/Domain.Tests/FinalizationProcessManagerTests.fs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
module Shipping.Domain.Tests.FinalizationProcessManagerTests | ||
|
||
open Shipping.Domain | ||
|
||
open FsCheck.Xunit | ||
open Swensen.Unquote | ||
|
||
[<Property>] | ||
let ``FinalizationProcessManager properties`` (Id transId1, Id transId2, Id containerId1, Id containerId2, IdsAtLeastOne shipmentIds1, IdsAtLeastOne shipmentIds2, Id shipment3) = | ||
let store = Equinox.MemoryStore.VolatileStore() | ||
let buffer = EventAccumulator() | ||
use __ = store.Committed.Subscribe buffer.Record | ||
let eventTypes = seq { for e in buffer.All() -> e.EventType } | ||
let processManager = createProcessManager 16 store | ||
Async.RunSynchronously <| async { | ||
(* First, run the happy path - should pass through all stages of the lifecycle *) | ||
let requestedShipmentIds = Array.append shipmentIds1 shipmentIds2 | ||
let! res1 = processManager.TryFinalizeContainer(transId1, containerId1, requestedShipmentIds) | ||
let expectedEvents = | ||
[ "FinalizationRequested"; "ReservationCompleted"; "AssignmentCompleted"; "Completed" // Transaction | ||
"Reserved"; "Assigned" // Shipment | ||
"Finalized"] // Container | ||
test <@ res1 && set eventTypes = set expectedEvents @> | ||
let containerEvents = | ||
buffer.Queue(Container.streamName containerId1) | ||
|> Seq.choose Container.Events.codec.TryDecode | ||
|> List.ofSeq | ||
test <@ match containerEvents with | ||
| [ Container.Events.Finalized e ] -> e.shipmentIds = requestedShipmentIds | ||
| xs -> failwithf "Unexpected %A" xs @> | ||
(* Next, we run an overlapping finalize - this should | ||
a) yield a fail result | ||
b) result in triggering of Revert flow with associated Shipment revoke events *) | ||
buffer.Clear() | ||
let! res2 = processManager.TryFinalizeContainer(transId2, containerId2, Array.append shipmentIds2 [|shipment3|]) | ||
let expectedEvents = | ||
[ "FinalizationRequested"; "RevertCommenced"; "Completed" // Transaction | ||
"Reserved"; "Revoked" ] // Shipment | ||
test <@ not res2 | ||
&& set eventTypes = set expectedEvents @> | ||
} | ||
|
||
module Dummy = let [<EntryPoint>] main _argv = 0 |
12 changes: 12 additions & 0 deletions
12
equinox-shipping/Domain.Tests/FinalizationTransactionTests.fs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Shipping.Domain.Tests.FinalizationTransactionTests | ||
|
||
open Shipping.Domain.FinalizationTransaction | ||
|
||
open FsCheck.Xunit | ||
open Swensen.Unquote | ||
|
||
let [<Property>] ``events roundtrip`` (x : Events.Event) = | ||
let ee = Events.codec.Encode(None, x) | ||
let e = FsCodec.Core.TimelineEvent.Create(0L, ee.EventType, ee.Data) | ||
let des = Events.codec.TryDecode e | ||
test <@ des = Some x @> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
[<AutoOpen>] | ||
module Shipping.Domain.Tests.Fixtures | ||
|
||
open Shipping.Domain | ||
|
||
module FinalizationTransaction = | ||
open FinalizationTransaction | ||
module MemoryStore = | ||
open Equinox.MemoryStore | ||
let create store = | ||
let resolver = Resolver(store, Events.codec, Fold.fold, Fold.initial) | ||
create resolver.Resolve | ||
module Container = | ||
open Container | ||
module MemoryStore = | ||
open Equinox.MemoryStore | ||
let create store = | ||
let resolver = Resolver(store, Events.codec, Fold.fold, Fold.initial) | ||
create resolver.Resolve | ||
module Shipment = | ||
open Shipment | ||
module MemoryStore = | ||
open Equinox.MemoryStore | ||
let create store = | ||
let resolver = Resolver(store, Events.codec, Fold.fold, Fold.initial) | ||
create resolver.Resolve | ||
|
||
let createProcessManager maxDop store = | ||
let transactions = FinalizationTransaction.MemoryStore.create store | ||
let containers = Container.MemoryStore.create store | ||
let shipments = Shipment.MemoryStore.create store | ||
FinalizationProcessManager.Service(transactions, containers, shipments, maxDop=maxDop) | ||
|
||
(* Generic FsCheck helpers *) | ||
|
||
let (|Id|) (x : System.Guid) = x.ToString "N" |> FSharp.UMX.UMX.tag | ||
let (|Ids|) (xs : System.Guid[]) = xs |> Array.map (|Id|) | ||
let (|IdsAtLeastOne|) (Ids xs, Id x) = [| yield x; yield! xs |] | ||
let (|AtLeastOne|) (x, xs) = x::xs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[<AutoOpen>] | ||
module Shipping.Domain.Tests.Infrastructure | ||
|
||
open System.Collections.Concurrent | ||
|
||
type EventAccumulator<'E>() = | ||
let messages = ConcurrentDictionary<FsCodec.StreamName, ConcurrentQueue<'E>>() | ||
|
||
member __.Record(stream, events : 'E seq) = | ||
let initStreamQueue _ = ConcurrentQueue events | ||
let appendToQueue _ (queue : ConcurrentQueue<'E>) = events |> Seq.iter queue.Enqueue; queue | ||
messages.AddOrUpdate(stream, initStreamQueue, appendToQueue) |> ignore | ||
|
||
member __.Queue stream = | ||
match messages.TryGetValue stream with | ||
| false, _ -> Seq.empty<'E> | ||
| true, xs -> xs :> _ | ||
|
||
member __.All() = seq { for KeyValue (_, xs) in messages do yield! xs } | ||
|
||
member __.Clear() = | ||
messages.Clear() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Shipping.Domain.Tests.ShipmentTests | ||
|
||
open Shipping.Domain.Shipment | ||
|
||
open FsCheck.Xunit | ||
open Swensen.Unquote | ||
|
||
// We use Optional string values in the event representations | ||
// However, FsCodec.NewtonsoftJson.OptionConverter maps `Some null` to `None`, which does not roundtrip | ||
// In order to avoid having to special case the assertion in the roundtrip test, we stub out such values | ||
let (|ReplaceSomeNullWithNone|) = TypeShape.Generic.map (function Some (null : string) -> None | x -> x) | ||
|
||
let [<Property>] ``events roundtrip`` (ReplaceSomeNullWithNone (x : Events.Event)) = | ||
let ee = Events.codec.Encode(None, x) | ||
let e = FsCodec.Core.TimelineEvent.Create(0L, ee.EventType, ee.Data) | ||
let des = Events.codec.TryDecode e | ||
test <@ des = Some x @> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.