summaryrefslogtreecommitdiff
path: root/xdelta3/go/src/xdelta/test.go
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3/go/src/xdelta/test.go')
-rw-r--r--xdelta3/go/src/xdelta/test.go205
1 files changed, 205 insertions, 0 deletions
diff --git a/xdelta3/go/src/xdelta/test.go b/xdelta3/go/src/xdelta/test.go
new file mode 100644
index 0000000..9eb47f6
--- /dev/null
+++ b/xdelta3/go/src/xdelta/test.go
@@ -0,0 +1,205 @@
1package xdelta
2
3import (
4 "bufio"
5 "bytes"
6 "errors"
7 "fmt"
8 "io"
9 "io/ioutil"
10 "os"
11 "os/exec"
12 "path"
13 "sync/atomic"
14 "sync"
15
16 "golang.org/x/sys/unix"
17)
18
19var (
20 tmpDir = "/tmp"
21 srcSeq int64
22)
23
24type Program struct {
25 Path string
26}
27
28type Runner struct {
29 Testdir string
30}
31
32type TestGroup struct {
33 sync.WaitGroup
34}
35
36type Run struct {
37 Cmd exec.Cmd
38 Srcfile string
39 Stdin io.WriteCloser
40 Srcin io.WriteCloser
41 Stdout io.ReadCloser
42 Stderr io.ReadCloser
43}
44
45func (t *TestGroup) Panic(err error) {
46 t.Done() // For the caller
47 t.Wait()
48 panic(err)
49}
50
51func NewTestGroup() *TestGroup {
52 return &TestGroup{}
53}
54
55func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte {
56 c := make(chan []byte)
57 go func() {
58 t.Add(1)
59 //fmt.Println("Draining", desc)
60 if b, err := ioutil.ReadAll(f); err != nil {
61 t.Panic(err)
62 } else {
63 //fmt.Println("Draining", desc, "--got it")
64 c <- b
65 }
66 t.Done()
67 }()
68 return c
69}
70
71func (t *TestGroup) Empty(f io.ReadCloser, desc string) {
72 go func() {
73 t.Add(1)
74 s := bufio.NewScanner(f)
75 for s.Scan() {
76 os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n")))
77 }
78 if err := s.Err(); err != nil {
79 t.Panic(err)
80 }
81 t.Done()
82 }()
83}
84
85func (t *TestGroup) Write(what string, f io.WriteCloser, b []byte) {
86 //fmt.Println("Write (", what, ") ", len(b), "bytes")
87 if _, err := f.Write(b); err != nil {
88 t.Panic(errors.New(fmt.Sprint(what, ":", err)))
89 }
90 //fmt.Println("Write (", what, ") closing")
91 if err := f.Close(); err != nil {
92 t.Panic(errors.New(fmt.Sprint(what, ":", err)))
93 }
94}
95
96func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser) {
97 go func() {
98 t.Add(1)
99 _, err := io.Copy(w, r)
100 if err != nil {
101 t.Panic(err)
102 }
103 err = r.Close()
104 if err != nil {
105 t.Panic(err)
106 }
107 err = w.Close()
108 if err != nil {
109 t.Panic(err)
110 }
111 t.Done()
112 }()
113}
114
115func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) {
116 go func() {
117 t.Add(1)
118 b1 := make([]byte, blocksize)
119 b2 := make([]byte, blocksize)
120 var idx int64
121 for length > 0 {
122 c := blocksize
123 if length < blocksize {
124 c = int(length)
125 }
126 if _, err := io.ReadFull(r1, b1[0:c]); err != nil {
127 t.Panic(err)
128 }
129 if _, err := io.ReadFull(r2, b2[0:c]); err != nil {
130 t.Panic(err)
131 }
132 if bytes.Compare(b1[0:c], b2[0:c]) != 0 {
133 fmt.Println("B1 is", string(b1[0:c]))
134 fmt.Println("B2 is", string(b2[0:c]))
135 t.Panic(errors.New(fmt.Sprint("Bytes do not compare at ", idx)))
136 }
137 length -= int64(c)
138 idx += int64(c)
139 }
140 t.Done()
141 }()
142}
143
144func NewRunner() (*Runner, error) {
145 if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil {
146 return nil, err
147 } else {
148 return &Runner{dir}, nil
149 }
150}
151
152func (r *Runner) Cleanup() {
153 os.RemoveAll(r.Testdir)
154}
155
156func (r *Runner) Exec(p *Program, srcfifo bool, flags []string) (*Run, error) {
157 var err error
158 run := &Run{}
159 args := []string{p.Path}
160 if srcfifo {
161 num := atomic.AddInt64(&srcSeq, 1)
162 run.Srcfile = path.Join(r.Testdir, fmt.Sprint("source", num))
163 if err = unix.Mkfifo(run.Srcfile, 0600); err != nil {
164 return nil, err
165 }
166 // Because OpenFile blocks on the Fifo until the reader
167 // arrives, a pipe to defer open
168 read, write := io.Pipe()
169 run.Srcin = write
170
171 go writeFifo(run.Srcfile, read)
172 args = append(args, "-s")
173 args = append(args, run.Srcfile)
174 }
175 if run.Stdin, err = run.Cmd.StdinPipe(); err != nil {
176 return nil, err
177 }
178 if run.Stdout, err = run.Cmd.StdoutPipe(); err != nil {
179 return nil, err
180 }
181 if run.Stderr, err = run.Cmd.StderrPipe(); err != nil {
182 return nil, err
183 }
184
185 run.Cmd.Path = p.Path
186 run.Cmd.Args = append(args, flags...)
187 run.Cmd.Dir = r.Testdir
188 run.Cmd.Start()
189
190 return run, nil
191}
192
193func writeFifo(srcfile string, read io.Reader) error {
194 fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600)
195 if err != nil {
196 return err
197 }
198 if _, err := io.Copy(fifo, read); err != nil {
199 return err
200 }
201 if err := fifo.Close(); err != nil {
202 return err
203 }
204 return nil
205}