github.com/codeherentuk/terraform@v0.11.12-beta1/backend/local/testing.go (about)

     1  package local
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform/backend"
    10  	"github.com/hashicorp/terraform/state"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  // TestLocal returns a configured Local struct with temporary paths and
    15  // in-memory ContextOpts.
    16  //
    17  // No operations will be called on the returned value, so you can still set
    18  // public fields without any locks.
    19  func TestLocal(t *testing.T) (*Local, func()) {
    20  	tempDir := testTempDir(t)
    21  
    22  	local := New()
    23  	local.StatePath = filepath.Join(tempDir, "state.tfstate")
    24  	local.StateOutPath = filepath.Join(tempDir, "state.tfstate")
    25  	local.StateBackupPath = filepath.Join(tempDir, "state.tfstate.bak")
    26  	local.StateWorkspaceDir = filepath.Join(tempDir, "state.tfstate.d")
    27  	local.ContextOpts = &terraform.ContextOpts{}
    28  
    29  	cleanup := func() {
    30  		if err := os.RemoveAll(tempDir); err != nil {
    31  			t.Fatal("error clecanup up test:", err)
    32  		}
    33  	}
    34  
    35  	return local, cleanup
    36  }
    37  
    38  // TestLocalProvider modifies the ContextOpts of the *Local parameter to
    39  // have a provider with the given name.
    40  func TestLocalProvider(t *testing.T, b *Local, name string) *terraform.MockResourceProvider {
    41  	// Build a mock resource provider for in-memory operations
    42  	p := new(terraform.MockResourceProvider)
    43  	p.DiffReturn = &terraform.InstanceDiff{}
    44  	p.RefreshFn = func(
    45  		info *terraform.InstanceInfo,
    46  		s *terraform.InstanceState) (*terraform.InstanceState, error) {
    47  		return s, nil
    48  	}
    49  	p.ResourcesReturn = []terraform.ResourceType{
    50  		terraform.ResourceType{
    51  			Name: "test_instance",
    52  		},
    53  	}
    54  
    55  	// Initialize the opts
    56  	if b.ContextOpts == nil {
    57  		b.ContextOpts = &terraform.ContextOpts{}
    58  	}
    59  
    60  	// Setup our provider
    61  	b.ContextOpts.ProviderResolver = terraform.ResourceProviderResolverFixed(
    62  		map[string]terraform.ResourceProviderFactory{
    63  			name: terraform.ResourceProviderFactoryFixed(p),
    64  		},
    65  	)
    66  
    67  	return p
    68  }
    69  
    70  // TestNewLocalSingle is a factory for creating a TestLocalSingleState.
    71  // This function matches the signature required for backend/init.
    72  func TestNewLocalSingle() backend.Backend {
    73  	return &TestLocalSingleState{Local: New()}
    74  }
    75  
    76  // TestLocalSingleState is a backend implementation that wraps Local
    77  // and modifies it to only support single states (returns
    78  // ErrNamedStatesNotSupported for multi-state operations).
    79  //
    80  // This isn't an actual use case, this is exported just to provide a
    81  // easy way to test that behavior.
    82  type TestLocalSingleState struct {
    83  	*Local
    84  }
    85  
    86  func (b *TestLocalSingleState) State(name string) (state.State, error) {
    87  	if name != backend.DefaultStateName {
    88  		return nil, backend.ErrNamedStatesNotSupported
    89  	}
    90  
    91  	return b.Local.State(name)
    92  }
    93  
    94  func (b *TestLocalSingleState) States() ([]string, error) {
    95  	return nil, backend.ErrNamedStatesNotSupported
    96  }
    97  
    98  func (b *TestLocalSingleState) DeleteState(string) error {
    99  	return backend.ErrNamedStatesNotSupported
   100  }
   101  
   102  // TestNewLocalNoDefault is a factory for creating a TestLocalNoDefaultState.
   103  // This function matches the signature required for backend/init.
   104  func TestNewLocalNoDefault() backend.Backend {
   105  	return &TestLocalNoDefaultState{Local: New()}
   106  }
   107  
   108  // TestLocalNoDefaultState is a backend implementation that wraps
   109  // Local and modifies it to support named states, but not the
   110  // default state. It returns ErrDefaultStateNotSupported when the
   111  // DefaultStateName is used.
   112  type TestLocalNoDefaultState struct {
   113  	*Local
   114  }
   115  
   116  func (b *TestLocalNoDefaultState) State(name string) (state.State, error) {
   117  	if name == backend.DefaultStateName {
   118  		return nil, backend.ErrDefaultStateNotSupported
   119  	}
   120  	return b.Local.State(name)
   121  }
   122  
   123  func (b *TestLocalNoDefaultState) States() ([]string, error) {
   124  	states, err := b.Local.States()
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	filtered := states[:0]
   130  	for _, name := range states {
   131  		if name != backend.DefaultStateName {
   132  			filtered = append(filtered, name)
   133  		}
   134  	}
   135  
   136  	return filtered, nil
   137  }
   138  
   139  func (b *TestLocalNoDefaultState) DeleteState(name string) error {
   140  	if name == backend.DefaultStateName {
   141  		return backend.ErrDefaultStateNotSupported
   142  	}
   143  	return b.Local.DeleteState(name)
   144  }
   145  
   146  func testTempDir(t *testing.T) string {
   147  	d, err := ioutil.TempDir("", "tf")
   148  	if err != nil {
   149  		t.Fatalf("err: %s", err)
   150  	}
   151  
   152  	return d
   153  }