Merge branch 'jstemmer:master' into master

This commit is contained in:
Kevin 2022-09-22 12:48:14 -07:00 committed by GitHub
commit 03f6f9e2dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 160 additions and 28 deletions

View File

@ -236,5 +236,27 @@ func formatDuration(d time.Duration) string {
// formatOutput combines the lines from the given output into a single string.
func formatOutput(output []string) string {
return strings.Join(output, "\n")
return escapeIllegalChars(strings.Join(output, "\n"))
}
func escapeIllegalChars(str string) string {
return strings.Map(func(r rune) rune {
if isInCharacterRange(r) {
return r
}
return '\uFFFD'
}, str)
}
// Decide whether the given rune is in the XML Character Range, per
// the Char production of https://www.xml.com/axml/testaxml.htm,
// Section 2.2 Characters.
// From: encoding/xml/xml.go
func isInCharacterRange(r rune) (inrange bool) {
return r == 0x09 ||
r == 0x0A ||
r == 0x0D ||
r >= 0x20 && r <= 0xD7FF ||
r >= 0xE000 && r <= 0xFFFD ||
r >= 0x10000 && r <= 0x10FFFF
}

View File

@ -26,6 +26,11 @@ func TestCreateFromReport(t *testing.T) {
Result: gtr.Pass,
Output: []string{"ok"},
},
{
Name: "TestEscapeOutput",
Result: gtr.Pass,
Output: []string{"\x00\v\f \t\\"},
},
{
Name: "TestFail",
Result: gtr.Fail,
@ -47,14 +52,14 @@ func TestCreateFromReport(t *testing.T) {
}
want := Testsuites{
Tests: 6,
Tests: 7,
Errors: 3,
Failures: 1,
Skipped: 1,
Suites: []Testsuite{
{
Name: "package/name",
Tests: 6,
Tests: 7,
Errors: 3,
ID: 0,
Failures: 1,
@ -72,6 +77,12 @@ func TestCreateFromReport(t *testing.T) {
Time: "0.000",
SystemOut: &Output{Data: "ok"},
},
{
Name: "TestEscapeOutput",
Classname: "package/name",
Time: "0.000",
SystemOut: &Output{Data: `<EFBFBD><EFBFBD><EFBFBD> \`},
},
{
Name: "TestFail",
Classname: "package/name",
@ -133,7 +144,9 @@ func TestMarshalUnmarshal(t *testing.T) {
Skipped: 1,
Time: "12.345",
Timestamp: "2012-03-09T14:38:06+01:00",
Properties: properties("key", "value"),
Properties: &[]Property{
{Name: "key", Value: "value"},
},
Testcases: []Testcase{
{
Name: "test1",
@ -168,14 +181,3 @@ func TestMarshalUnmarshal(t *testing.T) {
t.Errorf("Unmarshal result incorrect, diff (-want +got):\n%s\n", diff)
}
}
func properties(keyvals ...string) *[]Property {
if len(keyvals)%2 != 0 {
panic("invalid keyvals specified")
}
var props []Property
for i := 0; i < len(keyvals); i += 2 {
props = append(props, Property{keyvals[i], keyvals[i+1]})
}
return &props
}

View File

@ -120,6 +120,11 @@ func (b *reportBuilder) Build() gtr.Report {
}
b.packages = append(b.packages, b.CreatePackage(name, b.packageName, "", 0, ""))
}
// Create packages for any leftover build errors.
for _, buildErr := range b.buildErrors {
b.packages = append(b.packages, b.CreatePackage("", buildErr.Name, "", 0, ""))
}
return gtr.Report{Packages: b.packages}
}
@ -145,7 +150,7 @@ func (b *reportBuilder) CreatePackage(packageName, newPackageName, result string
// First check if this package contained a build error. If that's the case,
// we won't find any tests in this package.
for id, buildErr := range b.buildErrors {
if buildErr.Name == newPackageName {
if buildErr.Name == newPackageName || strings.TrimSuffix(buildErr.Name, "_test") == newPackageName {
pkg.BuildError = buildErr
pkg.BuildError.ID = id
pkg.BuildError.Duration = duration
@ -164,7 +169,16 @@ func (b *reportBuilder) CreatePackage(packageName, newPackageName, result string
delete(b.packageBuilders, packageName)
pb.output.SetActiveID(0)
// If the packageBuilder is empty, we never received any events for this
// package so there's no need to continue.
if pb.IsEmpty() {
// However, we should at least report an error if the result says we
// failed.
if parseResult(result) == gtr.Fail {
pkg.RunError = gtr.Error{
Name: newPackageName,
}
}
return pkg
}

View File

@ -121,7 +121,7 @@ func TestReport(t *testing.T) {
}
got := rb.Build()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("FromEvents report incorrect, diff (-want, +got):\n%v", diff)
t.Errorf("Incorrect report created, diff (-want, +got):\n%v", diff)
}
}
@ -181,7 +181,7 @@ func TestBuildReportMultiplePackages(t *testing.T) {
}
got := rb.Build()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("FromEvents report incorrect, diff (-want, +got):\n%v", diff)
t.Errorf("Incorrect report created, diff (-want, +got):\n%v", diff)
}
}
@ -349,3 +349,82 @@ func TestGroupBenchmarksByName(t *testing.T) {
})
}
}
func TestReportSpecialCases(t *testing.T) {
tests := []struct {
name string
events []Event
want gtr.Report
}{
{
"failed-summary-only",
[]Event{{Type: "summary", Result: "FAIL", Name: "package/name", Duration: 1 * time.Millisecond}},
gtr.Report{
Packages: []gtr.Package{
{
Name: "package/name",
Duration: 1 * time.Millisecond,
Timestamp: testTimestamp,
RunError: gtr.Error{
Name: "package/name",
},
},
},
},
},
{
"leftover-builderror",
[]Event{
{Type: "build_output", Name: "package/name"},
{Type: "output", Data: "error message"},
},
gtr.Report{
Packages: []gtr.Package{
{
Name: "package/name",
Timestamp: testTimestamp,
BuildError: gtr.Error{
ID: 1,
Name: "package/name",
Output: []string{"error message"},
},
},
},
},
},
{
"build error in package with _test suffix",
[]Event{
{Type: "build_output", Name: "package/name_test"},
{Type: "summary", Name: "package/name", Result: "FAIL", Data: "[build failed]"},
},
gtr.Report{
Packages: []gtr.Package{
{
Name: "package/name",
Timestamp: testTimestamp,
BuildError: gtr.Error{
ID: 1,
Name: "package/name_test",
Cause: "[build failed]",
},
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
rb := newReportBuilder()
rb.timestampFunc = testTimestampFunc
for _, ev := range test.events {
rb.ProcessEvent(ev)
}
got := rb.Build()
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("Incorrect report created, diff (-want, +got):\n%v\n", diff)
}
})
}
}

11
testdata/038-report.xml vendored Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" errors="1">
<testsuite name="package/testpkg/pkg" tests="1" failures="0" errors="1" id="0" hostname="hostname" time="0.000" timestamp="2022-01-01T00:00:00Z">
<properties>
<property name="go.version" value="1.0"></property>
</properties>
<testcase name="[build failed]" classname="package/testpkg/pkg_test" time="0.000">
<error message="Build error"><![CDATA[pkg/pkg_test.go:5:2: imported and not used: "fmt"]]></error>
</testcase>
</testsuite>
</testsuites>

4
testdata/038-test-pkg-name.txt vendored Normal file
View File

@ -0,0 +1,4 @@
# package/testpkg/pkg_test [package/testpkg/pkg.test]
pkg/pkg_test.go:5:2: imported and not used: "fmt"
FAIL package/testpkg/pkg [build failed]
FAIL