Skip to content

Commit 4fb264d

Browse files
authored
make Assertions.withExitCode work (#17830)
* make Assertions.withExitCode work * allow for different error message in desktop tests * Still another check needed for the desktop error message
1 parent 69cc8a4 commit 4fb264d

File tree

16 files changed

+183
-126
lines changed

16 files changed

+183
-126
lines changed

src/Compiler/Service/service.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ module CompileHelpers =
7272

7373
try
7474
f exiter
75-
0
75+
None
7676
with e ->
7777
stopProcessingRecovery e range0
78-
1
78+
Some e
7979

8080
/// Compile using the given flags. Source files names are resolved via the FileSystem API. The output file must be given by a -o flag.
8181
let compileFromArgs (ctok, argv: string[], legacyReferenceResolver, tcImportsCapture, dynamicAssemblyCreator) =

src/Compiler/Service/service.fsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,12 @@ type public FSharpChecker =
400400
/// Compile using the given flags. Source files names are resolved via the FileSystem API.
401401
/// The output file must be given by a -o flag.
402402
/// The first argument is ignored and can just be "fsc.exe".
403+
/// The method returns the collected diagnostics, and (possibly) a terminating exception.
403404
/// </summary>
404405
///
405406
/// <param name="argv">The command line arguments for the project build.</param>
406407
/// <param name="userOpName">An optional string used for tracing compiler operations associated with this request.</param>
407-
member Compile: argv: string[] * ?userOpName: string -> Async<FSharpDiagnostic[] * int>
408+
member Compile: argv: string[] * ?userOpName: string -> Async<FSharpDiagnostic[] * exn option>
408409

409410
/// <summary>
410411
/// Try to get type check results for a file. This looks up the results of recent type checks of the
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
namespace CompilerDirectives
2+
3+
open Xunit
4+
open FSharp.Test.Compiler
5+
6+
module Ifdef =
7+
8+
let ifdefSource = """
9+
[<EntryPoint>]
10+
let main _ =
11+
#if MYDEFINE1
12+
1
13+
#else
14+
2
15+
#endif
16+
"""
17+
18+
[<InlineData("MYDEFINE1", 1)>]
19+
[<InlineData("MYDEFINE", 2)>]
20+
[<Theory>]
21+
let ifdefTest (mydefine, expectedExitCode) =
22+
23+
FSharp ifdefSource
24+
|> withDefines [mydefine]
25+
|> compileExeAndRun
26+
|> withExitCode expectedExitCode
27+
28+
29+
let sourceExtraEndif = """
30+
#if MYDEFINE1
31+
printf "1"
32+
#endif
33+
(**)#endif(**)
34+
0
35+
"""
36+
37+
[<Fact>]
38+
let extraEndif () =
39+
40+
FSharp sourceExtraEndif
41+
|> withDefines ["MYDEFINE1"]
42+
|> asExe
43+
|> compile
44+
|> withDiagnosticMessage "#endif has no matching #if in implementation file"
45+
46+
let sourceUnknownHash = """
47+
module A
48+
#ifxx
49+
#abc
50+
"""
51+
52+
[<Fact>]
53+
let unknownHashDirectiveIsIgnored () =
54+
55+
FSharp sourceUnknownHash
56+
|> compile
57+
|> shouldSucceed

tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ else ()
4545
|> compile
4646
|> run
4747
|> shouldSucceed
48-
|> withExitCode 0
4948

5049
[<Fact>]
5150
let ``Respect nowarn 957 for extension method`` () =

tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ let ``Stackoverflow reproduction`` compilation =
5656
| CompilationResult.Success ({OutputPath = Some dllFile} as s) ->
5757
let fsharpCoreFile = typeof<voption<_>>.Assembly.Location
5858
File.Copy(fsharpCoreFile, Path.Combine(Path.GetDirectoryName(dllFile), Path.GetFileName(fsharpCoreFile)), true)
59-
let exitCode, _stdout, _stderr = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
59+
let _exitCode, _stdout, stderr, _exn = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
6060

61-
Assert.NotEqual(0,exitCode)
61+
Assert.True(stderr.Contains "stack overflow" || stderr.Contains "StackOverflow")
6262

6363
| _ -> failwith (sprintf "%A" compilationResult)
6464

tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
</Compile>
3434
<Compile Include="CompilerDirectives\Line.fs" />
3535
<Compile Include="CompilerDirectives\NonStringArgs.fs" />
36+
<Compile Include="CompilerDirectives\Ifdef.fs" />
3637
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\Basic\Basic.fs" />
3738
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl\OnOverridesAndIFaceImpl.fs" />
3839
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnTypeMembers\OnTypeMembers.fs" />

tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ module CompilationFromCmdlineArgsTests =
3838
yield! methodOptions method
3939
|]
4040

41-
let diagnostics, exitCode = checker.Compile(args) |> Async.RunSynchronously
41+
let diagnostics, exn = checker.Compile(args) |> Async.RunSynchronously
4242

4343
for diag in diagnostics do
4444
printfn "%A" diag
4545

46-
Assert.Equal(exitCode, 0)
46+
Assert.Equal(exn, None)
4747
finally
4848
Environment.CurrentDirectory <- oldWorkDir
4949

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
21662166
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21672167
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
21682168
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
2169-
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
2169+
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
21702170
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21712171
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21722172
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
21662166
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21672167
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
21682168
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
2169-
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
2169+
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
21702170
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21712171
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
21722172
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked

