plugintest

package
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2024 License: MPL-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package plugintest contains utilities to help with writing tests for Terraform plugins.

This is not a package for testing configurations or modules written in the Terraform language. It is for testing the plugins that allow Terraform to manage various cloud services and other APIs.

Index

Constants

View Source
const (
	// Environment variable with acceptance testing temporary directory for
	// testing files and Terraform CLI installation, if installation is
	// required. By default, the operating system temporary directory is used.
	//
	// Setting TF_ACC_TERRAFORM_PATH does not override this value for Terraform
	// CLI installation, if installation is required.
	EnvTfAccTempDir = "TF_ACC_TEMP_DIR"

	// Environment variable with level to filter Terraform logs during
	// acceptance testing. This value sets TF_LOG in a safe manner when
	// executing Terraform CLI commands, which would otherwise interfere
	// with the testing framework using TF_LOG to set the Go standard library
	// log package level.
	//
	// This value takes precedence over TF_LOG_CORE, due to precedence rules
	// in the Terraform core code, so it is not possible to set this to a level
	// and also TF_LOG_CORE=OFF. Use TF_LOG_CORE and TF_LOG_PROVIDER in that
	// case instead.
	//
	// If not set, but TF_ACC_LOG_PATH or TF_LOG_PATH_MASK is set, it defaults
	// to TRACE. If Terraform CLI is version 0.14 or earlier, it will have no
	// separate affect from the TF_ACC_LOG_PATH or TF_LOG_PATH_MASK behavior,
	// as those earlier versions of Terraform are unreliable with the logging
	// level being outside TRACE.
	EnvTfAccLog = "TF_ACC_LOG"

	// Environment variable with path to save Terraform logs during acceptance
	// testing. This value sets TF_LOG_PATH in a safe manner when executing
	// Terraform CLI commands, which would otherwise be ignored since it could
	// interfere with how the underlying execution is performed.
	//
	// If TF_LOG_PATH_MASK is set, it takes precedence over this value.
	EnvTfAccLogPath = "TF_ACC_LOG_PATH"

	// Environment variable with level to filter Terraform core logs during
	// acceptance testing. This value sets TF_LOG_CORE separate from
	// TF_LOG_PROVIDER when calling Terraform.
	//
	// This value has no affect when TF_ACC_LOG is set (which sets Terraform's
	// TF_LOG), due to precedence rules in the Terraform core code. Use
	// TF_LOG_CORE and TF_LOG_PROVIDER in that case instead.
	//
	// If not set, defaults to TF_ACC_LOG behaviors.
	EnvTfLogCore = "TF_LOG_CORE"

	// Environment variable with path containing the string %s, which is
	// replaced with the test name, to save separate Terraform logs during
	// acceptance testing. This value sets TF_LOG_PATH in a safe manner when
	// executing Terraform CLI commands, which would otherwise be ignored since
	// it could interfere with how the underlying execution is performed.
	//
	// Takes precedence over TF_ACC_LOG_PATH.
	EnvTfLogPathMask = "TF_LOG_PATH_MASK"

	// Environment variable with level to filter Terraform provider logs during
	// acceptance testing. This value sets TF_LOG_PROVIDER separate from
	// TF_LOG_CORE.
	//
	// During testing, this only affects external providers whose logging goes
	// through Terraform. The logging for the provider under test is controlled
	// by the testing framework as it is running the provider code. Provider
	// code using the Go standard library log package is controlled by TF_LOG
	// for historical compatibility.
	//
	// This value takes precedence over TF_ACC_LOG for external provider logs,
	// due to rules in the Terraform core code.
	//
	// If not set, defaults to TF_ACC_LOG behaviors.
	EnvTfLogProvider = "TF_LOG_PROVIDER"

	// Environment variable with acceptance testing Terraform CLI version to
	// download from releases.hashicorp.com, checksum verify, and install. The
	// value can be any valid Terraform CLI version, such as 1.1.6, with or
	// without a prepended v character.
	//
	// Setting this value takes precedence over using an available Terraform
	// binary in the operation system PATH, or if not found, installing the
	// latest version according to checkpoint.hashicorp.com.
	//
	// By default, the binary is installed in the operating system temporary
	// directory, however that directory can be overridden with the
	// TF_ACC_TEMP_DIR environment variable.
	//
	// If TF_ACC_TERRAFORM_PATH is also set, this installation method is
	// only invoked when a binary does not exist at that path. No version
	// checks are performed against an existing TF_ACC_TERRAFORM_PATH.
	EnvTfAccTerraformVersion = "TF_ACC_TERRAFORM_VERSION"

	// Acceptance testing path to Terraform CLI binary.
	//
	// Setting this value takes precedence over using an available Terraform
	// binary in the operation system PATH, or if not found, installing the
	// latest version according to checkpoint.hashicorp.com. This value does
	// not override TF_ACC_TEMP_DIR for Terraform CLI installation, if
	// installation is required.
	//
	// If TF_ACC_TERRAFORM_VERSION is not set, the binary must exist and be
	// executable, or an error will be returned.
	//
	// If TF_ACC_TERRAFORM_VERSION is also set, that Terraform CLI version
	// will be installed if a binary is not found at the given path. No version
	// checks are performed against an existing binary.
	EnvTfAccTerraformPath = "TF_ACC_TERRAFORM_PATH"

	// EnvTfAccPersistWorkingDir environment variable enables persisting
	// the working directory and the files generated during execution of
	// TestStep(s). Default is disabled, in which case the working directory
	// and the files it contains are deleted at the end of each acceptance
	// test. Can be set to any value to persist the working directory and
	// its contents, however "1" is conventional.
	EnvTfAccPersistWorkingDir = "TF_ACC_PERSIST_WORKING_DIR"
)

