mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Build relevant binaries with coverage.
This commit is contained in:
parent
1b3a2dd083
commit
aa2a7d001a
@ -211,6 +211,15 @@ readonly KUBE_STATIC_LIBRARIES=(
|
||||
kubectl
|
||||
)
|
||||
|
||||
# Fully-qualified package names that we want to instrument for coverage information.
|
||||
readonly KUBE_COVERAGE_INSTRUMENTED_PACKAGES=(
|
||||
k8s.io/kubernetes/cmd/kube-apiserver
|
||||
k8s.io/kubernetes/cmd/kube-controller-manager
|
||||
k8s.io/kubernetes/cmd/kube-scheduler
|
||||
k8s.io/kubernetes/cmd/kube-proxy
|
||||
k8s.io/kubernetes/cmd/kubelet
|
||||
)
|
||||
|
||||
# KUBE_CGO_OVERRIDES is a space-separated list of binaries which should be built
|
||||
# with CGO enabled, assuming CGO is supported on the target platform.
|
||||
# This overrides any entry in KUBE_STATIC_LIBRARIES.
|
||||
@ -441,6 +450,104 @@ kube::golang::outfile_for_binary() {
|
||||
echo "${output_path}/${bin}"
|
||||
}
|
||||
|
||||
# Argument: the name of a Kubernetes package.
|
||||
# Returns 0 if the binary can be built with coverage, 0 otherwise.
|
||||
# NB: this ignores whether coverage is globally enabled or not.
|
||||
kube::golang::is_covered_binary() {
|
||||
return $(kube::util::array_contains "$1" "${KUBE_COVERAGE_INSTRUMENTED_PACKAGES[@]}")
|
||||
}
|
||||
|
||||
# Argument: the name of a Kubernetes package (e.g. k8s.io/kubernetes/cmd/kube-scheduler)
|
||||
# Echos the path to a dummy test used for coverage information.
|
||||
kube::golang::path_for_coverage_dummy_test() {
|
||||
local package=$1
|
||||
local path="${KUBE_GOPATH}/src/$package"
|
||||
local name=$(basename "$package")
|
||||
echo "$path/zz_autogenerated_${name}_test.go"
|
||||
}
|
||||
|
||||
# Argument: the name of a Kubernetes package (e.g. k8s.io/kubernetes/cmd/kube-scheduler).
|
||||
# Creates a dummy unit test on disk in the source directory for the given package.
|
||||
# This unit test will invoke the package's standard entry point when run.
|
||||
kube::golang::create_coverage_dummy_test() {
|
||||
local package="$1"
|
||||
local name="$(basename "$package")"
|
||||
cat <<EOF > $(kube::golang::path_for_coverage_dummy_test "$package")
|
||||
package main
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
func TestMain(m *testing.M) {
|
||||
// We need to pass coverage instructions to the unittest framework, so we hijack os.Args
|
||||
original_args := os.Args
|
||||
now := time.Now().UnixNano()
|
||||
test_args := []string{os.Args[0], "-test.coverprofile=/tmp/k8s-${name}-" + strconv.FormatInt(now, 10) + ".cov"}
|
||||
os.Args = test_args
|
||||
|
||||
// This is sufficient for the unit tests to be set up.
|
||||
flag.Parse()
|
||||
|
||||
// Restore the original args for use by the program.
|
||||
os.Args = original_args
|
||||
// Go!
|
||||
main()
|
||||
|
||||
// Make sure we actually write the profiling information to disk, if we make it here.
|
||||
// On long-running services, or anything that calls os.Exit(), this is insufficient,
|
||||
// so be sure to call this from inside the binary too.
|
||||
// TODO: actually have some code here.
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
# Argument: the name of a Kubernetes package (e.g. k8s.io/kubernetes/cmd/kube-scheduler).
|
||||
# Deletes a test generated by kube::golang::create_coverage_dumy_test.
|
||||
kube::golang::delete_coverage_dummy_test() {
|
||||
local package=$1
|
||||
rm $(kube::golang::path_for_coverage_dummy_test "$package")
|
||||
}
|
||||
|
||||
# Arguments: a list of kubernetes packages to build.
|
||||
# Expected variables: build_args should be set to an array of Go build arguments.
|
||||
# In addition, the standard build globals are assumed.
|
||||
#
|
||||
# Invokes Go to actually build some packages. If coverage is disabled, simply invokes
|
||||
# go install. If coverage is enabled, builds covered binaries using go test, temporarily
|
||||
# producing the required unit test files and then cleaning up after itself.
|
||||
# Non-covered binaries are then built using go install as usual.
|
||||
kube::golang::build_some_binaries() {
|
||||
if [[ -n "${build_with_coverage:-}" ]]; then
|
||||
local -a uncovered=()
|
||||
for package in "$@"; do
|
||||
if kube::golang::is_covered_binary "$package"; then
|
||||
V=2 kube::log::info "Building $package with coverage..."
|
||||
kube::golang::create_coverage_dummy_test "$package"
|
||||
go test -c -o "$(kube::golang::outfile_for_binary "$package" "$platform")" \
|
||||
-covermode count \
|
||||
-coverpkg k8s.io/... \
|
||||
"${build_args[@]}" \
|
||||
"$package"
|
||||
kube::golang::delete_coverage_dummy_test "$package"
|
||||
else
|
||||
uncovered+=("$package")
|
||||
fi
|
||||
done
|
||||
if [[ "${#uncovered[@]}" != 0 ]]; then
|
||||
V=2 kube::log::info "Building ${uncovered[@]} without coverage..."
|
||||
go install "${build_args[@]}" "${uncovered[@]}"
|
||||
else
|
||||
V=2 kube::log::info "Nothing to build without coverage."
|
||||
fi
|
||||
else
|
||||
V=2 kube::log::info "Coverage is disabled."
|
||||
go install "${build_args[@]}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
kube::golang::build_binaries_for_platform() {
|
||||
local platform=$1
|
||||
|
||||
@ -460,18 +567,24 @@ kube::golang::build_binaries_for_platform() {
|
||||
fi
|
||||
done
|
||||
|
||||
local -a build_args
|
||||
if [[ "${#statics[@]}" != 0 ]]; then
|
||||
CGO_ENABLED=0 go install -installsuffix static "${goflags[@]:+${goflags[@]}}" \
|
||||
-gcflags "${gogcflags}" \
|
||||
-ldflags "${goldflags}" \
|
||||
"${statics[@]:+${statics[@]}}"
|
||||
build_args=(
|
||||
-installsuffix static
|
||||
${goflags:+"${goflags[@]}"}
|
||||
-gcflags "${gogcflags:-}"
|
||||
-ldflags "${goldflags:-}"
|
||||
)
|
||||
CGO_ENABLED=0 kube::golang::build_some_binaries "${statics[@]}"
|
||||
fi
|
||||
|
||||
if [[ "${#nonstatics[@]}" != 0 ]]; then
|
||||
go install "${goflags[@]:+${goflags[@]}}" \
|
||||
-gcflags "${gogcflags}" \
|
||||
-ldflags "${goldflags}" \
|
||||
"${nonstatics[@]:+${nonstatics[@]}}"
|
||||
build_args=(
|
||||
${goflags:+"${goflags[@]}"}
|
||||
-gcflags "${gogcflags:-}"
|
||||
-ldflags "${goldflags:-}"
|
||||
)
|
||||
kube::golang::build_some_binaries "${nonstatics[@]}"
|
||||
fi
|
||||
|
||||
for test in "${tests[@]:+${tests[@]}}"; do
|
||||
@ -480,9 +593,9 @@ kube::golang::build_binaries_for_platform() {
|
||||
|
||||
mkdir -p "$(dirname ${outfile})"
|
||||
go test -c \
|
||||
"${goflags[@]:+${goflags[@]}}" \
|
||||
-gcflags "${gogcflags}" \
|
||||
-ldflags "${goldflags}" \
|
||||
${goflags:+"${goflags[@]}"} \
|
||||
-gcflags "${gogcflags:-}" \
|
||||
-ldflags "${goldflags:-}" \
|
||||
-o "${outfile}" \
|
||||
"${testpkg}"
|
||||
done
|
||||
@ -535,10 +648,11 @@ kube::golang::build_binaries() {
|
||||
host_platform=$(kube::golang::host_platform)
|
||||
|
||||
# Use eval to preserve embedded quoted strings.
|
||||
local goflags goldflags gogcflags
|
||||
local goflags goldflags gogcflags build_with_coverage
|
||||
eval "goflags=(${GOFLAGS:-})"
|
||||
goldflags="${GOLDFLAGS:-} $(kube::version::ldflags)"
|
||||
gogcflags="${GOGCFLAGS:-}"
|
||||
build_with_coverage="${KUBE_BUILD_WITH_COVERAGE:-}"
|
||||
|
||||
local -a targets=()
|
||||
local arg
|
||||
|
@ -18,6 +18,20 @@ kube::util::sortable_date() {
|
||||
date "+%Y%m%d-%H%M%S"
|
||||
}
|
||||
|
||||
# arguments: target, item1, item2, item3, ...
|
||||
# returns 0 if target is in the given items, 1 otherwise.
|
||||
kube::util::array_contains() {
|
||||
local search="$1"
|
||||
local element
|
||||
shift
|
||||
for element; do
|
||||
if [[ "$element" == "$search" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
kube::util::wait_for_url() {
|
||||
local url=$1
|
||||
local prefix=${2:-}
|
||||
|
Loading…
Reference in New Issue
Block a user