-
Notifications
You must be signed in to change notification settings - Fork 878
/
Copy pathexamples_test.go
118 lines (102 loc) · 3.12 KB
/
examples_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2016-2025, Pulumi Corporation. All rights reserved.
package examples
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"testing"
"time"
"github.com/pulumi/pulumi/pkg/v3/testing/integration"
"github.com/stretchr/testify/assert"
)
func TestS3Website(t *testing.T) {
cwd, err := os.Getwd()
if err != nil {
t.FailNow()
}
test := integration.ProgramTestOptions{
Dir: path.Join(cwd, "program"),
Quick: true,
SkipRefresh: true,
Config: map[string]string{
"aws:region": "us-west-1",
},
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
assertHTTPResult(t, "http://"+stack.Outputs["websiteUrl"].(string), nil, func(body string) bool {
return assert.Contains(t, body, "Hello, Pulumi!")
})
},
}
integration.ProgramTest(t, &test)
}
func assertHTTPResult(t *testing.T, output interface{}, headers map[string]string, check func(string) bool) bool {
return assertHTTPResultWithRetry(t, output, headers, 5*time.Minute, check)
}
func assertHTTPResultWithRetry(t *testing.T, output interface{}, headers map[string]string, maxWait time.Duration, check func(string) bool) bool {
return assertHTTPResultShapeWithRetry(t, output, headers, maxWait, func(string) bool { return true }, check)
}
func assertHTTPResultShapeWithRetry(t *testing.T, output interface{}, headers map[string]string, maxWait time.Duration,
ready func(string) bool, check func(string) bool) bool {
hostname, ok := output.(string)
if !assert.True(t, ok, fmt.Sprintf("expected `%s` output", output)) {
return false
}
if !(strings.HasPrefix(hostname, "http://") || strings.HasPrefix(hostname, "https://")) {
hostname = fmt.Sprintf("http://%s", hostname)
}
startTime := time.Now()
count, sleep := 0, 0
for {
now := time.Now()
req, err := http.NewRequest("GET", hostname, nil)
if !assert.NoError(t, err) {
return false
}
for k, v := range headers {
// Host header cannot be set via req.Header.Set(), and must be set
// directly.
if strings.ToLower(k) == "host" {
req.Host = v
continue
}
req.Header.Set(k, v)
}
client := &http.Client{Timeout: time.Second * 10}
resp, err := client.Do(req)
if err == nil && resp.StatusCode == 200 {
if !assert.NotNil(t, resp.Body, "resp.body was nil") {
return false
}
// Read the body
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if !assert.NoError(t, err) {
return false
}
bodyText := string(body)
// Even if we got 200 and a response, it may not be ready for assertion yet - that's specific per test.
if ready(bodyText) {
// Verify it matches expectations
return check(bodyText)
}
}
if now.Sub(startTime) >= maxWait {
fmt.Printf("Timeout after %v. Unable to http.get %v successfully.", maxWait, hostname)
return false
}
count++
// delay 10s, 20s, then 30s and stay at 30s
if sleep > 30 {
sleep = 30
} else {
sleep += 10
}
time.Sleep(time.Duration(sleep) * time.Second)
fmt.Printf("Http Error: %v\n", err)
fmt.Printf(" Retry: %v, elapsed wait: %v, max wait %v\n", count, now.Sub(startTime), maxWait)
}
return false
}