Skip to content

Commit

Permalink
Merge pull request #7590 from GoogleCloudPlatform/revert-7462-native-…
Browse files Browse the repository at this point in the history
…ginkgo-runner

Revert "Use native Ginkgo test runner instead of cmd/e2e"
  • Loading branch information
zmerlynn committed Apr 30, 2015
2 parents 8d24f73 + bfaf976 commit 2c4ad94
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 177 deletions.
89 changes: 89 additions & 0 deletions cmd/e2e/e2e.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
Copyright 2015 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.
*/

package main

import (
"fmt"
"os"
goruntime "runtime"
"strings"

"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/test/e2e"
"github.com/golang/glog"
flag "github.com/spf13/pflag"
)

var (
context = &e2e.TestContextType{}
cloudConfig = &context.CloudConfig

orderseed = flag.Int64("orderseed", 0, "If non-zero, seed of random test shuffle order. (Otherwise random.)")
reportDir = flag.String("report-dir", "", "Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
times = flag.Int("times", 1, "Number of times each test is eligible to be run. Individual order is determined by shuffling --times instances of each test using --orderseed (like a multi-deck shoe of cards).")
testList util.StringList
)

func init() {
flag.VarP(&testList, "test", "t", "Test to execute (may be repeated or comma separated list of tests.) Defaults to running all tests.")

flag.StringVar(&context.KubeConfig, clientcmd.RecommendedConfigPathFlag, "", "Path to kubeconfig containing embeded authinfo.")
flag.StringVar(&context.KubeContext, clientcmd.FlagContext, "", "kubeconfig context to use/override. If unset, will use value from 'current-context'")
flag.StringVar(&context.AuthConfig, "auth-config", "", "Path to the auth info file.")
flag.StringVar(&context.CertDir, "cert-dir", "", "Path to the directory containing the certs. Default is empty, which doesn't use certs.")
flag.StringVar(&context.Host, "host", "", "The host, or apiserver, to connect to")
flag.StringVar(&context.RepoRoot, "repo-root", "./", "Root directory of kubernetes repository, for finding test files. Default assumes working directory is repository root")
flag.StringVar(&context.Provider, "provider", "", "The name of the Kubernetes provider (gce, gke, local, vagrant, etc.)")

// TODO: Flags per provider? Rename gce_project/gce_zone?
flag.StringVar(&cloudConfig.MasterName, "kube-master", "", "Name of the kubernetes master. Only required if provider is gce or gke")
flag.StringVar(&cloudConfig.ProjectID, "gce-project", "", "The GCE project being used, if applicable")
flag.StringVar(&cloudConfig.Zone, "gce-zone", "", "GCE zone being used, if applicable")
}

func main() {
util.InitFlags()
goruntime.GOMAXPROCS(goruntime.NumCPU())
if context.Provider == "" {
glog.Info("The --provider flag is not set. Treating as a conformance test. Some tests may not be run.")
os.Exit(1)
}
if *times <= 0 {
glog.Error("Invalid --times (negative or no testing requested)!")
os.Exit(1)
}

if context.Provider == "aws" {
awsConfig := "[Global]\n"
if cloudConfig.Zone == "" {
glog.Error("--gce-zone must be specified for AWS")
os.Exit(1)
}
awsConfig += fmt.Sprintf("Zone=%s\n", cloudConfig.Zone)

var err error
cloudConfig.Provider, err = cloudprovider.GetCloudProvider(context.Provider, strings.NewReader(awsConfig))
if err != nil {
glog.Error("Error building AWS provider: ", err)
os.Exit(1)
}
}

e2e.RunE2ETests(context, *orderseed, *times, *reportDir, testList)
}
84 changes: 57 additions & 27 deletions hack/ginkgo-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,54 @@ set -o errexit
set -o nounset
set -o pipefail

GINKGO_PARALLEL=${GINKGO_PARALLEL:-n} # set to 'y' to run tests in parallel
KUBE_ROOT=$(readlink -f $(dirname "${BASH_SOURCE}")/..)

KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/cluster/common.sh"
source "${KUBE_ROOT}/hack/lib/init.sh"

# Ginkgo will build the e2e tests, so we need to make sure that the environment
# is set up correctly (including Godeps, etc).
kube::golang::setup_env

# --- Build the Ginkgo test runner from Godeps
godep go install github.com/onsi/ginkgo/ginkgo
ginkgo=$(godep path)/bin/ginkgo
# --- Find local test binaries.

# Detect the OS name/arch so that we can find our binary
case "$(uname -s)" in
Darwin)
host_os=darwin
;;
Linux)
host_os=linux
;;
*)
echo "Unsupported host OS. Must be Linux or Mac OS X." >&2
exit 1
;;
esac

