github.com/pdecat/terraform@v0.11.9-beta1/backend/remote/backend_test.go (about) 1 package remote 2 3 import ( 4 "errors" 5 "reflect" 6 "strings" 7 "testing" 8 9 "github.com/hashicorp/terraform/backend" 10 "github.com/hashicorp/terraform/config" 11 "github.com/hashicorp/terraform/terraform" 12 ) 13 14 func TestRemote(t *testing.T) { 15 var _ backend.Enhanced = New(nil) 16 var _ backend.CLI = New(nil) 17 } 18 19 func TestRemote_backendDefault(t *testing.T) { 20 b := testBackendDefault(t) 21 backend.TestBackendStates(t, b) 22 backend.TestBackendStateLocks(t, b, b) 23 backend.TestBackendStateForceUnlock(t, b, b) 24 } 25 26 func TestRemote_backendNoDefault(t *testing.T) { 27 b := testBackendNoDefault(t) 28 backend.TestBackendStates(t, b) 29 } 30 31 func TestRemote_config(t *testing.T) { 32 cases := map[string]struct { 33 config map[string]interface{} 34 err error 35 }{ 36 "with_a_name": { 37 config: map[string]interface{}{ 38 "organization": "hashicorp", 39 "workspaces": []interface{}{ 40 map[string]interface{}{ 41 "name": "prod", 42 }, 43 }, 44 }, 45 err: nil, 46 }, 47 "with_a_prefix": { 48 config: map[string]interface{}{ 49 "organization": "hashicorp", 50 "workspaces": []interface{}{ 51 map[string]interface{}{ 52 "prefix": "my-app-", 53 }, 54 }, 55 }, 56 err: nil, 57 }, 58 "without_either_a_name_and_a_prefix": { 59 config: map[string]interface{}{ 60 "organization": "hashicorp", 61 "workspaces": []interface{}{ 62 map[string]interface{}{}, 63 }, 64 }, 65 err: errors.New("either workspace 'name' or 'prefix' is required"), 66 }, 67 "with_both_a_name_and_a_prefix": { 68 config: map[string]interface{}{ 69 "organization": "hashicorp", 70 "workspaces": []interface{}{ 71 map[string]interface{}{ 72 "name": "prod", 73 "prefix": "my-app-", 74 }, 75 }, 76 }, 77 err: errors.New("only one of workspace 'name' or 'prefix' is allowed"), 78 }, 79 "with_an_unknown_host": { 80 config: map[string]interface{}{ 81 "hostname": "nonexisting.local", 82 "organization": "hashicorp", 83 "workspaces": []interface{}{ 84 map[string]interface{}{ 85 "name": "prod", 86 }, 87 }, 88 }, 89 err: errors.New("host nonexisting.local does not provide a remote backend API"), 90 }, 91 } 92 93 for name, tc := range cases { 94 s := testServer(t) 95 b := New(testDisco(s)) 96 97 // Get the proper config structure 98 rc, err := config.NewRawConfig(tc.config) 99 if err != nil { 100 t.Fatalf("%s: error creating raw config: %v", name, err) 101 } 102 conf := terraform.NewResourceConfig(rc) 103 104 // Validate 105 warns, errs := b.Validate(conf) 106 if len(warns) > 0 { 107 t.Fatalf("%s: validation warnings: %v", name, warns) 108 } 109 if len(errs) > 0 { 110 t.Fatalf("%s: validation errors: %v", name, errs) 111 } 112 113 // Configure 114 err = b.Configure(conf) 115 if err != tc.err && err != nil && tc.err != nil && err.Error() != tc.err.Error() { 116 t.Fatalf("%s: expected error %q, got: %q", name, tc.err, err) 117 } 118 } 119 } 120 121 func TestRemote_nonexistingOrganization(t *testing.T) { 122 msg := "does not exist" 123 124 b := testBackendNoDefault(t) 125 b.organization = "nonexisting" 126 127 if _, err := b.State("prod"); err == nil || !strings.Contains(err.Error(), msg) { 128 t.Fatalf("expected %q error, got: %v", msg, err) 129 } 130 131 if err := b.DeleteState("prod"); err == nil || !strings.Contains(err.Error(), msg) { 132 t.Fatalf("expected %q error, got: %v", msg, err) 133 } 134 135 if _, err := b.States(); err == nil || !strings.Contains(err.Error(), msg) { 136 t.Fatalf("expected %q error, got: %v", msg, err) 137 } 138 } 139 140 func TestRemote_addAndRemoveStatesDefault(t *testing.T) { 141 b := testBackendDefault(t) 142 if _, err := b.States(); err != backend.ErrNamedStatesNotSupported { 143 t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err) 144 } 145 146 if _, err := b.State(backend.DefaultStateName); err != nil { 147 t.Fatalf("expected no error, got %v", err) 148 } 149 150 if _, err := b.State("prod"); err != backend.ErrNamedStatesNotSupported { 151 t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err) 152 } 153 154 if err := b.DeleteState(backend.DefaultStateName); err != nil { 155 t.Fatalf("expected no error, got %v", err) 156 } 157 158 if err := b.DeleteState("prod"); err != backend.ErrNamedStatesNotSupported { 159 t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err) 160 } 161 } 162 163 func TestRemote_addAndRemoveStatesNoDefault(t *testing.T) { 164 b := testBackendNoDefault(t) 165 states, err := b.States() 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 expectedStates := []string(nil) 171 if !reflect.DeepEqual(states, expectedStates) { 172 t.Fatalf("expected states %#+v, got %#+v", expectedStates, states) 173 } 174 175 if _, err := b.State(backend.DefaultStateName); err != backend.ErrDefaultStateNotSupported { 176 t.Fatalf("expected error %v, got %v", backend.ErrDefaultStateNotSupported, err) 177 } 178 179 expectedA := "test_A" 180 if _, err := b.State(expectedA); err != nil { 181 t.Fatal(err) 182 } 183 184 states, err = b.States() 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 expectedStates = append(expectedStates, expectedA) 190 if !reflect.DeepEqual(states, expectedStates) { 191 t.Fatalf("expected %#+v, got %#+v", expectedStates, states) 192 } 193 194 expectedB := "test_B" 195 if _, err := b.State(expectedB); err != nil { 196 t.Fatal(err) 197 } 198 199 states, err = b.States() 200 if err != nil { 201 t.Fatal(err) 202 } 203 204 expectedStates = append(expectedStates, expectedB) 205 if !reflect.DeepEqual(states, expectedStates) { 206 t.Fatalf("expected %#+v, got %#+v", expectedStates, states) 207 } 208 209 if err := b.DeleteState(backend.DefaultStateName); err != backend.ErrDefaultStateNotSupported { 210 t.Fatalf("expected error %v, got %v", backend.ErrDefaultStateNotSupported, err) 211 } 212 213 if err := b.DeleteState(expectedA); err != nil { 214 t.Fatal(err) 215 } 216 217 states, err = b.States() 218 if err != nil { 219 t.Fatal(err) 220 } 221 222 expectedStates = []string{expectedB} 223 if !reflect.DeepEqual(states, expectedStates) { 224 t.Fatalf("expected %#+v got %#+v", expectedStates, states) 225 } 226 227 if err := b.DeleteState(expectedB); err != nil { 228 t.Fatal(err) 229 } 230 231 states, err = b.States() 232 if err != nil { 233 t.Fatal(err) 234 } 235 236 expectedStates = []string(nil) 237 if !reflect.DeepEqual(states, expectedStates) { 238 t.Fatalf("expected %#+v, got %#+v", expectedStates, states) 239 } 240 }