summaryrefslogtreecommitdiff
path: root/xdelta3/go/src/xdelta
diff options
context:
space:
mode:
authorJoshua MacDonald <josh.macdonald@gmail.com>2015-11-23 20:28:05 -0800
committerJoshua MacDonald <josh.macdonald@gmail.com>2015-11-23 20:28:05 -0800
commitb24969720ac9c92f3d7327250b3ee8e86acc6def (patch)
tree1e2401ee0b0cfa0f9d382fbc33f3445a3947fb49 /xdelta3/go/src/xdelta
parentede482d8f3398262adcfb23095b6caad5872d8ba (diff)
Improve error handling; allow two routines to have errors in a successful test (Empty, which can get bad file descriptor after the process exits, and the Decode-Source writer, since the decoder is not required to read the full source)
Diffstat (limited to 'xdelta3/go/src/xdelta')
-rw-r--r--xdelta3/go/src/xdelta/rstream.go15
-rw-r--r--xdelta3/go/src/xdelta/test.go6
-rw-r--r--xdelta3/go/src/xdelta/tgroup.go41
3 files changed, 40 insertions, 22 deletions
diff --git a/xdelta3/go/src/xdelta/rstream.go b/xdelta3/go/src/xdelta/rstream.go
index 3f520d7..e31b0b0 100644
--- a/xdelta3/go/src/xdelta/rstream.go
+++ b/xdelta3/go/src/xdelta/rstream.go
@@ -10,17 +10,20 @@ const (
10 blocksize = 16380 10 blocksize = 16380
11) 11)
12 12
13func WriteRstreams(t *TestGroup, seed, offset, len int64, 13func WriteRstreams(t *TestGroup, desc string, seed, offset, len int64,
14 src, tgt io.WriteCloser) { 14 src, tgt io.WriteCloser) {
15 t.Go("src", func (g Goroutine) { 15 t.Go("src-write:"+desc, func (g Goroutine) {
16 go writeOne(g, seed, 0, len, src) 16 writeOne(g, seed, 0, len, src, false)
17 }) 17 })
18 t.Go("tgt", func (g Goroutine) { 18 t.Go("tgt-write:"+desc, func (g Goroutine) {
19 go writeOne(g, seed, offset, len, tgt) 19 writeOne(g, seed, offset, len, tgt, true)
20 }) 20 })
21} 21}
22 22
23func writeOne(g Goroutine, seed, offset, len int64, stream io.WriteCloser) { 23func writeOne(g Goroutine, seed, offset, len int64, stream io.WriteCloser, readall bool) {
24 if !readall {
25 g.OK()
26 }
24 if offset != 0 { 27 if offset != 0 {
25 // Fill with other random data until the offset 28 // Fill with other random data until the offset
26 if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil { 29 if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil {
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go
index d11ec29..ab4137c 100644
--- a/xdelta3/go/src/xdelta/test.go
+++ b/xdelta3/go/src/xdelta/test.go
@@ -49,6 +49,7 @@ func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte {
49 49
50func (t *TestGroup) Empty(f io.ReadCloser, desc string) { 50func (t *TestGroup) Empty(f io.ReadCloser, desc string) {
51 t.Go(desc, func (g Goroutine) { 51 t.Go(desc, func (g Goroutine) {
52 g.OK()
52 s := bufio.NewScanner(f) 53 s := bufio.NewScanner(f)
53 for s.Scan() { 54 for s.Scan() {
54 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n"))) 55 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n")))
@@ -59,7 +60,6 @@ func (t *TestGroup) Empty(f io.ReadCloser, desc string) {
59 fmt.Println("Empty", desc, err) 60 fmt.Println("Empty", desc, err)
60 g.Panic(err) 61 g.Panic(err)
61 } 62 }
62 g.OK()
63 }) 63 })
64} 64}
65 65
@@ -126,7 +126,7 @@ func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length in
126 }) 126 })
127} 127}
128 128
129func (t *TestGroup) Exec(p *Program, srcfifo bool, flags []string) (*Run, error) { 129func (t *TestGroup) Exec(desc string, p *Program, srcfifo bool, flags []string) (*Run, error) {
130 var err error 130 var err error
131 run := &Run{} 131 run := &Run{}
132 args := []string{p.Path} 132 args := []string{p.Path}
@@ -162,7 +162,7 @@ func (t *TestGroup) Exec(p *Program, srcfifo bool, flags []string) (*Run, error)
162 if serr := run.Cmd.Start(); serr != nil { 162 if serr := run.Cmd.Start(); serr != nil {
163 return nil, serr 163 return nil, serr
164 } 164 }
165 t.Go("exec-wait", func (g Goroutine) { 165 t.Go("exec-wait:" + desc, func (g Goroutine) {
166 if err := run.Cmd.Wait(); err != nil { 166 if err := run.Cmd.Wait(); err != nil {
167 g.Panic(err) 167 g.Panic(err)
168 } 168 }
diff --git a/xdelta3/go/src/xdelta/tgroup.go b/xdelta3/go/src/xdelta/tgroup.go
index bb34258..b64827c 100644
--- a/xdelta3/go/src/xdelta/tgroup.go
+++ b/xdelta3/go/src/xdelta/tgroup.go
@@ -10,6 +10,7 @@ type TestGroup struct {
10 *Runner 10 *Runner
11 sync.Mutex 11 sync.Mutex
12 running []Goroutine 12 running []Goroutine
13 errors []error
13 waitChan <-chan bool 14 waitChan <-chan bool
14} 15}
15 16
@@ -31,13 +32,19 @@ func (g *Goroutine) String() string {
31} 32}
32 33
33func (g *Goroutine) OK() { 34func (g *Goroutine) OK() {
34 g.errChan <- nil 35 if g.errChan != nil {
35 _ = <- g.errChan 36 g.errChan <- nil
37 _ = <- g.errChan
38 g.errChan = nil
39 }
36} 40}
37 41
38func (g *Goroutine) Panic(err error) { 42func (g *Goroutine) Panic(err error) {
39 g.errChan <- err 43 fmt.Print("[", g.name, "] ", err, "\n")
40 _ = <- g.errChan 44 if g.errChan != nil {
45 g.errChan <- err
46 _ = <- g.errChan
47 }
41 select {} 48 select {}
42} 49}
43 50
@@ -52,15 +59,24 @@ func (t *TestGroup) Go(name string, f func(Goroutine)) {
52func (t *TestGroup) Wait(g Goroutine) { 59func (t *TestGroup) Wait(g Goroutine) {
53 g.OK() 60 g.OK()
54 t.Lock() 61 t.Lock()
55 t.waitChan = nil
56 wc := t.waitChan 62 wc := t.waitChan
63 t.waitChan = nil
57 t.Unlock() 64 t.Unlock()
58 _ = <- wc 65 _ = <- wc
66 t.Lock()
67 errs := t.errors
68 t.Unlock()
69 if len(errs) != 0 {
70 panic(fmt.Sprintln(len(errs), "errors in test"))
71 }
59} 72}
60 73
61func waitAll(t *TestGroup, wc chan bool) { 74func waitAll(t *TestGroup, wc chan bool) {
62 for { 75 for {
63 t.Lock() 76 t.Lock()
77 // for _, x := range t.running {
78 // fmt.Println("RUNNING", x.name)
79 // }
64 if len(t.running) == 0 { 80 if len(t.running) == 0 {
65 t.Unlock() 81 t.Unlock()
66 break 82 break
@@ -69,19 +85,18 @@ func waitAll(t *TestGroup, wc chan bool) {
69 t.running = t.running[1:] 85 t.running = t.running[1:]
70 t.Unlock() 86 t.Unlock()
71 87
72 timeout := make(chan bool, 1) 88 timeout := time.After(time.Second)
73 go func() { 89 // fmt.Println("Waiting on", runner)
74 time.Sleep(1 * time.Second)
75 timeout <- true
76 }()
77 fmt.Println("Waiting on", runner)
78 select { 90 select {
79 case err := <- runner.errChan: 91 case err := <- runner.errChan:
80 runner.errChan <- err 92 runner.errChan <- err
81 if err != nil { 93 if err != nil {
82 fmt.Println("[G]", runner, err) 94 // fmt.Println("[G]", runner, err)
95 t.Lock()
96 t.errors = append(t.errors, err)
97 t.Unlock()
83 } else { 98 } else {
84 fmt.Println("[G]", runner, "OK") 99 // fmt.Println("[G]", runner, "OK")
85 } 100 }
86 case <- timeout: 101 case <- timeout:
87 t.Lock() 102 t.Lock()