storj/scripts/xunit.go

273 lines
6.7 KiB
Go
Raw Normal View History

Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
// +build ignore
package main
import (
"bufio"
"bytes"
"encoding/json"
"encoding/xml"
"flag"
"fmt"
"io"
"os"
"strconv"
"strings"
"unicode"
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
"github.com/mfridman/tparse/parse"
)
var xunit = flag.String("out", "", "xunit output file")
func main() {
flag.Parse()
if *xunit == "" {
fmt.Fprintf(os.Stderr, "xunit file not specified\n")
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
os.Exit(1)
}
var buffer bytes.Buffer
stdin := io.TeeReader(os.Stdin, &buffer)
pkgs, err := ProcessWithEcho(stdin)
if err != nil {
if err == parse.ErrNotParseable {
fmt.Fprintf(os.Stderr, "tparse error: no parseable events: call go test with -json flag\n\n")
} else {
fmt.Fprintf(os.Stderr, "tparse error: %v\n\n", err)
}
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
}
defer os.Exit(pkgs.ExitCode())
output, err := os.Create(*xunit)
if err != nil {
fmt.Fprintf(os.Stderr, "create error: %v\n\n", err)
return
}
defer func() {
if err := output.Close(); err != nil {
fmt.Fprintf(os.Stderr, "close error: %v\n\n", err)
}
}()
_, _ = output.Write([]byte(xml.Header))
encoder := xml.NewEncoder(output)
encoder.Indent("", "\t")
defer encoder.Flush()
encoder.EncodeToken(xml.StartElement{Name: xml.Name{Local: "testsuites"}, Attr: nil})
defer encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "testsuites"}})
for _, pkg := range pkgs {
failed := pkg.TestsByAction(parse.ActionFail)
skipped := pkg.TestsByAction(parse.ActionSkip)
passed := pkg.TestsByAction(parse.ActionPass)
skipped = withoutEmptyName(skipped)
all := []*parse.Test{}
all = append(all, failed...)
all = append(all, skipped...)
all = append(all, passed...)
if !pkg.HasPanic && (pkg.NoTests || len(all) == 0) {
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
continue
}
func() {
encoder.EncodeToken(xml.StartElement{
Name: xml.Name{Local: "testsuite"},
Attr: []xml.Attr{
{xml.Name{Local: "name"}, pkg.Summary.Package},
{xml.Name{Local: "time"}, fmt.Sprintf("%.2f", pkg.Summary.Elapsed)},
{xml.Name{Local: "tests"}, strconv.Itoa(len(all))},
{xml.Name{Local: "failures"}, strconv.Itoa(len(failed))},
{xml.Name{Local: "skips"}, strconv.Itoa(len(skipped))},
},
})
defer encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "testsuite"}})
if pkg.HasPanic {
encoder.EncodeToken(xml.StartElement{
Name: xml.Name{Local: "testcase"},
Attr: []xml.Attr{
{xml.Name{Local: "classname"}, pkg.Summary.Package},
{xml.Name{Local: "name"}, "Panic"},
},
})
encoder.EncodeToken(xml.StartElement{Name: xml.Name{Local: "failure"}, Attr: nil})
encoder.EncodeToken(xml.CharData(eventOutput(pkg.PanicEvents)))
encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "failure"}})
encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "testcase"}})
}
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
for _, t := range all {
t.SortEvents()
func() {
encoder.EncodeToken(xml.StartElement{
Name: xml.Name{Local: "testcase"},
Attr: []xml.Attr{
{xml.Name{Local: "classname"}, t.Package},
{xml.Name{Local: "name"}, t.Name},
{xml.Name{Local: "time"}, fmt.Sprintf("%.2f", t.Elapsed())},
},
})
defer encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "testcase"}})
encoder.EncodeToken(xml.StartElement{xml.Name{Local: "system-out"}, nil})
encoder.EncodeToken(xml.CharData(eventOutput(t.Events)))
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
encoder.EncodeToken(xml.EndElement{xml.Name{Local: "system-out"}})
switch t.Status() {
case parse.ActionSkip:
encoder.EncodeToken(xml.StartElement{
Name: xml.Name{Local: "skipped"},
Attr: []xml.Attr{
{xml.Name{Local: "message"}, t.Stack()},
},
})
encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "skipped"}})
case parse.ActionFail:
encoder.EncodeToken(xml.StartElement{Name: xml.Name{Local: "failure"}, Attr: nil})
encoder.EncodeToken(xml.CharData(t.Stack()))
encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "failure"}})
}
}()
}
}()
}
}
func eventOutput(events parse.Events) string {
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
var out strings.Builder
for _, event := range events {
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
out.WriteString(event.Output)
}
return out.String()
}
func withoutEmptyName(tests []*parse.Test) []*parse.Test {
out := tests[:0]
for _, test := range tests {
if test.Name != "" {
out = append(out, test)
}
}
return out
}
// Code based on: https://github.com/mfridman/tparse/blob/master/parse/process.go#L27
func ProcessWithEcho(r io.Reader) (parse.Packages, error) {
pkgs := parse.Packages{}
var hasRace bool
var scan bool
var badLines int
scanner := bufio.NewScanner(r)
for scanner.Scan() {
// Scan up-to 50 lines for a parseable event, if we get one, expect
// no errors to follow until EOF.
event, err := parse.NewEvent(scanner.Bytes())
if err != nil {
badLines++
if scan || badLines > 50 {
switch err.(type) {
case *json.SyntaxError:
return nil, parse.ErrNotParseable
default:
return nil, err
}
}
continue
}
scan = true
if line := strings.TrimRightFunc(event.Output, unicode.IsSpace); line != "" {
fmt.Fprintln(os.Stdout, line)
}
Public Jenkins (#1779) * initial test * add parenthesis * remove pipeline * add few todos * use docker image for environment * use pipeline * fix * add missing steps * invoke with bash * disable protoc * try using golang image * try as root * Disable install-awscli.sh temporarily * Debugging * debugging part 2 * Set absolute path for debugging * Remove absolute path * Dont run as root * Install unzip * Dont forget to apt-get update * Put into folder that is in PATH * disable IPv6 Test * add verbose info and check protobuf * make integration non-parallel * remove -v and make checkout part of build * make a single block for linting * fix echo * update * try using things directly * try add xunit output * fix name * don't print empty lines * skip testsuites without any tests * remove coverage, because it's not showing the right thing * try using dockerfile * fix deb source * fix typos * setup postgres * use the right flag * try using postgresdb * expose different port * remove port mapping * start postgres * export * use env block * try using different host for integration tests * eat standard ports * try building images and binaries * remove if statement * add steps * do before verification * add go get goversioninfo * make separate jenkinsfile * add check * don't add empty packages * disable logging to reduce output size * add timeout * add comment about mfridman * Revert Absolute Path * Add aws to PATH * PATH Changes * Docker Env Fixes * PATH Simplification * Debugging the PATH * Debug Logs * Debugging * Update PATH Handling * Rename * revert changes to Jenkinsfile
2019-04-22 14:45:53 +01:00
pkg, ok := pkgs[event.Package]
if !ok {
pkg = parse.NewPackage()
pkgs[event.Package] = pkg
}
if event.IsPanic() {
pkg.HasPanic = true
pkg.Summary.Action = parse.ActionFail
pkg.Summary.Package = event.Package
pkg.Summary.Test = event.Test
}
// Short circuit output when panic is detected.
if pkg.HasPanic {
pkg.PanicEvents = append(pkg.PanicEvents, event)
continue
}
if event.IsRace() {
hasRace = true
}
if event.IsCached() {
pkg.Cached = true
}
if event.NoTestFiles() {
pkg.NoTestFiles = true
// Manually mark [no test files] as "pass", because the go test tool reports the
// package Summary action as "skip".
pkg.Summary.Package = event.Package
pkg.Summary.Action = parse.ActionPass
}
if event.NoTestsWarn() {
// One or more tests within the package contains no tests.
pkg.NoTestSlice = append(pkg.NoTestSlice, event)
}
if event.NoTestsToRun() {
// Only pkgs marked as "pass" will contain a summary line appended with [no tests to run].
// This indicates one or more tests is marked as having no tests to run.
pkg.NoTests = true
pkg.Summary.Package = event.Package
pkg.Summary.Action = parse.ActionPass
}
if event.LastLine() {
pkg.Summary = event
continue
}
cover, ok := event.Cover()
if ok {
pkg.Cover = true
pkg.Coverage = cover
}
if !event.Discard() {
pkg.AddEvent(event)
}
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("bufio scanner error: %v", err)
}
if !scan {
return nil, parse.ErrNotParseable
}
if hasRace {
return nil, parse.ErrRaceDetected
}
return pkgs, nil
}