158 lines
3.8 KiB
Go
158 lines
3.8 KiB
Go
// Licensed to Elasticsearch B.V. under one or more contributor
|
|
// license agreements. See the NOTICE file distributed with
|
|
// this work for additional information regarding copyright
|
|
// ownership. Elasticsearch B.V. licenses this file to you under
|
|
// the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package testing
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/mattn/go-colorable"
|
|
)
|
|
|
|
// ConsoleDriver outputs test result to the given stdout/stderr descriptors
|
|
type ConsoleDriver struct {
|
|
Stdout io.Writer
|
|
level int
|
|
reported bool
|
|
killer func()
|
|
result string
|
|
}
|
|
|
|
// NewConsoleDriver initializes and returns a new console driver with output to given file
|
|
func NewConsoleDriver(stdout io.Writer) *ConsoleDriver {
|
|
return NewConsoleDriverWithKiller(stdout, func() { os.Exit(1) })
|
|
}
|
|
|
|
// NewConsoleDriverWithKiller initializes and returns a new console driver with output file
|
|
// Killer function will be called on fatal errors
|
|
func NewConsoleDriverWithKiller(stdout io.Writer, killer func()) *ConsoleDriver {
|
|
// On Windows we must wrap file outputs with a Colorable to achieve the right
|
|
// escape sequences.
|
|
if f, ok := stdout.(*os.File); ok && runtime.GOOS == "windows" {
|
|
stdout = colorable.NewColorable(f)
|
|
}
|
|
return &ConsoleDriver{
|
|
Stdout: stdout,
|
|
level: 0,
|
|
killer: killer,
|
|
reported: true,
|
|
}
|
|
}
|
|
|
|
func (d *ConsoleDriver) Run(name string, f func(Driver)) {
|
|
if !d.reported {
|
|
fmt.Fprintln(d.Stdout, "")
|
|
}
|
|
d.printf("%s...", name)
|
|
|
|
// Run sub func
|
|
driver := &ConsoleDriver{
|
|
Stdout: d.Stdout,
|
|
level: d.level + 1,
|
|
killer: d.killer,
|
|
}
|
|
f(driver)
|
|
|
|
if !driver.reported {
|
|
color.New(color.FgGreen).Fprintf(driver.Stdout, "OK\n")
|
|
driver.reported = true
|
|
}
|
|
|
|
if driver.result != "" {
|
|
driver.Info("result", driver.indent(driver.result))
|
|
}
|
|
|
|
d.reported = true
|
|
}
|
|
|
|
func (d *ConsoleDriver) Info(field, value string) {
|
|
if !d.reported {
|
|
fmt.Fprintln(d.Stdout, "")
|
|
}
|
|
d.printf("%s: %s\n", field, value)
|
|
d.reported = true
|
|
}
|
|
|
|
func (d *ConsoleDriver) Warn(field, reason string) {
|
|
if !d.reported {
|
|
fmt.Fprintln(d.Stdout, "")
|
|
}
|
|
d.printf("%s... ", field)
|
|
color.New(color.FgYellow).Fprintf(d.Stdout, "WARN ")
|
|
fmt.Fprintln(d.Stdout, reason)
|
|
d.reported = true
|
|
}
|
|
|
|
func (d *ConsoleDriver) Error(field string, err error) {
|
|
if err == nil {
|
|
d.ok(field)
|
|
return
|
|
}
|
|
d.error(field, err)
|
|
}
|
|
|
|
func (d *ConsoleDriver) Fatal(field string, err error) {
|
|
if err == nil {
|
|
d.ok(field)
|
|
return
|
|
}
|
|
d.error(field, err)
|
|
d.killer()
|
|
}
|
|
|
|
func (d *ConsoleDriver) Result(data string) {
|
|
d.result = data
|
|
}
|
|
|
|
func (d *ConsoleDriver) ok(field string) {
|
|
if !d.reported {
|
|
fmt.Fprintln(d.Stdout, "")
|
|
}
|
|
d.printf("%s... ", field)
|
|
color.New(color.FgGreen).Fprintf(d.Stdout, "OK\n")
|
|
d.reported = true
|
|
}
|
|
|
|
func (d *ConsoleDriver) error(field string, err error) {
|
|
if !d.reported {
|
|
fmt.Fprintln(d.Stdout, "")
|
|
}
|
|
d.printf("%s... ", field)
|
|
color.New(color.FgRed).Fprintf(d.Stdout, "ERROR ")
|
|
fmt.Fprintln(d.Stdout, err.Error())
|
|
d.reported = true
|
|
}
|
|
|
|
func (d *ConsoleDriver) printf(format string, args ...interface{}) {
|
|
for i := 0; i < d.level; i++ {
|
|
fmt.Fprint(d.Stdout, " ")
|
|
}
|
|
fmt.Fprintf(d.Stdout, format, args...)
|
|
}
|
|
|
|
func (d *ConsoleDriver) indent(data string) string {
|
|
res := "\n"
|
|
for _, line := range strings.Split(data, "\n") {
|
|
res += strings.Repeat(" ", d.level+2) + line + "\n"
|
|
}
|
|
return res
|
|
}
|