-
Notifications
You must be signed in to change notification settings - Fork 429
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge coverage per file and line (#10315)
Merge coverage per file and line instead of just appending the content of each coverage result.
- Loading branch information
Showing
9 changed files
with
269 additions
and
30 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
// or more contributor license agreements. Licensed under the Elastic License; | ||
// you may not use this file except in compliance with the Elastic License. | ||
|
||
// File partially copied from elastic-package. | ||
|
||
package coverage | ||
|
||
import ( | ||
"bytes" | ||
"encoding/xml" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
// GenericCoverage is the root element for a Cobertura XML report. | ||
type GenericCoverage struct { | ||
XMLName xml.Name `xml:"coverage"` | ||
Version int64 `xml:"version,attr"` | ||
Files []*GenericFile `xml:"file"` | ||
Timestamp int64 `xml:"-"` | ||
TestType string `xml:",comment"` | ||
} | ||
|
||
type GenericFile struct { | ||
Path string `xml:"path,attr"` | ||
Lines []*GenericLine `xml:"lineToCover"` | ||
} | ||
|
||
type GenericLine struct { | ||
LineNumber int64 `xml:"lineNumber,attr"` | ||
Covered bool `xml:"covered,attr"` | ||
} | ||
|
||
func (c *GenericCoverage) Bytes() ([]byte, error) { | ||
out, err := xml.MarshalIndent(&c, "", " ") | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to format test results as Coverage: %w", err) | ||
} | ||
|
||
var buffer bytes.Buffer | ||
buffer.WriteString(xml.Header) | ||
buffer.WriteString("\n") | ||
buffer.Write(out) | ||
return buffer.Bytes(), nil | ||
} | ||
|
||
func (c *GenericFile) merge(b *GenericFile) error { | ||
// Merge files | ||
for _, coverageLine := range b.Lines { | ||
found := false | ||
foundId := 0 | ||
for idx, existingLine := range c.Lines { | ||
if existingLine.LineNumber == coverageLine.LineNumber { | ||
found = true | ||
foundId = idx | ||
break | ||
} | ||
} | ||
if !found { | ||
c.Lines = append(c.Lines, coverageLine) | ||
} else { | ||
c.Lines[foundId].Covered = c.Lines[foundId].Covered || coverageLine.Covered | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// merge merges two coverage reports. | ||
func (c *GenericCoverage) Merge(other *GenericCoverage) error { | ||
// Merge files | ||
for _, coverageFile := range other.Files { | ||
var target *GenericFile | ||
for _, existingFile := range c.Files { | ||
if existingFile.Path == coverageFile.Path { | ||
target = existingFile | ||
break | ||
} | ||
} | ||
if target != nil { | ||
if err := target.merge(coverageFile); err != nil { | ||
return err | ||
} | ||
} else { | ||
c.Files = append(c.Files, coverageFile) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func ReadGenericCoverage(path string) (*GenericCoverage, error) { | ||
f, err := os.Open(path) | ||
if err != nil { | ||
return nil, fmt.Errorf("open failed: %w", err) | ||
} | ||
defer f.Close() | ||
|
||
dec := xml.NewDecoder(f) | ||
|
||
var coverage GenericCoverage | ||
err = dec.Decode(&coverage) | ||
if err != nil { | ||
return nil, fmt.Errorf("xml decode failed: %w", err) | ||
} | ||
|
||
return &coverage, nil | ||
} | ||
|
||
func MergeGenericCoverageFiles(paths []string, output string) error { | ||
f, err := os.Create(output) | ||
if err != nil { | ||
return fmt.Errorf("cannot open file %s to write merged coverage: %w", output, err) | ||
} | ||
defer f.Close() | ||
|
||
var coverage *GenericCoverage | ||
for _, path := range paths { | ||
c, err := ReadGenericCoverage(path) | ||
if err != nil { | ||
return fmt.Errorf("failed to read coverage from %s: %w", path, err) | ||
} | ||
if coverage == nil { | ||
coverage = c | ||
continue | ||
} | ||
err = coverage.Merge(c) | ||
if err != nil { | ||
return fmt.Errorf("failed to merge coverage from %s: %w", path, err) | ||
} | ||
} | ||
|
||
d, err := coverage.Bytes() | ||
if err != nil { | ||
return fmt.Errorf("failed to encode merged coverage: %w", err) | ||
} | ||
|
||
_, err = f.Write(d) | ||
if err != nil { | ||
return fmt.Errorf("cannot write merged coverage to %s: %w", output, err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
// or more contributor license agreements. Licensed under the Elastic License; | ||
// you may not use this file except in compliance with the Elastic License. | ||
|
||
package coverage | ||
|
||
import ( | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestMergeCoverage(t *testing.T) { | ||
coverageFiles, err := filepath.Glob("testdata/test-coverage-*.xml") | ||
require.NoError(t, err) | ||
|
||
expectedCoverage, err := ReadGenericCoverage("testdata/expected-test-coverage.xml") | ||
require.NoError(t, err) | ||
|
||
output := filepath.Join(t.TempDir(), "coverage-merged.xml") | ||
|
||
err = MergeGenericCoverageFiles(coverageFiles, output) | ||
require.NoError(t, err) | ||
|
||
mergedCoverage, err := ReadGenericCoverage(output) | ||
require.NoError(t, err) | ||
|
||
assert.EqualValues(t, expectedCoverage, mergedCoverage) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<coverage version="1"> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/base-fields.yml"> | ||
<lineToCover lineNumber="1" covered="false"></lineToCover> | ||
<lineToCover lineNumber="2" covered="false"></lineToCover> | ||
<lineToCover lineNumber="3" covered="false"></lineToCover> | ||
<lineToCover lineNumber="4" covered="false"></lineToCover> | ||
<lineToCover lineNumber="5" covered="true"></lineToCover> | ||
<lineToCover lineNumber="6" covered="false"></lineToCover> | ||
<lineToCover lineNumber="7" covered="false"></lineToCover> | ||
<lineToCover lineNumber="8" covered="true"></lineToCover> | ||
<lineToCover lineNumber="9" covered="false"></lineToCover> | ||
<lineToCover lineNumber="10" covered="false"></lineToCover> | ||
<lineToCover lineNumber="11" covered="false"></lineToCover> | ||
<lineToCover lineNumber="12" covered="false"></lineToCover> | ||
</file> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/ecs.yml"> | ||
<lineToCover lineNumber="1" covered="true"></lineToCover> | ||
<lineToCover lineNumber="2" covered="true"></lineToCover> | ||
<lineToCover lineNumber="3" covered="true"></lineToCover> | ||
</file> | ||
</coverage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<coverage version="1"> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/base-fields.yml"> | ||
<lineToCover lineNumber="1" covered="false"></lineToCover> | ||
<lineToCover lineNumber="2" covered="false"></lineToCover> | ||
<lineToCover lineNumber="3" covered="false"></lineToCover> | ||
<lineToCover lineNumber="4" covered="false"></lineToCover> | ||
<lineToCover lineNumber="5" covered="true"></lineToCover> | ||
<lineToCover lineNumber="6" covered="false"></lineToCover> | ||
<lineToCover lineNumber="7" covered="false"></lineToCover> | ||
<lineToCover lineNumber="8" covered="false"></lineToCover> | ||
<lineToCover lineNumber="9" covered="false"></lineToCover> | ||
<lineToCover lineNumber="10" covered="false"></lineToCover> | ||
<lineToCover lineNumber="11" covered="false"></lineToCover> | ||
<lineToCover lineNumber="12" covered="false"></lineToCover> | ||
</file> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/ecs.yml"> | ||
<lineToCover lineNumber="1" covered="false"></lineToCover> | ||
<lineToCover lineNumber="2" covered="false"></lineToCover> | ||
<lineToCover lineNumber="3" covered="false"></lineToCover> | ||
</file> | ||
</coverage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<coverage version="1"> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/ecs.yml"> | ||
<lineToCover lineNumber="1" covered="false"></lineToCover> | ||
<lineToCover lineNumber="2" covered="false"></lineToCover> | ||
<lineToCover lineNumber="3" covered="false"></lineToCover> | ||
</file> | ||
</coverage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<coverage version="1"> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/base-fields.yml"> | ||
<lineToCover lineNumber="1" covered="false"></lineToCover> | ||
<lineToCover lineNumber="2" covered="false"></lineToCover> | ||
<lineToCover lineNumber="3" covered="false"></lineToCover> | ||
<lineToCover lineNumber="4" covered="false"></lineToCover> | ||
<lineToCover lineNumber="5" covered="false"></lineToCover> | ||
<lineToCover lineNumber="6" covered="false"></lineToCover> | ||
<lineToCover lineNumber="7" covered="false"></lineToCover> | ||
<lineToCover lineNumber="8" covered="true"></lineToCover> | ||
<lineToCover lineNumber="9" covered="false"></lineToCover> | ||
<lineToCover lineNumber="10" covered="false"></lineToCover> | ||
<lineToCover lineNumber="11" covered="false"></lineToCover> | ||
<lineToCover lineNumber="12" covered="false"></lineToCover> | ||
</file> | ||
<file path="packages/elastic_package_registry/data_stream/metrics/fields/ecs.yml"> | ||
<lineToCover lineNumber="1" covered="true"></lineToCover> | ||
<lineToCover lineNumber="2" covered="true"></lineToCover> | ||
<lineToCover lineNumber="3" covered="true"></lineToCover> | ||
</file> | ||
</coverage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters