mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
New e2e script (in go this time) that doesn't completely suck
This commit is contained in:
parent
77d2815b86
commit
bfabb41604
@ -34,6 +34,7 @@ server_targets=(
|
||||
client_targets=(
|
||||
cmd/kubecfg
|
||||
cmd/kubectl
|
||||
cmd/e2e
|
||||
)
|
||||
|
||||
mkdir -p "${KUBE_TARGET}"
|
||||
|
@ -518,7 +518,6 @@ function test-build-release {
|
||||
#
|
||||
# Assumed vars:
|
||||
# PROJECT
|
||||
# ALREADY_UP
|
||||
# Variables from config.sh
|
||||
function test-setup {
|
||||
|
||||
@ -526,18 +525,15 @@ function test-setup {
|
||||
# gce specific
|
||||
detect-project
|
||||
|
||||
if [[ ${ALREADY_UP} -ne 1 ]]; then
|
||||
# Open up port 80 & 8080 so common containers on minions can be reached
|
||||
gcutil addfirewall \
|
||||
--project "${PROJECT}" \
|
||||
--norespect_terminal_width \
|
||||
--sleep_between_polls "${POLL_SLEEP_INTERVAL}" \
|
||||
--target_tags "${MINION_TAG}" \
|
||||
--allowed tcp:80,tcp:8080 \
|
||||
--network "${NETWORK}" \
|
||||
"${MINION_TAG}-${INSTANCE_PREFIX}-http-alt"
|
||||
fi
|
||||
|
||||
# Open up port 80 & 8080 so common containers on minions can be reached
|
||||
gcutil addfirewall \
|
||||
--project "${PROJECT}" \
|
||||
--norespect_terminal_width \
|
||||
--sleep_between_polls "${POLL_SLEEP_INTERVAL}" \
|
||||
--target_tags "${MINION_TAG}" \
|
||||
--allowed tcp:80,tcp:8080 \
|
||||
--network "${NETWORK}" \
|
||||
"${MINION_TAG}-${INSTANCE_PREFIX}-http-alt"
|
||||
}
|
||||
|
||||
# Execute after running tests to perform any required clean-up. This is called
|
||||
|
@ -14,88 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Starts a Kubernetes cluster, runs the e2e test suite, and shuts it
|
||||
# down.
|
||||
#
|
||||
# Environment flags:
|
||||
# TEST_PATTERN: A pattern to match test filenames against.
|
||||
# Example: "TEST_PATTERN=up" would match tests named "update.sh" and
|
||||
# "hiccup.sh".
|
||||
# Provided for backwards compatibility
|
||||
go run e2e.go -v -build -up -tests="*" -down
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Use testing config
|
||||
export KUBE_CONFIG_FILE="config-test.sh"
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||
|
||||
# TODO(jbeda): This will break on usage if there is a space in
|
||||
# ${KUBE_ROOT}. Covert to an array? Or an exported function?
|
||||
export KUBECFG="${KUBE_ROOT}/cluster/kubecfg.sh -expect_version_match"
|
||||
|
||||
source "${KUBE_ROOT}/cluster/kube-env.sh"
|
||||
source "${KUBE_ROOT}/cluster/$KUBERNETES_PROVIDER/util.sh"
|
||||
|
||||
# For debugging of this test's components, it's helpful to leave the test
|
||||
# cluster running.
|
||||
ALREADY_UP=${1:-0}
|
||||
LEAVE_UP=${2:-0}
|
||||
TEAR_DOWN=${3:-0}
|
||||
|
||||
if [[ $TEAR_DOWN -ne 0 ]]; then
|
||||
detect-project
|
||||
trap test-teardown EXIT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Build a release required by the test provider [if any]
|
||||
test-build-release
|
||||
|
||||
if [[ ${ALREADY_UP} -ne 1 ]]; then
|
||||
# Now bring a test cluster up with that release.
|
||||
"${KUBE_ROOT}/cluster/kube-up.sh"
|
||||
else
|
||||
# Just push instead
|
||||
"${KUBE_ROOT}/cluster/kube-push.sh"
|
||||
fi
|
||||
|
||||
# Perform any required setup of the cluster
|
||||
test-setup
|
||||
|
||||
set +e
|
||||
|
||||
if [[ ${LEAVE_UP} -ne 1 ]]; then
|
||||
trap test-teardown EXIT
|
||||
fi
|
||||
|
||||
TEST_PATTERN="${TEST_PATTERN:-}"
|
||||
failed=()
|
||||
for test_file in $(ls "${KUBE_ROOT}/hack/e2e-suite/"); do
|
||||
if [[ "${TEST_PATTERN}" != "" ]]; then
|
||||
check=".*${TEST_PATTERN}.*"
|
||||
if [[ ! "$test_file" =~ $check ]]; then
|
||||
echo "skipping $test_file"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "+++ Running $test_file"
|
||||
result=0
|
||||
"${KUBE_ROOT}/hack/e2e-suite/${test_file}" || result="$?"
|
||||
if [[ "${result}" -eq "0" ]]; then
|
||||
echo "${test_file} returned ${result}; passed!"
|
||||
else
|
||||
echo "${test_file} returned ${result}; FAIL!"
|
||||
failed+=(${test_file})
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
if [[ "${#failed[*]}" -eq 0 ]]; then
|
||||
echo "Final: All tests passed."
|
||||
else
|
||||
echo "Final: ${#failed[@]} tests failed: ${failed[@]}."
|
||||
fi
|
||||
|
||||
exit "${#failed[@]}"
|
||||
exit $?
|
||||
|
203
hack/e2e.go
Normal file
203
hack/e2e.go
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// e2e.go runs the e2e test suite. No non-standard package dependencies; call with "go run".
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
build = flag.Bool("build", false, "If true, build a new release. Otherwise, use whatever is there.")
|
||||
up = flag.Bool("up", false, "If true, start the the e2e cluster. If cluster is already up, recreate it.")
|
||||
push = flag.Bool("push", false, "If true, push to e2e cluster. Has no effect if -up is true.")
|
||||
down = flag.Bool("down", false, "If true, tear down the cluster before exiting.")
|
||||
tests = flag.String("tests", "*", "Run tests in hack/e2e-suite matching this glob.")
|
||||
root = flag.String("root", absOrDie(filepath.Clean(filepath.Join(path.Base(os.Args[0]), ".."))), "Root directory of kubernetes repository.")
|
||||
verbose = flag.Bool("v", false, "If true, print all command output.")
|
||||
)
|
||||
|
||||
var signals = make(chan os.Signal, 100)
|
||||
|
||||
func absOrDie(path string) string {
|
||||
out, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
signal.Notify(signals, os.Interrupt)
|
||||
|
||||
if *build {
|
||||
if runBash("build", `test-build-release`) {
|
||||
log.Fatal("Error building. Aborting.")
|
||||
}
|
||||
}
|
||||
|
||||
if *up {
|
||||
if !Up() {
|
||||
log.Fatal("Error starting e2e cluster. Aborting.")
|
||||
}
|
||||
} else if *push {
|
||||
if !runBash("push", path.Join(*root, "/cluster/kube-push.sh")) {
|
||||
log.Fatal("Error pushing e2e cluster. Aborting.")
|
||||
}
|
||||
}
|
||||
|
||||
failed, passed := []string{}, []string{}
|
||||
if *tests != "" {
|
||||
failed, passed = Test()
|
||||
}
|
||||
|
||||
if *down {
|
||||
TearDown()
|
||||
}
|
||||
|
||||
log.Printf("Passed tests: %v", passed)
|
||||
log.Printf("Failed tests: %v", failed)
|
||||
if len(failed) > 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func TearDown() {
|
||||
runBash("teardown", "test-teardown")
|
||||
}
|
||||
|
||||
func Up() bool {
|
||||
if !tryUp() {
|
||||
log.Printf("kube-up failed; will tear down and retry. (Possibly your cluster was in some partially created state?)")
|
||||
TearDown()
|
||||
return tryUp()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func tryUp() bool {
|
||||
return runBash("up", path.Join(*root, "/cluster/kube-up.sh; test-setup;"))
|
||||
}
|
||||
|
||||
func Test() (failed, passed []string) {
|
||||
// run tests!
|
||||
dir, err := os.Open(filepath.Join(*root, "hack", "e2e-suite"))
|
||||
if err != nil {
|
||||
log.Fatal("Couldn't open e2e-suite dir")
|
||||
}
|
||||
defer dir.Close()
|
||||
names, err := dir.Readdirnames(0)
|
||||
if err != nil {
|
||||
log.Fatal("Couldn't read names in e2e-suite dir")
|
||||
}
|
||||
|
||||
for i := range names {
|
||||
name := names[i]
|
||||
if name == "." || name == ".." {
|
||||
continue
|
||||
}
|
||||
if match, err := path.Match(*tests, name); !match && err == nil {
|
||||
continue
|
||||
}
|
||||
absName := filepath.Join(*root, "hack", "e2e-suite", name)
|
||||
log.Printf("%v matches %v. Starting test.", name, *tests)
|
||||
if runBash(name, absName) {
|
||||
log.Printf("%v passed", name)
|
||||
passed = append(passed, name)
|
||||
} else {
|
||||
log.Printf("%v failed", name)
|
||||
failed = append(failed, name)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// All nonsense below is temporary until we have go versions of these things.
|
||||
|
||||
func runBash(stepName, bashFragment string) bool {
|
||||
log.Printf("Running: %v", stepName)
|
||||
cmd := exec.Command("bash", "-s")
|
||||
cmd.Stdin = strings.NewReader(bashWrap(bashFragment))
|
||||
stdout, stderr := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
|
||||
if *verbose {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
} else {
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case s := <-signals:
|
||||
cmd.Process.Signal(s)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("Error running %v: %v", stepName, err)
|
||||
if !*verbose {
|
||||
fmt.Printf("stdout:\n------\n%v\n------\n", string(stdout.Bytes()))
|
||||
fmt.Printf("stderr:\n------\n%v\n------\n", string(stderr.Bytes()))
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var bashCommandPrefix = `
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
export KUBE_CONFIG_FILE="config-test.sh"
|
||||
|
||||
# TODO(jbeda): This will break on usage if there is a space in
|
||||
# ${KUBE_ROOT}. Covert to an array? Or an exported function?
|
||||
export KUBECFG="` + *root + `/cluster/kubecfg.sh -expect_version_match"
|
||||
|
||||
source "` + *root + `/cluster/kube-env.sh"
|
||||
source "` + *root + `/cluster/${KUBERNETES_PROVIDER}/util.sh"
|
||||
|
||||
detect-project
|
||||
|
||||
`
|
||||
|
||||
var bashCommandSuffix = `
|
||||
|
||||
`
|
||||
|
||||
func bashWrap(cmd string) string {
|
||||
return bashCommandPrefix + cmd + bashCommandSuffix
|
||||
}
|
Loading…
Reference in New Issue
Block a user