Skip to content

Commit

Permalink
Merge pull request #15605 from smarterclayton/int2
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

Run integration tests in parallel
  • Loading branch information
openshift-merge-robot committed Aug 28, 2017
2 parents e88a6b0 + cd94e23 commit 3616a5b
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 182 deletions.
6 changes: 3 additions & 3 deletions Makefile
Expand Up @@ -175,7 +175,7 @@ test-unit:
# Example:
# make test-integration
test-integration:
KUBE_COVER=" " KUBE_RACE=" " hack/test-integration.sh
hack/test-integration.sh
.PHONY: test-integration

# Run command tests. Uses whatever binaries are currently built.
Expand All @@ -191,8 +191,8 @@ test-cmd: build
#
# Example:
# make test-end-to-end
test-end-to-end: build
KUBE_COVER=" " KUBE_RACE=" " OS_TEST_PACKAGE=test/end-to-end hack/test-integration.sh
test-end-to-end:
COVERAGE_SPEC=' ' DETECT_RACES='false' TIMEOUT='10m' hack/test-go.sh ./test/end-to-end
hack/test-end-to-end.sh
.PHONY: test-end-to-end

Expand Down
10 changes: 7 additions & 3 deletions hack/build-dind-images.sh
Expand Up @@ -5,11 +5,15 @@
#
# Reference: https://github.com/openshift/origin/issues/11452

STARTTIME=$(date +%s)
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

function cleanup() {
return_code=$?
os::util::describe_return_code "${return_code}"
exit "${return_code}"
}
trap "cleanup" EXIT

os::build::image openshift/dind "${OS_ROOT}/images/dind"
os::build::image openshift/dind-node "${OS_ROOT}/images/dind/node"
os::build::image openshift/dind-master "${OS_ROOT}/images/dind/master"

ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret"
10 changes: 7 additions & 3 deletions hack/build-go.sh
@@ -1,9 +1,15 @@
#!/bin/bash

# This script sets up a go workspace locally and builds all go components.
STARTTIME=$(date +%s)
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

function cleanup() {
return_code=$?
os::util::describe_return_code "${return_code}"
exit "${return_code}"
}
trap "cleanup" EXIT

build_targets=("$@")
platform="$(os::build::host_platform)"

Expand Down Expand Up @@ -37,5 +43,3 @@ OS_BUILD_PLATFORMS=("${OS_BUILD_PLATFORMS[@]:-${platform}}")
os::build::build_binaries "${build_targets[@]}"
os::build::place_bins "${build_targets[@]}"
os::build::make_openshift_binary_symlinks

ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret"
11 changes: 8 additions & 3 deletions hack/build-in-docker.sh
Expand Up @@ -8,10 +8,15 @@ function absolute_path() {
popd > /dev/null
}

STARTTIME=$(date +%s)
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

function cleanup() {
return_code=$?
os::util::describe_return_code "${return_code}"
exit "${return_code}"
}
trap "cleanup" EXIT

origin_path="src/github.com/openshift/origin"

docker run -e "OWNER_GROUP=$UID:$GROUPS" --rm -v "$(absolute_path $OS_ROOT):/go/${origin_path}:z" openshift/origin-release /usr/bin/openshift-origin-build.sh $@

ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret"
10 changes: 7 additions & 3 deletions hack/build-release.sh
Expand Up @@ -4,9 +4,15 @@
# image to be built prior to executing this command via hack/build-base-images.sh.

# NOTE: only committed code is built.
STARTTIME=$(date +%s)
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

function cleanup() {
return_code=$?
os::util::describe_return_code "${return_code}"
exit "${return_code}"
}
trap "cleanup" EXIT

export OS_BUILD_ENV_FROM_ARCHIVE=y
export OS_BUILD_ENV_PRESERVE=_output/local

Expand All @@ -29,5 +35,3 @@ trap "os::build::environment::cleanup ${container}" EXIT
)
os::build::environment::withsource "${container}" "${OS_GIT_COMMIT:-HEAD}"
echo "${OS_GIT_COMMIT}" > "${OS_OUTPUT_RELEASEPATH}/.commit"

