Skip to content

Commit ef23387

Browse files
author
Jimmy Byrd
committed
Add Rx tests
1 parent 58d2b88 commit ef23387

File tree

8 files changed

+263
-3
lines changed

8 files changed

+263
-3
lines changed

.paket/Paket.Restore.targets

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,11 @@
252252
</PropertyGroup>
253253

254254
<ItemGroup>
255-
<_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion).nuspec"/>
255+
<_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/>
256256
</ItemGroup>
257257

258-
<Exec Command='$(PaketCommand) fix-nuspecs files "@(_NuspecFiles)" project-file "$(PaketProjectFile)" ' Condition="@(_NuspecFiles) != ''" />
258+
<Exec Condition="@(_NuspecFiles) != ''" Command='$(PaketCommand) fix-nuspecs files "@(_NuspecFiles)" project-file "$(PaketProjectFile)" ' />
259+
<Error Condition="@(_NuspecFiles) == ''" Text='Could not find nuspec files in "$(AdjustedNuspecOutputPath)" (Version: "$(PackageVersion)"), therefore we cannot call "paket fix-nuspecs" and have to error out!' />
259260

260261
<ConvertToAbsolutePath Condition="@(_NuspecFiles) != ''" Paths="@(_NuspecFiles)">
261262
<Output TaskParameter="AbsolutePaths" PropertyName="NuspecFileAbsolutePath" />

FSharp.Control.Redis.Streams.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Control.Redis.Stream
1515
EndProject
1616
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Control.Redis.Streams.Akka", "src\FSharp.Control.Redis.Streams.Akka\FSharp.Control.Redis.Streams.Akka.fsproj", "{C1AF5E8A-28CC-4CC3-B3A5-30EAEE1D22F0}"
1717
EndProject
18+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Control.Redis.Streams.Reactive.Tests", "tests\FSharp.Control.Redis.Streams.Reactive.Tests\FSharp.Control.Redis.Streams.Reactive.Tests.fsproj", "{2CCEB944-20F6-4461-A517-31555822C36F}"
19+
EndProject
20+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Control.Redis.Streams.Reactive", "src\FSharp.Control.Redis.Streams.Reactive\FSharp.Control.Redis.Streams.Reactive.fsproj", "{F260F85B-FAC8-484F-AD86-88808E271F9B}"
21+
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2024
Debug|Any CPU = Debug|Any CPU
@@ -76,11 +80,37 @@ Global
7680
{C1AF5E8A-28CC-4CC3-B3A5-30EAEE1D22F0}.Release|x64.Build.0 = Release|Any CPU
7781
{C1AF5E8A-28CC-4CC3-B3A5-30EAEE1D22F0}.Release|x86.ActiveCfg = Release|Any CPU
7882
{C1AF5E8A-28CC-4CC3-B3A5-30EAEE1D22F0}.Release|x86.Build.0 = Release|Any CPU
83+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
84+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|Any CPU.Build.0 = Debug|Any CPU
85+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|x64.ActiveCfg = Debug|Any CPU
86+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|x64.Build.0 = Debug|Any CPU
87+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|x86.ActiveCfg = Debug|Any CPU
88+
{2CCEB944-20F6-4461-A517-31555822C36F}.Debug|x86.Build.0 = Debug|Any CPU
89+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|Any CPU.ActiveCfg = Release|Any CPU
90+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|Any CPU.Build.0 = Release|Any CPU
91+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|x64.ActiveCfg = Release|Any CPU
92+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|x64.Build.0 = Release|Any CPU
93+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|x86.ActiveCfg = Release|Any CPU
94+
{2CCEB944-20F6-4461-A517-31555822C36F}.Release|x86.Build.0 = Release|Any CPU
95+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
96+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
97+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|x64.ActiveCfg = Debug|Any CPU
98+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|x64.Build.0 = Debug|Any CPU
99+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|x86.ActiveCfg = Debug|Any CPU
100+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Debug|x86.Build.0 = Debug|Any CPU
101+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
102+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|Any CPU.Build.0 = Release|Any CPU
103+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|x64.ActiveCfg = Release|Any CPU
104+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|x64.Build.0 = Release|Any CPU
105+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|x86.ActiveCfg = Release|Any CPU
106+
{F260F85B-FAC8-484F-AD86-88808E271F9B}.Release|x86.Build.0 = Release|Any CPU
79107
EndGlobalSection
80108
GlobalSection(NestedProjects) = preSolution
81109
{5D30E174-2538-47AC-8443-318C8C5DC2C9} = {C397A34C-84F1-49E7-AEBC-2F9F2B196216}
82110
{1CA2E092-2320-451D-A4F0-9ED7C7C528CA} = {ACBEE43C-7A88-4FB1-9B06-DB064D22B29F}
83111
{5469ACDC-F198-4451-944E-08616A1AAE95} = {C397A34C-84F1-49E7-AEBC-2F9F2B196216}
84112
{C1AF5E8A-28CC-4CC3-B3A5-30EAEE1D22F0} = {C397A34C-84F1-49E7-AEBC-2F9F2B196216}
113+
{2CCEB944-20F6-4461-A517-31555822C36F} = {ACBEE43C-7A88-4FB1-9B06-DB064D22B29F}
114+
{F260F85B-FAC8-484F-AD86-88808E271F9B} = {C397A34C-84F1-49E7-AEBC-2F9F2B196216}
85115
EndGlobalSection
86116
EndGlobal

