@@ -2,18 +2,83 @@ package views
2
2
3
3
import (
4
4
"fmt"
5
+ "net/http"
5
6
"strings"
6
7
"testing"
7
8
"time"
8
9
9
- "github.com/google/go-cmp/cmp"
10
10
"github.com/hashicorp/hcl/v2"
11
11
"github.com/hashicorp/terraform/internal/command/arguments"
12
12
"github.com/hashicorp/terraform/internal/terminal"
13
13
"github.com/hashicorp/terraform/internal/tfdiags"
14
14
tfversion "github.com/hashicorp/terraform/version"
15
15
)
16
16
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\n Terraform 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
+
17
82
func TestNewCloud_unsupportedViewDiagnostics (t * testing.T ) {
18
83
defer func () {
19
84
r := recover ()
@@ -67,24 +132,6 @@ func TestNewCloud_humanViewOutput(t *testing.T) {
67
132
})
68
133
}
69
134
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 := "\n There was an error connecting to HCP Terraform. Please do not exit\n Terraform 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
-
88
135
func TestNewCloud_humanViewDiagnostics (t * testing.T ) {
89
136
streams , done := terminal .StreamsForTesting (t )
90
137
@@ -103,16 +150,41 @@ func TestNewCloud_humanViewDiagnostics(t *testing.T) {
103
150
}
104
151
}
105
152
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 ) {
108
155
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
+ }
109
161
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 )
110
181
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 )
113
185
}
114
186
115
- newCloud . Output ( InitialRetryErrorMessage )
187
+ cloudJSON . RetryLog ( 1 , & http. Response { StatusCode : 500 } )
116
188
117
189
version := tfversion .String ()
118
190
want := []map [string ]interface {}{
@@ -132,21 +204,82 @@ func TestNewCloud_jsonViewOutput(t *testing.T) {
132
204
"type" : "cloud_output" ,
133
205
},
134
206
}
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
+ }
135
240
136
241
actual := done (t ).Stdout ()
137
242
testJSONViewOutputEqualsFull (t , actual , want )
138
243
})
139
244
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 ) {
141
275
streams , done := terminal .StreamsForTesting (t )
142
276
143
277
newCloud := NewCloud (arguments .ViewJSON , NewView (streams ).SetRunningInAutomation (true ))
144
278
if _ , ok := newCloud .(* CloudJSON ); ! ok {
145
279
t .Fatalf ("unexpected return type %t" , newCloud )
146
280
}
147
281
148
- duration := 5 * time .Second
149
- newCloud .Output (RepeatedRetryErrorMessage , duration )
282
+ newCloud .Output (InitialRetryErrorMessage )
150
283
151
284
version := tfversion .String ()
152
285
want := []map [string ]interface {}{
@@ -160,33 +293,49 @@ func TestNewCloud_jsonViewOutput(t *testing.T) {
160
293
},
161
294
{
162
295
"@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\n Terraform to prevent data loss! Trying to restore the connection..." ,
297
+ "message_code" : "initial_retry_error_message" ,
164
298
"@module" : "terraform.ui" ,
165
- "message_code" : "repeated_retry_error_message" ,
166
299
"type" : "cloud_output" ,
167
300
},
168
301
}
169
302
170
303
actual := done (t ).Stdout ()
171
304
testJSONViewOutputEqualsFull (t , actual , want )
172
305
})
173
- }
174
306
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 )
178
309
179
310
newCloud := NewCloud (arguments .ViewJSON , NewView (streams ).SetRunningInAutomation (true ))
180
311
if _ , ok := newCloud .(* CloudJSON ); ! ok {
181
312
t .Fatalf ("unexpected return type %t" , newCloud )
182
313
}
183
314
184
- want := "There was an error connecting to HCP Terraform. Please do not exit\n Terraform to prevent data loss! Trying to restore the connection..."
315
+ duration := 5 * time .Second
316
+ newCloud .Output (RepeatedRetryErrorMessage , duration )
185
317
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
+ },
189
335
}
336
+
337
+ actual := done (t ).Stdout ()
338
+ testJSONViewOutputEqualsFull (t , actual , want )
190
339
})
191
340
}
192
341
0 commit comments