...

Source file src/golang.conradwood.net/tests/ctx/test_mgr.go

Documentation: golang.conradwood.net/tests/ctx

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"golang.conradwood.net/go-easyops/cmdline"
     7  	"golang.conradwood.net/go-easyops/errors"
     8  	"golang.conradwood.net/go-easyops/utils"
     9  	"html/template"
    10  	"io"
    11  	"os"
    12  	"sort"
    13  	"strings"
    14  	"sync"
    15  )
    16  
    17  var (
    18  	old_stdout *os.File
    19  	testctr    = 0
    20  	tests      []*test
    21  	newidlock  sync.Mutex
    22  )
    23  
    24  type test struct {
    25  	err           error
    26  	id            int
    27  	prefix        string
    28  	dc_start      bool
    29  	dc_error      bool
    30  	builder_start int
    31  	builder_error int
    32  	stdout_writer io.Writer
    33  	stdout_buf    *bytes.Buffer
    34  }
    35  
    36  func NewTest(format string, args ...interface{}) *test {
    37  	t := &test{
    38  		id:            newid(),
    39  		prefix:        fmt.Sprintf(format, args...),
    40  		dc_start:      cmdline.Datacenter(),
    41  		builder_start: cmdline.GetContextBuilderVersion(),
    42  		stdout_buf:    &bytes.Buffer{},
    43  	}
    44  	t.builder_error = t.builder_start
    45  	t.dc_error = t.dc_start
    46  	if old_stdout == nil {
    47  		old_stdout = os.Stdout
    48  	}
    49  	r, w, err := os.Pipe()
    50  	utils.Bail("failed to open pipe for stdout", err)
    51  	wrprefix := fmt.Sprintf("TEST %s ", t.Prefix())
    52  	t.stdout_writer = NewTee(t.stdout_buf, old_stdout, wrprefix)
    53  	os.Stdout = w
    54  	go t.pipe_reader(r)
    55  	fmt.Printf("%s -------- STARTING\n", t.Prefix())
    56  	tests = append(tests, t)
    57  	return t
    58  }
    59  func newid() int {
    60  	newidlock.Lock()
    61  	testctr++
    62  	newid := testctr
    63  	newidlock.Unlock()
    64  	return newid
    65  }
    66  func (t *test) Prefix() string {
    67  	v := fmt.Sprintf("%v", t.builder_start)
    68  	d := fmt.Sprintf("%v", t.dc_start)
    69  	return fmt.Sprintf("[#%02d dc=%5s %s (builder=%5s)]", t.id, d, t.prefix, v)
    70  }
    71  
    72  func (t *test) Printf(format string, args ...interface{}) {
    73  	fmt.Printf(t.Prefix()+" "+format, args...)
    74  }
    75  func (t *test) Error(err error) {
    76  	if err == nil {
    77  		return
    78  	}
    79  	if t.err != nil {
    80  		return
    81  	}
    82  	t.dc_error = cmdline.Datacenter()
    83  	t.builder_error = cmdline.GetContextBuilderVersion()
    84  
    85  	t.err = err
    86  	fmt.Printf("%s Failed (%s)\n", t.Prefix(), err)
    87  }
    88  func (t *test) Getstdout() string {
    89  	return t.stdout_buf.String()
    90  }
    91  func (t *test) Done() {
    92  	if t.err != nil {
    93  		fmt.Printf("%s -------- FAILURE\n", t.Prefix())
    94  		return
    95  	}
    96  	fmt.Printf("%s -------- SUCCESS\n", t.Prefix())
    97  }
    98  
    99  func PrintResult() {
   100  	os.Stdout = old_stdout
   101  	failed := 0
   102  	succeeded := 0
   103  	sort.Slice(tests, func(i, j int) bool {
   104  		if tests[i].prefix != tests[j].prefix {
   105  			return tests[i].prefix < tests[j].prefix
   106  		}
   107  		if tests[i].builder_start != tests[j].builder_start {
   108  			return tests[i].builder_start < tests[j].builder_start
   109  		}
   110  		if tests[i].builder_error != tests[j].builder_error {
   111  			return tests[i].builder_error < tests[j].builder_error
   112  		}
   113  		return tests[i].id < tests[j].id
   114  	})
   115  	var failed_tests []*test
   116  	for _, t := range tests {
   117  		if t.err != nil {
   118  			failed++
   119  			failed_tests = append(failed_tests, t)
   120  		} else {
   121  			succeeded++
   122  		}
   123  	}
   124  	if failed > 0 {
   125  		fmt.Printf("List of failed tests:\n")
   126  		for _, t := range failed_tests {
   127  			fmt.Println(t.Getstdout())
   128  		}
   129  		ta := utils.Table{}
   130  		//		ta.SetMaxLen(5, 30)
   131  		ta.AddHeaders("name", "dc (start)", "dc (error)", "builder (start)", "builder (error)", "error", "long")
   132  		for _, t := range failed_tests {
   133  			s := utils.ErrorString(t.err) + "\n" + t.Getstdout()
   134  			ge := errors.UnmarshalError(t.err)
   135  			se := ge.MultilineError()
   136  			ta.AddString(t.prefix)
   137  			ta.AddBool(t.dc_start)
   138  			ta.AddBool(t.dc_error)
   139  			ta.AddInt(t.builder_start)
   140  			ta.AddInt(t.builder_error)
   141  			ta.AddString(se)
   142  			ta.AddString(s)
   143  			ta.NewRow()
   144  		}
   145  		fmt.Println(ta.ToPrettyString())
   146  	}
   147  	fmt.Printf("Overall Result: %d tests suceeded, %d tests failed\n", succeeded, failed)
   148  
   149  	if failed > 0 {
   150  		fmt.Printf("TESTS FAILED\n")
   151  	}
   152  
   153  	b, err := render_tests_to_html(tests)
   154  	if err != nil {
   155  		fmt.Printf("failed to render to html: %s", err)
   156  	} else {
   157  		fname := "/tmp/tests.html"
   158  		err = utils.WriteFile(fname, b)
   159  		utils.Bail("failed to write file", err)
   160  		fmt.Printf("HTML written to %s\n", fname)
   161  	}
   162  }
   163  
   164  func (t *test) pipe_reader(r *os.File) {
   165  	io.Copy(t.stdout_writer, r)
   166  
   167  }
   168  func (t *test) BuilderStart() int {
   169  	return t.builder_start
   170  }
   171  func (t *test) BuilderError() int {
   172  	return t.builder_error
   173  }
   174  func (t *test) GetError() error {
   175  	return t.err
   176  }
   177  func (t *test) ID() int {
   178  	return t.id
   179  }
   180  func (t *test) Name() string {
   181  	return t.prefix
   182  }
   183  func (t *test) HtmlErrorDetails() template.HTML {
   184  	lines := strings.Split(t.Getstdout(), "\n")
   185  	res := ""
   186  	for _, l := range lines {
   187  		res = res + l + "<br/>"
   188  	}
   189  	return template.HTML(res)
   190  }
   191  func (t *test) DCStart() bool {
   192  	return t.dc_start
   193  }
   194  func (t *test) DCError() bool {
   195  	return t.dc_error
   196  }
   197  

View as plain text