tests/FSharp.Test.Utilities/Compiler.fs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,13 @@ module rec Compiler =
170170
Message: string
171171
SubCategory: string }
172172

173+
// This type is used either for the output of the compiler (typically in CompilationResult coming from 'compile')
174+
// or for the output of the code generated by the compiler (in CompilationResult coming from 'run')
173175
type ExecutionOutput =
174-
{ ExitCode: int
176+
{ ExitCode: int option
175177
StdOut: string
176-
StdErr: string }
178+
StdErr: string
179+
Exn: exn option }
177180

178181
type RunOutput =
179182
| EvalOutput of Result<FsiValue option, exn>
@@ -699,7 +702,7 @@ module rec Compiler =
699702
let private compileFSharpCompilation compilation ignoreWarnings (cUnit: CompilationUnit) : CompilationResult =
700703

701704
use redirect = new RedirectConsole()
702-
let ((err: FSharpDiagnostic[], rc: int, outputFilePath: string), deps) =
705+
let ((err: FSharpDiagnostic[], exn, outputFilePath: string), deps) =
703706
CompilerAssert.CompileRaw(compilation, ignoreWarnings)
704707

705708
// Create and stash the console output
@@ -711,7 +714,7 @@ module rec Compiler =
711714
Adjust = 0
712715
PerFileErrors = diagnostics
713716
Diagnostics = diagnostics |> List.map snd
714-
Output = Some (RunOutput.ExecutionOutput { ExitCode = rc; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput() })
717+
Output = Some (RunOutput.ExecutionOutput { ExitCode = None; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput(); Exn = exn })
715718
Compilation = cUnit
716719
}
717720

@@ -978,14 +981,13 @@ module rec Compiler =
978981
| SourceCodeFileKind.Fsx _ -> true
979982
| _ -> false
980983
| _ -> false
981-
let exitCode, output, errors = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
984+
let exitCode, output, errors, exn = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
982985
printfn "---------output-------\n%s\n-------" output
983986
printfn "---------errors-------\n%s\n-------" errors
984-
let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) }
985-
if exitCode = 0 then
986-
CompilationResult.Success executionResult
987-
else
988-
CompilationResult.Failure executionResult
987+
let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors; Exn = exn }) }
988+
match exn with
989+
| None -> CompilationResult.Success executionResult
990+
| Some _ -> CompilationResult.Failure executionResult
989991

990992
let compileAndRun = compile >> run
991993

@@ -1080,27 +1082,25 @@ module rec Compiler =
10801082
opts.ToArray()
10811083
let errors, stdOut = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
10821084

1083-
let executionOutputwithStdOut: RunOutput option =
1084-
ExecutionOutput { StdOut = stdOut; ExitCode = 0; StdErr = "" }
1085-
|> Some
1086-
let result =
1085+
let mkResult output =
10871086
{ OutputPath = None
10881087
Dependencies = []
10891088
Adjust = 0
10901089
Diagnostics = []
10911090
PerFileErrors= []
1092-
Output = executionOutputwithStdOut
1091+
Output = Some output
10931092
Compilation = cUnit }
1094-
1095-
if errors.Count > 0 then
1096-
let output = ExecutionOutput {
1097-
ExitCode = -1
1098-
StdOut = String.Empty
1099-
StdErr = ((errors |> String.concat "\n").Replace("\r\n","\n")) }
1100-
CompilationResult.Failure { result with Output = Some output }
1093+
1094+
if errors.Count = 0 then
1095+
let output =
1096+
ExecutionOutput { ExitCode = None; StdOut = stdOut; StdErr = ""; Exn = None }
1097+
CompilationResult.Success (mkResult output)
11011098
else
1102-
CompilationResult.Success result
1103-
1099+
let err = (errors |> String.concat "\n").Replace("\r\n","\n")
1100+
let output =
1101+
ExecutionOutput {ExitCode = None; StdOut = String.Empty; StdErr = err; Exn = None }
1102+
CompilationResult.Failure (mkResult output)
1103+
11041104
finally
11051105
disposals
11061106
|> Seq.iter (fun x -> x.Dispose())
@@ -1190,7 +1190,7 @@ Actual:
11901190
| Some p ->
11911191
match ILChecker.verifyILAndReturnActual [] p expected with
11921192
| true, _, _ -> result
1193-
| false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput { StdOut = errorMsg; ExitCode = 0; StdErr = "" })} )
1193+
| false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput {ExitCode = None; StdOut = errorMsg; StdErr = ""; Exn = None })} )
11941194

11951195
| CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}"
11961196

@@ -1706,7 +1706,7 @@ Actual:
17061706
| None -> failwith "Execution output is missing, cannot check exit code."
17071707
| Some o ->
17081708
match o with
1709-
| ExecutionOutput e -> Assert.Equal(expectedExitCode, e.ExitCode)
1709+
| ExecutionOutput {ExitCode = Some exitCode} -> Assert.Equal(expectedExitCode, exitCode)
17101710
| _ -> failwith "Cannot check exit code on this run result."
17111711
result
17121712

0 commit comments

Comments
 (0)