Revision 36452a1c1d43f8f90511642643a5b3aff2d00391 authored by Jack Kleeman on 06 May 2020, 10:57:19 UTC, committed by tangcong on 23 June 2020, 11:50:21 UTC
Currently, watch cancel requests are only sent to the server after a message comes through on a watch where the client has cancelled. This means that cancelled watches that don't receive any new messages are never cancelled; they persist for the lifetime of the client stream. This has negative connotations for locking applications where a watch may observe a key which might never change again after cancellation, leading to many accumulating watches on the server. By cancelling proactively, in most cases we simply move the cancel request to happen earlier, and additionally we solve the case where the cancel request would never be sent. Fixes #9416 Heavy inspiration drawn from the solutions proposed there.
1 parent 37ac222
test
#!/usr/bin/env bash
#
# Run all etcd tests
# ./test
# ./test -v
#
#
# Run specified test pass
#
# $ PASSES=unit ./test
# $ PASSES=integration ./test
#
#
# Run tests for one package
# Each pass has different default timeout, if you just run tests in one package or 1 test case then you can set TIMEOUT
# flag for different expectation
#
# $ PASSES=unit PKG=./wal TIMEOUT=1m ./test
# $ PASSES=integration PKG=client/integration TIMEOUT=1m ./test
#
#
# Run specified unit tests in one package
# To run all the tests with prefix of "TestNew", set "TESTCASE=TestNew ";
# to run only "TestNew", set "TESTCASE="\bTestNew\b""
#
# $ PASSES=unit PKG=./wal TESTCASE=TestNew TIMEOUT=1m ./test
# $ PASSES=unit PKG=./wal TESTCASE="\bTestNew\b" TIMEOUT=1m ./test
# $ PASSES=integration PKG=client/integration TESTCASE="\bTestV2NoRetryEOF\b" TIMEOUT=1m ./test
#
#
# Run code coverage
# COVERDIR must either be a absolute path or a relative path to the etcd root
# $ COVERDIR=coverage PASSES="build_cov cov" ./test
set -e
source ./build
# build before setting up test GOPATH
if [[ "${PASSES}" == *"functional"* ]]; then
./functional/build
fi
if [ -z "$PASSES" ]; then
PASSES="fmt bom dep build unit"
fi
USERPKG=${PKG:-}
# Invoke ./tests/cover.test.bash for HTML output
COVER=${COVER:-"-cover"}
# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt.
IGNORE_PKGS="(vendor/|etcdserverpb|rafttest|gopath.proto|v3lockpb|v3electionpb)"
INTEGRATION_PKGS="(integration|tests/e2e|contrib|functional)"
# all github.com/etcd-io/etcd/whatever pkgs that are not auto-generated / tools
# shellcheck disable=SC1117
PKGS=$(find . -name \*.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | grep -vE "(tools/|contrib/|tests/e2e|pb)" | sed "s|\.|${REPO_PATH}|g" | xargs echo)
# pkg1,pkg2,pkg3
PKGS_COMMA=${PKGS// /,}
# shellcheck disable=SC1117
TEST_PKGS=$(find . -name \*_test.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g")
# shellcheck disable=SC1117
FORMATTABLE=$(find . -name \*.go | while read -r a; do echo "$(dirname "$a")/*.go"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g")
TESTABLE_AND_FORMATTABLE=$(echo "$TEST_PKGS" | grep -vE "$INTEGRATION_PKGS")
# check if user provided PKG override
if [ -z "${USERPKG}" ]; then
TEST=$TESTABLE_AND_FORMATTABLE
FMT=$FORMATTABLE
else
# strip out leading dotslashes and trailing slashes from PKG=./foo/
TEST=${USERPKG/#./}
TEST=${TEST/#\//}
TEST=${TEST/%\//}
# only run gofmt on packages provided by user
FMT="$TEST"
fi
# shellcheck disable=SC2206
FMT=($FMT)
if [ "${VERBOSE}" == "1" ]; then
# shellcheck disable=SC2128
echo "Running with FMT:" "${FMT[@]}"
fi
# prepend REPO_PATH to each local package
split=$TEST
TEST=""
for a in $split; do TEST="$TEST ${REPO_PATH}/${a}"; done
# shellcheck disable=SC2206
TEST=($TEST)
if [ "${VERBOSE}" == "1" ]; then
# shellcheck disable=SC2128
echo "Running with TEST:" "${TEST[@]}"
fi
# TODO: 'rafttest' is failing with unused
STATIC_ANALYSIS_PATHS=$(find . -name \*.go ! -path './vendor/*' ! -path './gopath.proto/*' ! -path '*pb/*' | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS")
# shellcheck disable=SC2206
STATIC_ANALYSIS_PATHS=($STATIC_ANALYSIS_PATHS)
if [ "${VERBOSE}" == "1" ]; then
# shellcheck disable=SC2128
echo "Running with STATIC_ANALYSIS_PATHS:" "${STATIC_ANALYSIS_PATHS[@]}"
fi
if [ -z "$GOARCH" ]; then
GOARCH=$(go env GOARCH);
fi
# determine the number of CPUs to use for Go tests
TEST_CPUS="1,2,4"
if [ -n "${CPU}" ]; then
TEST_CPUS="${CPU}"
fi
echo "Running with TEST_CPUS:" "${TEST_CPUS}"
# determine whether target supports race detection
if [ "$GOARCH" == "amd64" ]; then
RACE="--race"
fi
RUN_ARG=""
if [ -n "${TESTCASE}" ]; then
RUN_ARG="-run=${TESTCASE}"
fi
function unit_pass {
echo "Running unit tests..."
GO_TEST_FLAG=""
if [ "${VERBOSE}" == "1" ]; then
GO_TEST_FLAG="-v"
fi
if [ "${VERBOSE}" == "2" ]; then
GO_TEST_FLAG="-v"
export CLIENT_DEBUG=1
fi
if [ "${RUN_ARG}" == "" ]; then
RUN_ARG="-run=Test"
fi
# check if user provided time out, especially useful when just run one test case
# expectation could be different
USERTIMEOUT=""
if [ -z "${TIMEOUT}" ]; then
USERTIMEOUT="3m"
else
USERTIMEOUT="${TIMEOUT}"
fi
go test ${GO_TEST_FLAG} -timeout "${USERTIMEOUT}" "${COVER}" ${RACE} -cpu "${TEST_CPUS}" ${RUN_ARG} "$@" "${TEST[@]}"
}
function integration_pass {
echo "Running integration tests..."
# check if user provided time out, especially useful when just run one test case
# expectation could be different
USERTIMEOUT=""
if [ -z "${TIMEOUT}" ]; then
USERTIMEOUT="30m"
else
USERTIMEOUT="${TIMEOUT}"
fi
# if TESTCASE and PKG set, run specified test case in specified PKG
# if TESTCASE set, PKG not set, run specified test case in all integration and integration_extra packages
# if TESTCASE not set, PKG set, run all test cases in specified package
# if TESTCASE not set, PKG not set, run all tests in all integration and integration_extra packages
if [ -z "${TESTCASE}" ] && [ -z "${USERPKG}" ]; then
go test -timeout "${USERTIMEOUT}" -v -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/integration"
integration_extra "$@"
else
if [ -z "${USERPKG}" ]; then
INTEGTESTPKG=("${REPO_PATH}/integration"
"${REPO_PATH}/client/integration"
"${REPO_PATH}/clientv3/integration"
"${REPO_PATH}/contrib/raftexample"
"${REPO_PATH}/store")
else
INTEGTESTPKG=("${TEST[@]}")
fi
go test -timeout "${USERTIMEOUT}" -v -cpu "${TEST_CPUS}" "${RUN_ARG}" "$@" "${INTEGTESTPKG[@]}"
fi
}
function integration_extra {
go test -timeout 1m -v ${RACE} -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/client/integration"
go test -timeout 25m -v ${RACE} -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/clientv3/integration"
go test -timeout 1m -v -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/contrib/raftexample"
go test -timeout 5m -v ${RACE} -tags v2v3 "$@" "${REPO_PATH}/etcdserver/api/v2store"
go test -timeout 1m -v ${RACE} -cpu "${TEST_CPUS}" -run=Example "$@" "${TEST[@]}"
}
function functional_pass {
# Clean up any data and logs from previous runs
rm -rf /tmp/etcd-functional-* /tmp/etcd-functional-*.backup
for a in 1 2 3; do
./bin/etcd-agent --network tcp --address 127.0.0.1:${a}9027 &
pid="$!"
agent_pids="${agent_pids} $pid"
done
for a in 1 2 3; do
echo "Waiting for 'etcd-agent' on ${a}9027..."
while ! nc -z localhost ${a}9027; do
sleep 1
done
done
echo "functional test START!"
./bin/etcd-tester --config ./functional.yaml && echo "'etcd-tester' succeeded"
ETCD_TESTER_EXIT_CODE=$?
echo "ETCD_TESTER_EXIT_CODE:" ${ETCD_TESTER_EXIT_CODE}
# shellcheck disable=SC2206
agent_pids=($agent_pids)
kill -s TERM "${agent_pids[@]}" || true
if [[ "${ETCD_TESTER_EXIT_CODE}" -ne "0" ]]; then
printf "\n"
echo "FAILED! 'tail -1000 /tmp/etcd-functional-1/etcd.log'"
tail -1000 /tmp/etcd-functional-1/etcd.log
printf "\n"
echo "FAILED! 'tail -1000 /tmp/etcd-functional-2/etcd.log'"
tail -1000 /tmp/etcd-functional-2/etcd.log
printf "\n"
echo "FAILED! 'tail -1000 /tmp/etcd-functional-3/etcd.log'"
tail -1000 /tmp/etcd-functional-3/etcd.log
echo "--- FAIL: exit code" ${ETCD_TESTER_EXIT_CODE}
exit ${ETCD_TESTER_EXIT_CODE}
fi
echo "functional test PASS!"
}
function cov_pass {
echo "Running code coverage..."
# install gocovmerge before running code coverage from github.com/wadey/gocovmerge
# gocovmerge merges coverage files
if ! command -v gocovmerge >/dev/null; then
echo "gocovmerge not installed"
exit 255
fi
if [ -z "$COVERDIR" ]; then
echo "COVERDIR undeclared"
exit 255
fi
if [ ! -f "bin/etcd_test" ]; then
echo "etcd_test binary not found"
exit 255
fi
mkdir -p "$COVERDIR"
# run code coverage for unit and integration tests
GOCOVFLAGS="-covermode=set -coverpkg ${PKGS_COMMA} -v -timeout 30m"
# shellcheck disable=SC2206
GOCOVFLAGS=($GOCOVFLAGS)
failed=""
for t in $(echo "${TEST_PKGS}" | grep -vE "(tests/e2e|functional)"); do
tf=$(echo "$t" | tr / _)
# cache package compilation data for faster repeated builds
go test "${GOCOVFLAGS[@]}" -i "${REPO_PATH}/$t" || true
# uses -run=Test to skip examples because clientv3/ example tests will leak goroutines
go test "${GOCOVFLAGS[@]}" -run=Test -coverprofile "$COVERDIR/${tf}.coverprofile" "${REPO_PATH}/$t" || failed="$failed $t"
done
# v2v3 tests
go test -tags v2v3 "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/store-v2v3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed store-v2v3"
# proxy tests
go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_integration.coverprofile" "${REPO_PATH}/integration" || failed="$failed proxy-integration"
go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_clientv3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed proxy-clientv3/integration"
# run code coverage for e2e tests
# use 30m timeout because e2e coverage takes longer
# due to many tests cause etcd process to wait
# on leadership transfer timeout during gracefully shutdown
echo Testing tests/e2e without proxy...
go test -tags cov -timeout 30m -v "${REPO_PATH}/tests/e2e" || failed="$failed tests/e2e"
echo Testing tests/e2e with proxy...
go test -tags "cov cluster_proxy" -timeout 30m -v "${REPO_PATH}/tests/e2e" || failed="$failed tests/e2e-proxy"
# incrementally merge to get coverage data even if some coverage files are corrupted
# optimistically assume etcdserver package's coverage file is OK since gocovmerge
# expects to start with a non-empty file
cp "$COVERDIR"/etcdserver.coverprofile "$COVERDIR"/cover.out
for f in "$COVERDIR"/*.coverprofile; do
echo "merging test coverage file ${f}"
gocovmerge "$f" "$COVERDIR"/cover.out >"$COVERDIR"/cover.tmp || failed="$failed $f"
if [ -s "$COVERDIR"/cover.tmp ]; then
mv "$COVERDIR"/cover.tmp "$COVERDIR"/cover.out
fi
done
# strip out generated files (using GNU-style sed)
sed --in-place '/generated.go/d' "$COVERDIR"/cover.out || true
# held failures to generate the full coverage file, now fail
if [ -n "$failed" ]; then
for f in $failed; do
echo "--- FAIL:" "$f"
done
exit 255
fi
}
function e2e_pass {
echo "Running e2e tests..."
# check if user provided time out, especially useful when just run one test case
# expectation could be different
USERTIMEOUT=""
if [ -z "${TIMEOUT}" ]; then
USERTIMEOUT="30m"
else
USERTIMEOUT="${TIMEOUT}"
fi
go test -timeout "${USERTIMEOUT}" -v -cpu "${TEST_CPUS}" "${RUN_ARG}" "$@" "${REPO_PATH}/tests/e2e"
}
function integration_e2e_pass {
echo "Running integration and e2e tests..."
go test -timeout 30m -v -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/tests/e2e" &
e2epid="$!"
go test -timeout 30m -v -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/integration" &
intpid="$!"
wait $e2epid
wait $intpid
integration_extra "$@"
}
function grpcproxy_pass {
go test -timeout 30m -v ${RACE} -tags cluster_proxy -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/integration"
go test -timeout 30m -v ${RACE} -tags cluster_proxy -cpu "${TEST_CPUS}" "$@" "${REPO_PATH}/clientv3/integration"
go test -timeout 30m -v -tags cluster_proxy "$@" "${REPO_PATH}/tests/e2e"
}
function release_pass {
rm -f ./bin/etcd-last-release
# to grab latest patch release; bump this up for every minor release
UPGRADE_VER=$(git tag -l --sort=-version:refname "v3.3.*" | head -1)
if [ -n "$MANUAL_VER" ]; then
# in case, we need to test against different version
UPGRADE_VER=$MANUAL_VER
fi
if [[ -z ${UPGRADE_VER} ]]; then
UPGRADE_VER="v3.3.0"
echo "fallback to" ${UPGRADE_VER}
fi
local file="etcd-$UPGRADE_VER-linux-$GOARCH.tar.gz"
echo "Downloading $file"
set +e
curl --fail -L "https://github.com/etcd-io/etcd/releases/download/$UPGRADE_VER/$file" -o "/tmp/$file"
local result=$?
set -e
case $result in
0) ;;
*) echo "--- FAIL:" ${result}
exit $result
;;
esac
tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
mkdir -p ./bin
mv /tmp/etcd ./bin/etcd-last-release
}
function shellcheck_pass {
if command -v shellcheck >/dev/null; then
shellcheckResult=$(shellcheck -fgcc build test scripts/*.sh 2>&1 || true)
if [ -n "${shellcheckResult}" ]; then
echo -e "shellcheck checking failed:\\n${shellcheckResult}"
exit 255
fi
fi
}
function markdown_you_pass {
# eschew you
yous=$(find . -name \*.md ! -path './vendor/*' ! -path './Documentation/v2/*' ! -path './gopath.proto/*' -exec grep -E --color "[Yy]ou[r]?[ '.,;]" {} + || true)
if [ -n "$yous" ]; then
echo -e "found 'you' in documentation:\\n${yous}"
exit 255
fi
}
function markdown_marker_pass {
# TODO: check other markdown files when marker handles headers with '[]'
if command -v marker >/dev/null; then
markerResult=$(marker --skip-http --root ./Documentation 2>&1 || true)
if [ -n "${markerResult}" ]; then
echo -e "marker checking failed:\\n${markerResult}"
exit 255
fi
else
echo "Skipping marker..."
fi
}
function goword_pass {
if command -v goword >/dev/null; then
# get all go files to process
gofiles=$(find "${FMT[@]}" -iname '*.go' 2>/dev/null)
# shellcheck disable=SC2206
gofiles_all=($gofiles)
# ignore tests and protobuf files
# shellcheck disable=SC1117
gofiles=$(echo "${gofiles_all[@]}" | sort | uniq | sed "s/ /\n/g" | grep -vE "(\\_test.go|\\.pb\\.go)")
# shellcheck disable=SC2206
gofiles=($gofiles)
# only check for broken exported godocs
gowordRes=$(goword -use-spell=false "${gofiles[@]}" | grep godoc-export | sort)
if [ -n "$gowordRes" ]; then
echo -e "goword checking failed:\\n${gowordRes}"
exit 255
fi
# check some spelling
gowordRes=$(goword -ignore-file=.words clientv3/{*,*/*}.go 2>&1 | grep spell | sort)
if [ -n "$gowordRes" ]; then
echo -e "goword checking failed:\\n${gowordRes}"
exit 255
fi
else
echo "Skipping goword..."
fi
}
function gofmt_pass {
fmtRes=$(gofmt -l -s -d "${FMT[@]}")
if [ -n "${fmtRes}" ]; then
echo -e "gofmt checking failed:\\n${fmtRes}"
exit 255
fi
}
function govet_pass {
vetRes=$(go vet "${TEST[@]}")
if [ -n "${vetRes}" ]; then
echo -e "govet checking failed:\\n${vetRes}"
exit 255
fi
}
function govet_shadow_pass {
fmtpkgs=$(for a in "${FMT[@]}"; do dirname "$a"; done | sort | uniq | grep -v "\\.")
# shellcheck disable=SC2206
fmtpkgs=($fmtpkgs)
# Golang 1.12 onwards the experimental -shadow option is no longer available with go vet
go get golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
export PATH=${GOPATH}/bin:${PATH}
shadow_tool=$(which shadow)
vetRes=$(go vet -all -vettool="${shadow_tool}" "${TEST[@]}")
if [ -n "${vetRes}" ]; then
echo -e "govet -all -shadow checking failed:\\n${vetRes}"
exit 255
fi
}
function unparam_pass {
if command -v unparam >/dev/null; then
unparamResult=$(unparam "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
if [ -n "${unparamResult}" ]; then
echo -e "unparam checking failed:\\n${unparamResult}"
exit 255
fi
else
echo "Skipping unparam..."
fi
}
function staticcheck_pass {
if command -v staticcheck >/dev/null; then
staticcheckResult=$(staticcheck "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
if [ -n "${staticcheckResult}" ]; then
# TODO: resolve these after go1.8 migration
# See https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck
STATIC_CHECK_MASK="S(A|T)(1002|1005|1006|1008|1012|1019|1032|2002|4003|4006)"
if echo "${staticcheckResult}" | grep -vE "$STATIC_CHECK_MASK"; then
echo -e "staticcheck checking failed:\\n${staticcheckResult}"
exit 255
else
suppressed=$(echo "${staticcheckResult}" | sed 's/ /\n/g' | grep "(SA" | sort | uniq -c)
echo -e "staticcheck suppressed warnings:\\n${suppressed}"
fi
fi
else
echo "Skipping staticcheck..."
fi
}
function revive_pass {
if command -v revive >/dev/null; then
reviveResult=$(revive -config ./tests/revive.toml -exclude "vendor/..." ./... 2>&1 || true)
if [ -n "${reviveResult}" ]; then
echo -e "revive checking failed:\\n${reviveResult}"
exit 255
fi
else
echo "Skipping revive..."
fi
}
function unconvert_pass {
if command -v unconvert >/dev/null; then
unconvertResult=$(unconvert -v "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
if [ -n "${unconvertResult}" ]; then
echo -e "unconvert checking failed:\\n${unconvertResult}"
exit 255
fi
else
echo "Skipping unconvert..."
fi
}
function ineffassign_pass {
if command -v ineffassign >/dev/null; then
ineffassignResult=$(ineffassign "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
if [ -n "${ineffassignResult}" ]; then
echo -e "ineffassign checking failed:\\n${ineffassignResult}"
exit 255
fi
else
echo "Skipping ineffassign..."
fi
}
function nakedret_pass {
if command -v nakedret >/dev/null; then
nakedretResult=$(nakedret "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
if [ -n "${nakedretResult}" ]; then
echo -e "nakedret checking failed:\\n${nakedretResult}"
exit 255
fi
else
echo "Skipping nakedret..."
fi
}
function license_header_pass {
licRes=""
files=$(find . -type f -iname '*.go' ! -path './vendor/*' ! -path './gopath.proto/*')
for file in $files; do
if ! head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED)" ; then
licRes="${licRes}"$(echo -e " ${file}")
fi
done
if [ -n "${licRes}" ]; then
echo -e "license header checking failed:\\n${licRes}"
exit 255
fi
}
function receiver_name_pass {
# shellcheck disable=SC1117
recvs=$(grep 'func ([^*]' {*,*/*,*/*/*}.go | grep -Ev "(generated|pb/)" | tr ':' ' ' | \
awk ' { print $2" "$3" "$4" "$1 }' | sed "s/[a-zA-Z\.]*go//g" | sort | uniq | \
grep -Ev "(Descriptor|Proto|_)" | awk ' { print $3" "$4 } ' | sort | uniq -c | grep -v ' 1 ' | awk ' { print $2 } ')
if [ -n "${recvs}" ]; then
# shellcheck disable=SC2206
recvs=($recvs)
for recv in "${recvs[@]}"; do
echo "Mismatched receiver for $recv..."
grep "$recv" "${FMT[@]}" | grep 'func ('
done
exit 255
fi
}
function commit_title_pass {
git log --oneline "$(git merge-base HEAD "$(git rev-parse --abbrev-ref --symbolic-full-name "@{u}")")"...HEAD | while read -r l; do
commitMsg=$(echo "$l" | cut -f2- -d' ')
if [[ "$commitMsg" == Merge* ]]; then
# ignore "Merge pull" commits
continue
fi
if [[ "$commitMsg" == Revert* ]]; then
# ignore revert commits
continue
fi
pkgPrefix=$(echo "$commitMsg" | cut -f1 -d':')
spaceCommas=$(echo "$commitMsg" | sed 's/ /\n/g' | grep -c ',$' || echo 0)
commaSpaces=$(echo "$commitMsg" | sed 's/,/\n/g' | grep -c '^ ' || echo 0)
if [[ $(echo "$commitMsg" | grep -c ":..*") == 0 || "$commitMsg" == "$pkgPrefix" || "$spaceCommas" != "$commaSpaces" ]]; then
echo "$l"...
echo "Expected commit title format '<package>{\", \"<package>}: <description>'"
echo "Got: $l"
exit 255
fi
done
}
# tools gosimple,unused,staticheck,unconvert,ineffasign,nakedret
# are not module-aware. See https://github.com/golang/go/issues/24661
# The module-aware versions need to be used when they become available
function fmt_pass {
toggle_failpoints disable
# TODO: add "unparam"
for p in shellcheck \
markdown_you \
markdown_marker \
goword \
gofmt \
govet \
govet_shadow \
revive \
license_header \
receiver_name \
commit_title \
; do
echo "'$p' started at $(date)"
"${p}"_pass "$@"
echo "'$p' completed at $(date)"
done
}
function bom_pass {
if ! command -v license-bill-of-materials >/dev/null; then
return
fi
if [ "${GO111MODULE}" == "on" ]; then
# license-bill-off-materials calls "go list std cmd" which cannot handle modules
# Please see https://github.com/golang/go/issues/26924
echo "Skipping license-bill-of-materials with go modules..."
return
fi
echo "Checking bill of materials..."
license-bill-of-materials \
--override-file bill-of-materials.override.json \
go.etcd.io/etcd go.etcd.io/etcd/etcdctl >bom-now.json || true
if ! diff bill-of-materials.json bom-now.json; then
echo "vendored licenses do not match given bill of materials"
exit 255
fi
rm bom-now.json
}
function dep_pass {
echo "Checking package dependencies..."
# don't pull in etcdserver package
pushd clientv3 >/dev/null
badpkg="(etcdserver$|mvcc$|backend$|grpc-gateway)"
deps=$(go list -f '{{ .Deps }}' | sed 's/ /\n/g' | grep -E "${badpkg}" || echo "")
popd >/dev/null
if [ -n "$deps" ]; then
echo -e "clientv3 has masked dependencies:\\n${deps}"
exit 255
fi
}
function build_cov_pass {
out="bin"
if [ -n "${BINDIR}" ]; then out="${BINDIR}"; fi
go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcd_test"
go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcdctl_test" "${REPO_PATH}/etcdctl"
}
# fail fast on static tests
function build_pass {
echo "Checking build..."
GO_BUILD_FLAGS="-v" etcd_build
GO_BUILD_FLAGS="-v" tools_build
}
for pass in $PASSES; do
echo "Starting '$pass' pass at $(date)"
"${pass}"_pass "$@"
echo "Finished '$pass' pass at $(date)"
done
echo "Success"
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...