Skip to content

Commit

Permalink
Try to not assume testing.T (#79)
Browse files Browse the repository at this point in the history
Generalizing from concrete `*testing.T` allows using pulumitest in other test contexts, such as rapid testing. A new PT interface is added to abstract over concrete testing contexts.

Breaking: remove `PulumiTest.T()` accessor:

```
func (a *PulumiTest) T() T
```

---------

Co-authored-by: Daniel Bradley <daniel@pulumi.com>
  • Loading branch information
t0yv0 and danielrbradley authored Apr 11, 2024
1 parent f71d02a commit 1eb757e
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 60 deletions.
9 changes: 5 additions & 4 deletions previewProviderUpgrade.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package providertest

import (
"fmt"
"path/filepath"

"github.com/pulumi/providertest/optproviderupgrade"
Expand All @@ -14,8 +15,8 @@ import (
// PreviewProviderUpgrade captures the state of a stack from a baseline provider configuration, then previews the stack
// with the current provider configuration.
// Uses a default cache directory of "testdata/recorded/TestProviderUpgrade/{programName}/{baselineVersion}".
func PreviewProviderUpgrade(pulumiTest *pulumitest.PulumiTest, providerName string, baselineVersion string, opts ...optproviderupgrade.PreviewProviderUpgradeOpt) auto.PreviewResult {
pulumiTest.T().Helper()
func PreviewProviderUpgrade(t pulumitest.PT, pulumiTest *pulumitest.PulumiTest, providerName string, baselineVersion string, opts ...optproviderupgrade.PreviewProviderUpgradeOpt) auto.PreviewResult {
t.Helper()
previewTest := pulumiTest.CopyToTempDir(opttest.NewStackOptions(optnewstack.DisableAutoDestroy()))
options := optproviderupgrade.Defaults()
for _, opt := range opts {
Expand All @@ -25,11 +26,11 @@ func PreviewProviderUpgrade(pulumiTest *pulumitest.PulumiTest, providerName stri
cacheDir := getCacheDir(options, programName, baselineVersion)
previewTest.Run(
func(test *pulumitest.PulumiTest) {
test.T().Helper()
t.Helper()
test.Up()
grptLog := test.GrpcLog()
grpcLogPath := filepath.Join(cacheDir, "grpc.json")
test.T().Logf("writing grpc log to %s", grpcLogPath)
t.Log(fmt.Sprintf("writing grpc log to %s", grpcLogPath))
grptLog.WriteTo(grpcLogPath)
},
optrun.WithCache(filepath.Join(cacheDir, "stack.json")),
Expand Down
4 changes: 2 additions & 2 deletions previewProviderUpgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ func TestPreviewUpgradeCached(t *testing.T) {
test := pulumitest.NewPulumiTest(t, filepath.Join("pulumitest", "testdata", "yaml_program"),
opttest.DownloadProviderVersion("random", "4.15.0"))

uncachedPreviewResult := providertest.PreviewProviderUpgrade(test, "random", "4.5.0",
uncachedPreviewResult := providertest.PreviewProviderUpgrade(t, test, "random", "4.5.0",
optproviderupgrade.CacheDir(cacheDir, "{programName}", "{baselineVersion}"),
optproviderupgrade.DisableAttach())
assertpreview.HasNoReplacements(t, uncachedPreviewResult)
assertpreview.HasNoChanges(t, uncachedPreviewResult)

cachedPreviewResult := providertest.PreviewProviderUpgrade(test, "random", "4.5.0",
cachedPreviewResult := providertest.PreviewProviderUpgrade(t, test, "random", "4.5.0",
optproviderupgrade.CacheDir(cacheDir, "{programName}", "{baselineVersion}"),
optproviderupgrade.DisableAttach())
assert.Equal(t, uncachedPreviewResult, cachedPreviewResult, "expected uncached and cached preview to be the same")
Expand Down
6 changes: 3 additions & 3 deletions pulumitest/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ func (a *PulumiTest) Convert(language string, opts ...opttest.Option) ConvertRes
targetDir := filepath.Join(tempDir, fmt.Sprintf("%s-%s", base, language))
err := os.Mkdir(targetDir, 0755)
if err != nil {
a.t.Fatal(err)
a.fatal(err)
}

a.t.Logf("converting to %s", language)
a.logf("converting to %s", language)
cmd := exec.Command("pulumi", "convert", "--language", language, "--generate-only", "--out", targetDir)
cmd.Dir = a.source
out, err := cmd.CombinedOutput()
if err != nil {
a.t.Fatalf("failed to convert directory: %s\n%s", err, out)
a.fatalf("failed to convert directory: %s\n%s", err, out)
}

options := a.options.Copy()
Expand Down
4 changes: 2 additions & 2 deletions pulumitest/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (a *PulumiTest) CopyToTempDir(opts ...opttest.Option) *PulumiTest {
destination := filepath.Join(tempDir, sourceBase)
err := os.Mkdir(destination, 0755)
if err != nil {
a.t.Fatal(err)
a.fatal(err)
}

return a.CopyTo(destination, opts...)
Expand All @@ -34,7 +34,7 @@ func (a *PulumiTest) CopyTo(dir string, opts ...opttest.Option) *PulumiTest {

err := copyDirectory(a.source, dir)
if err != nil {
a.t.Fatal(err)
a.fatal(err)
}

options := a.options.Copy()
Expand Down
4 changes: 2 additions & 2 deletions pulumitest/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ func (a *PulumiTest) Destroy(opts ...optdestroy.Option) auto.DestroyResult {

a.t.Log("destroying")
if a.currentStack == nil {
a.t.Fatal("no current stack")
a.fatal("no current stack")
}
if !a.options.DisableGrpcLog {
a.ClearGrpcLog()
}
result, err := a.currentStack.Destroy(a.ctx, opts...)
if err != nil {
a.t.Fatalf("failed to destroy: %s", err)
a.fatalf("failed to destroy: %s", err)
}
return result
}
4 changes: 2 additions & 2 deletions pulumitest/exportStack.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ func (a *PulumiTest) ExportStack() apitype.UntypedDeployment {

a.t.Log("exporting stack")
if a.currentStack == nil {
a.t.Fatal("no current stack")
a.fatal("no current stack")
}
out, err := a.currentStack.Workspace().ExportStack(a.Context(), a.currentStack.Name())
if err != nil {
a.t.Fatalf("failed to export stack: %s", err)
a.fatalf("failed to export stack: %s", err)
}
return out
}
4 changes: 2 additions & 2 deletions pulumitest/grpcLog.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (pt *PulumiTest) GrpcLog() *grpclog.GrpcLog {

log, err := grpclog.LoadLog(env["PULUMI_DEBUG_GRPC"])
if err != nil {
pt.t.Fatalf("failed to load grpc log: %s", err)
pt.fatalf("failed to load grpc log: %s", err)
}
return log
}
Expand All @@ -35,6 +35,6 @@ func (pt *PulumiTest) ClearGrpcLog() {
return
}
if err := os.RemoveAll(env["PULUMI_DEBUG_GRPC"]); err != nil {
pt.t.Fatalf("failed to clear gRPC log: %s", err)
pt.fatalf("failed to clear gRPC log: %s", err)
}
}
4 changes: 2 additions & 2 deletions pulumitest/importStack.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ func (a *PulumiTest) ImportStack(source apitype.UntypedDeployment) {

a.t.Log("importing stack")
if a.currentStack == nil {
a.t.Fatal("no current stack")
a.fatal("no current stack")
}
err := a.currentStack.Workspace().ImportStack(a.Context(), a.currentStack.Name(), source)
if err != nil {
a.t.Fatalf("failed to import stack: %s", err)
a.fatalf("failed to import stack: %s", err)
}
}
2 changes: 1 addition & 1 deletion pulumitest/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (a *PulumiTest) Install() string {
cmd.Dir = a.source
out, err := cmd.CombinedOutput()
if err != nil {
a.t.Fatalf("failed to install packages and plugins: %s\n%s", err, out)
a.fatalf("failed to install packages and plugins: %s\n%s", err, out)
}
return string(out)
}
26 changes: 13 additions & 13 deletions pulumitest/newStack.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
providerPorts, err := providers.StartProviders(providerContext, providerFactories, pt)
if err != nil {
cancelProviders()
pt.t.Fatalf("failed to start providers: %v", err)
pt.fatalf("failed to start providers: %v", err)
} else {
pt.t.Cleanup(func() {
cancelProviders()
Expand All @@ -79,14 +79,14 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
stackOpts = append(stackOpts, options.ExtraWorkspaceOptions...)
stackOpts = append(stackOpts, stackOptions.Opts...)

pt.T().Logf("creating stack %s", stackName)
pt.logf("creating stack %s", stackName)
stack, err := auto.NewStackLocalSource(pt.ctx, stackName, pt.source, stackOpts...)

providerPluginPaths := options.ProviderPluginPaths()
if len(providerPluginPaths) > 0 {
projectSettings, err := stack.Workspace().ProjectSettings(pt.ctx)
if err != nil {
pt.t.Fatalf("failed to get project settings: %s", err)
pt.fatalf("failed to get project settings: %s", err)
}
var plugins workspace.Plugins
if projectSettings.Plugins != nil {
Expand All @@ -103,7 +103,7 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
relPath := providerPluginPaths[providers.ProviderName(name)]
absPath, err := filepath.Abs(relPath)
if err != nil {
pt.t.Fatalf("failed to get absolute path for %s: %s", relPath, err)
pt.fatalf("failed to get absolute path for %s: %s", relPath, err)
}

found := false
Expand All @@ -125,18 +125,18 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
projectSettings.Plugins = &plugins
err = stack.Workspace().SaveProjectSettings(pt.ctx, projectSettings)
if err != nil {
pt.t.Fatalf("failed to save project settings: %s", err)
pt.fatalf("failed to save project settings: %s", err)
}
}

if options.YarnLinks != nil && len(options.YarnLinks) > 0 {
for _, pkg := range options.YarnLinks {
cmd := exec.Command("yarn", "link", pkg)
cmd.Dir = pt.source
pt.t.Logf("linking yarn package: %s", cmd)
pt.logf("linking yarn package: %s", cmd)
out, err := cmd.CombinedOutput()
if err != nil {
pt.t.Fatalf("failed to link yarn package %s: %s\n%s", pkg, err, out)
pt.fatalf("failed to link yarn package %s: %s\n%s", pkg, err, out)
}
}
}
Expand All @@ -151,21 +151,21 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
relPath := options.GoModReplacements[old]
absPath, err := filepath.Abs(relPath)
if err != nil {
pt.t.Fatalf("failed to get absolute path for %s: %s", relPath, err)
pt.fatalf("failed to get absolute path for %s: %s", relPath, err)
}
replacement := fmt.Sprintf("%s=%s", old, absPath)
cmd := exec.Command("go", "mod", "edit", "-replace", replacement)
cmd.Dir = pt.source
pt.t.Logf("adding go.mod replacement: %s", cmd)
pt.logf("adding go.mod replacement: %s", cmd)
out, err := cmd.CombinedOutput()
if err != nil {
pt.t.Fatalf("failed to add go.mod replacement %s: %s\n%s", replacement, err, out)
pt.fatalf("failed to add go.mod replacement %s: %s\n%s", replacement, err, out)
}
}
}

if err != nil {
pt.t.Fatalf("failed to create stack: %s", err)
pt.fatalf("failed to create stack: %s", err)
return nil
}
if !stackOptions.SkipDestroy {
Expand All @@ -174,11 +174,11 @@ func (pt *PulumiTest) NewStack(stackName string, opts ...optnewstack.NewStackOpt
pt.t.Log("cleaning up stack")
_, err := stack.Destroy(pt.ctx)
if err != nil {
pt.t.Errorf("failed to destroy stack: %s", err)
pt.errorf("failed to destroy stack: %s", err)
}
err = stack.Workspace().RemoveStack(pt.ctx, stackName, optremove.Force())
if err != nil {
pt.t.Errorf("failed to remove stack: %s", err)
pt.errorf("failed to remove stack: %s", err)
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions pulumitest/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ func (a *PulumiTest) Preview(opts ...optpreview.Option) auto.PreviewResult {

a.t.Log("previewing update")
if a.currentStack == nil {
a.t.Fatal("no current stack")
a.fatal("no current stack")
}
if !a.options.DisableGrpcLog {
a.ClearGrpcLog()
}
result, err := a.currentStack.Preview(a.ctx, opts...)
if err != nil {
a.t.Fatalf("failed to preview update: %s", err)
a.fatalf("failed to preview update: %s", err)
}
return result
}
41 changes: 32 additions & 9 deletions pulumitest/pulumiTest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package pulumitest

import (
"context"
"testing"
"fmt"

"github.com/pulumi/providertest/pulumitest/opttest"
"github.com/pulumi/pulumi/sdk/v3/go/auto"
)

type PulumiTest struct {
t *testing.T
t PT
ctx context.Context
source string
options *opttest.Options
Expand All @@ -21,7 +21,7 @@ type PulumiTest struct {
// 1. Copy the source to a temporary directory.
// 2. Install dependencies.
// 3. Create a new stack called "test" with state stored to a local temporary directory and a fixed passphrase for encryption.
func NewPulumiTest(t *testing.T, source string, opts ...opttest.Option) *PulumiTest {
func NewPulumiTest(t PT, source string, opts ...opttest.Option) *PulumiTest {
t.Helper()
ctx := testContext(t)
options := opttest.DefaultOptions()
Expand All @@ -42,7 +42,7 @@ func NewPulumiTest(t *testing.T, source string, opts ...opttest.Option) *PulumiT
return pt
}

func testContext(t *testing.T) context.Context {
func testContext(t PT) context.Context {
t.Helper()
var ctx context.Context
var cancel context.CancelFunc
Expand Down Expand Up @@ -71,11 +71,6 @@ func (a *PulumiTest) Source() string {
return a.source
}

// T returns the current testing.T instance.
func (a *PulumiTest) T() *testing.T {
return a.t
}

// Context returns the current context.Context instance used for automation API calls.
func (a *PulumiTest) Context() context.Context {
return a.ctx
Expand All @@ -85,3 +80,31 @@ func (a *PulumiTest) Context() context.Context {
func (a *PulumiTest) CurrentStack() *auto.Stack {
return a.currentStack
}

func (a *PulumiTest) logf(format string, args ...any) {
a.t.Log(fmt.Sprintf(format, args...))
}

func (a *PulumiTest) log(args ...any) {
a.t.Log(args...)
}

func (a *PulumiTest) errorf(format string, args ...any) {
a.t.Log(fmt.Sprintf(format, args...))
a.t.Fail()
}

func (a *PulumiTest) error(args ...any) {
a.t.Log(args...)
a.t.Fail()
}

func (a *PulumiTest) fatalf(format string, args ...any) {
a.t.Log(fmt.Sprintf(format, args...))
a.t.FailNow()
}

func (a *PulumiTest) fatal(args ...any) {
a.t.Log(args...)
a.t.FailNow()
}
4 changes: 2 additions & 2 deletions pulumitest/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ func (a *PulumiTest) Refresh(opts ...optrefresh.Option) auto.RefreshResult {

a.t.Log("refreshing")
if a.currentStack == nil {
a.t.Fatal("no current stack")
a.fatal("no current stack")
}
if !a.options.DisableGrpcLog {
a.ClearGrpcLog()
}
result, err := a.currentStack.Refresh(a.ctx, opts...)
if err != nil {
a.t.Fatalf("failed to refresh: %s", err)
a.fatalf("failed to refresh: %s", err)
}
return result
}
Loading

0 comments on commit 1eb757e

Please sign in to comment.