pulumi / pulumi-dotnet

.NET support for Pulumi
Apache License 2.0
27 stars 25 forks source link

Deployment.TestAsync hangs forever when resource transformation throws an exception #312

Closed darthkurak closed 2 months ago

darthkurak commented 3 months ago

What happened?

Same behavior like in: https://github.com/pulumi/pulumi-dotnet/issues/174 Don't have obvious repro code, because it failed in my bigger codebase. But I think you may throw some exceptions in transformation when running Stack inside from Deployment.TestAsync, something like

Deployment.TestAsync(p => new SomeStackThatHaveTransformations() ) - and you should have a similar effect - the test should hang forever.

Example

Deployment.TestAsync(p => new SomeStackThatHaveTransformations() ) - and you should have a similar effect - the test should hang forever.

Output of pulumi about

'dotnet build -nologo .' completed successfully CLI
Version 3.121.0 Go Version go1.22.4 Go Compiler gc

Plugins KIND NAME VERSION resource azure-native 2.36.0 resource azuread 5.47.2 language dotnet unknown resource mssql 0.0.8 resource random 4.16.0

Host
OS darwin Version 14.5 Arch arm64

This project is written in dotnet: executable='/usr/local/share/dotnet/dotnet' version='8.0.200'

Dependencies: NAME VERSION Pulumi 3.66.0-alpha.48eae07

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

darthkurak commented 3 months ago

@Zaid-Ajaj It would be great If you have time to look at this.

justinvp commented 3 months ago

Thanks for opening the issue @darthkurak. Planning to take a look this week.

justinvp commented 3 months ago

@darthkurak, I haven't been able to reproduce the hang.

I do the following:

pulumi new aws-csharp
dotnet add package xunit
dotnet add package xunit.runner.visualstudio
dotnet add package Microsoft.NET.Test.Sdk

Swap out this code for Program.cs:

using System;
using System.Threading.Tasks;
using Pulumi;
using Pulumi.Aws.S3;
using Pulumi.Testing;
using Xunit;

class MyStack : Stack
{
    static StackOptions Options() => new StackOptions()
    {
        ResourceTransformations = { FailingTransform() }
    };

    public MyStack() : base(Options())
    {
        new Bucket("my-bucket");
    }

    static ResourceTransformation FailingTransform()
        => args => throw new Exception("Boom!");
}

class MyMocks : IMocks
{
    public Task<object> CallAsync(MockCallArgs args)
        => Task.FromResult<object>(args);

    public Task<(string? id, object state)> NewResourceAsync(MockResourceArgs args)
        => Task.FromResult<(string?, object)>((args.Name + "_id", args.Inputs));
}

public class Tests
{
    [Fact]
    public async Task TestTestAsyncStackWithFailingTransform()
    {
        await Assert.ThrowsAnyAsync<Exception>(async () => await Deployment.TestAsync<MyStack>(new MyMocks()));
    }
}

class Program
{
    static Task<int> Main() => Deployment.RunAsync<MyStack>();
}

Run dotnet test and it runs without hanging and the test passes.

darthkurak commented 3 months ago

Hmm… I will check this again on Monday and return to you.

darthkurak commented 2 months ago

Ok, I've checked this. It seems that I made a mistake in the code, running assert inside a lambda function passed to TestAsync:

 _ = await Deployment.TestAsync(
            mocks,
            new TestOptions
            {
                IsPreview = false,
                ProjectName = typeof(BaseTestStack).ToString()
            },
            () =>
            {
                //some code before
                Action act = () => _ = new BaseTestStack(config);
                act.Should().Throw<OptionsValidationException>();
            });

Move this to the outer body and everything works :) Thanks for checking this out, and giving an example!