summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xdelta3/go/src/regtest.go148
-rw-r--r--xdelta3/go/src/xdelta/rstream.go12
-rw-r--r--xdelta3/go/src/xdelta/test.go99
3 files changed, 146 insertions, 113 deletions
diff --git a/xdelta3/go/src/regtest.go b/xdelta3/go/src/regtest.go
index 52547e1..1798f40 100644
--- a/xdelta3/go/src/regtest.go
+++ b/xdelta3/go/src/regtest.go
@@ -1,12 +1,9 @@
1package main 1package main
2 2
3import ( 3import (
4 "bufio" 4 "errors"
5 "bytes"
6 "fmt" 5 "fmt"
7 "io" 6 "io"
8 "io/ioutil"
9 "os"
10 7
11 "xdelta" 8 "xdelta"
12) 9)
@@ -14,150 +11,83 @@ import (
14const ( 11const (
15 blocksize = 1<<16 12 blocksize = 1<<16
16 winsize = 1<<26 13 winsize = 1<<26
17 prog = "/Users/jmacd/src/xdelta/xdelta3/build/m64/64size-64off/xdelta3" 14 xdelta3 = "/volume/home/jmacd/src/xdelta-64bithash/xdelta3/build/x86_64-pc-linux-gnu-m64/usize64/xoff64/xdelta3"
18 seed = 1422253499919909358 15 seed = 1422253499919909358
19) 16)
20 17
21func drain(f io.ReadCloser) <-chan []byte { 18func smokeTest(r *xdelta.Runner, t *xdelta.TestGroup, p *xdelta.Program) {
22 c := make(chan []byte) 19 t.Add(1)
23 go func() {
24 if b, err := ioutil.ReadAll(f); err != nil {
25 panic(err)
26 } else {
27 c <- b
28 }
29 }()
30 return c
31}
32
33func empty(f io.ReadCloser, desc string) {
34 go func() {
35 s := bufio.NewScanner(f)
36 for s.Scan() {
37 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n")))
38 }
39 if err := s.Err(); err != nil {
40 fmt.Println("error reading input:", err)
41 }
42 }()
43}
44
45func write(f io.WriteCloser, b []byte) {
46 if _, err := f.Write(b); err != nil {
47 panic(err)
48 }
49 if err := f.Close(); err != nil {
50 panic(err)
51 }
52}
53
54func smokeTest(r *xdelta.Runner, p *xdelta.Program) {
55 target := "Hello world!" 20 target := "Hello world!"
56 source := "Hello world, nice to meet you!" 21 source := "Hello world, nice to meet you!"
57 22
58 run, err := r.Exec(p, true, []string{"-e"}) 23 run, err := r.Exec(p, true, []string{"-e"})
59 if err != nil { 24 if err != nil {
60 panic(err) 25 t.Panic(err)
61 } 26 }
62 encodeout := drain(run.Stdout) 27 encodeout := t.Drain(run.Stdout)
63 empty(run.Stderr, "encode") 28 t.Empty(run.Stderr, "encode")
64 29
65 write(run.Stdin, []byte(target)) 30 t.Write("encode.stdin", run.Stdin, []byte(target))
66 write(run.Srcin, []byte(source)) 31 t.Write("encode.stdout", run.Srcin, []byte(source))
67 32
68 if err := run.Cmd.Wait(); err != nil { 33 if err := run.Cmd.Wait(); err != nil {
69 panic(err) 34 t.Panic(err)
70 } 35 }
71 36
72 run, err = r.Exec(p, true, []string{"-d"}) 37 run, err = r.Exec(p, true, []string{"-d"})
73 if err != nil { 38 if err != nil {
74 panic(err) 39 t.Panic(err)
75 } 40 }
76 41
77 decodeout := drain(run.Stdout) 42 decodeout := t.Drain(run.Stdout)
78 empty(run.Stderr, "decode") 43 t.Empty(run.Stderr, "decode")
79 44
80 write(run.Stdin, <-encodeout) 45 t.Write("decode.stdin", run.Stdin, <-encodeout)
81 write(run.Srcin, []byte(source)) 46 t.Write("decode.stdout", run.Srcin, []byte(source))
82 47
83 if err := run.Cmd.Wait(); err != nil { 48 if err := run.Cmd.Wait(); err != nil {
84 panic(err) 49 t.Panic(err)
85 } 50 }
86 51
87 if string(<-decodeout) != target { 52 if string(<-decodeout) != target {
88 panic("It's not working!!!") 53 t.Panic(errors.New("It's not working!!!"))
89 } 54 }
55 t.Done()
90} 56}
91 57
92func copyStreams(r io.ReadCloser, w io.WriteCloser) { 58func offsetTest(r *xdelta.Runner, t *xdelta.TestGroup, p *xdelta.Program, offset, bufsize, length int64) {
93 _, err := io.Copy(w, r) 59 t.Add(1)
60 eargs := []string{"-e", "-1", "-n", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)}
61 enc, err := r.Exec(p, true, eargs)
94 if err != nil { 62 if err != nil {
95 panic(err) 63 t.Panic(err)
96 } 64 }
97 err = r.Close() 65 dargs := []string{"-d", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)}
66 dec, err := r.Exec(p, true, dargs)
98 if err != nil { 67 if err != nil {
99 panic(err) 68 t.Panic(err)
100 }
101 err = w.Close()
102 if err != nil {
103 panic(err)
104 }
105}
106
107func compareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) {
108 b1 := make([]byte, blocksize)
109 b2 := make([]byte, blocksize)
110 var idx int64
111 for length > 0 {
112 c := blocksize
113 if length < blocksize {
114 c = int(length)
115 }
116 if _, err := io.ReadFull(r1, b1[0:c]); err != nil {
117 panic(err)
118 }
119 if _, err := io.ReadFull(r2, b2[0:c]); err != nil {
120 panic(err)
121 }
122 if bytes.Compare(b1[0:c], b2[0:c]) != 0 {
123 fmt.Println("B1 is", string(b1[0:c]))
124 fmt.Println("B2 is", string(b2[0:c]))
125 panic(fmt.Sprint("Bytes do not compare at ", idx))
126 }
127 length -= int64(c)
128 idx += int64(c)
129 }
130}
131
132func offsetTest(r *xdelta.Runner, p *xdelta.Program, offset, bufsize, length int64) {
133 enc, err := r.Exec(p, true, []string{"-e", "-1", "-n", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)})
134 if err != nil {
135 panic(err)
136 }
137 dec, err := r.Exec(p, true, []string{"-d", fmt.Sprint("-B", bufsize), "-vv", fmt.Sprint("-W", winsize)})
138 if err != nil {
139 panic(err)
140 } 69 }
141 70
142 read, write := io.Pipe() 71 read, write := io.Pipe()
143 72
144 go copyStreams(enc.Stdout, dec.Stdin) 73 t.CopyStreams(enc.Stdout, dec.Stdin)
145 go compareStreams(dec.Stdout, read, length) 74 t.CompareStreams(dec.Stdout, read, length)
146 75
147 empty(enc.Stderr, "encode") 76 t.Empty(enc.Stderr, "encode")
148 empty(dec.Stderr, "decode") 77 t.Empty(dec.Stderr, "decode")
149 78
150 // TODO: seems possible to use one WriteRstreams call to generate 79 // TODO: seems possible to use one WriteRstreams call to generate
151 // the source and target for both encoder and decoder. Why not? 80 // the source and target for both encoder and decoder. Why not?
152 xdelta.WriteRstreams(seed, offset, length, enc.Srcin, enc.Stdin) 81 xdelta.WriteRstreams(t, seed, offset, length, enc.Srcin, enc. Stdin)
153 xdelta.WriteRstreams(seed, offset, length, dec.Srcin, write) 82 xdelta.WriteRstreams(t, seed, offset, length, dec.Srcin, write)
154 83
155 if err := enc.Cmd.Wait(); err != nil { 84 if err := enc.Cmd.Wait(); err != nil {
156 panic(err) 85 t.Panic(err)
157 } 86 }
158 if err := dec.Cmd.Wait(); err != nil { 87 if err := dec.Cmd.Wait(); err != nil {
159 panic(err) 88 t.Panic(err)
160 } 89 }
90 t.Done()
161} 91}
162 92
163func main() { 93func main() {
@@ -167,9 +97,11 @@ func main() {
167 } 97 }
168 defer r.Cleanup() 98 defer r.Cleanup()
169 99
170 prog := &xdelta.Program{prog} 100 prog := &xdelta.Program{xdelta3}
101
102 smokeTest(r, xdelta.NewTestGroup(), prog)
171 103
172 smokeTest(r, prog) 104 offsetTest(r, xdelta.NewTestGroup(), prog, 1 << 8, 1 << 9, 1 << 10)
173 105
174 offsetTest(r, prog, 1 << 31, 1 << 32, 1 << 33) 106 //offsetTest(r, prog, 1 << 31, 1 << 32, 1 << 33)
175} 107}
diff --git a/xdelta3/go/src/xdelta/rstream.go b/xdelta3/go/src/xdelta/rstream.go
index 1d56031..3e7265f 100644
--- a/xdelta3/go/src/xdelta/rstream.go
+++ b/xdelta3/go/src/xdelta/rstream.go
@@ -7,16 +7,17 @@ import (
7) 7)
8 8
9const ( 9const (
10 blocksize = 16380 // A factor of 7 10 blocksize = 16380
11) 11)
12 12
13func WriteRstreams(seed, offset, len int64, 13func WriteRstreams(t *TestGroup, seed, offset, len int64,
14 first, second io.WriteCloser) { 14 first, second io.WriteCloser) {
15 go writeOne(seed, 0, len, first) 15 go writeOne(t, seed, 0, len, first)
16 go writeOne(seed, offset, len, second) 16 go writeOne(t, seed, offset, len, second)
17} 17}
18 18
19func writeOne(seed, offset, len int64, stream io.WriteCloser) error { 19func writeOne(t *TestGroup, seed, offset, len int64, stream io.WriteCloser) error {
20 t.WaitGroup.Add(1)
20 if offset != 0 { 21 if offset != 0 {
21 // Fill with other random data until the offset 22 // Fill with other random data until the offset
22 if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil { 23 if err := writeRand(rand.New(rand.NewSource(^seed)), offset, stream); err != nil {
@@ -27,6 +28,7 @@ func writeOne(seed, offset, len int64, stream io.WriteCloser) error {
27 len - offset, stream); err != nil { 28 len - offset, stream); err != nil {
28 return err 29 return err
29 } 30 }
31 t.WaitGroup.Done()
30 return stream.Close() 32 return stream.Close()
31} 33}
32 34
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go
index 3143dfa..50ddeae 100644
--- a/xdelta3/go/src/xdelta/test.go
+++ b/xdelta3/go/src/xdelta/test.go
@@ -1,6 +1,9 @@
1package xdelta 1package xdelta
2 2
3import ( 3import (
4 "bufio"
5 "bytes"
6 "errors"
4 "fmt" 7 "fmt"
5 "io" 8 "io"
6 "io/ioutil" 9 "io/ioutil"
@@ -8,6 +11,7 @@ import (
8 "os/exec" 11 "os/exec"
9 "path" 12 "path"
10 "sync/atomic" 13 "sync/atomic"
14 "sync"
11 15
12 "golang.org/x/sys/unix" 16 "golang.org/x/sys/unix"
13) 17)
@@ -25,6 +29,10 @@ type Runner struct {
25 Testdir string 29 Testdir string
26} 30}
27 31
32type TestGroup struct {
33 sync.WaitGroup
34}
35
28type Run struct { 36type Run struct {
29 Cmd exec.Cmd 37 Cmd exec.Cmd
30 Srcfile string 38 Srcfile string
@@ -34,6 +42,97 @@ type Run struct {
34 Stderr io.ReadCloser 42 Stderr io.ReadCloser
35} 43}
36 44
45func (t *TestGroup) Panic(err error) {
46 t.WaitGroup.Done() // For the caller
47 t.WaitGroup.Wait()
48 panic(err)
49}
50
51func NewTestGroup() *TestGroup {
52 return &TestGroup{}
53}
54
55func (t *TestGroup) Drain(f io.ReadCloser) <-chan []byte {
56 c := make(chan []byte)
57 go func() {
58 t.WaitGroup.Add(1)
59 if b, err := ioutil.ReadAll(f); err != nil {
60 t.Panic(err)
61 } else {
62 c <- b
63 }
64 t.WaitGroup.Done()
65 }()
66 return c
67}
68
69func (t *TestGroup) Empty(f io.ReadCloser, desc string) {
70 go func() {
71 t.WaitGroup.Add(1)
72 s := bufio.NewScanner(f)
73 for s.Scan() {
74 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n")))
75 }
76 if err := s.Err(); err != nil {
77 t.Panic(err)
78 }
79 t.WaitGroup.Done()
80 }()
81}
82
83func (t *TestGroup) Write(what string, f io.WriteCloser, b []byte) {
84 if _, err := f.Write(b); err != nil {
85 t.Panic(errors.New(fmt.Sprint(what, ":", err)))
86 }
87 if err := f.Close(); err != nil {
88 t.Panic(errors.New(fmt.Sprint(what, ":", err)))
89 }
90}
91
92func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) {
93 t.Add(1)
94 _, err := io.Copy(w, r)
95 if err != nil {
96 t.Panic(err)
97 }
98 err = r.Close()
99 if err != nil {
100 t.Panic(err)
101 }
102 err = w.Close()
103 if err != nil {
104 t.Panic(err)
105 }
106 t.Done()
107}
108
109func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) {
110 t.Add(1)
111 b1 := make([]byte, blocksize)
112 b2 := make([]byte, blocksize)
113 var idx int64
114 for length > 0 {
115 c := blocksize
116 if length < blocksize {
117 c = int(length)
118 }
119 if _, err := io.ReadFull(r1, b1[0:c]); err != nil {
120 t.Panic(err)
121 }
122 if _, err := io.ReadFull(r2, b2[0:c]); err != nil {
123 t.Panic(err)
124 }
125 if bytes.Compare(b1[0:c], b2[0:c]) != 0 {
126 fmt.Println("B1 is", string(b1[0:c]))
127 fmt.Println("B2 is", string(b2[0:c]))
128 t.Panic(errors.New(fmt.Sprint("Bytes do not compare at ", idx)))
129 }
130 length -= int64(c)
131 idx += int64(c)
132 }
133 t.Done()
134}
135
37func NewRunner() (*Runner, error) { 136func NewRunner() (*Runner, error) {
38 if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil { 137 if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil {
39 return nil, err 138 return nil, err