Environment variables

View Source
const (
	ConfigFileName = "terraform_plugin_test.tf"
	PlanFileName   = "tfplan"
)

Variables

This section is empty.

Functions

func CopyDir added in v1.1.0

func CopyDir(src, dest, baseDirName string) error

CopyDir recursively copies directories and files from src to dest.

func CopyFile added in v1.1.0

func CopyFile(src, dest string) error

CopyFile copies a single file from src to dest.

func TestExpectTFatal added in v1.3.0

func TestExpectTFatal(t *testing.T, testLogic func())

TestExpectTFatal provides a wrapper for logic which should call (*testing.T).Fatal() or (*testing.T).Fatalf().

Since we do not want the wrapping test to fail when an expected test error occurs, it is required that the testLogic passed in uses github.com/mitchellh/go-testing-interface.RuntimeT instead of the real *testing.T.

If Fatal() or Fatalf() is not called in the logic, the real (*testing.T).Fatal() will be called to fail the test.

Types

type Config

type Config struct {
	SourceDir     string
	TerraformExec string

	PreviousPluginExec string
	// contains filtered or unexported fields
}

Config is used to configure the test helper. In most normal test programs the configuration is discovered automatically by an Init* function using DiscoverConfig, but this is exposed so that more complex scenarios can be implemented by direct configuration.

func DiscoverConfig

func DiscoverConfig(ctx context.Context, sourceDir string) (*Config, error)

DiscoverConfig uses environment variables and other means to automatically discover a reasonable test helper configuration.

type Helper

type Helper struct {
	// contains filtered or unexported fields
}

Helper is intended as a per-package singleton created in TestMain which other tests in a package can use to create Terraform execution contexts

func AutoInitHelper

func AutoInitHelper(ctx context.Context, sourceDir string) (*Helper, error)

AutoInitHelper uses the auto-discovery behavior of DiscoverConfig to prepare a configuration and then calls InitHelper with it. This is a convenient way to get the standard init behavior based on environment variables, and callers should use this unless they have an unusual requirement that calls for constructing a config in a different way.

func AutoInitProviderHelper

func AutoInitProviderHelper(ctx context.Context, sourceDir string) *Helper

AutoInitProviderHelper is the main entrypoint for testing provider plugins using this package. It is intended to be called during TestMain to prepare for provider testing.

AutoInitProviderHelper will discover the location of a current Terraform CLI executable to test against, detect whether a prior version of the plugin is available for upgrade tests, and then will return an object containing the results of that initialization which can then be stored in a global variable for use in other tests.

func InitHelper

func InitHelper(ctx context.Context, config *Config) (*Helper, error)

InitHelper prepares a testing helper with the given configuration.

For most callers it is sufficient to call AutoInitHelper instead, which will construct a configuration automatically based on certain environment variables.

If this function returns an error then it may have left some temporary files behind in the system's temporary directory. There is currently no way to automatically clean those up.

func (*Helper) Close

func (h *Helper) Close() error

Close cleans up temporary files and directories created to support this helper, returning an error if any of the cleanup fails.

Call this before returning from TestMain to minimize the amount of detritus left behind in the filesystem after the tests complete.

func (*Helper) NewWorkingDir

func (h *Helper) NewWorkingDir(ctx context.Context, t TestControl, wd string) (*WorkingDir, error)

NewWorkingDir creates a new working directory for use in the implementation of a single test, returning a WorkingDir object representing that directory.

If the working directory object is not itself closed by the time the test program exits, the Close method on the helper itself will attempt to delete it.

func (*Helper) RequireNewWorkingDir

func (h *Helper) RequireNewWorkingDir(ctx context.Context, t TestControl, workingDir string) *WorkingDir

RequireNewWorkingDir is a variant of NewWorkingDir that takes a TestControl object and will immediately fail the running test if the creation of the working directory fails.

func (*Helper) TerraformExecPath

func (h *Helper) TerraformExecPath() string

TerraformExecPath returns the location of the Terraform CLI executable that should be used when running tests.

func (*Helper) TerraformVersion added in v1.3.0

func (h *Helper) TerraformVersion() *version.Version

TerraformVersion returns the Terraform CLI version being used when running tests.

func (*Helper) WorkingDirectory

func (h *Helper) WorkingDirectory() string

WorkingDirectory returns the working directory being used when running tests.

type TestControl

