SwensenSoftware / unquote

Write F# unit test assertions as quoted expressions, get step-by-step failure messages for free
http://www.swensensoftware.com/unquote
Apache License 2.0
285 stars 26 forks source link

Random crashes #160

Open tmoers opened 2 years ago

tmoers commented 2 years ago

Every once in a while we have two tests that fail and we get this call stack in the exception:

System.NullReferenceException : Object reference not set to an instance of an object.
at Microsoft.FSharp.Quotations.FSharpVar..ctor(String name, Type typ, FSharpOption`1 isMutable) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 91
at Microsoft.FSharp.Quotations.PatternsModule.u_VarDecl@1530.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1530
at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1508-2.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1508
at Microsoft.FSharp.Primitives.Basics.List.mapToFreshConsTail[a,b](FSharpList`1 cons, FSharpFunc`2 f, FSharpList`1 x) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 241
at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 251
at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1492.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1493
at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 250
at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1492.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1493
at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 250
at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1492.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1493
at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1519-5.Invoke(BindingEnv env) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1519
at Microsoft.FSharp.Quotations.PatternsModule.deserialize(Type localAssembly, Type[] referencedTypeDefs, Type[] spliceTypes, FSharpExpr[] spliceExprs, Byte[] bytes) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1896
at Microsoft.FSharp.Quotations.FSharpExpr.Deserialize40(Type qualifyingType, Type[] referencedTypes, Type[] spliceTypes, FSharpExpr[] spliceExprs, Byte[] bytes) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 2092
at Tomra.Ts.Core.MapTests.Keys works as expected()

This is the test:

    let [<Fact>] ``Keys works as expected``() =
        let map = Map.ofList [ (1, "One"); (2, "Two"); (3, "Three") ]
        test <@ map |> Map.keys |> List.ofSeq = [1; 2; 3] @>

And this is the code being tested:

namespace global

open System

[<RequireQualifiedAccess>]
module Map =

    let keys (map: Map<_, _>) =
        seq {
            for KeyValue(key, _) in map do
                yield key
        }

I have no clue why it sometimes fails. It's all pure, nothing changes. I'm not saying it's Unquote that's at fault here, but I'm wondering if this rings a bell or if I'm maybe doing something incorrect here?

stephen-swensen commented 2 years ago

Hi @tmoers - curious, your test as written looks perfectly legitimate and I can't see offhand why it would randomly fail. The stack trace seems to indicate the issue may be within the FSharp.Core quotation code itself. Perhaps some kind of assembly loading race condition (just a hunch). I wonder if the issue could be reproduce by running the code in a loop or something like that (again just thinking aloud). I'll reflect on it a bit and maybe try some things to see if I can reproduce.