Skip to content

Commit

Permalink
Re-enable previously hanging and crashing tests, add extra, more comp…
Browse files Browse the repository at this point in the history
…lex, mutable state scenario
  • Loading branch information
abelbraaksma committed Oct 28, 2022
1 parent bad7b99 commit 9fe7631
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 25 deletions.
6 changes: 5 additions & 1 deletion src/FSharpy.TaskSeq.Test/TaskSeq.Realworld.fs
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,17 @@ type ``Real world tests``(output: ITestOutputHelper) =
}


// This test used to have the following, which has since been solved through #42
// please leave this test in, as it tests a case that's quite easily reached if we
// introduce mistakes in the resumable code.
//
//System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
// at <StartupCode$FSharpy-TaskSeq-Test>.$TaskSeq.Realworld.clo@58-4.MoveNext() in D:\Projects\OpenSource\Abel\TaskSeq\src\FSharpy.TaskSeq.Test\TaskSeq.Realworld.fs:line 77
// at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_0.<<InvokeTestMethodAsync>b__1>d.MoveNext() in /_/src/xunit.execution/Sdk/Frameworks/Runners/TestInvoker.cs:line 264
//--- End of stack trace from previous location ---
// at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in /_/src/xunit.execution/Sdk/Frameworks/ExecutionTimer.cs:line 48
// at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90\
[<Fact(Skip = "Currently fails")>]
[<Fact>]
let ``Reading a 1MB buffered IAsync stream from start to finish InvalidOperationException`` () = task {
let mutable count = 0
use reader = AsyncBufferedReader(output, Array.init 1_048_576 byte, 256)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,17 @@ let ``CE empty taskSeq, GetAsyncEnumerator multiple times`` variant = task {
()
}

[<Theory(Skip = "Test hangs");
InlineData "do";
InlineData "do!";
InlineData "yield! (seq)";
InlineData "yield! (taskseq)">]
// Note: this test used to hang (#42), please leave it in, no matter how silly it looks
[<Theory; InlineData "do"; InlineData "do!"; InlineData "yield! (seq)"; InlineData "yield! (taskseq)">]
let ``CE empty taskSeq, GetAsyncEnumerator multiple times and then MoveNextAsync`` variant = task {
let tskSeq = getEmptyVariant variant
use enumerator = tskSeq.GetAsyncEnumerator()
use enumerator = tskSeq.GetAsyncEnumerator()
do! moveNextAndCheck false enumerator
}

[<Theory(Skip = "Weird behavior");
InlineData "do";
InlineData "do!";
InlineData "yield! (seq)";
InlineData "yield! (taskseq)">]
// Note: this test used to cause xUnit to crash (#42), please leave it in, no matter how silly it looks
[<Theory; InlineData "do"; InlineData "do!"; InlineData "yield! (seq)"; InlineData "yield! (taskseq)">]
let ``CE empty taskSeq, GetAsyncEnumerator + MoveNextAsync multiple times`` variant = task {
let tskSeq = getEmptyVariant variant
use enumerator1 = tskSeq.GetAsyncEnumerator()
Expand All @@ -84,11 +78,8 @@ let ``CE empty taskSeq, GetAsyncEnumerator + MoveNextAsync multiple times`` vari
do! moveNextAndCheck false enumerator2 // new hone should also work without raising
}

[<Theory(Skip = "Weird behavior");
InlineData "do";
InlineData "do!";
InlineData "yield! (seq)";
InlineData "yield! (taskseq)">]
// Note: this test used to cause xUnit to crash (#42), please leave it in, no matter how silly it looks
[<Theory; InlineData "do"; InlineData "do!"; InlineData "yield! (seq)"; InlineData "yield! (taskseq)">]
let ``CE empty taskSeq, GetAsyncEnumerator + MoveNextAsync in a loop`` variant = task {
let tskSeq = getEmptyVariant variant

Expand Down Expand Up @@ -193,7 +184,8 @@ let ``CE taskSeq, MoveNext too far`` () = task {
enum.Current |> should equal Guid.Empty // we return Unchecked.defaultof, which is Guid.Empty for guids
}

[<Fact(Skip = "Weird behavior")>]
// Note: this test used to cause xUnit to crash (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``CE taskSeq, call GetAsyncEnumerator twice, both should have equal behavior`` () = task {
let tskSeq = taskSeq {
do! delayRandom ()
Expand All @@ -218,7 +210,8 @@ let ``CE taskSeq, call GetAsyncEnumerator twice, both should have equal behavior
do! moveNextAndCheckCurrent false 0 enum2 // this used to be an error, see issue #39 and PR #42
}

[<Fact(Skip = "Weird behavior")>]
// Note: this test used to cause xUnit to crash (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``CE taskSeq, cal GetAsyncEnumerator twice -- in lockstep`` () = task {
let tskSeq = taskSeq {
do! delayRandom ()
Expand All @@ -244,7 +237,8 @@ let ``CE taskSeq, cal GetAsyncEnumerator twice -- in lockstep`` () = task {
do! moveNextAndCheckCurrent false 0 enum2 // this used to be an error, see issue #39 and PR #42
}

[<Fact(Skip = "Weird behavior")>]
// Note: this test used to cause xUnit to crash (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``CE taskSeq, call GetAsyncEnumerator twice -- after full iteration`` () = task {
let tskSeq = taskSeq {
yield 1
Expand All @@ -267,7 +261,8 @@ let ``CE taskSeq, call GetAsyncEnumerator twice -- after full iteration`` () = t
do! moveNextAndCheckCurrent false 0 enum2 // this used to be an error, see issue #39 and PR #42
}

[<Fact(Skip = "Test hangs")>]
// Note: this test used to hang (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``CE taskSeq, call GetAsyncEnumerator twice -- random mixed iteration`` () = task {
let tskSeq = taskSeq {
yield 1
Expand Down Expand Up @@ -323,7 +318,8 @@ let ``CE taskSeq, call GetAsyncEnumerator twice -- random mixed iteration`` () =
enum1.Current |> should equal 0
}

[<Fact(Skip = "Timeout expires")>]
// Note: this test used to hang (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``TaskSeq-toArray can be applied multiple times to the same sequence`` () =
let tq = taskSeq {
yield! [ 1..3 ]
Expand All @@ -336,7 +332,36 @@ let ``TaskSeq-toArray can be applied multiple times to the same sequence`` () =
let (results2: _[]) = tq |> TaskSeq.toArray
let (results3: _[]) = tq |> TaskSeq.toArray
let (results4: _[]) = tq |> TaskSeq.toArray
results1 |> should equal [| 1..10 |]
results2 |> should equal [| 1..10 |]
results3 |> should equal [| 1..10 |]
results4 |> should equal [| 1..10 |]
results1 |> should equal [| 1..7 |]
results2 |> should equal [| 1..7 |] // no mutable state in taskSeq, multi iter remains stable
results3 |> should equal [| 1..7 |] // id
results4 |> should equal [| 1..7 |] // id

// Note: this test used to hang (#42), please leave it in, no matter how silly it looks
[<Fact>]
let ``TaskSeq-toArray can be applied multiple times to the same sequence -- mutable state`` () =
let mutable before, middle, after = (0, 0, 0)

let tq = taskSeq {
before <- before + 1
yield before
yield! [ 100..120 ]
do! delayRandom ()
middle <- middle + 1
yield middle
yield! [ 100..120 ]
do! delayRandom ()
after <- after + 1
yield after
}

let (results1: _ list) = tq |> TaskSeq.toList
let (results2: _ list) = tq |> TaskSeq.toList
let (results3: _ list) = tq |> TaskSeq.toList
let (results4: _ list) = tq |> TaskSeq.toList

let expectMutatedTo a = (a :: [ 100..120 ] @ [ a ] @ [ 100..120 ] @ [ a ])
results1 |> should equal (expectMutatedTo 1)
results2 |> should equal (expectMutatedTo 2)
results3 |> should equal (expectMutatedTo 3)
results4 |> should equal (expectMutatedTo 4)

0 comments on commit 9fe7631

Please sign in to comment.