Skip to content

Commit fc57ccc

Browse files
views: add tests for cloud view
Signed-off-by: Bruno Schaatsbergen <[email protected]>
1 parent f4fbb62 commit fc57ccc

File tree

1 file changed

+186
-37
lines changed

1 file changed

+186
-37
lines changed

internal/command/views/cloud_test.go

Lines changed: 186 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,83 @@ package views
22

33
import (
44
"fmt"
5+
"net/http"
56
"strings"
67
"testing"
78
"time"
89

9-
"github.com/google/go-cmp/cmp"
1010
"github.com/hashicorp/hcl/v2"
1111
"github.com/hashicorp/terraform/internal/command/arguments"
1212
"github.com/hashicorp/terraform/internal/terminal"
1313
"github.com/hashicorp/terraform/internal/tfdiags"
1414
tfversion "github.com/hashicorp/terraform/version"
1515
)
1616

17+
func TestNewCloudHuman_RetryLog(t *testing.T) {
18+
t.Run("first retry, no output", func(t *testing.T) {
19+
streams, done := terminal.StreamsForTesting(t)
20+
newCloud := NewCloud(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true))
21+
cloudHuman, ok := newCloud.(*CloudHuman)
22+
if !ok {
23+
t.Fatalf("unexpected return type %T", newCloud)
24+
}
25+
26+
cloudHuman.RetryLog(0, nil)
27+
output := done(t).All()
28+
if output != "" {
29+
t.Fatalf("expected no output for the first retry attempt, but got: %s", output)
30+
}
31+
})
32+
33+
t.Run("second retry, server error", func(t *testing.T) {
34+
streams, done := terminal.StreamsForTesting(t)
35+
newCloud := NewCloud(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true))
36+
cloudHuman, ok := newCloud.(*CloudHuman)
37+
if !ok {
38+
t.Fatalf("unexpected return type %T", newCloud)
39+
}
40+
41+
cloudHuman.RetryLog(1, &http.Response{StatusCode: 500})
42+
output := done(t).All()
43+
expected := "There was an error connecting to HCP Terraform. Please do not exit\nTerraform to prevent data loss! Trying to restore the connection..."
44+
if !strings.Contains(output, expected) {
45+
t.Fatalf("expected output to contain: %s, but got %s", expected, output)
46+
}
47+
})
48+
49+
t.Run("subsequent retry with elapsed time", func(t *testing.T) {
50+
streams, done := terminal.StreamsForTesting(t)
51+
newCloud := NewCloud(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true))
52+
cloudHuman, ok := newCloud.(*CloudHuman)
53+
if !ok {
54+
t.Fatalf("unexpected return type %T", newCloud)
55+
}
56+
57+
cloudHuman.lastRetry = time.Now().Add(-2 * time.Second) // Simulate a delay of 2 seconds
58+
cloudHuman.RetryLog(2, &http.Response{StatusCode: 500})
59+
output := done(t).All()
60+
expected := "Still trying to restore the connection... (2s elapsed)"
61+
if !strings.Contains(output, expected) {
62+
t.Fatalf("expected output to contain: %s, but got %s", expected, output)
63+
}
64+
})
65+
66+
t.Run("retry with 429 status, no output", func(t *testing.T) {
67+
streams, done := terminal.StreamsForTesting(t)
68+
newCloud := NewCloud(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true))
69+
cloudHuman, ok := newCloud.(*CloudHuman)
70+
if !ok {
71+
t.Fatalf("unexpected return type %T", newCloud)
72+
}
73+
74+
cloudHuman.RetryLog(2, &http.Response{StatusCode: 429})
75+
output := done(t).All()
76+
if output != "" {
77+
t.Fatalf("expected no output for status code 429, but got: %s", output)
78+
}
79+
})
80+
}
81+
1782
func TestNewCloud_unsupportedViewDiagnostics(t *testing.T) {
1883
defer func() {
1984
r := recover()
@@ -67,24 +132,6 @@ func TestNewCloud_humanViewOutput(t *testing.T) {
67132
})
68133
}
69134

