From ede482d8f3398262adcfb23095b6caad5872d8ba Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Sat, 21 Nov 2015 23:36:51 -0800 Subject: New TestGroup.Go method, improved error handling --- xdelta3/go/src/xdelta/test.go | 132 +++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 80 deletions(-) (limited to 'xdelta3/go/src/xdelta/test.go') diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go index e853554..d11ec29 100644 --- a/xdelta3/go/src/xdelta/test.go +++ b/xdelta3/go/src/xdelta/test.go @@ -11,7 +11,6 @@ import ( "os/exec" "path" "sync/atomic" - "sync" "golang.org/x/sys/unix" ) @@ -25,16 +24,6 @@ type Program struct { Path string } -type Runner struct { - Testdir string -} - -type TestGroup struct { - sync.WaitGroup - sync.Mutex - errs []error -} - type Run struct { Cmd exec.Cmd Srcfile string @@ -44,86 +33,71 @@ type Run struct { Stderr io.ReadCloser } - -func (t *TestGroup) Panic(err error) { - t.Lock() - t.errs = append(t.errs, err) - t.Unlock() - t.Done() // For the caller - t.Wait() - for _, e := range t.errs { - fmt.Println(e) - } - panic(fmt.Sprintf("%d errors", len(t.errs))) -} - -func NewTestGroup() *TestGroup { - return &TestGroup{} -} - func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte { c := make(chan []byte) - go func() { - t.Add(1) - //fmt.Println("Draining", desc) + t.Go(desc, func(g Goroutine) { if b, err := ioutil.ReadAll(f); err != nil { - t.Panic(err) + fmt.Println("Drain", err) + g.Panic(err) } else { - //fmt.Println("Draining", desc, "--got it") c <- b } - t.Done() - }() + g.OK() + }) return c } func (t *TestGroup) Empty(f io.ReadCloser, desc string) { - go func() { - t.Add(1) + t.Go(desc, func (g Goroutine) { s := bufio.NewScanner(f) for s.Scan() { os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n"))) } - if err := s.Err(); err != nil { - t.Panic(err) + err := s.Err() + f.Close() + if err != nil { + fmt.Println("Empty", desc, err) + g.Panic(err) } - t.Done() - }() + g.OK() + }) } -func (t *TestGroup) Write(what string, f io.WriteCloser, b []byte) { - //fmt.Println("Write (", what, ") ", len(b), "bytes") +func TestWrite(what string, f io.WriteCloser, b []byte) error { if _, err := f.Write(b); err != nil { - t.Panic(errors.New(fmt.Sprint(what, ":", err))) + fmt.Println("Write", err) + return errors.New(fmt.Sprint(what, ":", err)) } - //fmt.Println("Write (", what, ") closing") if err := f.Close(); err != nil { - t.Panic(errors.New(fmt.Sprint(what, ":", err))) + fmt.Println("Close", err) + return errors.New(fmt.Sprint(what, ":", err)) } + return nil } func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) { - go func() { - t.Add(1) + t.Go("copy", func(g Goroutine) { _, err := io.Copy(w, r) if err != nil { - t.Panic(err) + fmt.Println("CopyS", err) + g.Panic(err) } err = r.Close() if err != nil { - t.Panic(err) + fmt.Println("CloseS1", err) + g.Panic(err) } err = w.Close() if err != nil { - t.Panic(err) + fmt.Println("CloseS2", err) + g.Panic(err) } - t.Done() - }() + g.OK() + }) } func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) { - go func() { - t.Add(1) + t.Go("compare", func(g Goroutine) { b1 := make([]byte, blocksize) b2 := make([]byte, blocksize) var idx int64 @@ -133,42 +107,32 @@ func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length in c = int(length) } if _, err := io.ReadFull(r1, b1[0:c]); err != nil { - t.Panic(err) + fmt.Println("ReadFull1", err) + g.Panic(err) } if _, err := io.ReadFull(r2, b2[0:c]); err != nil { - t.Panic(err) + fmt.Println("ReadFull2", err) + g.Panic(err) } if bytes.Compare(b1[0:c], b2[0:c]) != 0 { fmt.Println("B1 is", string(b1[0:c])) fmt.Println("B2 is", string(b2[0:c])) - t.Panic(errors.New(fmt.Sprint("Bytes do not compare at ", idx))) + g.Panic(errors.New(fmt.Sprint("Bytes do not compare at ", idx))) } length -= int64(c) idx += int64(c) } - t.Done() - }() + g.OK() + }) } -func NewRunner() (*Runner, error) { - if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil { - return nil, err - } else { - return &Runner{dir}, nil - } -} - -func (r *Runner) Cleanup() { - os.RemoveAll(r.Testdir) -} - -func (r *Runner) Exec(p *Program, srcfifo bool, flags []string) (*Run, error) { +func (t *TestGroup) Exec(p *Program, srcfifo bool, flags []string) (*Run, error) { var err error run := &Run{} args := []string{p.Path} if srcfifo { num := atomic.AddInt64(&srcSeq, 1) - run.Srcfile = path.Join(r.Testdir, fmt.Sprint("source", num)) + run.Srcfile = path.Join(t.Runner.Testdir, fmt.Sprint("source", num)) if err = unix.Mkfifo(run.Srcfile, 0600); err != nil { return nil, err } @@ -193,21 +157,29 @@ func (r *Runner) Exec(p *Program, srcfifo bool, flags []string) (*Run, error) { run.Cmd.Path = p.Path run.Cmd.Args = append(args, flags...) - run.Cmd.Dir = r.Testdir + run.Cmd.Dir = t.Runner.Testdir - return run, run.Cmd.Start() + if serr := run.Cmd.Start(); serr != nil { + return nil, serr + } + t.Go("exec-wait", func (g Goroutine) { + if err := run.Cmd.Wait(); err != nil { + g.Panic(err) + } + g.OK() + }) + return run, nil } func writeFifo(srcfile string, read io.Reader) error { fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) if err != nil { + fifo.Close() return err } if _, err := io.Copy(fifo, read); err != nil { + fifo.Close() return err } - if err := fifo.Close(); err != nil { - return err - } - return nil + return fifo.Close() } -- cgit v1.2.3