github.com/ojiry/terraform@v0.8.2-0.20161218223921-e50cec712c4a/state/remote/remote_test.go (about) 1 package remote 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "os" 7 "testing" 8 9 "github.com/hashicorp/terraform/state" 10 "github.com/hashicorp/terraform/terraform" 11 ) 12 13 // testClient is a generic function to test any client. 14 func testClient(t *testing.T, c Client) { 15 var buf bytes.Buffer 16 s := state.TestStateInitial() 17 if err := terraform.WriteState(s, &buf); err != nil { 18 t.Fatalf("err: %s", err) 19 } 20 data := buf.Bytes() 21 22 if err := c.Put(data); err != nil { 23 t.Fatalf("put: %s", err) 24 } 25 26 p, err := c.Get() 27 if err != nil { 28 t.Fatalf("get: %s", err) 29 } 30 if !bytes.Equal(p.Data, data) { 31 t.Fatalf("bad: %#v", p) 32 } 33 34 if err := c.Delete(); err != nil { 35 t.Fatalf("delete: %s", err) 36 } 37 38 p, err = c.Get() 39 if err != nil { 40 t.Fatalf("get: %s", err) 41 } 42 if p != nil { 43 t.Fatalf("bad: %#v", p) 44 } 45 } 46 47 func TestRemoteClient_noPayload(t *testing.T) { 48 s := &State{ 49 Client: nilClient{}, 50 } 51 if err := s.RefreshState(); err != nil { 52 t.Fatal("error refreshing empty remote state") 53 } 54 } 55 56 // nilClient returns nil for everything 57 type nilClient struct{} 58 59 func (nilClient) Get() (*Payload, error) { return nil, nil } 60 61 func (c nilClient) Put([]byte) error { return nil } 62 63 func (c nilClient) Delete() error { return nil } 64 65 // ensure that remote state can be properly initialized 66 func TestRemoteClient_stateInit(t *testing.T) { 67 localStateFile, err := ioutil.TempFile("", "tf") 68 if err != nil { 69 t.Fatal(err) 70 } 71 72 // we need to remove the temp files so we recognize there's no local or 73 // remote state. 74 localStateFile.Close() 75 os.Remove(localStateFile.Name()) 76 defer os.Remove(localStateFile.Name()) 77 78 remoteStateFile, err := ioutil.TempFile("", "tf") 79 if err != nil { 80 t.Fatal(err) 81 } 82 remoteStateFile.Close() 83 os.Remove(remoteStateFile.Name()) 84 defer os.Remove(remoteStateFile.Name()) 85 86 // Now we need an empty state to initialize the state files. 87 newState := terraform.NewState() 88 newState.Remote = &terraform.RemoteState{ 89 Type: "_local", 90 Config: map[string]string{"path": remoteStateFile.Name()}, 91 } 92 93 remoteClient := &FileClient{ 94 Path: remoteStateFile.Name(), 95 } 96 97 cache := &state.CacheState{ 98 Cache: &state.LocalState{ 99 Path: localStateFile.Name(), 100 }, 101 Durable: &State{ 102 Client: remoteClient, 103 }, 104 } 105 106 // This will write the local state file, and set the state field in the CacheState 107 err = cache.WriteState(newState) 108 if err != nil { 109 t.Fatal(err) 110 } 111 112 // This will persist the local state we just wrote to the remote state file 113 err = cache.PersistState() 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 // now compare the two state files just to be sure 119 localData, err := ioutil.ReadFile(localStateFile.Name()) 120 if err != nil { 121 t.Fatal(err) 122 } 123 124 remoteData, err := ioutil.ReadFile(remoteStateFile.Name()) 125 if err != nil { 126 t.Fatal(err) 127 } 128 129 if !bytes.Equal(localData, remoteData) { 130 t.Log("state files don't match") 131 t.Log("Local:\n", string(localData)) 132 t.Log("Remote:\n", string(remoteData)) 133 t.Fatal("failed to initialize remote state") 134 } 135 }