type TestControl interface {
	Helper()
	Log(args ...interface{})
	FailNow()
	SkipNow()
	Name() string
}

TestControl is an interface requiring a subset of *testing.T which is used by the test guards and helpers in this package. Most callers can simply pass their *testing.T value here, but the interface allows other implementations to potentially be provided instead, for example to allow meta-testing (testing of the test utilities themselves).

This interface also describes the subset of normal test functionality the guards and helpers can perform: they can only create log lines, fail tests, and skip tests. All other test control is the responsibility of the main test code.

type WorkingDir

type WorkingDir struct {
	// contains filtered or unexported fields
}

WorkingDir represents a distinct working directory that can be used for running tests. Each test should construct its own WorkingDir by calling NewWorkingDir or RequireNewWorkingDir on its package's singleton plugintest.Helper.

func (*WorkingDir) Apply

func (wd *WorkingDir) Apply(ctx context.Context) error

Apply runs "terraform apply". If CreatePlan has previously completed successfully and the saved plan has not been cleared in the meantime then this will apply the saved plan. Otherwise, it will implicitly create a new plan and apply it.

func (*WorkingDir) BaseDir added in v1.3.0

func (wd *WorkingDir) BaseDir() string

BaseDir returns the path to the root of the working directory tree.

func (*WorkingDir) ClearPlan

func (wd *WorkingDir) ClearPlan(ctx context.Context) error

ClearPlan deletes any saved plan present in the working directory.

func (*WorkingDir) ClearState

func (wd *WorkingDir) ClearState(ctx context.Context) error

ClearState deletes any Terraform state present in the working directory.

Any remote objects tracked by the state are not destroyed first, so this will leave them dangling in the remote system.

func (*WorkingDir) Close

func (wd *WorkingDir) Close() error

Close deletes the directories and files created to represent the receiving working directory. After this method is called, the working directory object is invalid and may no longer be used.

func (*WorkingDir) CreatePlan

func (wd *WorkingDir) CreatePlan(ctx context.Context, opts ...tfexec.PlanOption) error

CreatePlan runs "terraform plan" to create a saved plan file, which if successful will then be used for the next call to Apply.

func (*WorkingDir) Destroy

func (wd *WorkingDir) Destroy(ctx context.Context) error

Destroy runs "terraform destroy". It does not consider or modify any saved plan, and is primarily for cleaning up at the end of a test run.

If destroy fails then remote objects might still exist, and continue to exist after a particular test is concluded.

func (*WorkingDir) GetHelper

func (wd *WorkingDir) GetHelper() *Helper

GetHelper returns the Helper set on the WorkingDir.

func (*WorkingDir) HasSavedPlan

func (wd *WorkingDir) HasSavedPlan() bool

HasSavedPlan returns true if there is a saved plan in the working directory. If so, a subsequent call to Apply will apply that saved plan.

func (*WorkingDir) Import

func (wd *WorkingDir) Import(ctx context.Context, resource, id string) error

Import runs terraform import

func (*WorkingDir) Init

func (wd *WorkingDir) Init(ctx context.Context) error

Init runs "terraform init" for the given working directory, forcing Terraform to use the current version of the plugin under test.

func (*WorkingDir) Refresh

func (wd *WorkingDir) Refresh(ctx context.Context) error

Refresh runs terraform refresh

func (*WorkingDir) SavedPlan

func (wd *WorkingDir) SavedPlan(ctx context.Context) (*tfjson.Plan, error)

SavedPlan returns an object describing the current saved plan file, if any.

If no plan is saved or if the plan file cannot be read, SavedPlan returns an error.

func (*WorkingDir) SavedPlanRawStdout

func (wd *WorkingDir) SavedPlanRawStdout(ctx context.Context) (string, error)

SavedPlanRawStdout returns a human readable stdout capture of the current saved plan file, if any.

If no plan is saved or if the plan file cannot be read, SavedPlanRawStdout returns an error.

func (*WorkingDir) Schemas

func (wd *WorkingDir) Schemas(ctx context.Context) (*tfjson.ProviderSchemas, error)

Schemas returns an object describing the provider schemas.

If the schemas cannot be read, Schemas returns an error.

func (*WorkingDir) SetConfig

func (wd *WorkingDir) SetConfig(ctx context.Context, cfg teststep.Config, vars config.Variables) error

SetConfig sets a new configuration for the working directory.

This must be called at least once before any call to Init, Plan, Apply, or Destroy to establish the configuration. Any previously-set configuration is discarded and any saved plan is cleared.

func (*WorkingDir) SetReattachInfo

func (wd *WorkingDir) SetReattachInfo(ctx context.Context, reattachInfo tfexec.ReattachInfo)

func (*WorkingDir) State

func (wd *WorkingDir) State(ctx context.Context) (*tfjson.State, error)

If the state cannot be read, State returns an error.

func (*WorkingDir) Taint

func (wd *WorkingDir) Taint(ctx context.Context, address string) error

Taint runs terraform taint

func (*WorkingDir) UnsetReattachInfo

func (wd *WorkingDir) UnsetReattachInfo()

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL