Commit c82a6307 authored by Dhananjay Nakrani's avatar Dhananjay Nakrani Committed by Ian Lance Taylor

cmd/cover: take default value of total only once.

Defaulting total to 1 for each function, adds up to the
counting error. testing/cover.go already does this once.

Fixes #20515

Change-Id: I0e3f524c2ccb628eb9a8f0a1f81c22365c24cf9a
Reviewed-on: https://go-review.googlesource.com/44337
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent b928e2fa
...@@ -26,10 +26,11 @@ const ( ...@@ -26,10 +26,11 @@ const (
var ( var (
// Files we use. // Files we use.
testMain = filepath.Join(testdata, "main.go") testMain = filepath.Join(testdata, "main.go")
testTest = filepath.Join(testdata, "test.go") testTest = filepath.Join(testdata, "test.go")
coverInput = filepath.Join(testdata, "test_line.go") coverInput = filepath.Join(testdata, "test_line.go")
coverOutput = filepath.Join(testdata, "test_cover.go") coverOutput = filepath.Join(testdata, "test_cover.go")
coverProfile = filepath.Join(testdata, "profile.cov")
) )
var debug = false // Keeps the rewritten files around if set. var debug = false // Keeps the rewritten files around if set.
...@@ -102,6 +103,25 @@ func TestCover(t *testing.T) { ...@@ -102,6 +103,25 @@ func TestCover(t *testing.T) {
} }
} }
// Makes sure that `cover -func=profile.cov` reports accurate coverage.
// Issue #20515.
func TestCoverFunc(t *testing.T) {
// go tool cover -func ./testdata/profile.cov
cmd := exec.Command(testenv.GoToolPath(t), "tool", "cover", "-func", coverProfile)
out, err := cmd.Output()
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
t.Logf("%s", ee.Stderr)
}
t.Fatal(err)
}
if got, err := regexp.Match(".*total:.*100.0.*", out); err != nil || !got {
t.Logf("%s", out)
t.Errorf("invalid coverage counts. got=(%v, %v); want=(true; nil)", got, err)
}
}
func run(c *exec.Cmd, t *testing.T) { func run(c *exec.Cmd, t *testing.T) {
c.Stdout = os.Stdout c.Stdout = os.Stdout
c.Stderr = os.Stderr c.Stderr = os.Stderr
......
...@@ -66,12 +66,12 @@ func funcOutput(profile, outputFile string) error { ...@@ -66,12 +66,12 @@ func funcOutput(profile, outputFile string) error {
// Now match up functions and profile blocks. // Now match up functions and profile blocks.
for _, f := range funcs { for _, f := range funcs {
c, t := f.coverage(profile) c, t := f.coverage(profile)
fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n", fn, f.startLine, f.name, 100.0*float64(c)/float64(t)) fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n", fn, f.startLine, f.name, percent(c, t))
total += t total += t
covered += c covered += c
} }
} }
fmt.Fprintf(tabber, "total:\t(statements)\t%.1f%%\n", 100.0*float64(covered)/float64(total)) fmt.Fprintf(tabber, "total:\t(statements)\t%.1f%%\n", percent(covered, total))
return nil return nil
} }
...@@ -147,9 +147,6 @@ func (f *FuncExtent) coverage(profile *Profile) (num, den int64) { ...@@ -147,9 +147,6 @@ func (f *FuncExtent) coverage(profile *Profile) (num, den int64) {
covered += int64(b.NumStmt) covered += int64(b.NumStmt)
} }
} }
if total == 0 {
total = 1 // Avoid zero denominator.
}
return covered, total return covered, total
} }
...@@ -162,3 +159,10 @@ func findFile(file string) (string, error) { ...@@ -162,3 +159,10 @@ func findFile(file string) (string, error) {
} }
return filepath.Join(pkg.Dir, file), nil return filepath.Join(pkg.Dir, file), nil
} }
func percent(covered, total int64) float64 {
if total == 0 {
total = 1 // Avoid zero denominator.
}
return 100.0 * float64(covered) / float64(total)
}
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// A package such that there are 3 functions with zero total and covered lines.
// And one with 1 total and covered lines. Reproduces issue #20515.
package p
//go:noinline
func A() {
}
//go:noinline
func B() {
}
//go:noinline
func C() {
}
//go:noinline
func D() int64 {
return 42
}
mode: set
./testdata/p.go:10.10,12.2 0 0
./testdata/p.go:15.10,17.2 0 0
./testdata/p.go:20.10,22.2 0 0
./testdata/p.go:25.16,27.2 1 1
...@@ -24,7 +24,6 @@ runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: I ...@@ -24,7 +24,6 @@ runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: I
// Legitimate vet complaints in which we are testing for correct runtime behavior // Legitimate vet complaints in which we are testing for correct runtime behavior
// in bad situations that vet can also detect statically. // in bad situations that vet can also detect statically.
cmd/cover/testdata/test.go: unreachable code
encoding/json/decode_test.go: struct field m has json tag but is not exported encoding/json/decode_test.go: struct field m has json tag but is not exported
encoding/json/decode_test.go: struct field m2 has json tag but is not exported encoding/json/decode_test.go: struct field m2 has json tag but is not exported
encoding/json/tagkey_test.go: struct field tag `:"BadFormat"` not compatible with reflect.StructTag.Get: bad syntax for struct tag key encoding/json/tagkey_test.go: struct field tag `:"BadFormat"` not compatible with reflect.StructTag.Get: bad syntax for struct tag key
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment