summaryrefslogtreecommitdiff
path: root/xdelta3
diff options
context:
space:
mode:
authorJoshua MacDonald <josh.macdonald@gmail.com>2015-12-02 22:06:38 -0800
committerJoshua MacDonald <josh.macdonald@gmail.com>2015-12-02 22:06:38 -0800
commit6d9ad86987f926068d0d4d503c4c23efa7af511f (patch)
tree3866c603a2f6be195349b483ca51ae7545bd4fcf /xdelta3
parentfe97307cf9257460d4d9b076a00752e4e60121ba (diff)
Fixes regtest.go running against xdelta3 head
Diffstat (limited to 'xdelta3')
-rw-r--r--xdelta3/go/src/regtest.go10
-rw-r--r--xdelta3/go/src/xdelta/rstream.go12
-rw-r--r--xdelta3/go/src/xdelta/test.go21
-rw-r--r--xdelta3/go/src/xdelta/tgroup.go119
4 files changed, 65 insertions, 97 deletions
diff --git a/xdelta3/go/src/regtest.go b/xdelta3/go/src/regtest.go
index 194761a..adb4ae4 100644
--- a/xdelta3/go/src/regtest.go
+++ b/xdelta3/go/src/regtest.go
@@ -53,7 +53,6 @@ func smokeTest(r *xdelta.Runner, p *xdelta.Program) {
53 g.Panic(errors.New("It's not working!!!")) 53 g.Panic(errors.New("It's not working!!!"))
54 } 54 }
55 t.Wait(g, enc, dec) 55 t.Wait(g, enc, dec)
56 fmt.Println("Smoketest pass")
57} 56}
58 57
59func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int64) { 58func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int64) {
@@ -64,13 +63,13 @@ func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int
64 // (c) open on a fifo blocks until a reader opens 63 // (c) open on a fifo blocks until a reader opens
65 // (d) sub-process Wait can invalidate busy file descriptors 64 // (d) sub-process Wait can invalidate busy file descriptors
66 t, g := xdelta.NewTestGroup(r) 65 t, g := xdelta.NewTestGroup(r)
67 eargs := []string{"-e", "-0", fmt.Sprint("-B", bufsize), "-vvvvvvv", fmt.Sprint("-W", winsize)} 66 eargs := []string{"-e", "-0", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)}
68 enc, err := t.Exec("encode", p, true, eargs) 67 enc, err := t.Exec("encode", p, true, eargs)
69 if err != nil { 68 if err != nil {
70 g.Panic(err) 69 g.Panic(err)
71 } 70 }
72 71
73 dargs := []string{"-d", fmt.Sprint("-B", bufsize), "-vvvvvvv", fmt.Sprint("-W", winsize)} 72 dargs := []string{"-d", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)}
74 dec, err := t.Exec("decode", p, true, dargs) 73 dec, err := t.Exec("decode", p, true, dargs)
75 if err != nil { 74 if err != nil {
76 g.Panic(err) 75 g.Panic(err)
@@ -101,8 +100,11 @@ func main() {
101 100
102 prog := &xdelta.Program{xdelta3} 101 prog := &xdelta.Program{xdelta3}
103 102
104 //smokeTest(r, prog) 103 smokeTest(r, prog)
104 fmt.Println("Smoke-test pass")
105
105 offsetTest(r, prog, 4 << 20, 3 << 20, 5 << 20) 106 offsetTest(r, prog, 4 << 20, 3 << 20, 5 << 20)
107 fmt.Println("Offset-test pass")
106 108
107 //offsetTest(r, xdelta.NewTestGroup(), prog, 1 << 31, 1 << 32, 1 << 33) 109 //offsetTest(r, xdelta.NewTestGroup(), prog, 1 << 31, 1 << 32, 1 << 33)
108} 110}
diff --git a/xdelta3/go/src/xdelta/rstream.go b/xdelta3/go/src/xdelta/rstream.go
index 7d205c6..9481f22 100644
--- a/xdelta3/go/src/xdelta/rstream.go
+++ b/xdelta3/go/src/xdelta/rstream.go
@@ -13,15 +13,15 @@ const (
13 13
14func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64, 14func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64,
15 src, tgt io.WriteCloser) { 15 src, tgt io.WriteCloser) {
16 t.Go("src-write:"+desc, func (g Goroutine) { 16 t.Go("src-write:"+desc, func (g *Goroutine) {
17 writeOne(g, seed, 0, len, src, false) 17 writeOne(g, seed, 0, len, src, false)
18 }) 18 })
19 t.Go("tgt-write:"+desc, func (g Goroutine) { 19 t.Go("tgt-write:"+desc, func (g *Goroutine) {
20 writeOne(g, seed, offset, len, tgt, true) 20 writeOne(g, seed, offset, len, tgt, true)
21 }) 21 })
22} 22}
23 23
24func writeOne(g Goroutine, seed, offset, len int64, stream io.WriteCloser, readall bool) { 24func writeOne(g *Goroutine, seed, offset, len int64, stream io.WriteCloser, readall bool) {
25 if !readall { 25 if !readall {
26 // Allow the source-read to fail or block until the process terminates. 26 // Allow the source-read to fail or block until the process terminates.
27 // This behavior is reserved for the decoder, which is not required to 27 // This behavior is reserved for the decoder, which is not required to
@@ -40,27 +40,23 @@ func writeOne(g Goroutine, seed, offset, len int64, stream io.WriteCloser, reada
40 len - offset, stream); err != nil { 40 len - offset, stream); err != nil {
41 g.Panic(err) 41 g.Panic(err)
42 } 42 }
43 fmt.Println(g, "closing", len)
44 if err := stream.Close(); err != nil { 43 if err := stream.Close(); err != nil {
45 g.Panic(err) 44 g.Panic(err)
46 } 45 }
47 g.OK() 46 g.OK()
48} 47}
49 48
50func writeRand(g Goroutine, r *rand.Rand, len int64, s io.Writer) error { 49func writeRand(g *Goroutine, r *rand.Rand, len int64, s io.Writer) error {
51 blk := make([]byte, blocksize) 50 blk := make([]byte, blocksize)
52 fmt.Println(g, "rstream", len)
53 for len > 0 { 51 for len > 0 {
54 fillRand(r, blk) 52 fillRand(r, blk)
55 c := blocksize 53 c := blocksize
56 if len < blocksize { 54 if len < blocksize {
57 c = int(len) 55 c = int(len)
58 } 56 }
59 fmt.Println(g, "writing...", c, s)
60 if _, err := s.Write(blk[0:c]); err != nil { 57 if _, err := s.Write(blk[0:c]); err != nil {
61 return err 58 return err
62 } 59 }
63 fmt.Println(g, "...written", c)
64 len -= int64(c) 60 len -= int64(c)
65 } 61 }
66 return nil 62 return nil
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go
index 427e4c7..00f3dd7 100644
--- a/xdelta3/go/src/xdelta/test.go
+++ b/xdelta3/go/src/xdelta/test.go
@@ -35,9 +35,8 @@ type Run struct {
35 35
36func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte { 36func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte {
37 c := make(chan []byte) 37 c := make(chan []byte)
38 t.Go(desc, func(g Goroutine) { 38 t.Go(desc, func(g *Goroutine) {
39 if b, err := ioutil.ReadAll(f); err != nil { 39 if b, err := ioutil.ReadAll(f); err != nil {
40 fmt.Println("Drain", err)
41 g.Panic(err) 40 g.Panic(err)
42 } else { 41 } else {
43 c <- b 42 c <- b
@@ -47,8 +46,8 @@ func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte {
47 return c 46 return c
48} 47}
49 48
50func (t *TestGroup) Empty(f io.ReadCloser, desc string) Goroutine { 49func (t *TestGroup) Empty(f io.ReadCloser, desc string) *Goroutine {
51 return t.Go("empty:"+desc, func (g Goroutine) { 50 return t.Go("empty:"+desc, func (g *Goroutine) {
52 s := bufio.NewScanner(f) 51 s := bufio.NewScanner(f)
53 for s.Scan() { 52 for s.Scan() {
54 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n"))) 53 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n")))
@@ -64,18 +63,16 @@ func (t *TestGroup) Empty(f io.ReadCloser, desc string) Goroutine {
64 63
65func TestWrite(what string, f io.WriteCloser, b []byte) error { 64func TestWrite(what string, f io.WriteCloser, b []byte) error {
66 if _, err := f.Write(b); err != nil { 65 if _, err := f.Write(b); err != nil {
67 fmt.Println("Write", err)
68 return errors.New(fmt.Sprint(what, ":", err)) 66 return errors.New(fmt.Sprint(what, ":", err))
69 } 67 }
70 if err := f.Close(); err != nil { 68 if err := f.Close(); err != nil {
71 fmt.Println("Close", err)
72 return errors.New(fmt.Sprint(what, ":", err)) 69 return errors.New(fmt.Sprint(what, ":", err))
73 } 70 }
74 return nil 71 return nil
75} 72}
76 73
77func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) Goroutine { 74func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) *Goroutine {
78 return t.Go("copy", func(g Goroutine) { 75 return t.Go("copy", func(g *Goroutine) {
79 _, err := io.Copy(w, r) 76 _, err := io.Copy(w, r)
80 if err != nil { 77 if err != nil {
81 g.Panic(err) 78 g.Panic(err)
@@ -92,8 +89,8 @@ func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) Goroutine {
92 }) 89 })
93} 90}
94 91
95func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) Goroutine { 92func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) *Goroutine {
96 return t.Go("compare", func(g Goroutine) { 93 return t.Go("compare", func(g *Goroutine) {
97 b1 := make([]byte, blocksize) 94 b1 := make([]byte, blocksize)
98 b2 := make([]byte, blocksize) 95 b2 := make([]byte, blocksize)
99 var idx int64 96 var idx int64
@@ -103,11 +100,9 @@ func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length in
103 c = int(length) 100 c = int(length)
104 } 101 }
105 if _, err := io.ReadFull(r1, b1[0:c]); err != nil { 102 if _, err := io.ReadFull(r1, b1[0:c]); err != nil {
106 fmt.Println("ReadFull1", err)
107 g.Panic(err) 103 g.Panic(err)
108 } 104 }
109 if _, err := io.ReadFull(r2, b2[0:c]); err != nil { 105 if _, err := io.ReadFull(r2, b2[0:c]); err != nil {
110 fmt.Println("ReadFull2", err)
111 g.Panic(err) 106 g.Panic(err)
112 } 107 }
113 if bytes.Compare(b1[0:c], b2[0:c]) != 0 { 108 if bytes.Compare(b1[0:c], b2[0:c]) != 0 {
@@ -166,9 +161,7 @@ func (r *Run) Wait() error {
166} 161}
167 162
168func writeFifo(srcfile string, read io.Reader) error { 163func writeFifo(srcfile string, read io.Reader) error {
169 fmt.Println("About to open", srcfile)
170 fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) 164 fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600)
171 fmt.Println("Opened!!!", srcfile)
172 if err != nil { 165 if err != nil {
173 fifo.Close() 166 fifo.Close()
174 return err 167 return err
diff --git a/xdelta3/go/src/xdelta/tgroup.go b/xdelta3/go/src/xdelta/tgroup.go
index f94c03e..7f6c875 100644
--- a/xdelta3/go/src/xdelta/tgroup.go
+++ b/xdelta3/go/src/xdelta/tgroup.go
@@ -3,114 +3,91 @@ package xdelta
3import ( 3import (
4 "fmt" 4 "fmt"
5 "sync" 5 "sync"
6 "time"
7) 6)
8 7
9type TestGroup struct { 8type TestGroup struct {
10 *Runner 9 *Runner
11 sync.Mutex 10 sync.Mutex
12 running []Goroutine 11 sync.WaitGroup
12 running []*Goroutine
13 errors []error 13 errors []error
14 waitChan <-chan bool 14 nonerrors []error // For tolerated / expected conditions
15} 15}
16 16
17type Goroutine struct { 17type Goroutine struct {
18 *TestGroup
18 name string 19 name string
19 errChan chan error 20 done bool
20} 21}
21 22
22func NewTestGroup(r *Runner) (*TestGroup, Goroutine) { 23func NewTestGroup(r *Runner) (*TestGroup, *Goroutine) {
23 g := Goroutine{"main", make(chan error, 1)} 24 tg := &TestGroup{Runner: r}
24 wc := make(chan bool) 25 tg.WaitGroup.Add(1)
25 tg := &TestGroup{Runner: r, running: []Goroutine{g}, waitChan: wc} 26 g0 := &Goroutine{tg, "main", false}
26 go waitAll(tg, wc) 27 tg.running = append(tg.running, g0)
27 return tg, g 28 return tg, g0
28} 29}
29 30
30func (g *Goroutine) String() string { 31func (g *Goroutine) String() string {
31 return fmt.Sprint("[", g.name, "]") 32 return fmt.Sprint("[", g.name, "]")
32} 33}
33 34
34func (g *Goroutine) OK() { 35func (g *Goroutine) finish(err error) {
35 fmt.Println("OK", g) 36 wait := false
36 if g.errChan != nil { 37 tg := g.TestGroup
37 g.errChan <- nil 38 tg.Lock()
38 _ = <- g.errChan 39 if g.done {
39 g.errChan = nil 40 if err != nil {
41 tg.nonerrors = append(tg.nonerrors, err)
42 }
43 } else {
44 wait = true
45 g.done = true
46 if err != nil {
47 tg.errors = append(tg.errors, err)
48 }
49 }
50 tg.Unlock()
51 if wait {
52 tg.WaitGroup.Done()
40 } 53 }
41} 54}
42 55
56func (g *Goroutine) OK() {
57 g.finish(nil)
58}
59
43func (g *Goroutine) Panic(err error) { 60func (g *Goroutine) Panic(err error) {
44 fmt.Println("PANIC", g, err) 61 g.finish(err)
45 if g.errChan != nil {
46 g.errChan <- err
47 _ = <- g.errChan
48 }
49 select {} 62 select {}
50} 63}
51 64
52func (t *TestGroup) Go(name string, f func(Goroutine)) Goroutine { 65func (t *TestGroup) Go(name string, f func(*Goroutine)) *Goroutine {
53 g := Goroutine{name, make(chan error, 1)} 66 g := &Goroutine{t, name, false}
54 t.Lock() 67 t.Lock()
68 t.WaitGroup.Add(1)
55 t.running = append(t.running, g) 69 t.running = append(t.running, g)
56 t.Unlock() 70 t.Unlock()
57 go f(g) 71 go f(g)
58 return g 72 return g
59} 73}
60 74
61func (t *TestGroup) Wait(self Goroutine, procs... *Run) { 75func (t *TestGroup) Wait(self *Goroutine, procs... *Run) {
62 self.OK() 76 self.OK()
63 t.Lock() 77 t.WaitGroup.Wait()
64 wc := t.waitChan
65 t.waitChan = nil
66 t.Unlock()
67 _ = <- wc
68 t.Lock()
69 errs := t.errors
70 t.Unlock()
71 for _, p := range procs { 78 for _, p := range procs {
72 if err := p.Wait(); err != nil { 79 if err := p.Wait(); err != nil {
73 errs = append(errs, err) 80 t.errors = append(t.errors, err)
74 } 81 }
75 } 82 }
76 if len(errs) != 0 { 83 for _, err := range t.errors {
77 for _, err := range errs { 84 fmt.Println(":ERROR:", err)
78 fmt.Println(err)
79 }
80 panic(fmt.Sprint(len(errs), " errors"))
81 } 85 }
82} 86 for _, err := range t.nonerrors {
83 87 fmt.Println("(ERROR)", err)
84func waitAll(t *TestGroup, wc chan bool) { 88 }
85 for { 89 if len(t.errors) != 0 {
86 t.Lock() 90 panic(fmt.Sprintf("Test failed with", len(t.errors), "errors"))
87 if len(t.running) == 0 {
88 t.Unlock()
89 break
90 }
91 // fmt.Println("----------------------------------------------------------------------")
92 // for _, r := range t.running {
93 // fmt.Println("Waiting for", r)
94 // }
95 runner := t.running[0]
96 t.running = t.running[1:]
97 t.Unlock()
98
99 timeout := time.After(time.Second)
100
101 select {
102 case err := <- runner.errChan:
103 runner.errChan <- err
104 if err != nil {
105 t.Lock()
106 t.errors = append(t.errors, err)
107 t.Unlock()
108 }
109 case <- timeout:
110 t.Lock()
111 t.running = append(t.running, runner)
112 t.Unlock()
113 }
114 } 91 }
115 wc <- true
116} 92}
93