1#!/usr/bin/env bash 2# 3# Run all etcd tests 4# ./test 5# ./test -v 6# 7# 8# Run specified test pass 9# 10# $ PASSES=unit ./test 11# $ PASSES=integration ./test 12# 13# 14# Run tests for one package 15# Each pass has different default timeout, if you just run tests in one package or 1 test case then you can set TIMEOUT 16# flag for different expectation 17# 18# $ PASSES=unit PKG=./wal TIMEOUT=1m ./test 19# $ PASSES=integration PKG=client/integration TIMEOUT=1m ./test 20# 21# 22# Run specified unit tests in one package 23# To run all the tests with prefix of "TestNew", set "TESTCASE=TestNew "; 24# to run only "TestNew", set "TESTCASE="\bTestNew\b"" 25# 26# $ PASSES=unit PKG=./wal TESTCASE=TestNew TIMEOUT=1m ./test 27# $ PASSES=unit PKG=./wal TESTCASE="\bTestNew\b" TIMEOUT=1m ./test 28# $ PASSES=integration PKG=client/integration TESTCASE="\bTestV2NoRetryEOF\b" TIMEOUT=1m ./test 29# 30# 31# Run code coverage 32# COVERDIR must either be a absolute path or a relative path to the etcd root 33# $ COVERDIR=coverage PASSES="build_cov cov" ./test 34set -e 35 36source ./build 37 38# build before setting up test GOPATH 39if [[ "${PASSES}" == *"functional"* ]]; then 40 ./functional/build 41fi 42 43# build tests with vendored dependencies 44etcd_setup_gopath 45 46if [ -z "$PASSES" ]; then 47 PASSES="fmt bom dep build unit" 48fi 49 50USERPKG=${PKG:-} 51 52# Invoke ./tests/cover.test.bash for HTML output 53COVER=${COVER:-"-cover"} 54 55# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt. 56IGNORE_PKGS="(cmd/|etcdserverpb|rafttest|gopath.proto|v3lockpb|v3electionpb)" 57INTEGRATION_PKGS="(integration|e2e|contrib|functional)" 58 59# all github.com/coreos/etcd/whatever pkgs that are not auto-generated / tools 60# shellcheck disable=SC1117 61PKGS=$(find . -name \*.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | grep -vE "(tools/|contrib/|e2e|pb)" | sed "s|\.|${REPO_PATH}|g" | xargs echo) 62# pkg1,pkg2,pkg3 63PKGS_COMMA=${PKGS// /,} 64 65# shellcheck disable=SC1117 66TEST_PKGS=$(find . -name \*_test.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g") 67 68# shellcheck disable=SC1117 69FORMATTABLE=$(find . -name \*.go | while read -r a; do echo "$(dirname "$a")/*.go"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g") 70 71TESTABLE_AND_FORMATTABLE=$(echo "$TEST_PKGS" | grep -vE "$INTEGRATION_PKGS") 72 73# check if user provided PKG override 74if [ -z "${USERPKG}" ]; then 75 TEST=$TESTABLE_AND_FORMATTABLE 76 FMT=$FORMATTABLE 77else 78 # strip out leading dotslashes and trailing slashes from PKG=./foo/ 79 TEST=${USERPKG/#./} 80 TEST=${TEST/#\//} 81 TEST=${TEST/%\//} 82 # only run gofmt on packages provided by user 83 FMT="$TEST" 84fi 85 86# shellcheck disable=SC2206 87FMT=($FMT) 88 89# prepend REPO_PATH to each local package 90split=$TEST 91TEST="" 92for a in $split; do TEST="$TEST ${REPO_PATH}/${a}"; done 93 94# shellcheck disable=SC2206 95TEST=($TEST) 96 97# TODO: 'client' pkg fails with gosimple from generated files 98# TODO: 'rafttest' is failing with unused 99STATIC_ANALYSIS_PATHS=$(find . -name \*.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | grep -v 'client') 100# shellcheck disable=SC2206 101STATIC_ANALYSIS_PATHS=($STATIC_ANALYSIS_PATHS) 102 103if [ -z "$GOARCH" ]; then 104 GOARCH=$(go env GOARCH); 105fi 106 107# determine whether target supports race detection 108if [ "$GOARCH" == "amd64" ]; then 109 RACE="--race" 110fi 111 112RUN_ARG="" 113if [ ! -z "${TESTCASE}" ]; then 114 RUN_ARG="-run=${TESTCASE}" 115fi 116 117function unit_pass { 118 echo "Running unit tests..." 119 GO_TEST_FLAG="" 120 if [ "${VERBOSE}" == "1" ]; then 121 GO_TEST_FLAG="-v" 122 fi 123 if [ "${VERBOSE}" == "2" ]; then 124 GO_TEST_FLAG="-v" 125 export CLIENT_DEBUG=1 126 fi 127 128 if [ "${RUN_ARG}" == "" ]; then 129 RUN_ARG="-run=Test" 130 fi 131 132 # check if user provided time out, especially useful when just run one test case 133 # expectation could be different 134 USERTIMEOUT="" 135 if [ -z "${TIMEOUT}" ]; then 136 USERTIMEOUT="3m" 137 else 138 USERTIMEOUT="${TIMEOUT}" 139 fi 140 go test ${GO_TEST_FLAG} -timeout "${USERTIMEOUT}" "${COVER}" ${RACE} -cpu 4 ${RUN_ARG} "$@" "${TEST[@]}" 141} 142 143function integration_pass { 144 echo "Running integration tests..." 145 146 # check if user provided time out, especially useful when just run one test case 147 # expectation could be different 148 USERTIMEOUT="" 149 if [ -z "${TIMEOUT}" ]; then 150 USERTIMEOUT="20m" 151 else 152 USERTIMEOUT="${TIMEOUT}" 153 fi 154 155 # if TESTCASE and PKG set, run specified test case in specified PKG 156 # if TESTCASE set, PKG not set, run specified test case in all integration and integration_extra packages 157 # if TESTCASE not set, PKG set, run all test cases in specified package 158 # if TESTCASE not set, PKG not set, run all tests in all integration and integration_extra packages 159 if [ -z "${TESTCASE}" ] && [ -z "${USERPKG}" ]; then 160 go test -timeout "${USERTIMEOUT}" -v -cpu 4 "$@" "${REPO_PATH}/integration" 161 integration_extra "$@" 162 else 163 if [ -z "${USERPKG}" ]; then 164 INTEGTESTPKG=("${REPO_PATH}/integration" 165 "${REPO_PATH}/client/integration" 166 "${REPO_PATH}/clientv3/integration" 167 "${REPO_PATH}/store") 168 else 169 INTEGTESTPKG=("${TEST[@]}") 170 fi 171 go test -timeout "${USERTIMEOUT}" -v -cpu 4 "${RUN_ARG}" "$@" "${INTEGTESTPKG[@]}" 172 fi 173} 174 175function integration_extra { 176 go test -timeout 1m -v ${RACE} -cpu 4 "$@" "${REPO_PATH}/client/integration" 177 go test -timeout 25m -v ${RACE} -cpu 4 "$@" "${REPO_PATH}/clientv3/integration" 178} 179 180function functional_pass { 181 # Clean up any data and logs from previous runs 182 rm -rf /tmp/etcd-functional-* /tmp/etcd-functional-*.backup 183 184 for a in 1 2 3; do 185 ./bin/etcd-agent --network tcp --address 127.0.0.1:${a}9027 & 186 pid="$!" 187 agent_pids="${agent_pids} $pid" 188 done 189 190 for a in 1 2 3; do 191 echo "Waiting for 'etcd-agent' on ${a}9027..." 192 while ! nc -z localhost ${a}9027; do 193 sleep 1 194 done 195 done 196 197 echo "functional test START!" 198 ./bin/etcd-tester --config ./functional.yaml && echo "'etcd-tester' succeeded" 199 ETCD_TESTER_EXIT_CODE=$? 200 echo "ETCD_TESTER_EXIT_CODE:" ${ETCD_TESTER_EXIT_CODE} 201 202 # shellcheck disable=SC2206 203 agent_pids=($agent_pids) 204 kill -s TERM "${agent_pids[@]}" || true 205 206 if [[ "${ETCD_TESTER_EXIT_CODE}" -ne "0" ]]; then 207 echo "--- FAIL: exit code" ${ETCD_TESTER_EXIT_CODE} 208 exit ${ETCD_TESTER_EXIT_CODE} 209 fi 210 echo "functional test PASS!" 211} 212 213function cov_pass { 214 echo "Running code coverage..." 215 # install gocovmerge before running code coverage from github.com/wadey/gocovmerge 216 # gocovmerge merges coverage files 217 if ! which gocovmerge >/dev/null; then 218 echo "gocovmerge not installed" 219 exit 255 220 fi 221 222 if [ -z "$COVERDIR" ]; then 223 echo "COVERDIR undeclared" 224 exit 255 225 fi 226 227 if [ ! -f "bin/etcd_test" ]; then 228 echo "etcd_test binary not found" 229 exit 255 230 fi 231 232 mkdir -p "$COVERDIR" 233 234 # run code coverage for unit and integration tests 235 GOCOVFLAGS="-covermode=set -coverpkg ${PKGS_COMMA} -v -timeout 20m" 236 # shellcheck disable=SC2206 237 GOCOVFLAGS=($GOCOVFLAGS) 238 failed="" 239 for t in $(echo "${TEST_PKGS}" | grep -vE "(e2e|functional)"); do 240 tf=$(echo "$t" | tr / _) 241 # cache package compilation data for faster repeated builds 242 go test "${GOCOVFLAGS[@]}" -i "${REPO_PATH}/$t" || true 243 # uses -run=Test to skip examples because clientv3/ example tests will leak goroutines 244 go test "${GOCOVFLAGS[@]}" -run=Test -coverprofile "$COVERDIR/${tf}.coverprofile" "${REPO_PATH}/$t" || failed="$failed $t" 245 done 246 247 # v2v3 tests 248 go test -tags v2v3 "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/store-v2v3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed store-v2v3" 249 250 # proxy tests 251 go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_integration.coverprofile" "${REPO_PATH}/integration" || failed="$failed proxy-integration" 252 go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_clientv3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed proxy-clientv3/integration" 253 254 # run code coverage for e2e tests 255 # use 30m timeout because e2e coverage takes longer 256 # due to many tests cause etcd process to wait 257 # on leadership transfer timeout during gracefully shutdown 258 echo Testing e2e without proxy... 259 go test -tags cov -timeout 30m -v "${REPO_PATH}/e2e" || failed="$failed e2e" 260 echo Testing e2e with proxy... 261 go test -tags "cov cluster_proxy" -timeout 30m -v "${REPO_PATH}/e2e" || failed="$failed e2e-proxy" 262 263 # incrementally merge to get coverage data even if some coverage files are corrupted 264 # optimistically assume etcdserver package's coverage file is OK since gocovmerge 265 # expects to start with a non-empty file 266 cp "$COVERDIR"/etcdserver.coverprofile "$COVERDIR"/cover.out 267 for f in "$COVERDIR"/*.coverprofile; do 268 echo "merging test coverage file ${f}" 269 gocovmerge "$f" "$COVERDIR"/cover.out >"$COVERDIR"/cover.tmp || failed="$failed $f" 270 if [ -s "$COVERDIR"/cover.tmp ]; then 271 mv "$COVERDIR"/cover.tmp "$COVERDIR"/cover.out 272 fi 273 done 274 # strip out generated files (using GNU-style sed) 275 sed --in-place '/generated.go/d' "$COVERDIR"/cover.out || true 276 277 # held failures to generate the full coverage file, now fail 278 if [ -n "$failed" ]; then 279 for f in $failed; do 280 echo "--- FAIL:" "$f" 281 done 282 exit 255 283 fi 284} 285 286function e2e_pass { 287 echo "Running e2e tests..." 288 289 # check if user provided time out, especially useful when just run one test case 290 # expectation could be different 291 USERTIMEOUT="" 292 if [ -z "${TIMEOUT}" ]; then 293 USERTIMEOUT="20m" 294 else 295 USERTIMEOUT="${TIMEOUT}" 296 fi 297 298 go test -timeout "${USERTIMEOUT}" -v -cpu 4 "${RUN_ARG}" "$@" "${REPO_PATH}/e2e" 299} 300 301function integration_e2e_pass { 302 echo "Running integration and e2e tests..." 303 304 go test -timeout 20m -v -cpu 4 "$@" "${REPO_PATH}/e2e" & 305 e2epid="$!" 306 go test -timeout 20m -v -cpu 4 "$@" "${REPO_PATH}/integration" & 307 intpid="$!" 308 wait $e2epid 309 wait $intpid 310 integration_extra "$@" 311} 312 313function grpcproxy_pass { 314 go test -timeout 20m -v ${RACE} -tags cluster_proxy -cpu 4 "$@" "${REPO_PATH}/integration" 315 go test -timeout 20m -v ${RACE} -tags cluster_proxy -cpu 4 "$@" "${REPO_PATH}/clientv3/integration" 316 go test -timeout 20m -v -tags cluster_proxy "$@" "${REPO_PATH}/e2e" 317} 318 319function release_pass { 320 rm -f ./bin/etcd-last-release 321 # to grab latest patch release; bump this up for every minor release 322 UPGRADE_VER=$(git tag -l --sort=-version:refname "v3.2.*" | head -1) 323 if [ -n "$MANUAL_VER" ]; then 324 # in case, we need to test against different version 325 UPGRADE_VER=$MANUAL_VER 326 fi 327 if [[ -z ${UPGRADE_VER} ]]; then 328 UPGRADE_VER="v3.2.0" 329 echo "fallback to" ${UPGRADE_VER} 330 fi 331 332 local file="etcd-$UPGRADE_VER-linux-$GOARCH.tar.gz" 333 echo "Downloading $file" 334 335 set +e 336 curl --fail -L "https://github.com/coreos/etcd/releases/download/$UPGRADE_VER/$file" -o "/tmp/$file" 337 local result=$? 338 set -e 339 case $result in 340 0) ;; 341 *) echo "--- FAIL:" ${result} 342 exit $result 343 ;; 344 esac 345 346 tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1 347 mkdir -p ./bin 348 mv /tmp/etcd ./bin/etcd-last-release 349} 350 351function shellcheck_pass { 352 if which shellcheck >/dev/null; then 353 shellcheckResult=$(shellcheck -fgcc build test scripts/*.sh 2>&1 || true) 354 if [ -n "${shellcheckResult}" ]; then 355 echo -e "shellcheck checking failed:\\n${shellcheckResult}" 356 exit 255 357 fi 358 fi 359} 360 361function markdown_you_pass { 362 # eschew you 363 yous=$(find . -name \*.md -exec grep -E --color "[Yy]ou[r]?[ '.,;]" {} + | grep -v /v2/ || true) 364 if [ ! -z "$yous" ]; then 365 echo -e "found 'you' in documentation:\\n${yous}" 366 exit 255 367 fi 368} 369 370function markdown_marker_pass { 371 # TODO: check other markdown files when marker handles headers with '[]' 372 if which marker >/dev/null; then 373 markerResult=$(marker --skip-http --root ./Documentation 2>&1 || true) 374 if [ -n "${markerResult}" ]; then 375 echo -e "marker checking failed:\\n${markerResult}" 376 exit 255 377 fi 378 else 379 echo "Skipping marker..." 380 fi 381} 382 383function goword_pass { 384 if which goword >/dev/null; then 385 # get all go files to process 386 gofiles=$(find "${FMT[@]}" -iname '*.go' 2>/dev/null) 387 # shellcheck disable=SC2206 388 gofiles_all=($gofiles) 389 # ignore tests and protobuf files 390 # shellcheck disable=SC1117 391 gofiles=$(echo "${gofiles_all[@]}" | sort | uniq | sed "s/ /\n/g" | grep -vE "(\\_test.go|\\.pb\\.go)") 392 # shellcheck disable=SC2206 393 gofiles=($gofiles) 394 # only check for broken exported godocs 395 gowordRes=$(goword -use-spell=false "${gofiles[@]}" | grep godoc-export | sort) 396 if [ ! -z "$gowordRes" ]; then 397 echo -e "goword checking failed:\\n${gowordRes}" 398 exit 255 399 fi 400 # check some spelling 401 gowordRes=$(goword -ignore-file=.words clientv3/{*,*/*}.go 2>&1 | grep spell | sort) 402 if [ ! -z "$gowordRes" ]; then 403 echo -e "goword checking failed:\\n${gowordRes}" 404 exit 255 405 fi 406 else 407 echo "Skipping goword..." 408 fi 409} 410 411function gofmt_pass { 412 fmtRes=$(gofmt -l -s -d "${FMT[@]}") 413 if [ -n "${fmtRes}" ]; then 414 echo -e "gofmt checking failed:\\n${fmtRes}" 415 exit 255 416 fi 417} 418 419function govet_pass { 420 vetRes=$(go vet "${TEST[@]}") 421 if [ -n "${vetRes}" ]; then 422 echo -e "govet checking failed:\\n${vetRes}" 423 exit 255 424 fi 425} 426 427function govet_shadow_pass { 428 fmtpkgs=$(for a in "${FMT[@]}"; do dirname "$a"; done | sort | uniq | grep -v "\\.") 429 # shellcheck disable=SC2206 430 fmtpkgs=($fmtpkgs) 431 vetRes=$(go tool vet -all -shadow "${fmtpkgs[@]}" 2>&1 | grep -v '/gw/' || true) 432 if [ -n "${vetRes}" ]; then 433 echo -e "govet -all -shadow checking failed:\\n${vetRes}" 434 exit 255 435 fi 436} 437 438function gosimple_pass { 439 if which gosimple >/dev/null; then 440 gosimpleResult=$(gosimple "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true) 441 if [ -n "${gosimpleResult}" ]; then 442 echo -e "gosimple checking failed:\\n${gosimpleResult}" 443 exit 255 444 fi 445 else 446 echo "Skipping gosimple..." 447 fi 448} 449 450function unused_pass { 451 if which unused >/dev/null; then 452 unusedResult=$(unused "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true) 453 if [ -n "${unusedResult}" ]; then 454 echo -e "unused checking failed:\\n${unusedResult}" 455 exit 255 456 fi 457 else 458 echo "Skipping unused..." 459 fi 460} 461 462function staticcheck_pass { 463 if which staticcheck >/dev/null; then 464 staticcheckResult=$(staticcheck "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true) 465 if [ -n "${staticcheckResult}" ]; then 466 # TODO: resolve these after go1.8 migration 467 # See https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck 468 STATIC_CHECK_MASK="SA(1012|1019|2002)" 469 if echo "${staticcheckResult}" | grep -vE "$STATIC_CHECK_MASK"; then 470 echo -e "staticcheck checking failed:\\n${staticcheckResult}" 471 exit 255 472 else 473 suppressed=$(echo "${staticcheckResult}" | sed 's/ /\n/g' | grep "(SA" | sort | uniq -c) 474 echo -e "staticcheck suppressed warnings:\\n${suppressed}" 475 fi 476 fi 477 else 478 echo "Skipping staticcheck..." 479 fi 480} 481 482function ineffassign_pass { 483 if which ineffassign >/dev/null; then 484 ineffassignResult=$(ineffassign "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true) 485 if [ -n "${ineffassignResult}" ]; then 486 echo -e "ineffassign checking failed:\\n${ineffassignResult}" 487 exit 255 488 fi 489 else 490 echo "Skipping ineffassign..." 491 fi 492} 493 494function nakedret_pass { 495 if which nakedret >/dev/null; then 496 nakedretResult=$(nakedret "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true) 497 if [ -n "${nakedretResult}" ]; then 498 echo -e "nakedret checking failed:\\n${nakedretResult}" 499 exit 255 500 fi 501 else 502 echo "Skipping nakedret..." 503 fi 504} 505 506function license_header_pass { 507 licRes="" 508 files=$(find . -type f -iname '*.go' ! -path './cmd/*' ! -path './gopath.proto/*') 509 for file in $files; do 510 if ! head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED)" ; then 511 licRes="${licRes}"$(echo -e " ${file}") 512 fi 513 done 514 if [ -n "${licRes}" ]; then 515 echo -e "license header checking failed:\\n${licRes}" 516 exit 255 517 fi 518} 519 520function receiver_name_pass { 521 # shellcheck disable=SC1117 522 recvs=$(grep 'func ([^*]' {*,*/*,*/*/*}.go | grep -Ev "(generated|pb/)" | tr ':' ' ' | \ 523 awk ' { print $2" "$3" "$4" "$1 }' | sed "s/[a-zA-Z\.]*go//g" | sort | uniq | \ 524 grep -Ev "(Descriptor|Proto|_)" | awk ' { print $3" "$4 } ' | sort | uniq -c | grep -v ' 1 ' | awk ' { print $2 } ') 525 if [ -n "${recvs}" ]; then 526 # shellcheck disable=SC2206 527 recvs=($recvs) 528 for recv in "${recvs[@]}"; do 529 echo "Mismatched receiver for $recv..." 530 grep "$recv" "${FMT[@]}" | grep 'func (' 531 done 532 exit 255 533 fi 534} 535 536function commit_title_pass { 537 git log --oneline "$(git merge-base HEAD master)"...HEAD | while read -r l; do 538 commitMsg=$(echo "$l" | cut -f2- -d' ') 539 if [[ "$commitMsg" == Merge* ]]; then 540 # ignore "Merge pull" commits 541 continue 542 fi 543 if [[ "$commitMsg" == Revert* ]]; then 544 # ignore revert commits 545 continue 546 fi 547 548 pkgPrefix=$(echo "$commitMsg" | cut -f1 -d':') 549 spaceCommas=$(echo "$commitMsg" | sed 's/ /\n/g' | grep -c ',$' || echo 0) 550 commaSpaces=$(echo "$commitMsg" | sed 's/,/\n/g' | grep -c '^ ' || echo 0) 551 if [[ $(echo "$commitMsg" | grep -c ":..*") == 0 || "$commitMsg" == "$pkgPrefix" || "$spaceCommas" != "$commaSpaces" ]]; then 552 echo "$l"... 553 echo "Expected commit title format '<package>{\", \"<package>}: <description>'" 554 echo "Got: $l" 555 exit 255 556 fi 557 done 558} 559 560function fmt_pass { 561 toggle_failpoints disable 562 563 for p in shellcheck \ 564 markdown_you \ 565 markdown_marker \ 566 goword \ 567 gofmt \ 568 govet \ 569 govet_shadow \ 570 gosimple \ 571 unused \ 572 staticcheck \ 573 ineffassign \ 574 nakedret \ 575 license_header \ 576 receiver_name \ 577 commit_title \ 578 ; do 579 echo "'$p' started at $(date)" 580 "${p}"_pass "$@" 581 echo "'$p' completed at $(date)" 582 done 583} 584 585function bom_pass { 586 if ! which license-bill-of-materials >/dev/null; then 587 return 588 fi 589 echo "Checking bill of materials..." 590 license-bill-of-materials \ 591 --override-file bill-of-materials.override.json \ 592 github.com/coreos/etcd github.com/coreos/etcd/etcdctl >bom-now.json || true 593 if ! diff bill-of-materials.json bom-now.json; then 594 echo "vendored licenses do not match given bill of materials" 595 exit 255 596 fi 597 rm bom-now.json 598} 599 600function dep_pass { 601 echo "Checking package dependencies..." 602 # don't pull in etcdserver package 603 pushd clientv3 >/dev/null 604 badpkg="(etcdserver$|mvcc$|backend$|grpc-gateway)" 605 deps=$(go list -f '{{ .Deps }}' | sed 's/ /\n/g' | grep -E "${badpkg}" || echo "") 606 popd >/dev/null 607 if [ ! -z "$deps" ]; then 608 echo -e "clientv3 has masked dependencies:\\n${deps}" 609 exit 255 610 fi 611} 612 613function build_cov_pass { 614 out="bin" 615 if [ -n "${BINDIR}" ]; then out="${BINDIR}"; fi 616 go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcd_test" 617 go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcdctl_test" "${REPO_PATH}/etcdctl" 618} 619 620# fail fast on static tests 621function build_pass { 622 echo "Checking build..." 623 GO_BUILD_FLAGS="-v" etcd_build 624} 625 626for pass in $PASSES; do 627 echo "Starting '$pass' pass at $(date)" 628 "${pass}"_pass "$@" 629 echo "Finished '$pass' pass at $(date)" 630done 631 632echo "Success" 633