70-
func TestNewCloud_humanViewPrepareMessage(t *testing.T) {
71-
t.Run("existing message code", func(t *testing.T) {
72-
streams, _ := terminal.StreamsForTesting(t)
73-
74-
newCloud := NewCloud(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true))
75-
if _, ok := newCloud.(*CloudHuman); !ok {
76-
t.Fatalf("unexpected return type %t", newCloud)
77-
}
78-
79-
want := "\nThere was an error connecting to HCP Terraform. Please do not exit\nTerraform to prevent data loss! Trying to restore the connection..."
80-
81-
actual := newCloud.PrepareMessage(InitialRetryErrorMessage)
82-
if !cmp.Equal(want, actual) {
83-
t.Errorf("unexpected output: %s", cmp.Diff(want, actual))
84-
}
85-
})
86-
}
87-
88135
func TestNewCloud_humanViewDiagnostics(t *testing.T) {
89136
streams, done := terminal.StreamsForTesting(t)
90137

@@ -103,16 +150,41 @@ func TestNewCloud_humanViewDiagnostics(t *testing.T) {
103150
}
104151
}
105152

106-
func TestNewCloud_jsonViewOutput(t *testing.T) {
107-
t.Run("no param", func(t *testing.T) {
153+
func TestNewCloudJSON_RetryLog(t *testing.T) {
154+
t.Run("attempt 0, no output", func(t *testing.T) {
108155
streams, done := terminal.StreamsForTesting(t)
156+
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
157+
cloudJSON, ok := newCloud.(*CloudJSON)
158+
if !ok {
159+
t.Fatalf("unexpected return type %T", newCloud)
160+
}
109161

162+
cloudJSON.RetryLog(0, nil)
163+
164+
version := tfversion.String()
165+
want := []map[string]interface{}{
166+
{
167+
"@level": "info",
168+
"@message": fmt.Sprintf("Terraform %s", version),
169+
"@module": "terraform.ui",
170+
"terraform": version,
171+
"type": "version",
172+
"ui": JSON_UI_VERSION,
173+
},
174+
}
175+
actual := done(t).Stdout()
176+
testJSONViewOutputEqualsFull(t, actual, want)
177+
})
178+
179+
t.Run("attempt 1, server error", func(t *testing.T) {
180+
streams, done := terminal.StreamsForTesting(t)
110181
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
111-
if _, ok := newCloud.(*CloudJSON); !ok {
112-
t.Fatalf("unexpected return type %t", newCloud)
182+
cloudJSON, ok := newCloud.(*CloudJSON)
183+
if !ok {
184+
t.Fatalf("unexpected return type %T", newCloud)
113185
}
114186

115-
newCloud.Output(InitialRetryErrorMessage)
187+
cloudJSON.RetryLog(1, &http.Response{StatusCode: 500})
116188

117189
version := tfversion.String()
118190
want := []map[string]interface{}{
@@ -132,21 +204,82 @@ func TestNewCloud_jsonViewOutput(t *testing.T) {
132204
"type": "cloud_output",
133205
},
134206
}
207+
actual := done(t).Stdout()
208+
testJSONViewOutputEqualsFull(t, actual, want)
209+
})
210+
211+
t.Run("subsequent retry with elapsed time", func(t *testing.T) {
212+
streams, done := terminal.StreamsForTesting(t)
213+
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
214+
cloudJSON, ok := newCloud.(*CloudJSON)
215+
if !ok {
216+
t.Fatalf("unexpected return type %T", newCloud)
217+
}
218+
219+
cloudJSON.lastRetry = time.Now().Add(-2 * time.Second) // Simulate a delay of 2 seconds
220+
cloudJSON.RetryLog(2, &http.Response{StatusCode: 500})
221+
222+
version := tfversion.String()
223+
want := []map[string]interface{}{
224+
{
225+
"@level": "info",
226+
"@message": fmt.Sprintf("Terraform %s", version),
227+
"@module": "terraform.ui",
228+
"terraform": version,
229+
"type": "version",
230+
"ui": JSON_UI_VERSION,
231+
},
232+
{
233+
"@level": "info",
234+
"@message": "Still trying to restore the connection... (2s elapsed)",
235+
"message_code": "repeated_retry_error_message",
236+
"@module": "terraform.ui",
237+
"type": "cloud_output",
238+
},
239+
}
135240

136241
actual := done(t).Stdout()
137242
testJSONViewOutputEqualsFull(t, actual, want)
138243
})
139244

140-
t.Run("single param", func(t *testing.T) {
245+
t.Run("retry with 429 status, no output", func(t *testing.T) {
246+
streams, done := terminal.StreamsForTesting(t)
247+
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
248+
cloudJSON, ok := newCloud.(*CloudJSON)
249+
if !ok {
250+
t.Fatalf("unexpected return type %T", newCloud)
251+
}
252+
253+
cloudJSON.RetryLog(0, &http.Response{
254+
StatusCode: http.StatusTooManyRequests, // HTTP: 429
255+
})
256+
257+
version := tfversion.String()
258+
want := []map[string]interface{}{
259+
{
260+
"@level": "info",
261+
"@message": fmt.Sprintf("Terraform %s", version),
262+
"@module": "terraform.ui",
263+
"terraform": version,
264+
"type": "version",
265+
"ui": JSON_UI_VERSION,
266+
},
267+
}
268+
actual := done(t).Stdout()
269+
testJSONViewOutputEqualsFull(t, actual, want)
270+
})
271+
}
272+
273+
func TestNewCloud_jsonViewOutput(t *testing.T) {
274+
t.Run("no param", func(t *testing.T) {
141275
streams, done := terminal.StreamsForTesting(t)
142276

143277
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
144278
if _, ok := newCloud.(*CloudJSON); !ok {
145279
t.Fatalf("unexpected return type %t", newCloud)
146280
}
147281

148-
duration := 5 * time.Second
149-
newCloud.Output(RepeatedRetryErrorMessage, duration)
282+
newCloud.Output(InitialRetryErrorMessage)
150283

151284
version := tfversion.String()
152285
want := []map[string]interface{}{
@@ -160,33 +293,49 @@ func TestNewCloud_jsonViewOutput(t *testing.T) {
160293
},
161294
{
162295
"@level": "info",
163-
"@message": fmt.Sprintf("Still trying to restore the connection... (%s elapsed)", duration),
296+
"@message": "There was an error connecting to HCP Terraform. Please do not exit\nTerraform to prevent data loss! Trying to restore the connection...",
297+
"message_code": "initial_retry_error_message",
164298
"@module": "terraform.ui",
165-
"message_code": "repeated_retry_error_message",
166299
"type": "cloud_output",
167300
},
168301
}
169302

170303
actual := done(t).Stdout()
171304
testJSONViewOutputEqualsFull(t, actual, want)
172305
})
173-
}
174306

175-
func TestNewCloud_jsonViewPrepareMessage(t *testing.T) {
176-
t.Run("existing message code", func(t *testing.T) {
177-
streams, _ := terminal.StreamsForTesting(t)
307+
t.Run("single param", func(t *testing.T) {
308+
streams, done := terminal.StreamsForTesting(t)
178309

179310
newCloud := NewCloud(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true))
180311
if _, ok := newCloud.(*CloudJSON); !ok {
181312
t.Fatalf("unexpected return type %t", newCloud)
182313
}
183314

184-
want := "There was an error connecting to HCP Terraform. Please do not exit\nTerraform to prevent data loss! Trying to restore the connection..."
315+
duration := 5 * time.Second
316+
newCloud.Output(RepeatedRetryErrorMessage, duration)
185317

186-
actual := newCloud.PrepareMessage(InitialRetryErrorMessage)
187-
if !cmp.Equal(want, actual) {
188-
t.Errorf("unexpected output: %s", cmp.Diff(want, actual))
318+
version := tfversion.String()
319+
want := []map[string]interface{}{
320+
{
321+
"@level": "info",
322+
"@message": fmt.Sprintf("Terraform %s", version),
323+
"@module": "terraform.ui",
324+
"terraform": version,
325+
"type": "version",
326+
"ui": JSON_UI_VERSION,
327+
},
328+
{
329+
"@level": "info",
330+
"@message": fmt.Sprintf("Still trying to restore the connection... (%s elapsed)", duration),
331+
"@module": "terraform.ui",
332+
"message_code": "repeated_retry_error_message",
333+
"type": "cloud_output",
334+
},
189335
}
336+
337+
actual := done(t).Stdout()
338+
testJSONViewOutputEqualsFull(t, actual, want)
190339
})
191340
}
192341

0 commit comments

Comments
 (0)