-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelloworld_shell_test.go
140 lines (118 loc) · 4.46 KB
/
helloworld_shell_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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// +build e2e
/*
Copyright 2018 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
"time"
"github.com/knative/serving/test"
"go.uber.org/zap"
)
const (
appYaml = "test_images/helloworld/helloworld.yaml"
yamlImagePlaceholder = "github.com/knative/serving/test_images/helloworld"
ingressTimeout = 5 * time.Minute
servingTimeout = 2 * time.Minute
checkInterval = 2 * time.Second
)
func noStderrShell(name string, arg ...string) string {
var void bytes.Buffer
cmd := exec.Command(name, arg...)
cmd.Stderr = &void
out, _ := cmd.Output()
return string(out)
}
func cleanup(yamlFilename string, logger *zap.SugaredLogger) {
exec.Command("kubectl", "delete", "-f", yamlFilename).Run()
os.Remove(yamlFilename)
// There seems to be an Istio bug where if we delete / create
// VirtualServices too quickly we will hit pro-longed "No health
// upstream" causing timeouts. Adding this small sleep to
// sidestep the issue.
//
// TODO(#1376): Fix this when upstream fix is released.
logger.Info("Sleeping for 20 seconds after Route deletion to avoid hitting issue in #1376")
time.Sleep(20 * time.Second)
}
func TestHelloWorldFromShell(t *testing.T) {
//add test case specific name to its own logger
logger := test.GetContextLogger("TestHelloWorldFromShell")
imagePath := strings.Join([]string{test.Flags.DockerRepo, "helloworld"}, "/")
logger.Infof("Creating manifest")
// Create manifest file.
newYaml, err := ioutil.TempFile("", "helloworld")
if err != nil {
t.Fatalf("Failed to create temporary manifest: %v", err)
}
newYamlFilename := newYaml.Name()
defer cleanup(newYamlFilename, logger)
test.CleanupOnInterrupt(func() { cleanup(newYamlFilename, logger) }, logger)
// Populate manifets file with the real path to the container
content, err := ioutil.ReadFile(appYaml)
if err != nil {
t.Fatalf("Failed to read file %s: %v", appYaml, err)
}
realContent := strings.Replace(string(content), yamlImagePlaceholder, imagePath, -1)
if _, err = newYaml.WriteString(realContent); err != nil {
t.Fatalf("Failed to write new manifest: %v", err)
}
if err = newYaml.Close(); err != nil {
t.Fatalf("Failed to close new manifest file: %v", err)
}
logger.Infof("Manifest file is '%s'", newYamlFilename)
logger.Info("Deploying using kubectl")
// Deploy using kubectl
if output, err := exec.Command("kubectl", "apply", "-f", newYamlFilename).CombinedOutput(); err != nil {
t.Fatalf("Error running kubectl: %v", strings.TrimSpace(string(output)))
}
logger.Info("Waiting for ingress to come up")
// Wait for ingress to come up
serviceIP := ""
serviceHost := ""
timeout := ingressTimeout
for (serviceIP == "" || serviceHost == "") && timeout >= 0 {
serviceHost = noStderrShell("kubectl", "get", "route", "route-example", "-o", "jsonpath={.status.domain}")
serviceIP = noStderrShell("kubectl", "get", "svc", "knative-ingressgateway", "-n", "istio-system",
"-o", "jsonpath={.status.loadBalancer.ingress[*]['ip']}")
time.Sleep(checkInterval)
timeout = timeout - checkInterval
}
if serviceIP == "" || serviceHost == "" {
// serviceHost or serviceIP might contain a useful error, dump them.
t.Fatalf("Ingress not found (IP='%s', host='%s')", serviceIP, serviceHost)
}
logger.Infof("Ingress is at %s/%s", serviceIP, serviceHost)
logger.Info("Accessing app using curl")
outputString := ""
timeout = servingTimeout
for outputString != helloWorldExpectedOutput && timeout >= 0 {
output, err := exec.Command("curl", "--header", "Host:"+serviceHost, "http://"+serviceIP).Output()
errorString := "none"
time.Sleep(checkInterval)
timeout = timeout - checkInterval
if err != nil {
errorString = err.Error()
}
outputString = strings.TrimSpace(string(output))
logger.Infof("App replied with '%s' (error: %s)", outputString, errorString)
}
if outputString != helloWorldExpectedOutput {
t.Fatalf("Timeout waiting for app to start serving")
}
logger.Info("App is serving")
}