diff --git a/provider/provider_nodejs_test.go b/provider/provider_nodejs_test.go index 73ff42a577..750c2d18dc 100644 --- a/provider/provider_nodejs_test.go +++ b/provider/provider_nodejs_test.go @@ -313,6 +313,66 @@ func TestRegress4568(t *testing.T) { }) } +// Tests that there are no diagnostics by default on simple programs. +func TestNoExtranousLogOutput(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "bucket-obj") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + result := test.Preview(t) + assert.NotContainsf(t, result.StdOut, "Diagnostics:", + "No diagnostics should be emitted to stdout for simple programs") + assert.NotContainsf(t, result.StdErr, "Diagnostics:", + "No diagnostics should be emitted to stderr for simple programs") +} + +// Since AWS is doing something non-standard with logging, double-check that `log.Printf` messages do get propagated +// when TF_LOG=DEBUG is set. One such message is set by aws.s3.Bucketv2 when refresh finds that the bucket no longer +// exists. Emulate this situation and assert that the message has propagated. +func TestUpstreamWarningsPropagated(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "disappearing-bucket-object") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + opttest.Env("TF_LOG", "DEBUG"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + + t.Logf("Creating the bucket object") + test.Up(t) + + state := test.ExportStack(t) + + t.Logf("Deleting the bucket object") + test.SetConfig(t, "bucket-object", "exclude") + test.Up(t) + + t.Logf("Resetting the state back") + test.ImportStack(t, state) + + t.Logf("Refreshing the stack and expecting bucket to be deleted from the state") + rr := test.Refresh(t) + t.Logf("%v%v", rr.StdOut, rr.StdErr) + + // Upstream code has this line: + // + // log.Printf("[WARN] S3 Object (%s) not found, removing from state", d.Id()) + // + assert.Containsf(t, + rr.StdErr+rr.StdOut, + "warning: S3 Object (index.ts) not found, removing from state", + "Expected upstream log.Printf to propagate under TF_LOG=DEBUG") +} + func getJSBaseOptions(t *testing.T) integration.ProgramTestOptions { envRegion := getEnvRegion(t) baseJS := integration.ProgramTestOptions{ diff --git a/provider/test-programs/disappearing-bucket-object/Pulumi.yaml b/provider/test-programs/disappearing-bucket-object/Pulumi.yaml new file mode 100644 index 0000000000..de1098be9d --- /dev/null +++ b/provider/test-programs/disappearing-bucket-object/Pulumi.yaml @@ -0,0 +1,2 @@ +name: disappearing-bucket-object +runtime: nodejs diff --git a/provider/test-programs/disappearing-bucket-object/index.ts b/provider/test-programs/disappearing-bucket-object/index.ts new file mode 100644 index 0000000000..f050c1deed --- /dev/null +++ b/provider/test-programs/disappearing-bucket-object/index.ts @@ -0,0 +1,13 @@ +import * as aws from "@pulumi/aws"; +import * as pulumi from "@pulumi/pulumi"; + +const cfg = new pulumi.Config(); +const b = new aws.s3.BucketV2("my-bucket", {}); + +if (cfg.get("bucket-object") !== "exclude") { + const o = new aws.s3.BucketObjectv2("obj", { + bucket: b.bucket, + key: "index.ts", + source: new pulumi.asset.FileAsset("index.ts"), + }); +} diff --git a/provider/test-programs/disappearing-bucket-object/package.json b/provider/test-programs/disappearing-bucket-object/package.json new file mode 100644 index 0000000000..34852b9bd1 --- /dev/null +++ b/provider/test-programs/disappearing-bucket-object/package.json @@ -0,0 +1,15 @@ +{ + "name": "disappearing-bucket-object", + "version": "0.1.0", + "license": "Apache-2.0", + "scripts": { + "build": "tsc" + }, + "dependencies": { + "@pulumi/pulumi": "^3.0.0", + "@pulumi/aws": "^6.0.0" + }, + "devDependencies": { + "@types/node": "^8.0.0" + } +} diff --git a/provider/test-programs/disappearing-bucket-object/tsconfig.json b/provider/test-programs/disappearing-bucket-object/tsconfig.json new file mode 100644 index 0000000000..101fc997d5 --- /dev/null +++ b/provider/test-programs/disappearing-bucket-object/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "outDir": "bin", + "target": "es2016", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "experimentalDecorators": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true, + "strictNullChecks": true + }, + "files": [ + "index.ts" + ] +} \ No newline at end of file diff --git a/provider/upstream_provider.go b/provider/upstream_provider.go index 167ef09166..cf492dd7e4 100644 --- a/provider/upstream_provider.go +++ b/provider/upstream_provider.go @@ -16,6 +16,9 @@ package provider import ( "context" + "io" + "log" + "os" awsShim "github.com/hashicorp/terraform-provider-aws/shim" "github.com/pulumi/pulumi-aws/provider/v6/pkg/rds" @@ -30,6 +33,9 @@ import ( // runtime startup is somewhat performance sensitive. Therefore any modifications undertaken here should complete // quickly. func newUpstreamProvider(ctx context.Context) awsShim.UpstreamProvider { + log.SetOutput(io.Discard) // ignore logging from upstream constructors + defer log.SetOutput(os.Stderr) // revert to default + upstreamProvider, err := awsShim.NewUpstreamProvider(ctx) contract.AssertNoErrorf(err, "NewUpstreamProvider failed to initialize") rds.ReconfigureResources(upstreamProvider.SDKV2Provider)