diff options
Diffstat (limited to 'xdelta3/go/src')
-rw-r--r-- | xdelta3/go/src/regtest.go | 18 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/rstream.go | 21 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/test.go | 7 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/tgroup.go | 62 |
4 files changed, 37 insertions, 71 deletions
diff --git a/xdelta3/go/src/regtest.go b/xdelta3/go/src/regtest.go index 4507b8c..85bd43a 100644 --- a/xdelta3/go/src/regtest.go +++ b/xdelta3/go/src/regtest.go | |||
@@ -57,14 +57,20 @@ func smokeTest(r *xdelta.Runner, p *xdelta.Program) { | |||
57 | } | 57 | } |
58 | 58 | ||
59 | func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int64) { | 59 | func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int64) { |
60 | // Note there is a strong potential to deadlock or fail due to | ||
61 | // a broken test in this test for several reasons: | ||
62 | // (a) decoder is not required to read the entire source file | ||
63 | // (b) decoder defers open to source file until first window received | ||
64 | // (c) open on a fifo blocks until a reader opens | ||
65 | // (d) sub-process Wait can invalidate busy file descriptors | ||
60 | t, g := xdelta.NewTestGroup(r) | 66 | t, g := xdelta.NewTestGroup(r) |
61 | eargs := []string{"-e", "-0", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)} | 67 | eargs := []string{"-e", "-0", fmt.Sprint("-B", bufsize), "-vvvvvvv", fmt.Sprint("-W", winsize)} |
62 | enc, err := t.Exec("encode", p, true, eargs) | 68 | enc, err := t.Exec("encode", p, true, eargs) |
63 | if err != nil { | 69 | if err != nil { |
64 | g.Panic(err) | 70 | g.Panic(err) |
65 | } | 71 | } |
66 | 72 | ||
67 | dargs := []string{"-d", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)} | 73 | dargs := []string{"-d", fmt.Sprint("-B", bufsize), "-vvvvvvv", fmt.Sprint("-W", winsize)} |
68 | dec, err := t.Exec("decode", p, true, dargs) | 74 | dec, err := t.Exec("decode", p, true, dargs) |
69 | if err != nil { | 75 | if err != nil { |
70 | g.Panic(err) | 76 | g.Panic(err) |
@@ -79,10 +85,10 @@ func offsetTest(r *xdelta.Runner, p *xdelta.Program, bufsize, offset, length int | |||
79 | t.CompareStreams(dec.Stdout, read, length) | 85 | t.CompareStreams(dec.Stdout, read, length) |
80 | 86 | ||
81 | // The decoder output ("read", above) is compared with the | 87 | // The decoder output ("read", above) is compared with the |
82 | // test-provided output ("write", below). | 88 | // test-provided output ("write", below). The following |
83 | xdelta.WriteRstreams(t, seed, offset, length, | 89 | // generates the input and output twice. |
84 | t.NewDualWriter(enc.Srcin, dec.Srcin), | 90 | t.WriteRstreams("encode", seed, offset, length, enc.Srcin, dec.Srcin) |
85 | t.NewDualWriter(dec.Srcin, write)) | 91 | t.WriteRstreams("decode", seed, offset, length, dec.Srcin, write) |
86 | t.Wait(g, enc, dec) | 92 | t.Wait(g, enc, dec) |
87 | } | 93 | } |
88 | 94 | ||
diff --git a/xdelta3/go/src/xdelta/rstream.go b/xdelta3/go/src/xdelta/rstream.go index eafcfeb..7d205c6 100644 --- a/xdelta3/go/src/xdelta/rstream.go +++ b/xdelta3/go/src/xdelta/rstream.go | |||
@@ -3,19 +3,20 @@ package xdelta | |||
3 | 3 | ||
4 | import ( | 4 | import ( |
5 | "io" | 5 | "io" |
6 | "fmt" | ||
6 | "math/rand" | 7 | "math/rand" |
7 | ) | 8 | ) |
8 | 9 | ||
9 | const ( | 10 | const ( |
10 | blocksize = 1<<20 | 11 | blocksize = 1<<17 |
11 | ) | 12 | ) |
12 | 13 | ||
13 | func WriteRstreams(t *TestGroup, seed, offset, len int64, | 14 | func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64, |
14 | src, tgt io.WriteCloser) { | 15 | src, tgt io.WriteCloser) { |
15 | t.Go("src-write", func (g Goroutine) { | 16 | t.Go("src-write:"+desc, func (g Goroutine) { |
16 | writeOne(g, seed, 0, len, src, false) | 17 | writeOne(g, seed, 0, len, src, false) |
17 | }) | 18 | }) |
18 | t.Go("tgt-write", func (g Goroutine) { | 19 | t.Go("tgt-write:"+desc, func (g Goroutine) { |
19 | writeOne(g, seed, offset, len, tgt, true) | 20 | writeOne(g, seed, offset, len, tgt, true) |
20 | }) | 21 | }) |
21 | } | 22 | } |
@@ -29,31 +30,37 @@ func writeOne(g Goroutine, seed, offset, len int64, stream io.WriteCloser, reada | |||
29 | } | 30 | } |
30 | if offset != 0 { | 31 | if offset != 0 { |
31 | // Fill with other random data until the offset | 32 | // Fill with other random data until the offset |
32 | if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil { | 33 | fmt.Println(g, "pre-offset case", offset) |
34 | if err := writeRand(g, rand.New(rand.NewSource(^seed)), offset, stream); err != nil { | ||
33 | g.Panic(err) | 35 | g.Panic(err) |
34 | } | 36 | } |
35 | } | 37 | } |
36 | if err := writeRand(rand.New(rand.NewSource(seed)), | 38 | fmt.Println(g, "offset case", len - offset) |
39 | if err := writeRand(g, rand.New(rand.NewSource(seed)), | ||
37 | len - offset, stream); err != nil { | 40 | len - offset, stream); err != nil { |
38 | g.Panic(err) | 41 | g.Panic(err) |
39 | } | 42 | } |
43 | fmt.Println(g, "closing", len) | ||
40 | if err := stream.Close(); err != nil { | 44 | if err := stream.Close(); err != nil { |
41 | g.Panic(err) | 45 | g.Panic(err) |
42 | } | 46 | } |
43 | g.OK() | 47 | g.OK() |
44 | } | 48 | } |
45 | 49 | ||
46 | func writeRand(r *rand.Rand, len int64, s io.Writer) error { | 50 | func writeRand(g Goroutine, r *rand.Rand, len int64, s io.Writer) error { |
47 | blk := make([]byte, blocksize) | 51 | blk := make([]byte, blocksize) |
52 | fmt.Println(g, "rstream", len) | ||
48 | for len > 0 { | 53 | for len > 0 { |
49 | fillRand(r, blk) | 54 | fillRand(r, blk) |
50 | c := blocksize | 55 | c := blocksize |
51 | if len < blocksize { | 56 | if len < blocksize { |
52 | c = int(len) | 57 | c = int(len) |
53 | } | 58 | } |
59 | fmt.Println(g, "writing...", c, s) | ||
54 | if _, err := s.Write(blk[0:c]); err != nil { | 60 | if _, err := s.Write(blk[0:c]); err != nil { |
55 | return err | 61 | return err |
56 | } | 62 | } |
63 | fmt.Println(g, "...written", c) | ||
57 | len -= int64(c) | 64 | len -= int64(c) |
58 | } | 65 | } |
59 | return nil | 66 | return nil |
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go index 05de487..427e4c7 100644 --- a/xdelta3/go/src/xdelta/test.go +++ b/xdelta3/go/src/xdelta/test.go | |||
@@ -78,17 +78,14 @@ func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) Goroutine { | |||
78 | return t.Go("copy", func(g Goroutine) { | 78 | return t.Go("copy", func(g Goroutine) { |
79 | _, err := io.Copy(w, r) | 79 | _, err := io.Copy(w, r) |
80 | if err != nil { | 80 | if err != nil { |
81 | fmt.Println("CopyS", err) | ||
82 | g.Panic(err) | 81 | g.Panic(err) |
83 | } | 82 | } |
84 | err = r.Close() | 83 | err = r.Close() |
85 | if err != nil { | 84 | if err != nil { |
86 | fmt.Println("CloseS1", err) | ||
87 | g.Panic(err) | 85 | g.Panic(err) |
88 | } | 86 | } |
89 | err = w.Close() | 87 | err = w.Close() |
90 | if err != nil { | 88 | if err != nil { |
91 | fmt.Println("CloseS2", err) | ||
92 | g.Panic(err) | 89 | g.Panic(err) |
93 | } | 90 | } |
94 | g.OK() | 91 | g.OK() |
@@ -157,7 +154,7 @@ func (t *TestGroup) Exec(desc string, p *Program, srcfifo bool, flags []string) | |||
157 | run.Cmd.Path = p.Path | 154 | run.Cmd.Path = p.Path |
158 | run.Cmd.Args = append(args, flags...) | 155 | run.Cmd.Args = append(args, flags...) |
159 | run.Cmd.Dir = t.Runner.Testdir | 156 | run.Cmd.Dir = t.Runner.Testdir |
160 | 157 | fmt.Println("Start command", run.Cmd.Args) | |
161 | if serr := run.Cmd.Start(); serr != nil { | 158 | if serr := run.Cmd.Start(); serr != nil { |
162 | return nil, serr | 159 | return nil, serr |
163 | } | 160 | } |
@@ -169,7 +166,9 @@ func (r *Run) Wait() error { | |||
169 | } | 166 | } |
170 | 167 | ||
171 | func writeFifo(srcfile string, read io.Reader) error { | 168 | func writeFifo(srcfile string, read io.Reader) error { |
169 | fmt.Println("About to open", srcfile) | ||
172 | fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) | 170 | fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) |
171 | fmt.Println("Opened!!!", srcfile) | ||
173 | if err != nil { | 172 | if err != nil { |
174 | fifo.Close() | 173 | fifo.Close() |
175 | return err | 174 | return err |
diff --git a/xdelta3/go/src/xdelta/tgroup.go b/xdelta3/go/src/xdelta/tgroup.go index 1852bac..f94c03e 100644 --- a/xdelta3/go/src/xdelta/tgroup.go +++ b/xdelta3/go/src/xdelta/tgroup.go | |||
@@ -2,7 +2,6 @@ package xdelta | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "io" | ||
6 | "sync" | 5 | "sync" |
7 | "time" | 6 | "time" |
8 | ) | 7 | ) |
@@ -21,7 +20,7 @@ type Goroutine struct { | |||
21 | } | 20 | } |
22 | 21 | ||
23 | func NewTestGroup(r *Runner) (*TestGroup, Goroutine) { | 22 | func NewTestGroup(r *Runner) (*TestGroup, Goroutine) { |
24 | g := Goroutine{"main", make(chan error)} | 23 | g := Goroutine{"main", make(chan error, 1)} |
25 | wc := make(chan bool) | 24 | wc := make(chan bool) |
26 | tg := &TestGroup{Runner: r, running: []Goroutine{g}, waitChan: wc} | 25 | tg := &TestGroup{Runner: r, running: []Goroutine{g}, waitChan: wc} |
27 | go waitAll(tg, wc) | 26 | go waitAll(tg, wc) |
@@ -33,6 +32,7 @@ func (g *Goroutine) String() string { | |||
33 | } | 32 | } |
34 | 33 | ||
35 | func (g *Goroutine) OK() { | 34 | func (g *Goroutine) OK() { |
35 | fmt.Println("OK", g) | ||
36 | if g.errChan != nil { | 36 | if g.errChan != nil { |
37 | g.errChan <- nil | 37 | g.errChan <- nil |
38 | _ = <- g.errChan | 38 | _ = <- g.errChan |
@@ -41,7 +41,7 @@ func (g *Goroutine) OK() { | |||
41 | } | 41 | } |
42 | 42 | ||
43 | func (g *Goroutine) Panic(err error) { | 43 | func (g *Goroutine) Panic(err error) { |
44 | fmt.Println(g, err) | 44 | fmt.Println("PANIC", g, err) |
45 | if g.errChan != nil { | 45 | if g.errChan != nil { |
46 | g.errChan <- err | 46 | g.errChan <- err |
47 | _ = <- g.errChan | 47 | _ = <- g.errChan |
@@ -50,7 +50,7 @@ func (g *Goroutine) Panic(err error) { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | func (t *TestGroup) Go(name string, f func(Goroutine)) Goroutine { | 52 | func (t *TestGroup) Go(name string, f func(Goroutine)) Goroutine { |
53 | g := Goroutine{name, make(chan error)} | 53 | g := Goroutine{name, make(chan error, 1)} |
54 | t.Lock() | 54 | t.Lock() |
55 | t.running = append(t.running, g) | 55 | t.running = append(t.running, g) |
56 | t.Unlock() | 56 | t.Unlock() |
@@ -88,6 +88,10 @@ func waitAll(t *TestGroup, wc chan bool) { | |||
88 | t.Unlock() | 88 | t.Unlock() |
89 | break | 89 | break |
90 | } | 90 | } |
91 | // fmt.Println("----------------------------------------------------------------------") | ||
92 | // for _, r := range t.running { | ||
93 | // fmt.Println("Waiting for", r) | ||
94 | // } | ||
91 | runner := t.running[0] | 95 | runner := t.running[0] |
92 | t.running = t.running[1:] | 96 | t.running = t.running[1:] |
93 | t.Unlock() | 97 | t.Unlock() |
@@ -110,53 +114,3 @@ func waitAll(t *TestGroup, wc chan bool) { | |||
110 | } | 114 | } |
111 | wc <- true | 115 | wc <- true |
112 | } | 116 | } |
113 | |||
114 | type dualWriter struct { | ||
115 | e, d chan []byte | ||
116 | } | ||
117 | |||
118 | func (d *dualWriter) Write(p []byte) (int, error) { | ||
119 | if len(p) != 0 { | ||
120 | d.e <- p | ||
121 | d.d <- p | ||
122 | } | ||
123 | return len(p), nil | ||
124 | } | ||
125 | |||
126 | func (d *dualWriter) Close() error { | ||
127 | d.e <- nil | ||
128 | d.d <- nil | ||
129 | _ = <- d.e | ||
130 | _ = <- d.d | ||
131 | return nil | ||
132 | } | ||
133 | |||
134 | func newWriter(c chan []byte, a io.WriteCloser) func (Goroutine) { | ||
135 | return func (g Goroutine) { | ||
136 | for { | ||
137 | d := <- c | ||
138 | if d == nil { | ||
139 | if err := a.Close(); err != nil { | ||
140 | g.Panic(err) | ||
141 | } | ||
142 | c <- nil | ||
143 | g.OK() | ||
144 | return | ||
145 | } | ||
146 | if num, err := a.Write(d); err != nil { | ||
147 | g.Panic(err) | ||
148 | } else if num != len(d) { | ||
149 | g.Panic(fmt.Errorf("Invalid write: %v != %v", num, len(d))) | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
155 | func (t *TestGroup) NewDualWriter(a1, a2 io.WriteCloser) io.WriteCloser { | ||
156 | c1 := make(chan []byte) | ||
157 | c2 := make(chan []byte) | ||
158 | r := &dualWriter{c1, c2} | ||
159 | t.Go("writer0", newWriter(c1, a1)) | ||
160 | t.Go("writer1", newWriter(c2, a2)) | ||
161 | return r | ||
162 | } | ||