-
Notifications
You must be signed in to change notification settings - Fork 46
Feature/sonar generic data format #58
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package lib | ||
|
|
||
| import ( | ||
| "go/build" | ||
| "io/ioutil" | ||
| "path/filepath" | ||
| "strings" | ||
| ) | ||
|
|
||
| func fileFileForTest(suite *Suite, test *Test, pkg *build.Package, strip string) string { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I like the name |
||
| var ( | ||
| testFileContents = make(map[string]string) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually don't declare variables in advance, we use |
||
| body []byte | ||
| testFilePath string | ||
| contents string | ||
| err error | ||
| ok bool | ||
| ) | ||
| if strip == "" { | ||
| strip = pkg.SrcRoot + "/" | ||
| } | ||
| for _, testFile := range pkg.TestGoFiles { | ||
| testFilePath = filepath.Join(pkg.Dir, testFile) | ||
| if contents, ok = testFileContents[testFilePath]; !ok { | ||
| if body, err = ioutil.ReadFile(testFilePath); err != nil { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't ignore errors, unless there's a good reason |
||
| continue | ||
| } | ||
| contents = string(body) | ||
| testFileContents[testFilePath] = contents | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the test file contents in the XML example, why do we need it? |
||
| } | ||
| if strings.Contains(contents, test.Name) { | ||
| return strings.Replace(testFilePath, strip, "", 1) | ||
| } | ||
| } | ||
|
|
||
| return suite.Name | ||
| } | ||
|
|
||
| func tmplFuncFilePathForTest(suite *Suite, test *Test, strip string) string { | ||
| var ( | ||
| pkg *build.Package | ||
| err error | ||
| ) | ||
| if pkg, err = build.Import(suite.Name, build.Default.GOPATH, build.IgnoreVendor); err != nil { | ||
| return suite.Name | ||
| } | ||
| return fileFileForTest(suite, test, pkg, strip) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,6 +62,24 @@ const ( | |
| {{end}} | ||
| </assembly> | ||
| ` | ||
|
|
||
| // SGTDTemplate is XML template for Sonar Generic Test Data style reporting | ||
| // https://docs.sonarqube.org/display/SONAR/Generic+Test+Data | ||
| SGTDTemplate string = `<testExecutions version="1">{{range $suite := .Suites}} | ||
| {{range $test := $suite.Tests}} <file path="{{testFilePath $suite $test ""}}"> | ||
| <testCase name="{{$test.Name | escape}}" duration="{{secondsToMilliseconds $test.Time}}" | ||
| {{- if and (ne $test.Status $.Skipped) (ne $test.Status $.Failed)}} />{{else}}> | ||
| {{- if eq $test.Status $.Skipped }} | ||
| <skipped message=""> | ||
| <![CDATA[{{$test.Message}}]]> | ||
| </skipped>{{end}} | ||
| {{- if eq $test.Status $.Failed }} | ||
| <failure message="error"> | ||
| <![CDATA[{{$test.Message}}]]> | ||
| </failure>{{end}} | ||
| </testCase>{{end}} | ||
| </file> | ||
| {{end}}{{end}}</testExecutions>` | ||
| ) | ||
|
|
||
| // TestResults is passed to XML template | ||
|
|
@@ -104,6 +122,14 @@ func escapeForXML(in string) (string, error) { | |
| return w.String(), nil | ||
| } | ||
|
|
||
| func secondsToMilliseconds(seconds string) string { | ||
| t, err := time.ParseDuration(seconds + "s") | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you already know it's in seconds, why not just do the math directly? |
||
| if err != nil { | ||
| return "0" | ||
| } | ||
| return strconv.Itoa(int(t.Nanoseconds() / int64(time.Millisecond))) | ||
| } | ||
|
|
||
| // WriteXML exits xunit XML of tests to out | ||
| func WriteXML(suites []*Suite, out io.Writer, xmlTemplate string, testTime time.Time) { | ||
| testsResult := TestResults{ | ||
|
|
@@ -117,7 +143,9 @@ func WriteXML(suites []*Suite, out io.Writer, xmlTemplate string, testTime time. | |
| } | ||
| testsResult.calcTotals() | ||
| t := template.New("test template").Funcs(template.FuncMap{ | ||
| "escape": escapeForXML, | ||
| "escape": escapeForXML, | ||
| "testFilePath": tmplFuncFilePathForTest, | ||
| "secondsToMilliseconds": secondsToMilliseconds, | ||
| }) | ||
|
|
||
| t, err := t.Parse(xml.Header + xmlTemplate) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add a check in main that it's no colliding with other formatting flags.