src/FSharp.Control.Redis.Streams.Reactive/FSharp.Control.Redis.Streams.Reactive.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace FSharp.Control.Redis.Streams
22

3-
module Hopac =
3+
module Reactive =
44
open System
55
open System.Threading
66
open System.Threading.Tasks
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Auto-Generated by FAKE; do not edit
2+
namespace System
3+
open System.Reflection
4+
5+
[<assembly: AssemblyTitleAttribute("Redis.Streams.Tests")>]
6+
[<assembly: AssemblyProductAttribute("Redis.Streams")>]
7+
[<assembly: AssemblyVersionAttribute("0.1.0")>]
8+
[<assembly: AssemblyMetadataAttribute("ReleaseDate","2017-03-17T00:00:00.0000000")>]
9+
[<assembly: AssemblyFileVersionAttribute("0.1.0")>]
10+
[<assembly: AssemblyInformationalVersionAttribute("0.1.0")>]
11+
[<assembly: AssemblyMetadataAttribute("ReleaseChannel","release")>]
12+
[<assembly: AssemblyMetadataAttribute("GitHash","bb8964b54bee133e9af64d316dc2cfee16df7f72")>]
13+
do ()
14+
15+
module internal AssemblyVersionInformation =
16+
let [<Literal>] AssemblyTitle = "Redis.Streams.Tests"
17+
let [<Literal>] AssemblyProduct = "Redis.Streams"
18+
let [<Literal>] AssemblyVersion = "0.1.0"
19+
let [<Literal>] AssemblyMetadata_ReleaseDate = "2017-03-17T00:00:00.0000000"
20+
let [<Literal>] AssemblyFileVersion = "0.1.0"
21+
let [<Literal>] AssemblyInformationalVersion = "0.1.0"
22+
let [<Literal>] AssemblyMetadata_ReleaseChannel = "release"
23+
let [<Literal>] AssemblyMetadata_GitHash = "bb8964b54bee133e9af64d316dc2cfee16df7f72"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<Compile Include="AssemblyInfo.fs" />
9+
<Compile Include="Tests.fs" />
10+
<Compile Include="Main.fs" />
11+
</ItemGroup>
12+
<ItemGroup>
13+
<ProjectReference Include="../../src/FSharp.Control.Redis.Streams.Reactive/FSharp.Control.Redis.Streams.Reactive.fsproj" />
14+
</ItemGroup>
15+
<!-- <Import Project="..\..\fsc.props" /> -->
16+
<Import Project="..\..\netfx.props" />
17+
<Import Project="..\..\.paket\Paket.Restore.targets" />
18+
</Project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module ExpectoTemplate
2+
open Expecto
3+
4+
[<EntryPoint>]
5+
let main argv =
6+
Tests.runTestsInAssembly defaultConfig argv
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
module Tests
2+
3+
open System
4+
open Expecto
5+
open StackExchange.Redis
6+
open System.Threading
7+
open System.Threading.Tasks
8+
open System.Reactive
9+
open System.Reactive.Linq
10+
open FSharp.Control.Redis.Streams.Core
11+
open FSharp.Control.Redis.Streams.Reactive
12+
open FSharp.Control.Tasks.V2.ContextInsensitive
13+
open Hopac
14+
15+
let getUniqueKey (keyType : string) (key : string) =
16+
let suffix = Guid.NewGuid().ToString()
17+
sprintf "%s:%s:%s" keyType key suffix
18+
|> RedisKey.op_Implicit
19+
20+
let printNameEntryValues (nve : NameValueEntry) =
21+
printfn "Key: %A - Value: %A" nve.Name nve.Value
22+
let printStreamEntry (se : StreamEntry) =
23+
printfn "Id: %A" se.Id
24+
se.Values |> Seq.iter(printNameEntryValues )
25+
let printRedisStream (rs : RedisStream) =
26+
printfn "key: %A" rs.Key
27+
rs.Entries |> Seq.iter(printStreamEntry)
28+
29+
let rkey (s : string) = RedisKey.op_Implicit s
30+
let rval (s : string) = RedisValue.op_Implicit s
31+
let nve name value = NameValueEntry(rval name, rval value)
32+
33+
34+
35+
let failDueToTimeout message (ts : TimeSpan) =
36+
failtestf "%s. Expected task to complete but failed after timeout of %f ms" message ts.TotalMilliseconds
37+
38+
type StreamExpect<'a> (predicate : seq<'a> -> bool) =
39+
let values = ResizeArray<'a>()
40+
let cts = new CancellationTokenSource()
41+
let predicateConditionMet = TaskCompletionSource<unit>()
42+
let mutable debugPrint : Option<'a -> unit> = None
43+
let mutable subscription : IDisposable = new Disposables.BooleanDisposable() :> IDisposable
44+
let checkPredicate () =
45+
if predicate values then
46+
predicateConditionMet.TrySetResult ()
47+
|> ignore
48+
49+
member this.Values
50+
with get () = values
51+
52+
member this.DebugPrint
53+
with get () = debugPrint
54+
and set (v) = debugPrint <- v
55+
member this.CaptureFromStream (s : IObservable<'a>) =
56+
let printer =
57+
match debugPrint with
58+
| Some d -> d
59+
| None -> ignore
60+
let d =
61+
s.Select(fun x -> x |> printer; x)
62+
.Subscribe(values.Add >> checkPredicate)
63+
subscription <- d
64+
65+
member this.Await message (timeout : TimeSpan) = task {
66+
let generateTimeout () = task {
67+
do! Task.Delay(timeout,cts.Token)
68+
failDueToTimeout message timeout
69+
}
70+
71+
let! firstFinishedTask = Task.WhenAny [
72+
predicateConditionMet.Task
73+
generateTimeout ()
74+
]
75+
cts.Cancel()
76+
do! firstFinishedTask
77+
}
78+
79+
interface IDisposable with
80+
member x.Dispose() =
81+
subscription.Dispose()
82+
cts.Dispose()
83+
84+
let ranStr n : string =
85+
let r = Random()
86+
String(Array.init n (fun _ -> char (r.Next(97,123))))
87+
88+
89+
90+
let options = ConfigurationOptions.Parse("localhost", ResponseTimeout = 100000, SyncTimeout=100000, ConnectTimeout=100000)
91+
let redis = ConnectionMultiplexer.Connect(options)
92+
[<Tests>]
93+
let tests =
94+
testSequenced <|
95+
testList "samples" [
96+
testCaseAsync "Stream should generate 2 events" <| async {
97+
let db = redis.GetDatabase()
98+
let key = getUniqueKey "stream" "Foo"
99+
use expecter = new StreamExpect<_>(fun s -> s |> Seq.length = 2)
100+
pollStreamForever db key StreamPosition.Beginning PollOptions.Default
101+
|> expecter.CaptureFromStream
102+
103+
let values =
104+
[|
105+
nve "Field1" "Value1"
106+
nve "Field2" "Value3"
107+
|]
108+
let! x = db.StreamAddAsync(key, values) |> Async.AwaitTask
109+
let values =
110+
[|
111+
nve "Field1" "Value4"
112+
nve "Field2" "Value6"
113+
|]
114+
let! x = db.StreamAddAsync(key, values) |> Async.AwaitTask
115+
do! expecter.Await "Should have 2 results" (TimeSpan.FromSeconds(1.)) |> Async.AwaitTask
116+
}
117+
118+
testCaseAsync "Stream should generate 20000 events" <| async {
119+
let total = 20000
120+
let db = redis.GetDatabase()
121+
let key = getUniqueKey "stream" "Foo"
122+
use expecter = new StreamExpect<_>(fun s -> s |> Seq.length = total)
123+
pollStreamForever db key StreamPosition.Beginning PollOptions.Default
124+
|> expecter.CaptureFromStream
125+
126+
job {
127+
do!
128+
[0..total]
129+
|> Seq.map(fun i ->
130+
let values =
131+
[|
132+
NameValueEntry (RedisValue.op_Implicit "Field1", RedisValue.op_Implicit total)
133+
|]
134+
job {
135+
let! x = db.StreamAddAsync(key, values) |> Async.AwaitTask
136+
return ()
137+
})
138+
|> Stream.ofSeq
139+
|> Stream.mapPipelinedJob (Environment.ProcessorCount * 4096 * 2) id
140+
|> Stream.iter
141+
} |> start
142+
143+
do! expecter.Await "Should have 20000 results" (TimeSpan.FromSeconds(30.)) |> Async.AwaitTask
144+
}
145+
146+
147+
testCaseAsync "Stream should generate large fields" <| async {
148+
let total = 200
149+
let db = redis.GetDatabase()
150+
let key = getUniqueKey "stream" "Foo"
151+
use expecter = new StreamExpect<_>(fun s -> s |> Seq.length = total)
152+
pollStreamForever db key StreamPosition.Beginning PollOptions.Default
153+
|> expecter.CaptureFromStream
154+
155+
job {
156+
do!
157+
[0..total]
158+
|> Seq.map(fun i ->
159+
let data = ranStr (20000)
160+
let values =
161+
[|
162+
NameValueEntry (RedisValue.op_Implicit "Field1", RedisValue.op_Implicit data)
163+
|]
164+
job {
165+
let! x = db.StreamAddAsync(key, values) |> Async.AwaitTask
166+
return ()
167+
})
168+
|> Stream.ofSeq
169+
|> Stream.mapPipelinedJob (Environment.ProcessorCount * 2) id
170+
|> Stream.iter
171+
} |> start
172+
173+
do! expecter.Await "Should have 2 results" (TimeSpan.FromSeconds(30.)) |> Async.AwaitTask
174+
}
175+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Expecto
2+
FSharp.Core
3+
dotnet-mono
4+
Microsoft.NET.Test.Sdk
5+
YoloDev.Expecto.TestSdk
6+
altcover
7+
Hopac

0 commit comments

Comments
 (0)