diff --git a/pkg/go.sum b/pkg/go.sum index 5c784a291..01b768ddd 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -416,7 +416,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/pulumi/pulumi-aws/sdk/v2 v2.13.1/go.mod h1:Ym4hqC6LOLnZQOtbcW4BkXKCFtAgyzbCGw4EotugYr8= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= diff --git a/scripts/go.mod b/scripts/go.mod index b48e0d02b..d2dbd579f 100644 --- a/scripts/go.mod +++ b/scripts/go.mod @@ -2,6 +2,6 @@ module github.com/pulumi/pulumi/scripts/v2 go 1.14 -require github.com/pulumi/pulumi/sdk/v2 v2.0.0 +require github.com/pulumi/pulumi/sdk/v2 v2.2.1 replace github.com/pulumi/pulumi/sdk/v2 => ../sdk diff --git a/sdk/go.mod b/sdk/go.mod index ef70f3a57..adce6163c 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -23,7 +23,6 @@ require ( github.com/opentracing/basictracer-go v1.0.0 // indirect github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 - github.com/pulumi/pulumi-aws/sdk/v2 v2.13.1 github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 github.com/spf13/cast v1.3.1 github.com/spf13/cobra v1.0.0 diff --git a/sdk/go.sum b/sdk/go.sum index 8a1f9deae..c6ba5d919 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -153,12 +153,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/pulumi/pulumi-aws v1.31.0 h1:m3RXWnrV6jzfHJdGc6iGouoQmCtNo69VxTq9Z3QPm2w= -github.com/pulumi/pulumi-aws v2.13.1+incompatible h1:5K7E2kLlxnguvY+rpvwbPkkoq9nJtxwzDCrHviiYAdA= -github.com/pulumi/pulumi-aws/sdk v1.31.0 h1:E6RfPg46zsDJLidyh1vC7Gq9M5zFbjnezJqcG7zKchw= -github.com/pulumi/pulumi-aws/sdk/v2 v2.13.1 h1:MpNG/tTijoVIj/iI59m93/XqJOyuoPuZ747ijHw6u74= -github.com/pulumi/pulumi-aws/sdk/v2 v2.13.1/go.mod h1:Ym4hqC6LOLnZQOtbcW4BkXKCFtAgyzbCGw4EotugYr8= -github.com/pulumi/pulumi/sdk/v2 v2.2.1/go.mod h1:QNbWpL4gvf3X0lUFT7TXA2Jo1ff/Ti2l97AyFGYwvW4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0= diff --git a/sdk/go/x/auto/errors_test.go b/sdk/go/x/auto/errors_test.go new file mode 100644 index 000000000..cab164f02 --- /dev/null +++ b/sdk/go/x/auto/errors_test.go @@ -0,0 +1,447 @@ +package auto + +import ( + "context" + "fmt" + "os/exec" + "path/filepath" + "testing" + + "github.com/pulumi/pulumi/sdk/v2/go/pulumi" + "github.com/stretchr/testify/assert" +) + +func TestConcurrentUpdateError(t *testing.T) { + ctx := context.Background() + pName := "conflict_error" + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, pName, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "conflict_error") + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + c := make(chan error) + + // parallel updates to cause conflict + for i := 0; i < 5; i++ { + go func() { + _, err := s.Up(ctx) + c <- err + }() + } + + conflicts := 0 + + for i := 0; i < 5; i++ { + err := <-c + if IsConcurrentUpdateError(err) { + conflicts++ + } + } + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } + + // should have at least one conflict + assert.Greater(t, conflicts, 0) +} + +func TestInlineConcurrentUpdateError(t *testing.T) { + ctx := context.Background() + pName := "inline_conflict_error" + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, pName, sName) + + // initialize + s, err := NewStackInlineSource(ctx, fqsn, func(ctx *pulumi.Context) error { + ctx.Export("exp_static", pulumi.String("foo")) + return nil + }) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + c := make(chan error) + + // parallel updates to cause conflict + for i := 0; i < 5; i++ { + go func() { + _, err := s.Up(ctx) + c <- err + }() + } + + conflicts := 0 + + for i := 0; i < 5; i++ { + err := <-c + if IsConcurrentUpdateError(err) { + conflicts++ + } + } + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } + + // should have at least one conflict + assert.Greater(t, conflicts, 0) +} + +const compilationErrProj = "compilation_error" + +func TestCompilationErrorGo(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, compilationErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "compilation_error", "go") + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsCompilationError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestCompilationErrorDotnet(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, compilationErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "compilation_error", "dotnet") + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsCompilationError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestCompilationErrorTypescript(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, compilationErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "compilation_error", "typescript") + + cmd := exec.Command("yarn", "install") + cmd.Dir = pDir + err := cmd.Run() + if err != nil { + t.Errorf("failed to install project dependencies") + t.FailNow() + } + + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsCompilationError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +const runtimeErrProj = "runtime_error" + +func TestRuntimeErrorGo(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "runtime_error", "go") + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestRuntimeErrorInlineGo(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + s, err := NewStackInlineSource(ctx, fqsn, func(ctx *pulumi.Context) error { + var x []string + ctx.Export("a", pulumi.String(x[0])) + return nil + }) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestRuntimeErrorPython(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "runtime_error", "python") + + cmd := exec.Command("python3", "-m", "venv", "venv") + cmd.Dir = pDir + err := cmd.Run() + if err != nil { + t.Errorf("failed to install project dependencies") + t.FailNow() + } + + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestRuntimeErrorJavascript(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "runtime_error", "javascript") + + cmd := exec.Command("yarn", "install") + cmd.Dir = pDir + err := cmd.Run() + if err != nil { + t.Errorf("failed to install project dependencies") + t.FailNow() + } + + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestRuntimeErrorTypescript(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "runtime_error", "typescript") + + cmd := exec.Command("yarn", "install") + cmd.Dir = pDir + err := cmd.Run() + if err != nil { + t.Errorf("failed to install project dependencies") + t.FailNow() + } + + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} + +func TestRuntimeErrorDotnet(t *testing.T) { + ctx := context.Background() + sName := fmt.Sprintf("int_test%d", rangeIn(10000000, 99999999)) + fqsn := FullyQualifiedStackName(pulumiOrg, runtimeErrProj, sName) + + // initialize + pDir := filepath.Join(".", "test", "errors", "runtime_error", "dotnet") + s, err := NewStackLocalSource(ctx, fqsn, pDir) + if err != nil { + t.Errorf("failed to initialize stack, err: %v", err) + t.FailNow() + } + + defer func() { + // -- pulumi stack rm -- + err = s.Workspace().RemoveStack(ctx, s.Name()) + assert.Nil(t, err, "failed to remove stack. Resources have leaked.") + }() + + _, err = s.Up(ctx) + assert.NotNil(t, err) + assert.True(t, IsRuntimeError(err)) + + // -- pulumi destroy -- + + _, err = s.Destroy(ctx) + if err != nil { + t.Errorf("destroy failed, err: %v", err) + t.FailNow() + } +} diff --git a/tests/go.sum b/tests/go.sum index c118cc2ea..f66992b86 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -400,7 +400,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/pulumi/pulumi-aws/sdk/v2 v2.13.1/go.mod h1:Ym4hqC6LOLnZQOtbcW4BkXKCFtAgyzbCGw4EotugYr8= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=