diff --git a/state/remote/remote_test.go b/state/remote/remote_test.go index 16afccdf1..04f875747 100644 --- a/state/remote/remote_test.go +++ b/state/remote/remote_test.go @@ -2,6 +2,9 @@ package remote import ( "bytes" + "fmt" + "io/ioutil" + "os" "testing" "github.com/hashicorp/terraform/state" @@ -46,8 +49,8 @@ func TestRemoteClient_noPayload(t *testing.T) { s := &State{ Client: nilClient{}, } - if err := s.RefreshState(); err != ErrRemoteStateNotFound { - t.Fatal("expected ErrRemoteStateNotFound, got", err) + if err := s.RefreshState(); err != nil { + t.Fatal("error refreshing empty remote state") } } @@ -59,3 +62,72 @@ func (nilClient) Get() (*Payload, error) { return nil, nil } func (c nilClient) Put([]byte) error { return nil } func (c nilClient) Delete() error { return nil } + +// ensure that remote state can be properly initialized +func TestRemoteClient_stateInit(t *testing.T) { + localStateFile, err := ioutil.TempFile("", "tf") + if err != nil { + t.Fatal(err) + } + + // we need to remove the temp files so we recognize there's no local or + // remote state. + localStateFile.Close() + os.Remove(localStateFile.Name()) + //defer os.Remove(localStateFile.Name()) + fmt.Println("LOCAL:", localStateFile.Name()) + + local := &state.LocalState{ + Path: localStateFile.Name(), + } + if err := local.RefreshState(); err != nil { + t.Fatal(err) + } + localState := local.State() + + fmt.Println("localState.Empty():", localState.Empty()) + + remoteStateFile, err := ioutil.TempFile("", "tf") + if err != nil { + t.Fatal(err) + } + remoteStateFile.Close() + os.Remove(remoteStateFile.Name()) + //defer os.Remove(remoteStateFile.Name() + fmt.Println("LOCAL:", localStateFile.Name()) + fmt.Println("REMOTE:", remoteStateFile.Name()) + + remoteClient := &FileClient{ + Path: remoteStateFile.Name(), + } + + durable := &State{ + Client: remoteClient, + } + + cache := &state.CacheState{ + Cache: local, + Durable: durable, + } + + if err := cache.RefreshState(); err != nil { + t.Fatal(err) + } + + switch cache.RefreshResult() { + + // we should be "refreshing" the remote state to initialize it + case state.CacheRefreshLocalNewer: + // Write our local state out to the durable storage to start. + if err := cache.WriteState(localState); err != nil { + t.Fatal("Error preparing remote state:", err) + } + if err := cache.PersistState(); err != nil { + t.Fatal("Error preparing remote state:", err) + } + default: + + t.Fatal("unexpected refresh result:", cache.RefreshResult()) + } + +} diff --git a/state/remote/state.go b/state/remote/state.go index 5f45129d6..18427f341 100644 --- a/state/remote/state.go +++ b/state/remote/state.go @@ -2,13 +2,10 @@ package remote import ( "bytes" - "errors" "github.com/hashicorp/terraform/terraform" ) -var ErrRemoteStateNotFound = errors.New("no remote state found") - // State implements the State interfaces in the state package to handle // reading and writing the remote state. This State on its own does no // local caching so every persist will go to the remote storage and local @@ -37,8 +34,9 @@ func (s *State) RefreshState() error { return err } + // no remote state is OK if payload == nil { - return ErrRemoteStateNotFound + return nil } state, err := terraform.ReadState(bytes.NewReader(payload.Data))