Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests to aws-typescript #863

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

justinvp
Copy link
Member

@justinvp justinvp commented Dec 17, 2024

This change updates the aws-typescript template to include unit tests using jest. (Once we're happy with this, I'll add the moral equivalent for aws-javascript in a separate PR).

Part of #865

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
import * as infra from "./infra";
Copy link
Member Author

@justinvp justinvp Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's necessary to separate out the resources into a separate module, because we need to export them to be able to interrogate them in the tests. If we exported them from index.ts then they'd show up as stack outputs, which isn't what we want.

This does make the template more complex, but I can't see a better way to handle it. A potential upside is that it does demonstrate how you can organize your resources into separate modules.

I'm using the generic name infra here for this module. We could pick a name related to the type of resource we're creating. In this case, we're creating a Bucket, so we could name this something like storage instead of infra. However, there's some concern new users might think storage has to do with some kind of Pulumi-specific storage so I'd prefer to keep it a generic name. Also, not all templates are going to be creating storage-related resources, and I'd prefer a generic name that could apply consistently to all of our templates (including the regular typescript template, which doesn't create any cloud resources). Happy to consider alternative generic names beside infra, though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the standard jest config, configured to support ts-jest.

Note that this file could be jest.config.ts (TypeScript file), but that requires an explicit dependency on ts-node, which we don't currently have for this template (the vendored copy of ts-node in @pulumi/pulumi is used when running the pulumi program), so I've opted to leave it as a JavaScript file. Let me know if you think we should make it a TypeScript file for the TypeScript templates.

Copy link
Contributor

@julienp julienp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that the line numbers are wrong on test failures:

Screenshot 2024-12-18 at 17 03 19

I /think/ this is because we include the package source-map-support in pulumi, and that might cause the issue jestjs/jest#10330, but I didn't look further than that.

// Test helper to convert a Pulumi Output to a Promise.
// This should only be used in tests.
function promiseOf<T>(output: pulumi.Output<T>): Promise<T> {
return new Promise(resolve => output.apply(resolve));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I experimented with custom jest matchers here #868

This keeps the "magic" of Outputs, and avoids the (slightly wrong) conversion to promises here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not arguing for including these custom matchers in this PR. I was curious to see what it would look like. I think it's something we can follow up with if there are is enough demand to warrant the extra work. We could package the matchers in a library, that can be (optionally) used for writing tests.

@justinvp
Copy link
Member Author

I noticed that the line numbers are wrong on test failures:
I /think/ this is because we include the package source-map-support in pulumi, and that might cause the issue jestjs/jest#10330, but I didn't look further than that.

Nice catch! I tried uncommenting our use of source-map-support in @pulumi/pulumi and that indeed fixed the line problem with jest. I wonder if we should remove our use of source-map-support and run node with the --enable-source-maps option, since the capability is now built-in to Node since 12.12.0 per that issue.

@julienp
Copy link
Contributor

julienp commented Dec 19, 2024

Nice catch! I tried uncommenting our use of source-map-support in @pulumi/pulumi and that indeed fixed the line problem with jest. I wonder if we should remove our use of source-map-support and run node with the --enable-source-maps option, since the capability is now built-in to Node since 12.12.0 per that issue.

Nice, yeah we should absolutely do that! The version of ts-node we include in our dev dependencies also includes source-map-support, but that will not be included in the built package, and in any case I believe the key is removing the line you highlighted, which prevents source-map-support from activating when just importing @pulumi/pulumi, such as when running under jest.

I don't think we need --enable-source-maps.

When running via the CLI, we'll usually run through ts-node (the vendored version, or the user installed version), which will enable source map support on its own. I think everything should be fine if we just remove our activation of it in sdk/nodejs/index.ts.

Source map handling is the business of whatever run the program that includes @pulumi/pulumi, so jest or pulumi CLI (via ts-node). The @pulumi/pulumi library is just that, a library, and it should not do anything about source maps.

import "jest";

// Test helper to convert a Pulumi Output to a Promise.
// This should only be used in tests.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could elaborate a bit more here why this should only be used in tests, maybe something along the lines of:

Suggested change
// This should only be used in tests.
// This should only be used in tests. Outputs track more information
// than Promises, such as the dependencies between resources.
// https://www.pulumi.com/docs/iac/concepts/inputs-outputs/#outputs

});

beforeEach(async () => {
// Dynamically import the infra module.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could mention that this needs to happen after the mocks have been setup, although it is already captured by the use of beforeEach vs beforeAll.

Suggested change
// Dynamically import the infra module.
// Dynamically import the infra module. This needs to happen
// after the mocks have been setup.

@tgummerer
Copy link
Contributor

Nice, yeah we should absolutely do that! The version of ts-node we include in our dev dependencies also includes source-map-support, but that will not be included in the built package, and in any case I believe the key is removing the line you highlighted, which prevents source-map-support from activating when just importing @pulumi/pulumi, such as when running under jest.

Would this also fix pulumi/pulumi#9218?

@julienp
Copy link
Contributor

julienp commented Dec 23, 2024

pulumi/pulumi#9218

Yes! I'll create a PR for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants