From 9fdbb91f50538e0e121a925505968e2e17fa1379 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Fri, 3 Jul 2020 13:34:20 +0200 Subject: [PATCH 01/14] Ignore NCrunch temp files and local user files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index b43741116dc..cd115a43aaa 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,7 @@ msbuild.binlog /tests/fsharp/regression/5531/compilation.output.test.txt /tests/fsharp/core/fsfromfsviacs/compilation.langversion.old.output.txt /tests/fsharp/core/fsfromfsviacs/compilation.errors.output.txt +*ncrunch*.user +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* From f6256e3933ec8db5147a05c9d90f57c506d55854 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 18:03:16 +0200 Subject: [PATCH 02/14] Showing only failing line in ExprTests, cleanup temp files --- tests/service/ExprTests.fs | 67 ++++++++++++++++++++++++++++---------- tests/service/FsUnit.fs | 20 +++++++++++- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 4b38a14031e..bca2260ebe7 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -13,6 +13,7 @@ open NUnit.Framework open FsUnit open System open System.IO +open System.Text open System.Collections.Generic open FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Service.Tests.Common @@ -929,32 +930,64 @@ let ``Test Optimized Declarations Project1`` () = () let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimized = - let basePath = Path.GetTempFileName() + + /// File is placed in local user's %TEMP%\ExprTests folder + let tempPath = Path.Combine(Path.GetTempPath(), "ExprTests") + do + if Directory.Exists tempPath then () + else Directory.CreateDirectory tempPath |> ignore + + let tempFileName = Path.GetFileName(Path.GetTempFileName()) + let basePath = Path.Combine(tempPath, tempFileName) let fileName = Path.ChangeExtension(basePath, ".fs") let dllName = Path.ChangeExtension(basePath, ".dll") let projFileName = Path.ChangeExtension(basePath, ".fsproj") - let source = System.String.Format(Project1.operatorTests, dnName, fsName) - let replace (s:string) r = s.Replace("let " + r, "// let " + r) - let fileSource = excludedTests |> List.fold replace source - File.WriteAllText(fileName, fileSource) - let args = mkProjectCommandLineArgsSilent (dllName, [fileName]) - let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) - let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously + try + let source = System.String.Format(Project1.operatorTests, dnName, fsName) + let replace (s:string) r = s.Replace("let " + r, "// let " + r) + let fileSource = excludedTests |> List.fold replace source + File.WriteAllText(fileName, fileSource) - for e in wholeProjectResults.Errors do - printfn "%s Operator Tests error: <<<%s>>>" dnName e.Message + let args = [| + yield! mkProjectCommandLineArgsSilent (dllName, [fileName]) + yield @"-r:System.Numerics.dll" // needed for some tests + |] - wholeProjectResults.Errors.Length |> shouldEqual 0 + let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously + + for r in wholeProjectResults.ProjectContext.GetReferencedAssemblies() do + printfn "Referenced assembly %s: %O" r.QualifiedName r.FileName + + let errors = StringBuilder() + for e in wholeProjectResults.Errors do + printfn "%s Operator Tests error: <<<%s>>>" dnName e.Message + errors.AppendLine e.Message |> ignore + + errors.ToString() |> shouldEqual "" + wholeProjectResults.Errors.Length |> shouldEqual 0 + + let fileUnoptimized = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] + let fileOptimized = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] + + // fail test on first line that fails, show difference in output window + printDeclarations None (List.ofSeq fileUnoptimized.Declarations) + |> shouldPairwiseEqual expectedUnoptimized - let fileUnoptimized = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] - let fileOptimized = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] + // fail test on first line that fails, show difference in output window + printDeclarations None (List.ofSeq fileOptimized.Declarations) + |> shouldPairwiseEqual expectedOptimized - printDeclarations None (List.ofSeq fileUnoptimized.Declarations) - |> Seq.toList |> shouldEqual expectedUnoptimized + finally + try + // cleanup: only the source file is written to the temp dir. + File.Delete fileName + if Directory.GetFiles(tempPath) |> Array.isEmpty then + Directory.Delete tempPath - printDeclarations None (List.ofSeq fileOptimized.Declarations) - |> Seq.toList |> shouldEqual expectedOptimized + with _ -> () () diff --git a/tests/service/FsUnit.fs b/tests/service/FsUnit.fs index 497b492cc5d..34a9d7ebdcd 100644 --- a/tests/service/FsUnit.fs +++ b/tests/service/FsUnit.fs @@ -15,9 +15,27 @@ let should (f : 'a -> #Constraint) x (y : obj) = let equal x = new EqualConstraint(x) -// like "should equal", but validates same-type +/// like "should equal", but validates same-type let shouldEqual (x: 'a) (y: 'a) = Assert.AreEqual(x, y, sprintf "Expected: %A\nActual: %A" x y) +/// Same as 'shouldEqual' but goes pairwise over the collections. Lengths must be equal. +let shouldPairwiseEqual (x: seq<_>) (y: seq<_>) = + // using enumerators, because Seq.iter2 allows different lengths silently + let ex = x.GetEnumerator() + let ey = y.GetEnumerator() + let mutable countx = 0 + let mutable county = 0 + while ex.MoveNext() do + countx <- countx + 1 + if ey.MoveNext() then + county <- county + 1 + ey.Current |> shouldEqual ex.Current + + while ex.MoveNext() do countx <- countx + 1 + while ey.MoveNext() do county <- county + 1 + if countx <> county then + Assert.Fail("Collections are of unequal lengths, expected length {0}, actual length is {1}.", countx, county) + let notEqual x = new NotConstraint(new EqualConstraint(x)) let contain x = new ContainsConstraint(x) From 3eb988d0db85a4c0eef95e7d5f2ac49294986930 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 18:04:15 +0200 Subject: [PATCH 03/14] Show sensible message when UnresolvedPathReferenceNoRange is raised by tests --- src/fsharp/ErrorLogger.fs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs index 3e345ea4abf..85dc5d80d47 100755 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -91,7 +91,12 @@ exception PossibleUnverifiableCode of range exception UnresolvedReferenceNoRange of (*assemblyName*) string exception UnresolvedReferenceError of (*assemblyName*) string * range -exception UnresolvedPathReferenceNoRange of (*assemblyName*) string * (*path*) string +exception UnresolvedPathReferenceNoRange of (*assemblyName*) string * (*path*) string with + override this.Message = + match this :> exn with + | UnresolvedPathReferenceNoRange(assemblyName, path) -> sprintf "Assembly: %s, full path: %s" assemblyName path + | _ -> "impossible" + exception UnresolvedPathReference of (*assemblyName*) string * (*path*) string * range From 07822dfed4f9d8b0ddd7c91ca7db28c42ded6d7c Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 18:30:02 +0200 Subject: [PATCH 04/14] Attempt to re-enable two base tests, may need to be re-disabled for Mono --- tests/service/ExprTests.fs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index bca2260ebe7..edcce108ee2 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -639,10 +639,6 @@ let test{0}ToStringOperator (e1:{1}) = string e1 """ [] -// FCS Has a problem with these tests because of FSharp Core versions. -#if !COMPILER_SERVICE_AS_DLL -[] -#endif let ``Test Unoptimized Declarations Project1`` () = let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously @@ -784,10 +780,6 @@ let ``Test Unoptimized Declarations Project1`` () = [] -// FCS Has a problem with these tests because of FSharp Core versions -#if !COMPILER_SERVICE_AS_DLL -[] -#endif let ``Test Optimized Declarations Project1`` () = let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously @@ -804,7 +796,7 @@ let ``Test Optimized Declarations Project1`` () = let file2 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[1] // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times - // Presumably this is very small differences in Mono reflection causing F# printing to change behavious + // Presumably this is very small differences in Mono reflection causing F# printing to change behaviour // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 let filterHack l = l |> List.map (fun (s:string) -> @@ -860,7 +852,7 @@ let ``Test Optimized Declarations Project1`` () = "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShapeFIX, !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; @@ -920,12 +912,12 @@ let ``Test Optimized Declarations Project1`` () = printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList |> filterHack - |> shouldEqual (filterHack expected) + |> shouldPairwiseEqual (filterHack expected) printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList |> filterHack - |> shouldEqual (filterHack expected2) + |> shouldPairwiseEqual (filterHack expected2) () From 3f0d53315614d868b5069ea22e5b19a1e12a0974 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 19:50:14 +0200 Subject: [PATCH 05/14] Cleanup tests that use global state, ensure deletion of temp files --- tests/service/ExprTests.fs | 170 +++++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 52 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index edcce108ee2..a78c8f50b7c 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -23,6 +23,49 @@ let internal exprChecker = FSharpChecker.Create(keepAssemblyContents=true) [] module internal Utils = + let getTempPath() = + Path.Combine(Path.GetTempPath(), "ExprTests") + + /// If it doesn't exists, create a folder 'ExprTests' in local user's %TEMP% folder + let createTempDir() = + let tempPath = getTempPath() + do + if Directory.Exists tempPath then () + else Directory.CreateDirectory tempPath |> ignore + + /// Returns the filename part of a temp file name created with Path.GetTempFileName(). + let getTempFileName() = + let tempFileName = Path.GetTempFileName() + try + let tempFileName = Path.GetFileName(tempFileName) + tempFileName + finally + try + // since Path.GetTempFileName() creates a *.tmp file in the %TEMP% folder, we want to clean it up + File.Delete tempFileName + with _ -> () + + /// Clean up after a test is run. If you need to inspect the create *.fs files, change this function to do nothing. + let cleanupTempFiles files = + for fileName in files do + try + // cleanup: only the source file is written to the temp dir. + File.Delete fileName + with _ -> () + + try + // remove the dir when empty + let tempPath = getTempPath() + if Directory.GetFiles tempPath |> Array.isEmpty then + Directory.Delete tempPath + with _ -> () + + + /// Given just a filename, returns it with changed extension located in %TEMP%\ExprTests + let getTempFilePathChangeExt tmp ext = + Path.Combine(getTempPath(), Path.ChangeExtension(tmp, ext)) + + let rec printExpr low (e:FSharpExpr) = match e with | BasicPatterns.AddressOf(e1) -> "&"+printExpr 0 e1 @@ -281,11 +324,6 @@ module internal Utils = module internal Project1 = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() - let fileName2 = Path.ChangeExtension(base2, ".fs") - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module M @@ -540,7 +578,7 @@ let anonRecd = {| X = 1; Y = 2 |} let anonRecdGet = (anonRecd.X, anonRecd.Y) """ - File.WriteAllText(fileName1, fileSource1) + let fileSource2 = """ module N @@ -573,11 +611,27 @@ let testMutableVar = mutableVar 1 let testMutableConst = mutableConst () """ - File.WriteAllText(fileName2, fileSource2) + let createOptions() = + let temp1 = Utils.getTempFileName() + let temp2 = Utils.getTempFileName() + let fileName1 = Utils.getTempFilePathChangeExt temp1 ".fs" // Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let fileName2 = Utils.getTempFilePathChangeExt temp2 ".fs" //Path.ChangeExtension(base2, ".fs") + let dllName = Utils.getTempFilePathChangeExt temp2 ".dll" //Path.ChangeExtension(base2, ".dll") + let projFileName = Utils.getTempFilePathChangeExt temp2 ".fsproj" //Path.ChangeExtension(base2, ".fsproj") + + Utils.createTempDir() + File.WriteAllText(fileName1, fileSource1) + File.WriteAllText(fileName2, fileSource2) + let fileNames = [fileName1; fileName2] + let args = mkProjectCommandLineArgs (dllName, fileNames) + let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + + [fileName1; fileName2; dllName; projFileName], options + + let options = lazy createOptions() + + - let fileNames = [fileName1; fileName2] - let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let operatorTests = """ module OperatorTests{0} @@ -638,9 +692,9 @@ let test{0}ToStringOperator (e1:{1}) = string e1 """ -[] +/// This test is run in unison with its optimized counterpart below let ``Test Unoptimized Declarations Project1`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = exprChecker.ParseAndCheckProject(snd Project1.options.Value) |> Async.RunSynchronously for e in wholeProjectResults.Errors do printfn "Project1 error: <<<%s>>>" e.Message @@ -769,19 +823,18 @@ let ``Test Unoptimized Declarations Project1`` () = printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList |> filterHack - |> shouldEqual (filterHack expected) + |> shouldPairwiseEqual (filterHack expected) printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList |> filterHack - |> shouldEqual (filterHack expected2) + |> shouldPairwiseEqual (filterHack expected2) () - -[] +/// This test is run in unison with its unoptimized counterpart below let ``Test Optimized Declarations Project1`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously + let wholeProjectResults = exprChecker.ParseAndCheckProject(snd Project1.options.Value) |> Async.RunSynchronously for e in wholeProjectResults.Errors do printfn "Project1 error: <<<%s>>>" e.Message @@ -921,32 +974,35 @@ let ``Test Optimized Declarations Project1`` () = () -let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimized = +[] +let ``Test Optimized and Unoptimized Declarations for Project1`` () = + let filenames = fst Project1.options.Value + try + ``Test Optimized Declarations Project1`` () + ``Test Unoptimized Declarations Project1`` () + finally + Utils.cleanupTempFiles filenames - /// File is placed in local user's %TEMP%\ExprTests folder - let tempPath = Path.Combine(Path.GetTempPath(), "ExprTests") - do - if Directory.Exists tempPath then () - else Directory.CreateDirectory tempPath |> ignore +let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimized = - let tempFileName = Path.GetFileName(Path.GetTempFileName()) - let basePath = Path.Combine(tempPath, tempFileName) - let fileName = Path.ChangeExtension(basePath, ".fs") - let dllName = Path.ChangeExtension(basePath, ".dll") - let projFileName = Path.ChangeExtension(basePath, ".fsproj") + let tempFileName = Utils.getTempFileName() + let filePath = Utils.getTempFilePathChangeExt tempFileName ".fs" + let dllPath =Utils.getTempFilePathChangeExt tempFileName ".dll" + let projFilePath = Utils.getTempFilePathChangeExt tempFileName ".fsproj" try + createTempDir() let source = System.String.Format(Project1.operatorTests, dnName, fsName) let replace (s:string) r = s.Replace("let " + r, "// let " + r) let fileSource = excludedTests |> List.fold replace source - File.WriteAllText(fileName, fileSource) + File.WriteAllText(filePath, fileSource) let args = [| - yield! mkProjectCommandLineArgsSilent (dllName, [fileName]) + yield! mkProjectCommandLineArgsSilent (dllPath, [filePath]) yield @"-r:System.Numerics.dll" // needed for some tests |] - let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + let options = checker.GetProjectOptionsFromCommandLineArgs (projFilePath, args) let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunSynchronously @@ -973,13 +1029,7 @@ let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimi |> shouldPairwiseEqual expectedOptimized finally - try - // cleanup: only the source file is written to the temp dir. - File.Delete fileName - if Directory.GetFiles(tempPath) |> Array.isEmpty then - Directory.Delete tempPath - - with _ -> () + Utils.cleanupTempFiles [filePath; dllPath; projFilePath] () @@ -2760,10 +2810,6 @@ let ``Test Operator Declarations for String`` () = module internal ProjectStressBigExpressions = - let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") - let base2 = Path.GetTempFileName() - let dllName = Path.ChangeExtension(base2, ".dll") - let projFileName = Path.ChangeExtension(base2, ".fsproj") let fileSource1 = """ module StressBigExpressions @@ -2951,16 +2997,30 @@ let BigSequenceExpression(outFileOpt,docFileOpt,baseAddressOpt) = """ - File.WriteAllText(fileName1, fileSource1) - let fileNames = [fileName1] - let args = mkProjectCommandLineArgs (dllName, fileNames) - let options = exprChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + let createOptions() = + let temp1 = Utils.getTempFileName() + let temp2 = Utils.getTempFileName() + let fileName1 = Utils.getTempFilePathChangeExt temp1 ".fs" //Path.ChangeExtension(Path.GetTempFileName(), ".fs") + let dllName = Utils.getTempFilePathChangeExt temp2 ".dll" //Path.ChangeExtension(base2, ".dll") + let projFileName = Utils.getTempFilePathChangeExt temp2 ".fsproj" //Path.ChangeExtension(base2, ".fsproj") -[] + Utils.createTempDir() + File.WriteAllText(fileName1, fileSource1) + + let fileNames = [fileName1] + let args = mkProjectCommandLineArgs (dllName, fileNames) + let options = exprChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + + [fileName1; dllName; projFileName], options + + let options = lazy createOptions() + + +/// This test is run in unison with its optimized counterpart below let ``Test expressions of declarations stress big expressions`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(ProjectStressBigExpressions.options) |> Async.RunSynchronously + let wholeProjectResults = exprChecker.ParseAndCheckProject(snd ProjectStressBigExpressions.options.Value) |> Async.RunSynchronously wholeProjectResults.Errors.Length |> shouldEqual 0 @@ -2971,9 +3031,9 @@ let ``Test expressions of declarations stress big expressions`` () = printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList |> ignore -[] +/// This test is run in unison with its unoptimized counterpart below let ``Test expressions of optimized declarations stress big expressions`` () = - let wholeProjectResults = exprChecker.ParseAndCheckProject(ProjectStressBigExpressions.options) |> Async.RunSynchronously + let wholeProjectResults = exprChecker.ParseAndCheckProject(snd ProjectStressBigExpressions.options.Value) |> Async.RunSynchronously wholeProjectResults.Errors.Length |> shouldEqual 0 @@ -2983,5 +3043,11 @@ let ``Test expressions of optimized declarations stress big expressions`` () = // This should not stack overflow printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList |> ignore - - +[] +let ``Test expressions of both optimized and unoptimized declarations for StressTest Big Expressions`` () = + let filenames = fst ProjectStressBigExpressions.options.Value + try + ``Test expressions of optimized declarations stress big expressions`` () + ``Test expressions of declarations stress big expressions`` () + finally + Utils.cleanupTempFiles filenames From f1c0904b7d95c9b9a5fd32188ad72ce081247b95 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 21:06:54 +0200 Subject: [PATCH 06/14] Fix difference Mono, fix spacing difference CI vs VS IDE --- tests/service/ExprTests.fs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index a78c8f50b7c..8a181b1b3fb 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -853,8 +853,10 @@ let ``Test Optimized Declarations Project1`` () = // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 let filterHack l = l |> List.map (fun (s:string) -> - s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShapeFIX") - .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX")) + // potential difference on Mono + s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShape [(Some 0, null)]") + // spacing difference when run locally in VS + .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, None)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)]")) let expected = [ "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; @@ -905,7 +907,7 @@ let ``Test Optimized Declarations Project1`` () = "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShapeFIX, !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; From 513345eee3b3090695d321346a0318c0baab30a5 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 4 Jul 2020 21:33:40 +0200 Subject: [PATCH 07/14] Normalize null vs None --- tests/service/ExprTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 8a181b1b3fb..f75e156c157 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -856,7 +856,7 @@ let ``Test Optimized Declarations Project1`` () = // potential difference on Mono s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShape [(Some 0, null)]") // spacing difference when run locally in VS - .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, None)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)]")) + .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, null)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)]")) let expected = [ "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; @@ -907,7 +907,7 @@ let ``Test Optimized Declarations Project1`` () = "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, None)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; From bc2c707182ad54097455b96a6852b98b28e3a22e Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sun, 5 Jul 2020 00:23:41 +0200 Subject: [PATCH 08/14] Fix next issue difference between CI and local --- tests/service/ExprTests.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index f75e156c157..e01fd72c974 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -714,7 +714,8 @@ let ``Test Unoptimized Declarations Project1`` () = let filterHack l = l |> List.map (fun (s:string) -> s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShapeFIX") - .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX")) + .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX") + .Replace("Operators.Hash (x)", "x.GetHashCode()")) let expected = [ "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; From 8caa000cf2560995fe16e505ff31da4fa71454e8 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sun, 5 Jul 2020 01:00:50 +0200 Subject: [PATCH 09/14] Make sure both smoke tests use the same filterhack function --- tests/service/ExprTests.fs | 46 ++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index e01fd72c974..f60b6cd7f03 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -65,6 +65,17 @@ module internal Utils = let getTempFilePathChangeExt tmp ext = Path.Combine(getTempPath(), Path.ChangeExtension(tmp, ext)) + // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times + // Presumably this is very small differences in Mono reflection causing F# printing to change behaviour + // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 + let filterHack l = + l |> List.map (fun (s:string) -> + // potential difference on Mono + s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShape [(Some 0, null)]") + // spacing difference when run locally in VS + .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, null)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)]") + // local VS IDE vs CI env difference + .Replace("Operators.Hash (x)", "x.GetHashCode()")) let rec printExpr low (e:FSharpExpr) = match e with @@ -708,15 +719,6 @@ let ``Test Unoptimized Declarations Project1`` () = let file1 = wholeProjectResults.AssemblyContents.ImplementationFiles.[0] let file2 = wholeProjectResults.AssemblyContents.ImplementationFiles.[1] - // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times - // Presumably this is very small differences in Mono reflection causing F# printing to change behavious - // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 - let filterHack l = - l |> List.map (fun (s:string) -> - s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShapeFIX") - .Replace("ILArrayShape [(Some 0, null)]", "ILArrayShapeFIX") - .Replace("Operators.Hash (x)", "x.GetHashCode()")) - let expected = [ "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; @@ -823,13 +825,13 @@ let ``Test Unoptimized Declarations Project1`` () = printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList - |> filterHack - |> shouldPairwiseEqual (filterHack expected) + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected) printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList - |> filterHack - |> shouldPairwiseEqual (filterHack expected2) + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected2) () @@ -849,16 +851,6 @@ let ``Test Optimized Declarations Project1`` () = let file1 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[0] let file2 = wholeProjectResults.GetOptimizedAssemblyContents().ImplementationFiles.[1] - // This behaves slightly differently on Mono versions, 'null' is printed somethimes, 'None' other times - // Presumably this is very small differences in Mono reflection causing F# printing to change behaviour - // For now just disabling this test. See https://github.com/fsharp/FSharp.Compiler.Service/pull/766 - let filterHack l = - l |> List.map (fun (s:string) -> - // potential difference on Mono - s.Replace("ILArrayShape [(Some 0, None)]", "ILArrayShape [(Some 0, null)]") - // spacing difference when run locally in VS - .Replace("I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, null)],!0)]", "I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)]")) - let expected = [ "type M"; "type IntAbbrev"; "let boolEx1 = True @ (6,14--6,18)"; "let intEx1 = 1 @ (7,13--7,14)"; "let int64Ex1 = 1 @ (8,15--8,17)"; @@ -967,13 +959,13 @@ let ``Test Optimized Declarations Project1`` () = printDeclarations None (List.ofSeq file1.Declarations) |> Seq.toList - |> filterHack - |> shouldPairwiseEqual (filterHack expected) + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected) printDeclarations None (List.ofSeq file2.Declarations) |> Seq.toList - |> filterHack - |> shouldPairwiseEqual (filterHack expected2) + |> Utils.filterHack + |> shouldPairwiseEqual (Utils.filterHack expected2) () From 6684c2bfd10ad721dbae5008f52fafcf1fd58931 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sun, 5 Jul 2020 01:35:06 +0200 Subject: [PATCH 10/14] Next fix, overlooked --- tests/service/ExprTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index f60b6cd7f03..c18232ba7dc 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -768,7 +768,7 @@ let ``Test Unoptimized Declarations Project1`` () = "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition (m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShapeFIX, !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; + "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress, false, ILArrayShape [(Some 0, null)], !0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = Operators.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref = &dt2 in let dt7: System.TimeSpan = Operators.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; From 60fa6b10e072dc80b373107f4d263db7f81eb6e7 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 11 Jul 2020 17:51:36 +0200 Subject: [PATCH 11/14] Add procid and threadid to temp file --- tests/service/ExprTests.fs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index c18232ba7dc..ba7acd11209 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -33,19 +33,22 @@ module internal Utils = if Directory.Exists tempPath then () else Directory.CreateDirectory tempPath |> ignore - /// Returns the filename part of a temp file name created with Path.GetTempFileName(). + /// Returns the filename part of a temp file name created with Path.GetTempFileName() + /// and an added process id and thread id to ensure uniqueness between threads. let getTempFileName() = let tempFileName = Path.GetTempFileName() try - let tempFileName = Path.GetFileName(tempFileName) - tempFileName + let tempFile, tempExt = Path.GetFileNameWithoutExtension tempFileName, Path.GetExtension tempFileName + let procId, threadId = System.Diagnostics.Process.GetCurrentProcess().Id, System.Threading.Thread.CurrentThread.ManagedThreadId + String.concat "" [tempFile; "_"; string procId; "_"; string threadId; tempExt] // ext includes dot finally try - // since Path.GetTempFileName() creates a *.tmp file in the %TEMP% folder, we want to clean it up + // Since Path.GetTempFileName() creates a *.tmp file in the %TEMP% folder, we want to clean it up. + // This also prevents a system to run out of available randomized temp files (the pool is only 64k large). File.Delete tempFileName with _ -> () - /// Clean up after a test is run. If you need to inspect the create *.fs files, change this function to do nothing. + /// Clean up after a test is run. If you need to inspect the create *.fs files, change this function to do nothing, or just break here. let cleanupTempFiles files = for fileName in files do try From 2a64fa8a3ad1185616e4466c16877adacf443bf5 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 11 Jul 2020 18:02:51 +0200 Subject: [PATCH 12/14] Move #r System.Numerics to mkStandardProjectReferences --- tests/service/Common.fs | 1 + tests/service/ExprTests.fs | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/service/Common.fs b/tests/service/Common.fs index 8eff8813050..5b48e637d96 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -96,6 +96,7 @@ let mkStandardProjectReferences () = [ yield sysLib "mscorlib" yield sysLib "System" yield sysLib "System.Core" + yield sysLib "System.Numerics" yield fsCoreDefaultReference() ] #endif diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index ba7acd11209..131bf149c87 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -995,10 +995,7 @@ let testOperators dnName fsName excludedTests expectedUnoptimized expectedOptimi let fileSource = excludedTests |> List.fold replace source File.WriteAllText(filePath, fileSource) - let args = [| - yield! mkProjectCommandLineArgsSilent (dllPath, [filePath]) - yield @"-r:System.Numerics.dll" // needed for some tests - |] + let args = mkProjectCommandLineArgsSilent (dllPath, [filePath]) let options = checker.GetProjectOptionsFromCommandLineArgs (projFilePath, args) From 04b8032c244e284637b526943d8ddbd85cb26b27 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 11 Jul 2020 18:07:45 +0200 Subject: [PATCH 13/14] Cleanup --- tests/service/ExprTests.fs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 131bf149c87..b2198e71748 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -15,6 +15,8 @@ open System open System.IO open System.Text open System.Collections.Generic +open System.Diagnostics +open System.Threading open FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Service.Tests.Common @@ -39,7 +41,7 @@ module internal Utils = let tempFileName = Path.GetTempFileName() try let tempFile, tempExt = Path.GetFileNameWithoutExtension tempFileName, Path.GetExtension tempFileName - let procId, threadId = System.Diagnostics.Process.GetCurrentProcess().Id, System.Threading.Thread.CurrentThread.ManagedThreadId + let procId, threadId = Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId String.concat "" [tempFile; "_"; string procId; "_"; string threadId; tempExt] // ext includes dot finally try From 70b58eb084f5b036eee78dfc3f74d5c185134e9f Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Sat, 11 Jul 2020 20:18:06 +0200 Subject: [PATCH 14/14] Fix tests that actually count references and are dependent on Common.fs --- tests/service/MultiProjectAnalysisTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/service/MultiProjectAnalysisTests.fs b/tests/service/MultiProjectAnalysisTests.fs index 6d915d486a8..8a7cc4b6836 100644 --- a/tests/service/MultiProjectAnalysisTests.fs +++ b/tests/service/MultiProjectAnalysisTests.fs @@ -142,7 +142,7 @@ let ``Test multi project 1 whole project errors`` () = printfn "multi project 1 error: <<<%s>>>" e.Message wholeProjectResults .Errors.Length |> shouldEqual 0 - wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual 6 + wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual 7 [] let ``Test multi project 1 basic`` () = @@ -335,7 +335,7 @@ let ``Test ManyProjectsStressTest whole project errors`` () = printfn "ManyProjectsStressTest error: <<<%s>>>" e.Message wholeProjectResults .Errors.Length |> shouldEqual 0 - wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual (ManyProjectsStressTest.numProjectsForStressTest + 4) + wholeProjectResults.ProjectContext.GetReferencedAssemblies().Length |> shouldEqual (ManyProjectsStressTest.numProjectsForStressTest + 5) [] let ``Test ManyProjectsStressTest basic`` () =