public void InvokesEntrypoint_Async_Exception() { // Arrange var assembly = CompileToAssembly(@" public static TaskCompletionSource<object> ContinueTcs { get; } = new TaskCompletionSource<object>(); public static async Task Main() { await ContinueTcs.Task; DidMainExecute = true; throw new InvalidTimeZoneException(""Test message""); }", out var didMainExecute); // Act/Assert 1: Waits for task EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }); Assert.False(didMainExecute()); // Act/Assert 2: Continues // As above, we can't directly observe the exception handling behavior here, // so this is covered in E2E tests instead. var tcs = (TaskCompletionSource <object>)assembly.GetType("SomeApp.Program").GetProperty("ContinueTcs").GetValue(null); tcs.SetResult(null); Assert.True(didMainExecute()); }
public void InvokesEntrypoint_Async_Success(bool hasReturnValue, bool hasParams) { // Arrange var returnTypeGenericParam = hasReturnValue ? "<int>" : string.Empty; var paramsDecl = hasParams ? "string[] args" : string.Empty; var returnStatement = hasReturnValue ? "return 123;" : "return;"; var assembly = CompileToAssembly(@" public static TaskCompletionSource<object> ContinueTcs { get; } = new TaskCompletionSource<object>(); static async Task" + returnTypeGenericParam + @" Main(" + paramsDecl + @") { await ContinueTcs.Task; DidMainExecute = true; " + returnStatement + @" }", out var didMainExecute); // Act/Assert 1: Waits for task // The fact that we're not blocking here proves that we're not executing the // metadata-declared entrypoint, as that would block EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }); Assert.False(didMainExecute()); // Act/Assert 2: Continues var tcs = (TaskCompletionSource <object>)assembly.GetType("SomeApp.Program").GetProperty("ContinueTcs").GetValue(null); tcs.SetResult(null); Assert.True(didMainExecute()); }
public void InvokesEntrypoint_Sync_Exception() { // Arrange var assembly = CompileToAssembly(@" public static void Main() { DidMainExecute = true; throw new InvalidTimeZoneException(""Test message""); }", out var didMainExecute); // Act/Assert // The fact that this doesn't throw shows that EntrypointInvoker is doing something // to handle the exception. We can't assert about what it does here, because that // would involve capturing console output, which isn't safe in unit tests. Instead // we'll check this in E2E tests. EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }); Assert.True(didMainExecute()); }
public void InvokesEntrypoint_Sync_Success(bool hasReturnValue, bool hasParams) { // Arrange var returnType = hasReturnValue ? "int" : "void"; var paramsDecl = hasParams ? "string[] args" : string.Empty; var returnStatement = hasReturnValue ? "return 123;" : "return;"; var assembly = CompileToAssembly(@" static " + returnType + @" Main(" + paramsDecl + @") { DidMainExecute = true; " + returnStatement + @" }", out var didMainExecute); // Act EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }); // Assert Assert.True(didMainExecute()); }