Created
September 10, 2019 08:30
-
-
Save retrozoid/caee499dd2cb7488b6741a5f020c7cf6 to your computer and use it in GitHub Desktop.
golang test json converter to teamcity test format
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
package main | |
import ( | |
"bufio" | |
"encoding/json" | |
"fmt" | |
"io" | |
"os" | |
"strings" | |
"time" | |
) | |
var ( | |
input = os.Stdin | |
output = os.Stdout | |
testStarted = "##teamcity[testStarted name='%s' flowId='%d' captureStandardOutput='false']\n" | |
testFinished = "##teamcity[testFinished name='%s' flowId='%d' duration='%d']\n" | |
testFailed = "##teamcity[testFailed name='%s' flowId='%d' message='failure message' details='message and stack trace']\n" | |
testIgnored = "##teamcity[testIgnored name='%s' flowId='%d' message='skipped']\n" | |
testStdOut = "##teamcity[testStdOut name='%s' flowId='%d' out='%s']\n" | |
testStdErr = "##teamcity[testStdErr name='%s' flowId='%d' out='%s']\n" | |
) | |
// TestEvent The JSON stream is a newline-separated sequence of TestEvent objects corresponding to the Go struct: | |
type TestEvent struct { | |
Time time.Time // encodes as an RFC3339-format string | |
Action string | |
Package string | |
Test string | |
Elapsed float64 // seconds | |
Output string | |
} | |
// The Action field is one of a fixed set of action descriptions | |
const ( | |
RUN = "run" // the test has started running | |
PAUSE = "pause" // the test has been paused | |
CONT = "cont" // the test has continued running | |
PASS = "pass" // the test passed | |
BENCH = "bench" // the benchmark printed log output but did not fail | |
FAIL = "fail" // the test or benchmark failed | |
OUTPUT = "output" // the test printed output | |
SKIP = "skip" // the test was skipped or the package contained no tests | |
) | |
func main() { | |
reader := bufio.NewReader(input) | |
process(reader, output) | |
} | |
func escape(s string) string { | |
s = strings.TrimSuffix(s, "\n") | |
s = strings.Replace(s, "|", "||", -1) | |
s = strings.Replace(s, "\n", "|n", -1) | |
s = strings.Replace(s, "\r", "|n", -1) | |
s = strings.Replace(s, "'", "|'", -1) | |
s = strings.Replace(s, "]", "|]", -1) | |
s = strings.Replace(s, "[", "|[", -1) | |
return s | |
} | |
func process(r *bufio.Reader, w io.Writer) { | |
var id int64 | |
flows := make(map[string]int64) | |
flow := func(test string) int64 { | |
if _, ok := flows[test]; !ok { | |
flows[test] = id | |
id++ | |
} | |
return flows[test] | |
} | |
var event = new(TestEvent) | |
for { | |
line, err := r.ReadBytes('\n') | |
if err != nil { | |
break | |
} | |
err = json.Unmarshal(line, event) | |
if err != nil { | |
continue | |
} | |
if event.Test == "" { | |
continue | |
} | |
flowID := flow(event.Test) | |
switch event.Action { | |
case RUN: | |
fmt.Fprintf(w, testStarted, event.Test, flowID) | |
case PAUSE, CONT, BENCH: | |
case PASS, FAIL, SKIP: | |
if event.Action == SKIP { | |
fmt.Fprintf(w, testIgnored, event.Test, flowID) | |
} | |
if event.Action == FAIL { | |
fmt.Fprintf(w, testFailed, event.Test, flowID) | |
} | |
fmt.Fprintf(w, testFinished, event.Test, flowID, int64(event.Elapsed*1000)) | |
case OUTPUT: | |
fmt.Fprintf(w, testStdOut, event.Test, flowID, escape(event.Output)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment