Change:
Right now, we execute unit tests in Travis with , and you can see the results on each line: but we don't have an easy place to go browse our code and figure out what's covered and what isn't. Is there some awesome way to do this? At the very least, can we get the actual line-by-line coverage results integrated into our CI build process so we can poke at these somehow?
cc
I'm willing to take a look into this to at least see if something is possible.
Looking into using Coveralls; there are a few other teams at Google already using this. Integration with Travis and Go are supported with the goveralls package:
Unit test coverage can now be viewed at - both master push builds and PRs will be shown there; additionally, Coveralls will update the status and post comments on PRs with coverage stats. (If we find these too spammy, we can disable either or both.) The top-level also has a badge/link to the coverage dashbaord.

Discussion:
install: - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi <ins> - go get github.com/mattn/goveralls </ins> - ./hack/travis/install-etcd.sh - ./hack/verify-gofmt.sh - ./hack/verify-boilerplate.sh

- ./hack/build-go.sh script: <del> - KUBE_RACE="-race" KUBE_COVER="-cover -covermode=atomic" KUBE_TIMEOUT='-timeout 60s' ./hack/test-go.sh "" -p=4 </del> <ins> - KUBE_RACE="-race" KUBE_COVER="y" KUBE_GOVERALLS_BIN="$HOME/gopath/bin/goveralls" KUBE_TIMEOUT='-timeout 60s' ./hack/test-go.sh "" -p=4 </ins> - PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-cmd.sh - PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/verify-gendocs.sh - PATH=$HOME/gopath/bin:./third_party/etcd:$PATH ./hack/test-integration.sh

# Kubernetes <del> [![GoDoc](https://godoc.org/github.com/GoogleCloudPlatform/kubernetes?status.png)](https://godoc.org/github.com/GoogleCloudPlatform/kubernetes) [![Travis](https://travis-ci.org/GoogleCloudPlatform/kubernetes.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/kubernetes) </del> <ins> [![GoDoc](https://godoc.org/github.com/GoogleCloudPlatform/kubernetes?status.png)](https://godoc.org/github.com/GoogleCloudPlatform/kubernetes) [![Travis](https://travis-ci.org/GoogleCloudPlatform/kubernetes.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/kubernetes) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/kubernetes/badge.svg)](https://coveralls.io/r/GoogleCloudPlatform/kubernetes) </ins> Kubernetes is an open source system for managing containerized applications across multiple hosts, providing basic mechanisms for deployment, maintenance, and scaling of applications.

KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. <del> KUBE_COVER=" " KUBE_RACE=" " "${KUBE_ROOT}/hack/test-go.sh" "" -test.run="^X" -benchtime=1s -bench=. -benchmem </del> <ins> KUBE_COVER="" KUBE_RACE=" " "${KUBE_ROOT}/hack/test-go.sh" "" -test.run="^X" -benchtime=1s -bench=. -benchmem </ins>

) } <del> kube::test::find_pkgs() { kube::test::find_dirs | xargs -n1 printf "${KUBE_GO_PACKAGE}/%sn" } </del> # -covermode=atomic becomes default with -race in Go >=1.3 KUBE_TIMEOUT=${KUBE_TIMEOUT:--timeout 120s} <del> KUBE_COVER=${KUBE_COVER:-} # use KUBE_COVER="-cover -covermode=atomic" for full coverage </del> <ins> KUBE_COVER=${KUBE_COVER:-} # set to nonempty string to enable coverage collection KUBE_COVERMODE=${KUBE_COVERMODE:-atomic} </ins> KUBE_RACE=${KUBE_RACE:-}   # use KUBE_RACE="-race" to enable race testing <ins> # Set to the goveralls binary path to report coverage results to Coveralls.io. KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-} </ins> kube::test::usage() { kube::log::usage_from_stdin <<EOF

done set -- "${testcases[@]+${testcases[@]}}" <ins> # TODO: this should probably be refactored to avoid code duplication with the # coverage version. </ins> if [[ $iterations -gt 1 ]]; then if [[ $# -eq 0 ]]; then set -- $(kube::test::find_dirs)

fi fi <ins> cover_report_dir="" combined_cover_profile="" if [[ -n "${KUBE_COVER}" ]]; then cover_report_dir="/tmp/k8s_coverage/$(kube::util::sortable_date)" combined_cover_profile="${cover_report_dir}/combined-coverage.out" kube::log::status "Saving coverage output in '${cover_report_dir}'" mkdir -p ${cover_report_dir} # The combined coverage profile needs to start with a line indicating which # coverage mode was used (set, count, or atomic). This line is included in # each of the coverage profiles generated when running 'go test -cover', but # we strip these lines out when combining so that there's only one. echo "mode: ${KUBE_COVERMODE}" >${combined_cover_profile} fi </ins> if [[ -n "${1-}" ]]; then <del> cover_report_dir="" </del> <ins> test_dirs=$@ else test_dirs=$(kube::test::find_dirs) fi # Run all specified tests, optionally collecting coverage if KUBE_COVER is set. for arg in ${test_dirs}; do trap 'exit 1' SIGINT pkg=${KUBE_GO_PACKAGE}/${arg} cover_params=() cover_profile="" </ins> if [[ -n "${KUBE_COVER}" ]]; then <del> cover_report_dir="/tmp/k8s_coverage/$(kube::util::sortable_date)" kube::log::status "Saving coverage output in '${cover_report_dir}'" </del> <ins> cover_profile=${cover_report_dir}/${arg}/coverage.out mkdir -p "${cover_report_dir}/${arg}" cover_params=(-cover -covermode="${KUBE_COVERMODE}" -coverprofile="${cover_profile}") </ins> fi <del> for arg; do trap 'exit 1' SIGINT pkg=${KUBE_GO_PACKAGE}/${arg} </del> <ins> go test "${goflags[@]:+${goflags[@]}}"  ${KUBE_RACE}  ${KUBE_TIMEOUT}  "${cover_params[@]+${cover_params[@]}}"  "${pkg}" if [[ -f "${cover_profile}" ]]; then # Include all coverage reach data in the combined profile, but exclude the # 'mode' lines, as there should be only one. grep -h -v "^mode:" ${cover_profile} >>${combined_cover_profile} || true fi done </ins> <del> cover_params=() if [[ -n "${KUBE_COVER}" ]]; then mkdir -p "${cover_report_dir}/${arg}" cover_params=(${KUBE_COVER} -coverprofile="${cover_report_dir}/${arg}/coverage.out") fi go test "${goflags[@]:+${goflags[@]}}"  ${KUBE_RACE}  ${KUBE_TIMEOUT}  "${cover_params[@]+${cover_params[@]}}"  "${pkg}" done exit 0 </del> <ins> if [[ -f ${combined_cover_profile} ]]; then coverage_html_file="${cover_report_dir}/combined-coverage.html" go tool cover -html="${combined_cover_profile}" -o="${coverage_html_file}" kube::log::status "Combined coverage report: ${coverage_html_file}" if [[ -x "${KUBE_GOVERALLS_BIN}" ]]; then ${KUBE_GOVERALLS_BIN} -coverprofile="${combined_cover_profile}" || true fi </ins> fi <del> kube::test::find_pkgs | xargs go test "${goflags[@]:+${goflags[@]}}"  ${KUBE_RACE}  ${KUBE_TIMEOUT}  ${KUBE_COVER} </del>