Compare commits
16
Commits
47df0cc2d9
..
v0.0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe733f96d6 | ||
|
|
7cf5827f22 | ||
|
|
09fd2cb2a4 | ||
|
|
74383ddcc0 | ||
|
|
e20795e7b9 | ||
|
|
36563f55fb | ||
|
|
bfbf24a6c4 | ||
|
|
e0207bab2a | ||
|
|
37f4359dcb | ||
|
|
befec17e06 | ||
|
|
220b73dc49 | ||
|
|
d97ffd7fea | ||
|
|
18d362c926 | ||
|
|
8a2c4757b9 | ||
|
|
7643f37b73 | ||
|
|
991739b1ea |
@@ -0,0 +1,4 @@
|
||||
bin/
|
||||
.env
|
||||
*_templ.go
|
||||
.idea/
|
||||
@@ -0,0 +1,23 @@
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
# seems superfluous
|
||||
#.PHONY: fmt vet build clean
|
||||
|
||||
fmt:
|
||||
go fmt ./...
|
||||
|
||||
vet: fmt
|
||||
go vet ./...
|
||||
|
||||
|
||||
build: vet
|
||||
mkdir -p bin
|
||||
go build -o bin ./cmd/...
|
||||
|
||||
test: build
|
||||
go test -count=1 -coverprofile=testout/coverage.out ${TESTFLAGS} ./...
|
||||
|
||||
clean:
|
||||
rm -rf bin
|
||||
|
||||
all: build
|
||||
@@ -0,0 +1,182 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (t *Test) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if len(t.Tests) == 100000 {
|
||||
start.Name = xml.Name{Local: "testcase"}
|
||||
classname := ""
|
||||
if t.parent != nil {
|
||||
classname = t.parent.Name
|
||||
}
|
||||
var skipped *Result
|
||||
if t.Skipped > 0 {
|
||||
skipped = &Result{
|
||||
Message: "skipped",
|
||||
}
|
||||
}
|
||||
var failed *Result
|
||||
if t.Failures > 0 {
|
||||
failed = &Result{
|
||||
Message: "failed",
|
||||
}
|
||||
}
|
||||
log.Printf("TIME %f", t.Time)
|
||||
parts := strings.Split(t.Name, "/")
|
||||
tc := Testcase{
|
||||
Name: parts[len(parts)-1],
|
||||
// parent class name
|
||||
Classname: classname,
|
||||
Time: t.Time,
|
||||
Skipped: skipped,
|
||||
Error: nil,
|
||||
Failure: failed,
|
||||
SystemOut: t.SystemOut,
|
||||
}
|
||||
return e.EncodeElement(tc, start)
|
||||
}
|
||||
type Alias Test
|
||||
start.Name = xml.Name{Local: "testsuite"}
|
||||
return e.EncodeElement(Alias(*t), start)
|
||||
}
|
||||
|
||||
func main() {
|
||||
/*
|
||||
testsuites := Testsuites{
|
||||
Time: 1.23,
|
||||
TImestamp: time.Now(),
|
||||
Suites: []*Testsuite{
|
||||
{
|
||||
Name: "hello",
|
||||
Tests: 0,
|
||||
Failures: 0,
|
||||
Errors: 0,
|
||||
Disabled: 0,
|
||||
Package: "",
|
||||
Skipped: 0,
|
||||
Time: "",
|
||||
Timestamp: time.Now(),
|
||||
Testsuites: []*Testsuite{
|
||||
{
|
||||
Name: "abc",
|
||||
Tests: 0,
|
||||
Failures: 0,
|
||||
Errors: 0,
|
||||
Disabled: 0,
|
||||
Package: "",
|
||||
Skipped: 0,
|
||||
Time: "",
|
||||
Timestamp: time.Time{},
|
||||
Testsuites: nil,
|
||||
Testcases: []*Testcase{
|
||||
{
|
||||
Name: "test",
|
||||
Classname: "",
|
||||
Time: "",
|
||||
Skipped: nil,
|
||||
Error: &Result{
|
||||
Message: "error",
|
||||
},
|
||||
Failure: nil,
|
||||
SystemOut: "",
|
||||
},
|
||||
},
|
||||
SystemOut: "ddd",
|
||||
},
|
||||
},
|
||||
Testcases: nil,
|
||||
SystemOut: "hello",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
testsuites := Testsuites{}
|
||||
|
||||
if len(os.Args) != 2 && len(os.Args) != 3 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: go2junit <outputdir> [<prefix>]\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
path := os.Args[1]
|
||||
path = filepath.Clean(path)
|
||||
err := os.MkdirAll(path, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
prefix := ""
|
||||
if len(os.Args) == 3 {
|
||||
prefix = os.Args[2]
|
||||
}
|
||||
|
||||
var file = os.Stdin
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
lineno := 0
|
||||
|
||||
testsuites = Testsuites{}
|
||||
for scanner.Scan() {
|
||||
lineno++
|
||||
var item TestEvent
|
||||
line := scanner.Bytes()
|
||||
if err := json.Unmarshal(line, &item); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%d: %s: %v", lineno, line, err)
|
||||
continue
|
||||
}
|
||||
|
||||
//.fmt.Printf("Parsed %d:\n%v\n\n", lineno, item)
|
||||
|
||||
pkg := prefix + item.Package
|
||||
switch item.Action {
|
||||
case "start":
|
||||
testsuites.Start(item.Time, pkg)
|
||||
case "run":
|
||||
fmt.Println()
|
||||
testsuites.Test(item.Time, pkg, item.Test)
|
||||
case "output":
|
||||
testsuites.Output(item.Time, pkg, item.Test, item.Output)
|
||||
fmt.Printf("%s", item.Output)
|
||||
case "pause":
|
||||
testsuites.Output(item.Time, pkg, item.Test, "PAUSED")
|
||||
case "cont":
|
||||
testsuites.Output(item.Time, pkg, item.Test, "CONTINUED")
|
||||
case "pass":
|
||||
testsuites.Pass(item.Time, pkg, item.Test)
|
||||
case "bench":
|
||||
testsuites.Bench(item.Time, pkg, item.Test, item.Output)
|
||||
case "fail":
|
||||
testsuites.Fail(item.Time, pkg, item.Test)
|
||||
case "skip":
|
||||
testsuites.Skip(item.Time, pkg, item.Test)
|
||||
}
|
||||
}
|
||||
testsuites.Complete()
|
||||
|
||||
for _, suite := range testsuites.Suites {
|
||||
xml, err := xml.MarshalIndent(suite, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fname := path + "/" + suite.Name + ".xml"
|
||||
dir := filepath.Dir(fname)
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Writing %s\n", fname)
|
||||
err = os.WriteFile(fname, xml, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
type TestEvent struct {
|
||||
Time time.Time
|
||||
Action string
|
||||
Package string
|
||||
Test string
|
||||
Elapsed float64
|
||||
Output string
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Testsuites struct {
|
||||
XMLName xml.Name `xml:"testsuites"`
|
||||
|
||||
Tests int `xml:"tests,attr"`
|
||||
Failures int `xml:"failures,attr"`
|
||||
Errors int `xml:"errors,attr"`
|
||||
Disabled int `xml:"disabled,attr,omitempty"`
|
||||
Skipped int `xml:"skipped,attr,omitempty"`
|
||||
|
||||
Time float64 `xml:"time,attr"`
|
||||
|
||||
Suites []*Test `xml:"testsuite,omitempty"`
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
XMLName xml.Name `xml:"testsuite"`
|
||||
|
||||
// required attributes
|
||||
Name string `xml:"name,attr"`
|
||||
TestCount int `xml:"tests,attr"`
|
||||
Failures int `xml:"failures,attr"`
|
||||
Errors int `xml:"errors,attr"`
|
||||
|
||||
// optional attributes
|
||||
Disabled int `xml:"disabled,attr,omitempty"`
|
||||
Package string `xml:"package,attr,omitempty"`
|
||||
Skipped int `xml:"skipped,attr,omitempty"`
|
||||
Time float64 `xml:"time,attr"`
|
||||
Timestamp time.Time `xml:"timestamp,attr,omitempty"`
|
||||
|
||||
Tests []*Test `xml:"testsuite,omitempty"`
|
||||
SystemOut string `xml:"system-out,omitempty"`
|
||||
|
||||
parent *Test
|
||||
t0 time.Time
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Message string `xml:"message,attr"`
|
||||
}
|
||||
|
||||
type Testcase struct {
|
||||
// required attributes
|
||||
Name string `xml:"name,attr"`
|
||||
Classname string `xml:"classname,attr"`
|
||||
|
||||
// optional attributes
|
||||
Time float64 `xml:"time,attr,omitempty"`
|
||||
|
||||
Skipped *Result `xml:"skipped,omitempty"`
|
||||
Error *Result `xml:"error,omitempty"`
|
||||
Failure *Result `xml:"failure,omitempty"`
|
||||
SystemOut string `xml:"system-out,omitempty"`
|
||||
}
|
||||
|
||||
// Looks for a test in root
|
||||
func (testsuites *Testsuites) getRootSuite(t time.Time, pkg string, create bool) *Test {
|
||||
for _, suite := range testsuites.Suites {
|
||||
if suite.Name == pkg {
|
||||
return suite
|
||||
}
|
||||
}
|
||||
if !create {
|
||||
return nil
|
||||
}
|
||||
suite := Test{
|
||||
Name: pkg,
|
||||
Skipped: 0,
|
||||
Timestamp: t,
|
||||
t0: t,
|
||||
}
|
||||
testsuites.Suites = append(testsuites.Suites, &suite)
|
||||
return &suite
|
||||
}
|
||||
|
||||
func (suite *Test) getSuite(t time.Time, name string) *Test {
|
||||
for _, s := range suite.Tests {
|
||||
if s.Name == suite.Name+"/"+name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
s := Test{
|
||||
Name: suite.Name + "/" + name,
|
||||
Timestamp: t,
|
||||
t0: t,
|
||||
}
|
||||
suite.Tests = append(suite.Tests, &s)
|
||||
return &s
|
||||
}
|
||||
|
||||
func (suite *Test) getTest(t time.Time, testname string) *Test {
|
||||
if testname == "" {
|
||||
return suite
|
||||
}
|
||||
suitename := suite.Name
|
||||
path := strings.Split(testname, "/")
|
||||
for i := 0; i < len(path); i++ {
|
||||
suite = suite.getSuite(t, path[i])
|
||||
suitename = suitename + "/" + path[i]
|
||||
}
|
||||
return suite
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) getTest(t time.Time, pkg string, testname string) *Test {
|
||||
suite := testsuites.getRootSuite(t, pkg, true)
|
||||
test := suite.getTest(t, testname)
|
||||
return test
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Start(t time.Time, pkg string) {
|
||||
testsuites.getRootSuite(t, pkg, true)
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Test(t time.Time, pkg string, test string) {
|
||||
// This can be a test suite as well
|
||||
testsuites.getTest(t, pkg, test)
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Output(t time.Time, pkg string, test string, output string) {
|
||||
tc := testsuites.getTest(t, pkg, test)
|
||||
tc.SystemOut = tc.SystemOut + output
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Pass(t time.Time, pkg string, test string) {
|
||||
tc := testsuites.getTest(t, pkg, test)
|
||||
tc.Time = float64(t.Sub(tc.t0).Nanoseconds()) / 1000_000_000.0
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Bench(t time.Time, pkg string, test string, output string) {
|
||||
tc := testsuites.getTest(t, pkg, test)
|
||||
tc.SystemOut = tc.SystemOut + output + "\n"
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Fail(t time.Time, pkg string, test string) {
|
||||
tc := testsuites.getTest(t, pkg, test)
|
||||
tc.Time = float64(t.Sub(tc.t0).Nanoseconds()) / 1000_000_000.0
|
||||
tc.Failures = 1
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Skip(t time.Time, pkg string, test string) {
|
||||
tc := testsuites.getTest(t, pkg, test)
|
||||
tc.Time = float64(t.Sub(tc.t0).Nanoseconds()) / 1000_000_000.0
|
||||
tc.Skipped = 1
|
||||
}
|
||||
|
||||
func (suite *Test) Complete() {
|
||||
suite.TestCount = 0
|
||||
suite.Failures = 0
|
||||
suite.Errors = 0
|
||||
suite.Disabled = 0
|
||||
suite.Skipped = 0
|
||||
|
||||
if len(suite.Tests) == 0 {
|
||||
suite.TestCount = 1
|
||||
}
|
||||
|
||||
for _, ts := range suite.Tests {
|
||||
ts.Complete()
|
||||
suite.TestCount += ts.TestCount
|
||||
suite.Failures += ts.Failures
|
||||
suite.Errors += ts.Errors
|
||||
suite.Disabled += ts.Disabled
|
||||
suite.Skipped += ts.Skipped
|
||||
ts.parent = suite
|
||||
}
|
||||
}
|
||||
|
||||
func (testsuites *Testsuites) Complete() {
|
||||
testsuites.Tests = 0
|
||||
testsuites.Failures = 0
|
||||
testsuites.Errors = 0
|
||||
testsuites.Disabled = 0
|
||||
testsuites.Skipped = 0
|
||||
for _, ts := range testsuites.Suites {
|
||||
ts.Complete()
|
||||
testsuites.Tests += ts.TestCount
|
||||
testsuites.Failures += ts.Failures
|
||||
testsuites.Errors += ts.Errors
|
||||
testsuites.Disabled += ts.Disabled
|
||||
testsuites.Skipped += ts.Skipped
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user