Build/Test Issues

FSharp Expression causes compiler results not consistent across grid

Started by marklam on 8,330 views

Using an FSharp.Expr variable in a distributed test causes a warning because the compiler adds debug information containing file paths (NCrunch 3.8.0.3)

To reproduce: (F# 4.1, VS2017)
[list=1]
  • Create an F# class library project and add the NUnit 3.7 Nuget package

  • Use the following test implementation

  • namespace ExpressionTest
    
    open NUnit.Framework
    
    [<TestFixture>]
    type Fixture1() = 
        [<Test>]
        member __.Test1 () = 
            let expression = <@ 99 @>
            Assert.AreEqual("Hello", "Hello")


    The full path to the source file is stored in a byte array, and the length of the path affect the name (288Bytes here)
    .class private abstract auto ansi sealed beforefieldinit '<PrivateImplementationDetails$ExpressionTest>'
           extends [mscorlib]System.Object
    {
      .class explicit ansi sealed nested assembly beforefieldinit T1799_288Bytes@
             extends [mscorlib]System.ValueType
      {
        .pack 0
        .size 288
      } // end of class T1799_288Bytes@
    
    } // end of class '<PrivateImplementationDetails$ExpressionTest>'
    

    and also the call to deserialize the info (0x120 here)
          IL_0088:  ldc.i4     0x120
          IL_008d:  newarr     [mscorlib]System.Byte
          IL_0092:  dup
          IL_0093:  ldtoken    field valuetype '<PrivateImplementationDetails$ExpressionTest>'/T1799_288Bytes@ '<StartupCode$ExpressionTest>'.$Library1::field1800@
          IL_0098:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,
                                                                                                              valuetype [mscorlib]System.RuntimeFieldHandle)
          IL_009d:  call       class [FSharp.Core]Microsoft.FSharp.Quotations.FSharpExpr [FSharp.Core]Microsoft.FSharp.Quotations.FSharpExpr::Deserialize40(class [mscorlib]System.Type,
                                                                                                                                                            class [mscorlib]System.Type[],
                                                                                                                                                            class [mscorlib]System.Type[],
                                                                                                                                                            class [FSharp.Core]Microsoft.FSharp.Quotations.FSharpExpr[],
                                                                                                                                                            uint8[])
    
    Hi, thanks for sharing this problem. I've been able to reproduce it as per your instructions.

    I can confirm a fix for this will be in the next available build of NCrunch.
    A fix for this is available in the build below:

    http://downloads.ncrunch.net/NCrunch_Console_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_Console_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_GridNodeServer_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_GridNodeServer_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_LicenseServer_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_VS2008_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2010_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2010_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_VS2012_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2012_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_VS2013_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2013_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_VS2015_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2015_3.10.0.1.zip
    http://downloads.ncrunch.net/NCrunch_VS2017_3.10.0.1.msi
    http://downloads.ncrunch.net/NCrunch_VS2017_3.10.0.1.zip
    Thanks, but unfortunately, that doesn't fix this case:

    
    namespace ExpressionTest
    
    open NUnit.Framework
    open System.IO
    
    [<TestFixture>]
    type Fixture1() = 
        [<Test>]
        member __.Test1 () = 
            let expression = (fun (x : Stream) -> <@ x.Close() @>)
            Assert.AreEqual("Hello", "Hello")
    


    The differences I'm getting are in tests that use the Foq Nuget package, maybe my repro cases are too narrow.
    A bigger set of examples are available in https://github.com/fsprojects/Foq/tree/master/Examples if that's helpful.
    Thanks, I'll take another look and will get back to you.
    It looks as though these expressions can have a broader footprint in the method structure than I originally thought. I have a broader fix in the pipe for this, I'll include this for you in the next dev build when this is available.

    I recommend sticking with using an 'Impact analysis mode' of 'WatchText' for the time being if you need an immediate workaround for this problem.
    I haven't seen this happening with the newest build, looking good
    Thanks!

    Post a reply

    Log in to reply.