diff options
| author | Than McIntosh <thanm@google.com> | 2023-05-12 08:20:08 -0400 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2023-05-23 11:37:04 +0000 |
| commit | ef67022471bb26973168827ebf41e09f839fa0a7 (patch) | |
| tree | 1998bd5dfee920b3cf1d371fd59eacab700eadb3 /src/runtime/coverage/testsupport.go | |
| parent | 380529d5c371ac036c757a155453f618465ee8d3 (diff) | |
| download | go-ef67022471bb26973168827ebf41e09f839fa0a7.tar.xz | |
runtime/coverage: add coverage snapshot helper routine
Add a new function runtime/coverage.snapshot(), which samples the
current values of coverage counters in a running "go test -cover"
binary and returns percentage of statements executed so far. This
function is intended to be used by the function testing.Coverage().
Updates #59590.
Change-Id: I861393701c0cef47b4980aec14331168a9e64e8e
Reviewed-on: https://go-review.googlesource.com/c/go/+/495449
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/coverage/testsupport.go')
| -rw-r--r-- | src/runtime/coverage/testsupport.go | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/runtime/coverage/testsupport.go b/src/runtime/coverage/testsupport.go index 2b9e58b5f6..332b39b76e 100644 --- a/src/runtime/coverage/testsupport.go +++ b/src/runtime/coverage/testsupport.go @@ -15,7 +15,9 @@ import ( "internal/coverage/pods" "io" "os" + "runtime/internal/atomic" "strings" + "unsafe" ) // processCoverTestDir is called (via a linknamed reference) from @@ -232,3 +234,48 @@ func (ts *tstate) processPod(p pods.Pod) error { type pkfunc struct { pk, fcn uint32 } + +// snapshot returns a snapshot of coverage percentage at a moment of +// time within a running test, so as to support the testing.Coverage() +// function. This version doesn't examine coverage meta-data, so the +// result it returns will be less accurate (more "slop") due to the +// fact that we don't look at the meta data to see how many statements +// are associated with each counter. +func snapshot() float64 { + cl := getCovCounterList() + if len(cl) == 0 { + // no work to do here. + return 0.0 + } + + tot := uint64(0) + totExec := uint64(0) + for _, c := range cl { + sd := unsafe.Slice((*atomic.Uint32)(unsafe.Pointer(c.Counters)), c.Len) + tot += uint64(len(sd)) + for i := 0; i < len(sd); i++ { + // Skip ahead until the next non-zero value. + if sd[i].Load() == 0 { + continue + } + // We found a function that was executed. + nCtrs := sd[i+coverage.NumCtrsOffset].Load() + cst := i + coverage.FirstCtrOffset + + if cst+int(nCtrs) > len(sd) { + break + } + counters := sd[cst : cst+int(nCtrs)] + for i := range counters { + if counters[i].Load() != 0 { + totExec++ + } + } + i += coverage.FirstCtrOffset + int(nCtrs) - 1 + } + } + if tot == 0 { + return 0.0 + } + return float64(totExec) / float64(tot) +} |
