Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file attributes for JUnit Test Report #33

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.18

require (
github.com/google/go-cmp v0.5.5
github.com/jstemmer/go-junit-report v0.9.1
Copy link
Member Author

@Kuniwak Kuniwak Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library does not have ability to set file attributes. So I decided to purge the library.

github.com/pkg/errors v0.9.1
github.com/scylladb/go-set v1.0.2
)
5 changes: 1 addition & 4 deletions tool/gh-action/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/DeNA/unity-meta-check/unity/checker"
"github.com/DeNA/unity-meta-check/util/logging"
"io"
"time"
)

type Runner func(opts *Options) (bool, error)
Expand All @@ -25,8 +24,6 @@ func NewRunner(
logger logging.Logger,
) Runner {
return func(opts *Options) (bool, error) {
startTime := time.Now()

logger.Debug(fmt.Sprintf("check: %#v", opts.CheckerOpts))
resultNotFiltered, err := check(opts.RootDirAbs, opts.CheckerOpts)
if err != nil {
Expand Down Expand Up @@ -57,7 +54,7 @@ func NewRunner(

if opts.EnableJUnit {
logger.Debug(fmt.Sprintf("write junit report: %q", opts.JUnitOutPath))
if err := writeJunitXML(resultFiltered, startTime, opts.JUnitOutPath); err != nil {
if err := writeJunitXML(resultFiltered, opts.JUnitOutPath); err != nil {
return false, err
}
} else {
Expand Down
6 changes: 1 addition & 5 deletions tool/unity-meta-check-junit/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ import (
"github.com/DeNA/unity-meta-check/util/cli"
"github.com/DeNA/unity-meta-check/version"
"io"
"time"
)

func NewMain() cli.Command {
return func(args []string, procInout cli.ProcessInout, env cli.Env) cli.ExitStatus {
startTime := time.Now()

opts, err := options.BuildOptions(args, procInout)
if err != nil {
if err != flag.ErrHelp {
Expand All @@ -32,7 +29,7 @@ func NewMain() cli.Command {
parse := report.NewParser()
result := parse(io.TeeReader(procInout.Stdin, procInout.Stdout))

if err := junit.WriteToFile(result, startTime, opts.OutPath); err != nil {
if err := junit.WriteToFile(result, opts.OutPath); err != nil {
_, _ = fmt.Fprintln(procInout.Stderr, err.Error())
return cli.ExitAbnormal
}
Expand All @@ -43,4 +40,3 @@ func NewMain() cli.Command {
return cli.ExitNormal
}
}

161 changes: 119 additions & 42 deletions tool/unity-meta-check-junit/junit/junit.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,62 @@
package junit

import (
"encoding/xml"
"fmt"
"github.com/DeNA/unity-meta-check/unity"
"github.com/DeNA/unity-meta-check/unity/checker"
"github.com/DeNA/unity-meta-check/util/typedpath"
"github.com/jstemmer/go-junit-report/formatter"
"github.com/jstemmer/go-junit-report/parser"
"io"
"os"
"runtime"
"time"
)

type WriteToFileFunc func(result *checker.CheckResult, startTime time.Time, outPath typedpath.RawPath) error
type TestSuites struct {
XMLName xml.Name `xml:"testsuites"`
TestSuites []TestSuite `xml:"testsuite"`
}

type TestSuite struct {
XMLName xml.Name `xml:"testsuite"`
Tests int `xml:"tests,attr"`
Failures int `xml:"failures,attr"`
Time string `xml:"time,attr"`
Name string `xml:"name,attr"`
File *string `xml:"file,attr,omitempty"`
Properties Properties `xml:"properties"`
TestCases []TestCase `xml:"testcase"`
}

type TestCase struct {
XMLName xml.Name `xml:"testcase"`
ClassName string `xml:"classname,attr"`
Name string `xml:"name,attr"`
Time string `xml:"time,attr"`
File *string `xml:"file,attr,omitempty"`
Failure *Failure `xml:"failure,omitempty"`
}

type Failure struct {
XMLName xml.Name `xml:"failure"`
Message string `xml:"message,attr"`
Type string `xml:"type,attr"`
Contents string `xml:",chardata"`
}

func WriteToFile(result *checker.CheckResult, startTime time.Time, outPath typedpath.RawPath) error {
type Properties struct {
XMLName xml.Name `xml:"properties"`
Properties []Property `xml:"property"`
}

type Property struct {
XMLName xml.Name `xml:"property"`
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
}

type WriteToFileFunc func(result *checker.CheckResult, outPath typedpath.RawPath) error

func WriteToFile(result *checker.CheckResult, outPath typedpath.RawPath) error {
if err := os.MkdirAll(string(outPath.Dir()), 0755); err != nil {
return err
}
Expand All @@ -24,72 +65,108 @@ func WriteToFile(result *checker.CheckResult, startTime time.Time, outPath typed
if err != nil {
return err
}
defer func(){ _ = file.Close() }()
defer func() { _ = file.Close() }()

endTime := time.Now()
return Write(result, endTime.Sub(startTime), file)
return Write(result, file)
}

func Write(result *checker.CheckResult, duration time.Duration, writer io.Writer) error {
func Write(result *checker.CheckResult, writer io.Writer) error {
maxLen := result.Len()
var packages []parser.Package
if maxLen == 0 {
packages = []parser.Package{
props := &Properties{
Properties: []Property{
{
Name: "unity-meta-check",
Tests: []*parser.Test{
{
Name: "OK",
Result: parser.PASS,
Output: []string{"No missing or dangling .meta exist. Perfect!"},
Duration: duration,
Name: "go.version",
Value: runtime.Version(),
},
},
}
var testSuites *TestSuites
if maxLen == 0 {
testSuites = &TestSuites{
TestSuites: []TestSuite{
{
Name: "unity-meta-check",
Tests: 1,
Failures: 0,
Time: "0.000",
Properties: *props,
TestCases: []TestCase{
{
ClassName: "unity-meta-check",
Name: "OK",
Time: "0.000",
},
},
},
},
}
} else {
durationAvg := time.Duration(int(duration) / maxLen)
packages = make([]parser.Package, maxLen)
suites := make([]TestSuite, maxLen)
i := 0
for _, missingMeta := range result.MissingMeta {
packages[i] = parser.Package{
Name: string(unity.TrimMetaFromSlash(missingMeta)),
Tests: []*parser.Test{
file := string(unity.TrimMetaFromSlash(missingMeta))
suites[i] = TestSuite{
Name: file,
Tests: 1,
Time: "0.000",
Failures: 1,
File: &file,
Properties: *props,
TestCases: []TestCase{
{
Name: "meta",
Result: parser.FAIL,
Output: []string{
fmt.Sprintf("File or directory exists: %s", unity.TrimMetaFromSlash(missingMeta)),
fmt.Sprintf("But .meta is missing: %s", missingMeta),
ClassName: "missing",
Name: "meta",
Time: "0.000",
File: &file,
Failure: &Failure{
Message: "Failed",
Contents: fmt.Sprintf("File or directory exists: %s\nBut .meta is missing: %s", file, missingMeta),
},
Duration: durationAvg,
},
},
}
i++
}
for _, danglingMeta := range result.DanglingMeta {
packages[i] = parser.Package{
Name: string(unity.TrimMetaFromSlash(danglingMeta)),
Tests: []*parser.Test{
file := string(unity.TrimMetaFromSlash(danglingMeta))
suites[i] = TestSuite{
Name: file,
Tests: 1,
Time: "0.000",
Failures: 1,
File: &file,
Properties: *props,
TestCases: []TestCase{
{
Name: "meta",
Result: parser.FAIL,
Output: []string{
fmt.Sprintf("File or directory does not exist: %s", unity.TrimMetaFromSlash(danglingMeta)),
fmt.Sprintf("But .meta is present: %s", danglingMeta),
ClassName: "dangling",
Name: "meta",
Time: "0.000",
File: &file,
Failure: &Failure{
Message: "Failed",
Contents: fmt.Sprintf("File or directory does not exist: %s\nBut .meta is present: %s", file, danglingMeta),
},
Duration: durationAvg,
},
},
}
i++
}
testSuites = &TestSuites{
TestSuites: suites,
}
}

junitReport := &parser.Report{Packages: packages}

if err := formatter.JUnitReportXML(junitReport, false, runtime.Version(), writer); err != nil {
bs, err := xml.MarshalIndent(testSuites, "", "\t")
if err != nil {
return err
}
if _, err := io.WriteString(writer, xml.Header); err != nil {
return err
}
if _, err := writer.Write(bs); err != nil {
return err
}
if _, err := writer.Write([]byte{'\n'}); err != nil {
return err
}
return nil
Expand Down
11 changes: 4 additions & 7 deletions tool/unity-meta-check-junit/junit/junit_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,28 @@ import (
"errors"
"github.com/DeNA/unity-meta-check/unity/checker"
"github.com/DeNA/unity-meta-check/util/typedpath"
"time"
)

func StubWriteToFileFunc(err error) WriteToFileFunc {
return func(_ *checker.CheckResult, _ time.Time, _ typedpath.RawPath) error {
return func(_ *checker.CheckResult, _ typedpath.RawPath) error {
return err
}
}

type WriteToFileCallArgs struct {
CheckResult *checker.CheckResult
StartTime time.Time
OutPath typedpath.RawPath
}

func SpyWriteToFileFunc(inherited WriteToFileFunc, callArgs *[]WriteToFileCallArgs) WriteToFileFunc {
if inherited == nil {
inherited = StubWriteToFileFunc(errors.New("SPY_WRITE_TO_FILE_FUNC"))
}
return func(result *checker.CheckResult, startTime time.Time, outPath typedpath.RawPath) error {
return func(result *checker.CheckResult, outPath typedpath.RawPath) error {
*callArgs = append(*callArgs, WriteToFileCallArgs{
CheckResult: result,
StartTime: startTime,
OutPath: outPath,
})
return inherited(result, startTime, outPath)
return inherited(result, outPath)
}
}
}
Loading
Loading