Skip to content

Commit 77885e6

Browse files
authored
Improve AsyncMemoize tests (#16612)
1 parent 099d19f commit 77885e6

File tree

1 file changed

+42
-38
lines changed

1 file changed

+42
-38
lines changed

tests/FSharp.Compiler.ComponentTests/CompilerService/AsyncMemoize.fs

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ let waitFor (mre: ManualResetEvent) =
1818
if not <| mre.WaitOne timeout then
1919
failwith "waitFor timed out"
2020

21+
let waitUntil condition value =
22+
task {
23+
let sw = Stopwatch.StartNew()
24+
while not <| condition value do
25+
if sw.Elapsed > timeout then
26+
failwith "waitUntil timed out"
27+
do! Task.Delay 10
28+
}
2129

2230
let rec internal spinFor (duration: TimeSpan) =
2331
node {
@@ -29,6 +37,24 @@ let rec internal spinFor (duration: TimeSpan) =
2937
}
3038

3139

40+
type internal EventRecorder<'a, 'b, 'c when 'a : equality and 'b : equality>(memoize: AsyncMemoize<'a,'b,'c>) as self =
41+
42+
let events = ConcurrentQueue()
43+
44+
do memoize.OnEvent self.Add
45+
46+
member _.Add (e, (_label, k, _version)) = events.Enqueue (e, k)
47+
48+
member _.Received value = events |> Seq.exists (fst >> (=) value)
49+
50+
member _.CountOf value count = events |> Seq.filter (fst >> (=) value) |> Seq.length |> (=) count
51+
52+
member _.ShouldBe (expected) =
53+
let expected = expected |> Seq.toArray
54+
let actual = events |> Seq.toArray
55+
Assert.Equal<_ array>(expected, actual)
56+
57+
3258
[<Fact>]
3359
let ``Basics``() =
3460

@@ -69,21 +95,14 @@ let ``We can cancel a job`` () =
6995

7096
let jobStarted = new ManualResetEvent(false)
7197

72-
let jobCanceled = new ManualResetEvent(false)
73-
7498
let computation action = node {
7599
action() |> ignore
76100
do! spinFor timeout
77101
failwith "Should be canceled before it gets here"
78102
}
79103

80-
let eventLog = ConcurrentQueue()
81-
let memoize = AsyncMemoize<int, int, _>()
82-
memoize.OnEvent(fun (e, (_label, k, _version)) ->
83-
eventLog.Enqueue (e, k)
84-
if e = Canceled then
85-
jobCanceled.Set() |> ignore
86-
)
104+
let memoize = AsyncMemoize<_, int, _>()
105+
let events = EventRecorder(memoize)
87106

88107
use cts1 = new CancellationTokenSource()
89108
use cts2 = new CancellationTokenSource()
@@ -96,13 +115,10 @@ let ``We can cancel a job`` () =
96115
waitFor jobStarted
97116
jobStarted.Reset() |> ignore
98117

99-
let jobRequested = new ManualResetEvent(false)
100-
memoize.OnEvent(fun (e, _) -> if e = Requested then jobRequested.Set() |> ignore)
101-
102118
let _task2 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation ignore), ct = cts2.Token)
103119
let _task3 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation ignore), ct = cts3.Token)
104120

105-
waitFor jobRequested
121+
do! waitUntil (events.CountOf Requested) 3
106122

107123
cts1.Cancel()
108124
cts2.Cancel()
@@ -111,16 +127,16 @@ let ``We can cancel a job`` () =
111127

112128
cts3.Cancel()
113129

114-
waitFor jobCanceled
130+
do! waitUntil events.Received Canceled
115131

116-
Assert.Equal<(JobEvent * int) array>([|
132+
events.ShouldBe [
117133
Requested, key
118134
Started, key
119135
Requested, key
120136
Requested, key
121137
Restarted, key
122138
Canceled, key
123-
|], eventLog |> Seq.toArray )
139+
]
124140
}
125141

126142
[<Fact>]
@@ -136,9 +152,9 @@ let ``Job is restarted if first requestor cancels`` () =
136152
return key * 2
137153
}
138154

139-
let eventLog = ConcurrentStack()
140-
let memoize = AsyncMemoize<int, int, _>()
141-
memoize.OnEvent(fun (e, (_, k, _version)) -> eventLog.Push (e, k))
155+
let memoize = AsyncMemoize<_, int, _>()
156+
let events = EventRecorder(memoize)
157+
142158

143159
use cts1 = new CancellationTokenSource()
144160
use cts2 = new CancellationTokenSource()
@@ -151,13 +167,10 @@ let ``Job is restarted if first requestor cancels`` () =
151167
waitFor jobStarted
152168
jobStarted.Reset() |> ignore
153169

154-
let jobRequested = new ManualResetEvent(false)
155-
memoize.OnEvent(fun (e, _) -> if e = Requested then jobRequested.Set() |> ignore)
156-
157170
let _task2 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation key), ct = cts2.Token)
158171
let _task3 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation key), ct = cts3.Token)
159172

160-
waitFor jobRequested
173+
do! waitUntil (events.CountOf Requested) 3
161174

162175
cts1.Cancel()
163176

@@ -168,16 +181,13 @@ let ``Job is restarted if first requestor cancels`` () =
168181
let! result = _task2
169182
Assert.Equal(2, result)
170183

171-
let orderedLog = eventLog |> Seq.rev |> Seq.toList
172-
let expected = [
184+
events.ShouldBe [
173185
Requested, key
174186
Started, key
175187
Requested, key
176188
Requested, key
177189
Restarted, key
178190
Finished, key ]
179-
180-
Assert.Equal<_ list>(expected, orderedLog)
181191
}
182192

183193
[<Fact>]
@@ -192,10 +202,10 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
192202
waitFor jobCanComplete
193203
return key * 2
194204
}
205+
206+
let memoize = AsyncMemoize<_, int, _>()
207+
let events = EventRecorder(memoize)
195208

196-
let eventLog = ConcurrentStack()
197-
let memoize = AsyncMemoize<int, int, _>()
198-
memoize.OnEvent(fun (e, (_label, k, _version)) -> eventLog.Push (e, k))
199209

200210
use cts1 = new CancellationTokenSource()
201211
use cts2 = new CancellationTokenSource()
@@ -208,13 +218,10 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
208218
waitFor jobStarted
209219
jobStarted.Reset() |> ignore
210220

211-
let jobRequested = new ManualResetEvent(false)
212-
memoize.OnEvent(fun (e, _) -> if e = Requested then jobRequested.Set() |> ignore)
213-
214221
let _task2 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation key), ct = cts2.Token)
215222
let _task3 = NodeCode.StartAsTask_ForTesting( memoize.Get'(key, computation key), ct = cts3.Token)
216223

217-
waitFor jobRequested
224+
do! waitUntil (events.CountOf Requested) 3
218225

219226
cts1.Cancel()
220227

@@ -227,16 +234,13 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
227234
let! result = _task3
228235
Assert.Equal(2, result)
229236

230-
let orderedLog = eventLog |> Seq.rev |> Seq.toList
231-
let expected = [
237+
events.ShouldBe [
232238
Requested, key
233239
Started, key
234240
Requested, key
235241
Requested, key
236242
Restarted, key
237243
Finished, key ]
238-
239-
Assert.Equal<_ list>(expected, orderedLog)
240244
}
241245

242246

0 commit comments

Comments
 (0)