pulumi/pkg/codegen/testing/test
Zaid Ajaj e88cd05f52
[sdk/program-gen] Implementing DeferredOutput for Go SDK and program-gen (#17885)
### Description

This PR addresses https://github.com/pulumi/pulumi/issues/17788 by
implementing a `pulumi.DeferredOutput(ctx)` function which can be used
for generating Go programs with mutually dependant components. The
implementation is as follows:
```go
// <sdk/go/internal/types.go>
// DeferredOutput creates an Output whose value can be later resolved from another Output instance.
func DeferredOutput[T any](ctx context.Context) (pulumix.Output[T], func(Output)) {
	var zero T
	rt := reflect.TypeOf(zero)
	state := internal.NewOutputState(nil, rt)
	out := pulumix.Output[T]{OutputState: state}
	resolve := func(o Output) {
		go func() {
			v, known, secret, deps, err := internal.AwaitOutput(ctx, o)
			if err != nil {
				internal.RejectOutput(state, err)
				return
			}
			internal.ResolveOutput(out, v, known, secret, deps)
		}()
	}
	return out, resolve
}
```

This PR implements the usage of this function in Go program-gen but the
results are far from ideal:
- ~Usage of deferred output variables requires an explicit cast from
`AnyOutput` to the target output type where it was used~ Now correctly
casting from the generic output type to target component inputs
- Generating lists of referenced components via a `ForExpression` emits
`"TODO: For expression"`

Example generated code in programs:
```go
secondPasswordLength, resolveSecondPasswordLength := pulumi.DeferredOutput[int](ctx)
first, err := NewFirst(ctx, "first", &FirstArgs{
	PasswordLength: pulumix.Cast[pulumi.IntOutput](secondPasswordLength),
})
```

Fixes #17788

---------

Co-authored-by: Julien <julien@caffeine.lu>
2025-01-04 18:47:30 +00:00
..
README.md Added README.md for SDKGen tests. 2023-03-01 08:39:36 -08:00
dotnet.go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
generate.go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
go.go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
helpers.go Update dotnet to 3.71.1 (#18084) 2024-12-20 12:52:58 +00:00
nodejs.go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
program_driver.go [sdk/program-gen] Implementing DeferredOutput for Go SDK and program-gen (#17885) 2025-01-04 18:47:30 +00:00
program_driver_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
python.go Don't publish test code in `pkg/codegen` (#17517) 2024-10-09 11:09:54 +00:00
sdk_driver.go Reject duplicate schema paths (#17797) 2024-11-18 16:21:09 +00:00
testdata Move codegen testdata (#15549) 2024-03-06 20:36:50 +00:00
type_driver.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00

README.md

SDK Codegen Tests

TestSDKCodegen runs the complete set of SDK code generation tests against a particular language's code generator. It also verifies that the generated code is structurally sound.

The test files live in pkg/codegen/testing/test/testdata and are registered in the following globals in pkg/codegen/testing/test.

  • sdk_driver.go: PulumiPulumiSDKTests
  • program_driver.go: PulumiPulumiProgramTests
  • program_driver.go: PulumiPulumiYAMLProgramTests

An SDK code generation test files consists of a schema and a set of expected outputs for each language. Each test is structured as a directory that contains that information:

 testdata/
     my-simple-schema/   # i.e. `simple-enum-schema`
         schema.(json|yaml)
         go/
         python/
         nodejs/
         dotnet/
         ...

The schema is the only piece that must be manually authored.

Once the schema has been written, the actual codegen outputs can be generated by running the following in pkg/codegen directory:

PULUMI_ACCEPT=true go test ./...

This will rebuild subfolders such as go/ from scratch and store the set of code-generated file names in go/codegen-manifest.json. To generate the code for a specific directory in testdata, run the following instead:

PULUMI_ACCEPT=true go test ./... -run TestGenerate/$dirName

If these outputs look correct, they need to be checked into git and will then serve as the expected values for the normal test runs:

$ go test ./...

That is, the normal test runs will fail if changes to codegen or schema lead to a diff in the generated file set. If the diff is intentional, it can be accepted again via PULUMI_ACCEPT=true.

Writing Program Tests on Generated Code

To support running unit tests over the generated code, the tests also support mixing in manually written $lang-extras files into the generated tree. For example, given the following input:

 testdata/
     my-simple-schema/
         schema.json
         go/
         go-extras/
             tests/
                 go_test.go

The system will copy go-extras/tests/go_test.go into go/tests/go_test.go before performing compilation and unit test checks over the project generated in go.