ret=$?; ENDTIME=$(date +%s); echo "$0 took $(($ENDTIME - $STARTTIME)) seconds"; exit "$ret"
8 changes: 8 additions & 0 deletions hack/build-rpm-release.sh
Expand Up @@ -5,6 +5,14 @@
# be running `hack/build-cross.sh` under the covers, so we transitively
# consume all of the relevant envars.
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

function cleanup() {
return_code=$?
os::util::describe_return_code "${return_code}"
exit "${return_code}"
}
trap "cleanup" EXIT

os::util::ensure::system_binary_exists tito
os::util::ensure::system_binary_exists createrepo
os::build::setup_env
Expand Down
2 changes: 1 addition & 1 deletion hack/lib/test/junit.sh
Expand Up @@ -186,7 +186,7 @@ function os::test::junit::internal::generate_report() {
os::util::ensure::built_binary_exists 'junitreport'

local report_file
report_file="$( mktemp --tmpdir="${ARTIFACT_DIR}" "${report_type}_report_XXXXX" --suffix ".xml" )"
report_file="$( mktemp "${ARTIFACT_DIR}/${report_type}_report_XXXXX" ).xml"
os::log::info "jUnit XML report placed at $( os::util::repository_relative_path ${report_file} )"
junitreport --type "${report_type}" \
--suites nested \
Expand Down
151 changes: 5 additions & 146 deletions hack/test-integration.sh
Expand Up @@ -2,151 +2,10 @@
STARTTIME=$(date +%s)
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"

os::build::setup_env

export API_SCHEME="http"
export API_BIND_HOST="127.0.0.1"
os::cleanup::tmpdir
os::util::environment::setup_all_server_vars

function cleanup() {
return_code=$?

# this is a domain socket. CI falls over it.
rm -f "${BASETMPDIR}/dockershim.sock"

os::test::junit::generate_report
os::cleanup::all
os::util::describe_return_code "${return_code}"

exit "${return_code}"
}
trap "cleanup" EXIT

export GOMAXPROCS="$(grep "processor" -c /proc/cpuinfo 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || 1)"

# Internalize environment variables we consume and default if they're not set
package="${OS_TEST_PACKAGE:-test/integration}"
name="$(basename ${package})"
dlv_debug="${DLV_DEBUG:-}"
verbose="${VERBOSE:-}"
junit_report="${JUNIT_REPORT:-}"

if [[ -n "${JUNIT_REPORT:-}" ]]; then
export JUNIT_REPORT_OUTPUT="${LOG_DIR}/raw_test_output.log"
rm -rf "${JUNIT_REPORT_OUTPUT}"
fi

# CGO must be disabled in order to debug
if [[ -n "${dlv_debug}" ]]; then
export OS_TEST_CGO_ENABLED=0
fi

# build the test executable
if [[ -n "${OPENSHIFT_SKIP_BUILD:-}" ]]; then
os::log::warning "Skipping build due to OPENSHIFT_SKIP_BUILD"
else
"${OS_ROOT}/hack/build-go.sh" "${package}/${name}.test"
fi
testexec="$(os::util::find::built_binary "${name}.test")"

os::log::system::start

function exectest() {
echo "Running $1..."

export TEST_ETCD_DIR="${TMPDIR:-/tmp}/etcd-${1}"
rm -fr "${TEST_ETCD_DIR}"
mkdir -p "${TEST_ETCD_DIR}"
result=1
if [[ -n "${dlv_debug}" ]]; then
# run tests using delve debugger
dlv exec "${testexec}" -- -test.run="^$1$" "${@:2}"
result=$?
out=
elif [[ -n "${verbose}" ]]; then
# run tests with extra verbosity
out=$("${testexec}" -vmodule=*=5 -test.v -test.timeout=4m -test.run="^$1$" "${@:2}" 2>&1)
result=$?
elif [[ -n "${junit_report}" ]]; then
# run tests and generate jUnit xml
# when running with junit (normally done in CI), we retry failing tests to see if they just flaked
# this involves suppressing the first junit output in the case of failure to prevent dying jobs
firstJunitReport="${TMPDIR:-/tmp}/first-integration-attempt.xml"
out=$("${testexec}" -test.v -test.timeout=4m -test.run="^$1$" "${@:2}" 2>&1 | tee "${firstJunitReport}" )
result=$?

# if the test failed, retry it, but this time we're committed to the result and its junit wins
if [[ ${result} -eq 0 ]]; then
cat "${firstJunitReport}" >> "${JUNIT_REPORT_OUTPUT}"
else
os::text::clear_last_line
os::text::print_red "failed $1, retrying"
echo "Running $1..."
# skuznets, this is the spot to inject your counter of failures. The ${firstJunitReport} has the information about the failure
out=$("${testexec}" -test.v -test.timeout=4m -test.run="^$1$" "${@:2}" 2>&1 | tee -a "${JUNIT_REPORT_OUTPUT}" )
result=$?
fi
else
# run tests normally
out=$("${testexec}" -test.timeout=4m -test.run="^$1$" "${@:2}" 2>&1)
result=$?
fi

os::text::clear_last_line

if [[ ${result} -eq 0 ]]; then
os::text::print_green "ok $1"
# Remove the etcd directory to cleanup the space.
rm -rf "${TEST_ETCD_DIR}"
exit 0
else
os::text::print_red "failed $1"
echo "${out:-}"

exit 1
fi
}

export -f exectest
export testexec
export childargs

loop="${TIMES:-1}"
# $1 is passed to grep -E to filter the list of tests; this may be the name of a single test,
# a fragment of a test name, or a regular expression.
#
# Examples:
#
# hack/test-integration.sh WatchBuilds
# hack/test-integration.sh Template*
# hack/test-integration.sh "(WatchBuilds|Template)"
listTemplate='{{ range $i,$file := .TestGoFiles }}{{$.Dir}}/{{ $file }}{{ "\n" }}{{end}}'
tests=( $(go list -f "${listTemplate}" "./${package}" | xargs grep -E -o --no-filename '^func Test[^(]+' | cut -d ' ' -f 2 | grep -E "${1-Test}") )

if [[ "${#tests[@]}" == "0" ]]; then
os::text::print_red "No tests found matching \"${1-Test}\""
exit 1
# build the test executable and make sure it's on the path
if [[ -z "${OPENSHIFT_SKIP_BUILD-}" ]]; then
"${OS_ROOT}/hack/build-go.sh" "test/integration/integration.test"
fi
os::util::environment::update_path_var

# run each test as its own process
ret=0
test_result="ok"
pushd "${OS_ROOT}/${package}" &>/dev/null
test_start_time=$(date +%s)
for test in "${tests[@]}"; do
for((i=0;i<${loop};i+=1)); do
if ! (exectest "${test}" ${@:2}); then
ret=1
test_result="FAIL"
fi
done
done
test_end_time=$(date +%s)
test_duration=$((test_end_time - test_start_time))

echo "${test_result} github.com/openshift/origin/test/integration $((test_duration)).000s" >> "${JUNIT_REPORT_OUTPUT:-/dev/null}"

popd &>/dev/null

ENDTIME=$(date +%s); echo "$0 took $((ENDTIME - STARTTIME)) seconds"; exit "$ret"
COVERAGE_SPEC=" " DETECT_RACES=false TMPDIR="${BASETMPDIR}" TIMEOUT=30m GOTESTFLAGS="-sub.timeout=120s" "${OS_ROOT}/hack/test-go.sh" "test/integration/runner"
10 changes: 10 additions & 0 deletions pkg/cmd/flagtypes/addr.go
Expand Up @@ -55,6 +55,16 @@ func (a *Addr) String() string {
return a.URL.String()
}

// HostPort returns the host and port joined together. If no port is set :0 will
// be appended.
func (a *Addr) HostPort(defaultPort int) string {
port := a.Port
if port == 0 {
port = defaultPort
}
return net.JoinHostPort(a.Host, strconv.Itoa(port))
}

// Set attempts to set a string value to an address
func (a *Addr) Set(value string) error {
scheme := a.DefaultScheme
Expand Down
4 changes: 1 addition & 3 deletions pkg/cmd/server/admin/create_nodeconfig.go
Expand Up @@ -5,10 +5,8 @@ import (
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path"
"strconv"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -401,7 +399,7 @@ func (o CreateNodeConfigOptions) MakeNodeConfig(serverCertFile, serverKeyFile, n
NodeName: o.NodeName,

ServingInfo: configapi.ServingInfo{
BindAddress: net.JoinHostPort(o.ListenAddr.Host, strconv.Itoa(ports.KubeletPort)),
BindAddress: o.ListenAddr.HostPort(ports.KubeletPort),
},

VolumeDirectory: o.VolumeDir,
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/server/etcd/etcdserver/run.go
Expand Up @@ -93,6 +93,9 @@ func RunEtcd(etcdServerConfig *configapi.EtcdConfig) {
func addressToURLs(addr string, isTLS bool) []string {
addrs := strings.Split(addr, ",")
for i := range addrs {
if strings.HasPrefix(addrs[i], "unix://") || strings.HasPrefix(addrs[i], "unixs://") {
continue
}
if isTLS {
addrs[i] = "https://" + addrs[i]
} else {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/server/start/node_args.go
Expand Up @@ -179,7 +179,7 @@ func (args NodeArgs) BuildSerializeableNodeConfig() (*configapi.NodeConfig, erro
NodeName: args.NodeName,

ServingInfo: configapi.ServingInfo{
BindAddress: net.JoinHostPort(args.ListenArg.ListenAddr.Host, strconv.Itoa(ports.KubeletPort)),
BindAddress: args.ListenArg.ListenAddr.HostPort(ports.KubeletPort),
},

ImageConfig: configapi.ImageConfig{
Expand Down
9 changes: 9 additions & 0 deletions pkg/cmd/server/start/start_allinone.go
Expand Up @@ -21,6 +21,7 @@ import (
"k8s.io/apiserver/pkg/util/flag"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/master/ports"

"github.com/openshift/origin/pkg/cmd/server/admin"
configapi "github.com/openshift/origin/pkg/cmd/server/api"
Expand Down Expand Up @@ -240,6 +241,14 @@ func (o *AllInOneOptions) Complete() error {
o.NodeArgs.NodeName = strings.ToLower(o.NodeArgs.NodeName)
o.NodeArgs.MasterCertDir = o.MasterOptions.MasterArgs.ConfigDir.Value()

// if the node listen argument inherits the master listen argument, specialize it now to its own value so
// that the kubelet can have a customizable port
if o.NodeArgs.ListenArg == o.MasterOptions.MasterArgs.ListenArg {
o.NodeArgs.ListenArg = NewDefaultListenArg()
o.NodeArgs.ListenArg.ListenAddr.Set(fmt.Sprintf("%s:%d", o.MasterOptions.MasterArgs.ListenArg.ListenAddr.Host, ports.KubeletPort))
o.NodeArgs.ListenArg.ListenAddr.Default()
}

// For backward compatibility of DNS queries to the master service IP, enabling node DNS
// continues to start the master DNS, but the container DNS server will be the node's.
// However, if the user has provided an override DNSAddr, we need to honor the value if
Expand Down
2 changes: 1 addition & 1 deletion test/integration/gc_default_test.go
Expand Up @@ -83,7 +83,7 @@ func TestGCDefaults(t *testing.T) {

// the /oapi endpoints should orphan by default
// wait for a bit and make sure that the build is still there
time.Sleep(2 * time.Second)
time.Sleep(6 * time.Second)
childConfigMap, err = kubeClient.Core().ConfigMaps(ns).Get(childConfigMap.Name, metav1.GetOptions{})
if err != nil {
t.Error(err)
Expand Down

0 comments on commit 3616a5b

Please sign in to comment.