case "$(uname -m)" in
x86_64*)
host_arch=amd64
;;
i?86_64*)
host_arch=amd64
;;
amd64*)
host_arch=amd64
;;
arm*)
host_arch=arm
;;
i?86*)
host_arch=x86
;;
*)
echo "Unsupported host arch. Must be x86_64, 386 or arm." >&2
exit 1
;;
esac

# Gather up the list of likely places and use ls to find the latest one.
locations=(
"${KUBE_ROOT}/_output/dockerized/bin/${host_os}/${host_arch}/e2e"
"${KUBE_ROOT}/_output/local/bin/${host_os}/${host_arch}/e2e"
"${KUBE_ROOT}/platforms/${host_os}/${host_arch}/e2e"
)
e2e=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 )

# --- Setup some env vars.

Expand Down Expand Up @@ -62,8 +97,8 @@ if [[ -z "${AUTH_CONFIG:-}" ]]; then
)
elif [[ "${KUBERNETES_PROVIDER}" == "conformance_test" ]]; then
auth_config=(
"--auth-config=${KUBERNETES_CONFORMANCE_TEST_AUTH_CONFIG:-}"
"--cert-dir=${KUBERNETES_CONFORMANCE_TEST_CERT_DIR:-}"
"--auth_config=${KUBERNETES_CONFORMANCE_TEST_AUTH_CONFIG:-}"
"--cert_dir=${KUBERNETES_CONFORMANCE_TEST_CERT_DIR:-}"
)
else
auth_config=(
Expand All @@ -74,26 +109,21 @@ else
echo "Conformance Test. No cloud-provider-specific preparation."
KUBERNETES_PROVIDER=""
auth_config=(
"--auth-config=${AUTH_CONFIG:-}"
"--cert-dir=${CERT_DIR:-}"
"--auth_config=${AUTH_CONFIG:-}"
"--cert_dir=${CERT_DIR:-}"
)
fi

ginkgo_args=()
if [[ ${GINKGO_PARALLEL} =~ ^[yY]$ ]]; then
ginkgo_args+=("-p")
fi

# Use the kubectl binary from the same directory as the e2e binary.
# The --host setting is used only when providing --auth_config
# If --kubeconfig is used, the host to use is retrieved from the .kubeconfig
# file and the one provided with --host is ignored.
"${ginkgo}" "${ginkgo_args[@]:+${ginkgo_args[@]}}" test/e2e -- \
"${auth_config[@]:+${auth_config[@]}}" \
export PATH=$(dirname "${e2e}"):"${PATH}"
"${e2e}" "${auth_config[@]:+${auth_config[@]}}" \
--host="https://${KUBE_MASTER_IP-}" \
--provider="${KUBERNETES_PROVIDER}" \
--gce-project="${PROJECT:-}" \
--gce-zone="${ZONE:-}" \
--kube-master="${KUBE_MASTER:-}" \
--repo-root="${KUBE_VERSION_ROOT}" \
${E2E_REPORT_DIR+"--report-dir=${E2E_REPORT_DIR}"} \
--gce_project="${PROJECT:-}" \
--gce_zone="${ZONE:-}" \
--kube_master="${KUBE_MASTER:-}" \
${E2E_REPORT_DIR+"--report_dir=${E2E_REPORT_DIR}"} \
"${@:-}"
2 changes: 1 addition & 1 deletion hack/lib/golang.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ readonly KUBE_CLIENT_BINARIES_WIN=("${KUBE_CLIENT_BINARIES[@]/%/.exe}")

# The set of test targets that we are building for all platforms
readonly KUBE_TEST_TARGETS=(
cmd/e2e
cmd/integration
cmd/gendocs
cmd/genman
Expand All @@ -58,7 +59,6 @@ readonly KUBE_TEST_PORTABLE=(
hack/e2e-suite
hack/e2e-internal
hack/ginkgo-e2e.sh
hack/lib
)

# If we update this we need to also update the set of golang compilers we build
Expand Down
1 change: 0 additions & 1 deletion hack/test-go.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ kube::test::find_dirs() {
-o -wholename '*/third_party/*' \
-o -wholename '*/Godeps/*' \
-o -wholename '*/contrib/podex/*' \
-o -wholename '*/test/e2e/*' \
-o -wholename '*/test/integration/*' \
\) -prune \
\) -name '*_test.go' -print0 | xargs -0n1 dirname | sed 's|^\./||' | sort -u
Expand Down
98 changes: 98 additions & 0 deletions test/e2e/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
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.
*/

package e2e

import (
"fmt"
"path"
"regexp"
"strings"

"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
"github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
"github.com/onsi/ginkgo/reporters"
"github.com/onsi/gomega"
)

type testResult bool

type CloudConfig struct {
ProjectID string
Zone string
MasterName string

Provider cloudprovider.Interface
}

func init() {
// Turn on verbose by default to get spec names
config.DefaultReporterConfig.Verbose = true

// Turn on EmitSpecProgress to get spec progress (especially on interrupt)
config.GinkgoConfig.EmitSpecProgress = true

// Randomize specs as well as suites
config.GinkgoConfig.RandomizeAllSpecs = true
}

func (t *testResult) Fail() { *t = false }

// Run each Go end-to-end-test. This function assumes the
// creation of a test cluster.
func RunE2ETests(context *TestContextType, orderseed int64, times int, reportDir string, testList []string) {
testContext = *context
util.ReallyCrash = true
util.InitLogs()
defer util.FlushLogs()

if len(testList) != 0 {
if config.GinkgoConfig.FocusString != "" || config.GinkgoConfig.SkipString != "" {
glog.Fatal("Either specify --test/-t or --ginkgo.focus/--ginkgo.skip but not both.")
}
var testRegexps []string
for _, t := range testList {
testRegexps = append(testRegexps, regexp.QuoteMeta(t))
}
config.GinkgoConfig.FocusString = `\b(` + strings.Join(testRegexps, "|") + `)\b`
}

// Disable density test unless it's explicitly requested.
if config.GinkgoConfig.FocusString == "" && config.GinkgoConfig.SkipString == "" {
config.GinkgoConfig.SkipString = "Skipped"
}

// TODO: Make orderseed work again.
var passed testResult = true
gomega.RegisterFailHandler(ginkgo.Fail)
// Run the existing tests with output to console + JUnit for Jenkins
for i := 0; i < times && passed; i++ {
var r []ginkgo.Reporter
if reportDir != "" {
r = append(r, reporters.NewJUnitReporter(path.Join(reportDir, fmt.Sprintf("junit_%d.xml", i+1))))
}
ginkgo.RunSpecsWithDefaultAndCustomReporters(&passed, fmt.Sprintf("Kubernetes e2e Suite run %d of %d", i+1, times), r)
}

if !passed {
glog.Fatalf("At least one test failed")
} else {
glog.Infof("All tests pass")
}
}

0 comments on commit 2c4ad94

Please sign in to comment.