go/src/pkg/testing/cover.go

93 lines
2.2 KiB
Go
Raw Normal View History

// Copyright 2013 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.
// Support for test coverage.
package testing
import (
"fmt"
"os"
)
// CoverBlock records the coverage data for a single basic block.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
type CoverBlock struct {
Line0 uint32
Col0 uint16
Line1 uint32
Col1 uint16
Stmts uint16
}
var (
coverCounters map[string][]uint32
coverBlocks map[string][]CoverBlock
)
// RegisterCover records the coverage data accumulators for the tests.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
func RegisterCover(c map[string][]uint32, b map[string][]CoverBlock) {
coverCounters = c
coverBlocks = b
}
// mustBeNil checks the error and, if present, reports it and exits.
func mustBeNil(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "testing: %s\n", err)
os.Exit(2)
}
}
// coverReport reports the coverage percentage and writes a coverage profile if requested.
func coverReport() {
var f *os.File
var err error
if *coverProfile != "" {
f, err = os.Create(toOutputDir(*coverProfile))
mustBeNil(err)
fmt.Fprintf(f, "mode: %s\n", *coverMode)
defer func() { mustBeNil(f.Close()) }()
}
var active, total int64
packageName := ""
for name, counts := range coverCounters {
if packageName == "" {
// Package name ends at last slash.
for i, c := range name {
if c == '/' {
packageName = name[:i]
}
}
}
blocks := coverBlocks[name]
for i, count := range counts {
stmts := int64(blocks[i].Stmts)
total += stmts
if count > 0 {
active += stmts
}
if f != nil {
_, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
blocks[i].Line0, blocks[i].Col0,
blocks[i].Line1, blocks[i].Col1,
stmts,
count)
mustBeNil(err)
}
}
}
if total == 0 {
total = 1
}
if packageName == "" {
packageName = "package"
}
fmt.Printf("test coverage for %s: %.1f%% of statements\n", packageName, 100*float64(active)/float64(total))
}