blob: 7477a9c624ad552cc85ca7610f829d6e410a1cd3 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package test
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"os"
"path/filepath"
"v.io/jiri"
"v.io/jiri/profiles"
"v.io/jiri/profiles/profilesreader"
"v.io/x/devtools/tooldata"
)
type testCoverage struct {
BranchRate int `xml:"branch-rate,attr"`
LineRate int `xml:"line-rate,attr"`
TimeStamp int64 `xml:"timestamp,attr"`
Version string `xml:"version,attr"`
Packages []testCoveragePkg `xml:"packages>package"`
Sources []string `xml:"sources>source"`
XMLName xml.Name `xml:"coverage"`
}
type testCoveragePkg struct {
Name string `xml:"name,attr"`
BranchRate int `xml:"branch-rate,attr"`
LineRate int `xml:"line-rate,attr"`
Complexity int `xml:"complexity,attr"`
Classes []testCoverageClass `xml:"classes>class"`
}
type testCoverageClass struct {
Name string `xml:"name,attr"`
Filename string `xml:"filename,attr"`
BranchRate int `xml:"branch-rate,attr"`
LineRate int `xml:"line-rate,attr"`
Complexity int `xml:"complexity,attr"`
Methods []testCoverageMethod `xml:"methods>method"`
}
type testCoverageMethod struct {
Name string `xml:"name,attr"`
Signature string `xml:"signature,attr"`
BranchRate int `xml:"branch-rate,attr"`
LineRate int `xml:"line-rate,attr"`
Lines []testCoverageLine `xml:"lines>line"`
}
type testCoverageLine struct {
Number int `xml:"number,attr"`
Hits int `xml:"hits,attr"`
}
// coberturaReportPath returns the path to the cobertura report.
func coberturaReportPath(testName string) string {
workspace, fileName := os.Getenv("WORKSPACE"), "cobertura_report.xml"
if workspace == "" {
return filepath.Join(os.Getenv("HOME"), "tmp", testName, fileName)
} else {
return filepath.Join(workspace, fileName)
}
}
// coverageFromGoTestOutput reads data from the given input, assuming
// it contains the coverage information generated by "go test -cover",
// and returns it as an in-memory data structure.
func coverageFromGoTestOutput(jirix *jiri.X, testOutput io.Reader) (*testCoverage, error) {
bin, err := tooldata.ThirdPartyBinPath(jirix, "gocover-cobertura")
if err != nil {
return nil, err
}
rd, err := profilesreader.NewReader(jirix, profilesreader.UseProfiles, ProfilesDBFilename)
if err != nil {
return nil, err
}
rd.MergeEnvFromProfiles(profilesreader.JiriMergePolicies(), profiles.NativeTarget(), "jiri")
var out bytes.Buffer
if err := jirix.NewSeq().Read(testOutput).Capture(&out, nil).Env(rd.ToMap()).Last(bin); err != nil {
return nil, err
}
var coverage testCoverage
if err := xml.Unmarshal(out.Bytes(), &coverage); err != nil {
return nil, fmt.Errorf("Unmarshal() failed: %v\n%v", err, out.String())
}
return &coverage, nil
}
// createCoberturaReport generates a cobertura report using the given
// coverage information.
func createCoberturaReport(jirix *jiri.X, testName string, data *testCoverage) error {
bytes, err := xml.MarshalIndent(*data, "", " ")
if err != nil {
return fmt.Errorf("MarshalIndent(%v) failed: %v", *data, err)
}
if err := jirix.NewSeq().WriteFile(coberturaReportPath(testName), bytes, os.FileMode(0644)).Done(); err != nil {
return fmt.Errorf("WriteFile(%v) failed: %v", coberturaReportPath(testName), err)
}
return nil
}