diff options
Diffstat (limited to 'xdelta3/go/src/xdelta')
-rw-r--r-- | xdelta3/go/src/xdelta/rstream.go | 7 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/run.go | 49 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/test.go | 55 | ||||
-rw-r--r-- | xdelta3/go/src/xdelta/tgroup.go | 17 |
4 files changed, 79 insertions, 49 deletions
diff --git a/xdelta3/go/src/xdelta/rstream.go b/xdelta3/go/src/xdelta/rstream.go index 9481f22..99c3d17 100644 --- a/xdelta3/go/src/xdelta/rstream.go +++ b/xdelta3/go/src/xdelta/rstream.go | |||
@@ -3,7 +3,6 @@ package xdelta | |||
3 | 3 | ||
4 | import ( | 4 | import ( |
5 | "io" | 5 | "io" |
6 | "fmt" | ||
7 | "math/rand" | 6 | "math/rand" |
8 | ) | 7 | ) |
9 | 8 | ||
@@ -14,10 +13,10 @@ const ( | |||
14 | func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64, | 13 | func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64, |
15 | src, tgt io.WriteCloser) { | 14 | src, tgt io.WriteCloser) { |
16 | t.Go("src-write:"+desc, func (g *Goroutine) { | 15 | t.Go("src-write:"+desc, func (g *Goroutine) { |
17 | writeOne(g, seed, 0, len, src, false) | 16 | writeOne(g, seed, 0, len, tgt, false) |
18 | }) | 17 | }) |
19 | t.Go("tgt-write:"+desc, func (g *Goroutine) { | 18 | t.Go("tgt-write:"+desc, func (g *Goroutine) { |
20 | writeOne(g, seed, offset, len, tgt, true) | 19 | writeOne(g, seed, offset, len, src, true) |
21 | }) | 20 | }) |
22 | } | 21 | } |
23 | 22 | ||
@@ -30,12 +29,10 @@ func writeOne(g *Goroutine, seed, offset, len int64, stream io.WriteCloser, read | |||
30 | } | 29 | } |
31 | if offset != 0 { | 30 | if offset != 0 { |
32 | // Fill with other random data until the offset | 31 | // Fill with other random data until the offset |
33 | fmt.Println(g, "pre-offset case", offset) | ||
34 | if err := writeRand(g, rand.New(rand.NewSource(^seed)), offset, stream); err != nil { | 32 | if err := writeRand(g, rand.New(rand.NewSource(^seed)), offset, stream); err != nil { |
35 | g.Panic(err) | 33 | g.Panic(err) |
36 | } | 34 | } |
37 | } | 35 | } |
38 | fmt.Println(g, "offset case", len - offset) | ||
39 | if err := writeRand(g, rand.New(rand.NewSource(seed)), | 36 | if err := writeRand(g, rand.New(rand.NewSource(seed)), |
40 | len - offset, stream); err != nil { | 37 | len - offset, stream); err != nil { |
41 | g.Panic(err) | 38 | g.Panic(err) |
diff --git a/xdelta3/go/src/xdelta/run.go b/xdelta3/go/src/xdelta/run.go index f9b4185..3b07178 100644 --- a/xdelta3/go/src/xdelta/run.go +++ b/xdelta3/go/src/xdelta/run.go | |||
@@ -1,14 +1,34 @@ | |||
1 | package xdelta | 1 | package xdelta |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | ||
5 | "io" | ||
4 | "io/ioutil" | 6 | "io/ioutil" |
5 | "os" | 7 | "os" |
8 | "os/exec" | ||
6 | ) | 9 | ) |
7 | 10 | ||
11 | type Program struct { | ||
12 | Path string | ||
13 | } | ||
14 | |||
15 | type Run struct { | ||
16 | Cmd exec.Cmd | ||
17 | Srcfile string | ||
18 | Stdin io.WriteCloser | ||
19 | Srcin io.WriteCloser | ||
20 | Stdout io.ReadCloser | ||
21 | Stderr io.ReadCloser | ||
22 | } | ||
23 | |||
8 | type Runner struct { | 24 | type Runner struct { |
9 | Testdir string | 25 | Testdir string |
10 | } | 26 | } |
11 | 27 | ||
28 | func (r *Run) Wait() error { | ||
29 | return r.Cmd.Wait() | ||
30 | } | ||
31 | |||
12 | func NewRunner() (*Runner, error) { | 32 | func NewRunner() (*Runner, error) { |
13 | if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil { | 33 | if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil { |
14 | return nil, err | 34 | return nil, err |
@@ -17,6 +37,35 @@ func NewRunner() (*Runner, error) { | |||
17 | } | 37 | } |
18 | } | 38 | } |
19 | 39 | ||
40 | func (r *Runner) newTestGroup(name string) (*TestGroup) { | ||
41 | tg := &TestGroup{Runner: r} | ||
42 | tg.WaitGroup.Add(1) | ||
43 | g0 := &Goroutine{tg, name, false} | ||
44 | tg.running = append(tg.running, g0) | ||
45 | tg.main = g0 | ||
46 | return tg | ||
47 | } | ||
48 | |||
20 | func (r *Runner) Cleanup() { | 49 | func (r *Runner) Cleanup() { |
21 | os.RemoveAll(r.Testdir) | 50 | os.RemoveAll(r.Testdir) |
22 | } | 51 | } |
52 | |||
53 | func (r *Runner) RunTest(name string, f func (t *TestGroup)) { | ||
54 | t := r.newTestGroup(name) | ||
55 | var rec interface{} | ||
56 | defer func() { | ||
57 | if r := recover(); r != nil { | ||
58 | fmt.Println("PANIC in ", name, ": ", r) | ||
59 | rec = r | ||
60 | } else { | ||
61 | // Goexit | ||
62 | } | ||
63 | }() | ||
64 | fmt.Println("Testing", name, "...") | ||
65 | f(t) | ||
66 | if t.errors == nil && rec == nil { | ||
67 | fmt.Println("Success:", name) | ||
68 | } else { | ||
69 | fmt.Println("FAILED:", name, t.errors, rec) | ||
70 | } | ||
71 | } | ||
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go index 00f3dd7..bab66f3 100644 --- a/xdelta3/go/src/xdelta/test.go +++ b/xdelta3/go/src/xdelta/test.go | |||
@@ -8,7 +8,6 @@ import ( | |||
8 | "io" | 8 | "io" |
9 | "io/ioutil" | 9 | "io/ioutil" |
10 | "os" | 10 | "os" |
11 | "os/exec" | ||
12 | "path" | 11 | "path" |
13 | "sync/atomic" | 12 | "sync/atomic" |
14 | 13 | ||
@@ -20,19 +19,6 @@ var ( | |||
20 | srcSeq int64 | 19 | srcSeq int64 |
21 | ) | 20 | ) |
22 | 21 | ||
23 | type Program struct { | ||
24 | Path string | ||
25 | } | ||
26 | |||
27 | type Run struct { | ||
28 | Cmd exec.Cmd | ||
29 | Srcfile string | ||
30 | Stdin io.WriteCloser | ||
31 | Srcin io.WriteCloser | ||
32 | Stdout io.ReadCloser | ||
33 | Stderr io.ReadCloser | ||
34 | } | ||
35 | |||
36 | func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte { | 22 | func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte { |
37 | c := make(chan []byte) | 23 | c := make(chan []byte) |
38 | t.Go(desc, func(g *Goroutine) { | 24 | t.Go(desc, func(g *Goroutine) { |
@@ -71,9 +57,9 @@ func TestWrite(what string, f io.WriteCloser, b []byte) error { | |||
71 | return nil | 57 | return nil |
72 | } | 58 | } |
73 | 59 | ||
74 | func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) *Goroutine { | 60 | func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser, written *int64) *Goroutine { |
75 | return t.Go("copy", func(g *Goroutine) { | 61 | return t.Go("copy", func(g *Goroutine) { |
76 | _, err := io.Copy(w, r) | 62 | nwrite, err := io.Copy(w, r) |
77 | if err != nil { | 63 | if err != nil { |
78 | g.Panic(err) | 64 | g.Panic(err) |
79 | } | 65 | } |
@@ -86,6 +72,7 @@ func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) *Goroutine { | |||
86 | g.Panic(err) | 72 | g.Panic(err) |
87 | } | 73 | } |
88 | g.OK() | 74 | g.OK() |
75 | *written = nwrite | ||
89 | }) | 76 | }) |
90 | } | 77 | } |
91 | 78 | ||
@@ -127,12 +114,9 @@ func (t *TestGroup) Exec(desc string, p *Program, srcfifo bool, flags []string) | |||
127 | if err = unix.Mkfifo(run.Srcfile, 0600); err != nil { | 114 | if err = unix.Mkfifo(run.Srcfile, 0600); err != nil { |
128 | return nil, err | 115 | return nil, err |
129 | } | 116 | } |
130 | // Because OpenFile blocks on the Fifo until the reader | ||
131 | // arrives, a pipe to defer open | ||
132 | read, write := io.Pipe() | 117 | read, write := io.Pipe() |
118 | t.writeFifo(run.Srcfile, read) | ||
133 | run.Srcin = write | 119 | run.Srcin = write |
134 | |||
135 | go writeFifo(run.Srcfile, read) | ||
136 | args = append(args, "-s") | 120 | args = append(args, "-s") |
137 | args = append(args, run.Srcfile) | 121 | args = append(args, run.Srcfile) |
138 | } | 122 | } |
@@ -156,19 +140,24 @@ func (t *TestGroup) Exec(desc string, p *Program, srcfifo bool, flags []string) | |||
156 | return run, nil | 140 | return run, nil |
157 | } | 141 | } |
158 | 142 | ||
159 | func (r *Run) Wait() error { | 143 | func (t *TestGroup) Fail(v ...interface{}) { |
160 | return r.Cmd.Wait() | 144 | panic(fmt.Sprintln(v...)) |
161 | } | 145 | } |
162 | 146 | ||
163 | func writeFifo(srcfile string, read io.Reader) error { | 147 | func (t *TestGroup) writeFifo(srcfile string, read io.Reader) *Goroutine { |
164 | fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) | 148 | return t.Go("compare", func(g *Goroutine) { |
165 | if err != nil { | 149 | fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) |
166 | fifo.Close() | 150 | if err != nil { |
167 | return err | 151 | fifo.Close() |
168 | } | 152 | g.Panic(err) |
169 | if _, err := io.Copy(fifo, read); err != nil { | 153 | } |
170 | fifo.Close() | 154 | if _, err := io.Copy(fifo, read); err != nil { |
171 | return err | 155 | fifo.Close() |
172 | } | 156 | g.Panic(err) |
173 | return fifo.Close() | 157 | } |
158 | if err := fifo.Close(); err != nil { | ||
159 | g.Panic(err) | ||
160 | } | ||
161 | g.OK() | ||
162 | }) | ||
174 | } | 163 | } |
diff --git a/xdelta3/go/src/xdelta/tgroup.go b/xdelta3/go/src/xdelta/tgroup.go index 7f6c875..0a3b41b 100644 --- a/xdelta3/go/src/xdelta/tgroup.go +++ b/xdelta3/go/src/xdelta/tgroup.go | |||
@@ -2,11 +2,13 @@ package xdelta | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "runtime" | ||
5 | "sync" | 6 | "sync" |
6 | ) | 7 | ) |
7 | 8 | ||
8 | type TestGroup struct { | 9 | type TestGroup struct { |
9 | *Runner | 10 | *Runner |
11 | main *Goroutine | ||
10 | sync.Mutex | 12 | sync.Mutex |
11 | sync.WaitGroup | 13 | sync.WaitGroup |
12 | running []*Goroutine | 14 | running []*Goroutine |
@@ -20,14 +22,6 @@ type Goroutine struct { | |||
20 | done bool | 22 | done bool |
21 | } | 23 | } |
22 | 24 | ||
23 | func NewTestGroup(r *Runner) (*TestGroup, *Goroutine) { | ||
24 | tg := &TestGroup{Runner: r} | ||
25 | tg.WaitGroup.Add(1) | ||
26 | g0 := &Goroutine{tg, "main", false} | ||
27 | tg.running = append(tg.running, g0) | ||
28 | return tg, g0 | ||
29 | } | ||
30 | |||
31 | func (g *Goroutine) String() string { | 25 | func (g *Goroutine) String() string { |
32 | return fmt.Sprint("[", g.name, "]") | 26 | return fmt.Sprint("[", g.name, "]") |
33 | } | 27 | } |
@@ -59,9 +53,11 @@ func (g *Goroutine) OK() { | |||
59 | 53 | ||
60 | func (g *Goroutine) Panic(err error) { | 54 | func (g *Goroutine) Panic(err error) { |
61 | g.finish(err) | 55 | g.finish(err) |
62 | select {} | 56 | runtime.Goexit() |
63 | } | 57 | } |
64 | 58 | ||
59 | func (t *TestGroup) Main() *Goroutine { return t.main } | ||
60 | |||
65 | func (t *TestGroup) Go(name string, f func(*Goroutine)) *Goroutine { | 61 | func (t *TestGroup) Go(name string, f func(*Goroutine)) *Goroutine { |
66 | g := &Goroutine{t, name, false} | 62 | g := &Goroutine{t, name, false} |
67 | t.Lock() | 63 | t.Lock() |
@@ -87,7 +83,6 @@ func (t *TestGroup) Wait(self *Goroutine, procs... *Run) { | |||
87 | fmt.Println("(ERROR)", err) | 83 | fmt.Println("(ERROR)", err) |
88 | } | 84 | } |
89 | if len(t.errors) != 0 { | 85 | if len(t.errors) != 0 { |
90 | panic(fmt.Sprintf("Test failed with", len(t.errors), "errors")) | 86 | t.Fail("Test failed with", len(t.errors), "errors") |
91 | } | 87 | } |
92 | } | 88 | } |
93 | |||