diff options
author | yang.zhang <y0169.zhang@samsung.com> | 2016-05-18 11:25:47 +0800 |
---|---|---|
committer | yang.zhang <y0169.zhang@samsung.com> | 2016-05-18 11:27:16 +0800 |
commit | 41c06420b9ff028fd452cec19ac1412be665673f (patch) | |
tree | ece29e014e212b56654888fa3f95f50625164919 /go/src | |
parent | a96d62621beefe4aa20b696744be6325bc536fb6 (diff) | |
download | xdelta3-release-20160531.tar.gz xdelta3-release-20160531.tar.bz2 xdelta3-release-20160531.zip |
Imported upstream 3.0.8HEADsubmit/trunk/20191101.102136submit/trunk/20191030.112603submit/trunk/20191017.233826submit/trunk/20191017.111201submit/trunk/20190927.012842accepted/tools/devbase/tools/legacy/20240424.050617accepted/tools/devbase/tools/legacy/20240423.040635accepted/tools/devbase/tools/legacy/20240422.110744accepted/tizen/devbase/tools/20190927.044910spin-release-latestrelease-20161231release-20160930release-20160615release-20160531masterdevel_psk_20160727develaccepted/tools_devbase_tools_legacyaccepted/tizen_devbase_tools
Change-Id: I8423a2e4bed8a15b862b6b1ab6f6371c92e78b3f
Diffstat (limited to 'go/src')
-rw-r--r-- | go/src/regtest.go | 274 | ||||
-rw-r--r-- | go/src/xdelta/rstream.go | 71 | ||||
-rw-r--r-- | go/src/xdelta/run.go | 71 | ||||
-rw-r--r-- | go/src/xdelta/test.go | 164 | ||||
-rw-r--r-- | go/src/xdelta/tgroup.go | 97 |
5 files changed, 0 insertions, 677 deletions
diff --git a/go/src/regtest.go b/go/src/regtest.go deleted file mode 100644 index 9d91f69..0000000 --- a/go/src/regtest.go +++ /dev/null @@ -1,274 +0,0 @@ -package main - -import ( - "fmt" - "io" - "path" - "os" - "sort" - "time" - - "xdelta" -) - -const ( - xdataset = "/volume/home/jmacd/src/testdata" - xcompare = "/volume/home/jmacd/src/xdelta-devel/xdelta3/build/x86_64-pc-linux-gnu-m64/xoff64/xdelta3" - xdelta3 = "/volume/home/jmacd/src/xdelta-64bithash/xdelta3/build/x86_64-pc-linux-gnu-m64/usize64/xoff64/xdelta3" - seed = 1422253499919909358 -) - -type Config struct { - srcbuf_size int64 - window_size int64 - blocksize int -} - -func NewC() Config { - // TODO make these (and above) flags - return Config{1<<26, 1<<22, 1<<16} -} - -func (c Config) smokeTest(t *xdelta.TestGroup, p xdelta.Program) { - target := "Hello world!" - source := "Hello world, nice to meet you!" - - enc, err := t.Exec("encode", p, true, []string{"-e"}) - if err != nil { - t.Panic(err) - } - dec, err := t.Exec("decode", p, true, []string{"-d"}) - if err != nil { - t.Panic(err) - } - - encodeout := t.Drain(enc.Stdout, "encode.stdout") - decodeout := t.Drain(dec.Stdout, "decode.stdout") - - t.Empty(enc.Stderr, "encode") - t.Empty(dec.Stderr, "decode") - - t.TestWrite("encode.stdin", enc.Stdin, []byte(target)) - t.TestWrite("encode.srcin", enc.Srcin, []byte(source)) - - t.TestWrite("decode.stdin", dec.Stdin, <-encodeout) - t.TestWrite("decode.srcin", dec.Srcin, []byte(source)) - - if do := string(<-decodeout); do != target { - t.Panic(fmt.Errorf("It's not working! %s\n!=\n%s\n", do, target)) - } - t.Wait(enc, dec) -} - -type PairTest struct { - // Input - Config - program xdelta.Program - source, target string - - // Output - TestOutput -} - -type TestOutput struct { - encoded int64 - encDuration time.Duration - decDuration time.Duration - encSysDuration time.Duration - decSysDuration time.Duration -} - -func (to *TestOutput) Add(a TestOutput) { - to.encoded += a.encoded - to.encDuration += a.encDuration - to.decDuration += a.decDuration - to.encSysDuration += a.encSysDuration - to.decSysDuration += a.decSysDuration -} - -func (to *TestOutput) String() string { - return fmt.Sprintf("SIZE: %v\tT: %v\tTSYS: %v\tDT: %v\tDTSYS: %v", - to.encoded, to.encDuration, to.encSysDuration, to.decDuration, to.encSysDuration) -} - -// P is the test program, Q is the reference version. -func (cfg Config) datasetTest(t *xdelta.TestGroup, p, q xdelta.Program) { - dir, err := os.Open(xdataset) - if err != nil { - t.Panic(err) - } - dents, err := dir.Readdir(-1) - if err != nil { - t.Panic(err) - } - paths := make([]string, len(dents)) - var total int64 - for i, d := range dents { - if !d.Mode().IsRegular() { - continue - } - paths[i] = fmt.Sprint(xdataset, "/", d.Name()) - total += d.Size() - } - meansize := total / int64(len(dents)) - largest := uint(20) - for ; largest <= 31 && 1<<largest < meansize; largest++ {} - - sort.Strings(paths) - - testSum := map[uint]*TestOutput{} - compSum := map[uint]*TestOutput{} - - for _, in1 := range paths { - for _, in2 := range paths { - if in1 == in2 { continue } - - // 1/4, 1/2, and 1 of the power-of-2 rounded-up mean size - for b := largest - 2; b <= largest; b++ { - if _, has := testSum[b]; !has { - testSum[b] = &TestOutput{} - compSum[b] = &TestOutput{} - } - c1 := cfg - c1.srcbuf_size = 1<<b - ptest := &PairTest{c1, p, in1, in2, TestOutput{-1, 0, 0, 0, 0}} - ptest.datasetPairTest(t, 1<<b); - qtest := &PairTest{c1, q, in1, in2, TestOutput{-1, 0, 0, 0, 0}} - qtest.datasetPairTest(t, 1<<b) - - testSum[b].Add(ptest.TestOutput) - compSum[b].Add(qtest.TestOutput) - - fmt.Printf("%s, %s: %.2f%% %+d/%d\n\tE:%.2f%%/%s(%.2f%%/%s) D:%.2f%%/%s(%.2f%%/%s) [B=%d]\n", - path.Base(in1), path.Base(in2), - float64(ptest.encoded - qtest.encoded) * 100.0 / float64(qtest.encoded), - ptest.encoded - qtest.encoded, - qtest.encoded, - (ptest.encDuration - qtest.encDuration).Seconds() * 100.0 / qtest.encDuration.Seconds(), - qtest.encDuration, - (ptest.decDuration - qtest.decDuration).Seconds() * 100.0 / qtest.decDuration.Seconds(), - qtest.encDuration, - (ptest.encSysDuration - qtest.encSysDuration).Seconds() * 100.0 / qtest.encSysDuration.Seconds(), - qtest.encSysDuration, - (ptest.decSysDuration - qtest.decSysDuration).Seconds() * 100.0 / qtest.decSysDuration.Seconds(), - qtest.decSysDuration, - 1<<b) - } - } - } - var keys []uint - for k, _ := range testSum { - keys = append(keys, k) - } - for _, k := range keys { - fmt.Printf("B=%v\nTEST: %v\nCOMP: %v\n", 1<<k, testSum[k], compSum[k]) - } -} - -func (pt *PairTest) datasetPairTest(t *xdelta.TestGroup, meanSize int64) { - cfg := pt.Config - eargs := []string{"-e", fmt.Sprint("-B", cfg.srcbuf_size), // "-q", - fmt.Sprint("-W", cfg.window_size), "-s", pt.source, - "-I0", "-S", "none", pt.target} - enc, err := t.Exec("encode", pt.program, false, eargs) - if err != nil { - t.Panic(err) - } - - dargs := []string{"-dc", fmt.Sprint("-B", cfg.srcbuf_size), //"-q", - fmt.Sprint("-W", cfg.window_size), "-s", pt.source, - "-S", "none"} - - dec, err := t.Exec("decode", pt.program, false, dargs) - if err != nil { - t.Panic(err) - } - tgt_check, err := os.Open(pt.target) - if err != nil { - t.Panic(err) - } - tgt_info, err := tgt_check.Stat() - if err != nil { - t.Panic(err) - } - t.Empty(enc.Stderr, "encode") - t.Empty(dec.Stderr, "decode") - t.CopyStreams(enc.Stdout, dec.Stdin, &pt.encoded) - t.CompareStreams(dec.Stdout, tgt_check, tgt_info.Size()) - - t.Wait(enc, dec) - - pt.decDuration = dec.Cmd.ProcessState.UserTime() - pt.encDuration = enc.Cmd.ProcessState.UserTime() - pt.decSysDuration = dec.Cmd.ProcessState.SystemTime() - pt.encSysDuration = enc.Cmd.ProcessState.SystemTime() -} - -func (cfg Config) offsetTest(t *xdelta.TestGroup, p xdelta.Program, offset, length int64) { - eargs := []string{"-e", "-0", fmt.Sprint("-B", cfg.srcbuf_size), "-q", - fmt.Sprint("-W", cfg.window_size)} - enc, err := t.Exec("encode", p, true, eargs) - if err != nil { - t.Panic(err) - } - - dargs := []string{"-d", fmt.Sprint("-B", cfg.srcbuf_size), "-q", - fmt.Sprint("-W", cfg.window_size)} - dec, err := t.Exec("decode", p, true, dargs) - if err != nil { - t.Panic(err) - } - - // The pipe used to read the decoder output and compare - // against the target. - read, write := io.Pipe() - - t.Empty(enc.Stderr, "encode") - t.Empty(dec.Stderr, "decode") - - var encoded_size int64 - t.CopyStreams(enc.Stdout, dec.Stdin, &encoded_size) - t.CompareStreams(dec.Stdout, read, length) - - // The decoder output ("read", above) is compared with the - // test-provided output ("write", below). The following - // generates two identical inputs. - t.WriteRstreams("encode", seed, offset, length, enc.Srcin, enc.Stdin) - t.WriteRstreams("decode", seed, offset, length, dec.Srcin, write) - t.Wait(enc, dec) - - expect := cfg.srcbuf_size - offset - if float64(encoded_size) < (0.95 * float64(expect)) || - float64(encoded_size) > (1.05 * float64(expect)) { - t.Fail("encoded size should be ~=", expect, ", actual ", encoded_size) - } -} - -func main() { - r, err := xdelta.NewRunner() - if err != nil { - panic(err) - } - defer r.Cleanup() - - cfg := NewC() - - prog := xdelta.Program{xdelta3} - - r.RunTest("smoketest", func(t *xdelta.TestGroup) { cfg.smokeTest(t, prog) }) - - for i := uint(29); i <= 33; i += 1 { - // The arguments to offsetTest are offset, source - // window size, and file size. The source window size - // is (2 << i) and (in the 3.0x release branch) is - // limited to 2^31, so the the greatest value of i is - // 30. - cfg.srcbuf_size = 2 << i - r.RunTest(fmt.Sprint("offset", i), func(t *xdelta.TestGroup) { - cfg.offsetTest(t, prog, 1 << i, 3 << i) }) - } - - comp := xdelta.Program{xcompare} - - r.RunTest("dataset", func(t *xdelta.TestGroup) { cfg.datasetTest(t, prog, comp) }) -} diff --git a/go/src/xdelta/rstream.go b/go/src/xdelta/rstream.go deleted file mode 100644 index 99c3d17..0000000 --- a/go/src/xdelta/rstream.go +++ /dev/null @@ -1,71 +0,0 @@ -package xdelta - - -import ( - "io" - "math/rand" -) - -const ( - blocksize = 1<<17 -) - -func (t *TestGroup) WriteRstreams(desc string, seed, offset, len int64, - src, tgt io.WriteCloser) { - t.Go("src-write:"+desc, func (g *Goroutine) { - writeOne(g, seed, 0, len, tgt, false) - }) - t.Go("tgt-write:"+desc, func (g *Goroutine) { - writeOne(g, seed, offset, len, src, true) - }) -} - -func writeOne(g *Goroutine, seed, offset, len int64, stream io.WriteCloser, readall bool) { - if !readall { - // Allow the source-read to fail or block until the process terminates. - // This behavior is reserved for the decoder, which is not required to - // read the entire source. - g.OK() - } - if offset != 0 { - // Fill with other random data until the offset - if err := writeRand(g, rand.New(rand.NewSource(^seed)), offset, stream); err != nil { - g.Panic(err) - } - } - if err := writeRand(g, rand.New(rand.NewSource(seed)), - len - offset, stream); err != nil { - g.Panic(err) - } - if err := stream.Close(); err != nil { - g.Panic(err) - } - g.OK() -} - -func writeRand(g *Goroutine, r *rand.Rand, len int64, s io.Writer) error { - blk := make([]byte, blocksize) - for len > 0 { - fillRand(r, blk) - c := blocksize - if len < blocksize { - c = int(len) - } - if _, err := s.Write(blk[0:c]); err != nil { - return err - } - len -= int64(c) - } - return nil -} - -func fillRand(r *rand.Rand, blk []byte) { - for p := 0; p < len(blk); { - v := r.Int63() - for i := 7; i != 0 && p < len(blk); i-- { - blk[p] = byte(v) - p++ - v >>= 8 - } - } -} diff --git a/go/src/xdelta/run.go b/go/src/xdelta/run.go deleted file mode 100644 index 448fabe..0000000 --- a/go/src/xdelta/run.go +++ /dev/null @@ -1,71 +0,0 @@ -package xdelta - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" -) - -type Program struct { - Path string -} - -type Run struct { - Cmd exec.Cmd - Srcfile string - Stdin io.WriteCloser - Srcin io.WriteCloser - Stdout io.ReadCloser - Stderr io.ReadCloser -} - -type Runner struct { - Testdir string -} - -func (r *Run) Wait() error { - return r.Cmd.Wait() -} - -func NewRunner() (*Runner, error) { - if dir, err := ioutil.TempDir(tmpDir, "xrt"); err != nil { - return nil, err - } else { - return &Runner{dir}, nil - } -} - -func (r *Runner) newTestGroup(name string) (*TestGroup) { - tg := &TestGroup{Runner: r} - tg.WaitGroup.Add(1) - g0 := &Goroutine{tg, name, false} - tg.running = append(tg.running, g0) - tg.main = g0 - return tg -} - -func (r *Runner) Cleanup() { - os.RemoveAll(r.Testdir) -} - -func (r *Runner) RunTest(name string, f func (t *TestGroup)) { - t := r.newTestGroup(name) - c := make(chan interface{}) - go func() { - defer func() { - rec := recover() - c <- rec - }() - fmt.Println("Testing", name, "...") - f(t) - c <- nil - }() - rec := <- c - if t.errors == nil && rec == nil { - fmt.Println("Success:", name) - } else { - fmt.Println("FAILED:", name, t.errors, rec) - } -} diff --git a/go/src/xdelta/test.go b/go/src/xdelta/test.go deleted file mode 100644 index 7210698..0000000 --- a/go/src/xdelta/test.go +++ /dev/null @@ -1,164 +0,0 @@ -package xdelta - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "sync/atomic" - - "golang.org/x/sys/unix" -) - -var ( - tmpDir = "/tmp" - srcSeq int64 -) - -func (t *TestGroup) Drain(f io.ReadCloser, desc string) <-chan []byte { - c := make(chan []byte) - t.Go(desc, func(g *Goroutine) { - if b, err := ioutil.ReadAll(f); err != nil { - g.Panic(err) - } else { - c <- b - } - g.OK() - }) - return c -} - -func (t *TestGroup) Empty(f io.ReadCloser, desc string) *Goroutine { - return t.Go("empty:"+desc, func (g *Goroutine) { - s := bufio.NewScanner(f) - for s.Scan() { - os.Stderr.Write([]byte(fmt.Sprint(desc, ": ", s.Text(), "\n"))) - } - err := s.Err() - f.Close() - if err != nil { - g.Panic(err) - } - g.OK() - }) -} - -func (t *TestGroup) TestWrite(what string, f io.WriteCloser, b []byte) *Goroutine { - return t.Go("write", func(g *Goroutine) { - if _, err := f.Write(b); err != nil { - g.Panic(err) - } - if err := f.Close(); err != nil { - g.Panic(err) - } - g.OK() - }) -} - -func (t *TestGroup) CopyStreams(r io.ReadCloser, w io.WriteCloser, written *int64) *Goroutine { - return t.Go("copy", func(g *Goroutine) { - nwrite, err := io.Copy(w, r) - if err != nil { - g.Panic(err) - } - err = r.Close() - if err != nil { - g.Panic(err) - } - err = w.Close() - if err != nil { - g.Panic(err) - } - g.OK() - *written = nwrite - }) -} - -func (t *TestGroup) CompareStreams(r1 io.ReadCloser, r2 io.ReadCloser, length int64) *Goroutine { - return t.Go("compare", func(g *Goroutine) { - b1 := make([]byte, blocksize) - b2 := make([]byte, blocksize) - var idx int64 - for length > 0 { - c := blocksize - if length < blocksize { - c = int(length) - } - if _, err := io.ReadFull(r1, b1[0:c]); err != nil { - g.Panic(err) - } - if _, err := io.ReadFull(r2, b2[0:c]); err != nil { - g.Panic(err) - } - if bytes.Compare(b1[0:c], b2[0:c]) != 0 { - fmt.Println("B1 is", string(b1[0:c])) - fmt.Println("B2 is", string(b2[0:c])) - g.Panic(errors.New(fmt.Sprint("Bytes do not compare at ", idx))) - } - length -= int64(c) - idx += int64(c) - } - g.OK() - }) -} - -func (t *TestGroup) Exec(desc string, p Program, srcfifo bool, flags []string) (*Run, error) { - var err error - run := &Run{} - args := []string{p.Path} - if srcfifo { - num := atomic.AddInt64(&srcSeq, 1) - run.Srcfile = path.Join(t.Runner.Testdir, fmt.Sprint("source", num)) - if err = unix.Mkfifo(run.Srcfile, 0600); err != nil { - return nil, err - } - read, write := io.Pipe() - t.writeFifo(run.Srcfile, read) - run.Srcin = write - args = append(args, "-s") - args = append(args, run.Srcfile) - } - if run.Stdin, err = run.Cmd.StdinPipe(); err != nil { - return nil, err - } - if run.Stdout, err = run.Cmd.StdoutPipe(); err != nil { - return nil, err - } - if run.Stderr, err = run.Cmd.StderrPipe(); err != nil { - return nil, err - } - - run.Cmd.Path = p.Path - run.Cmd.Args = append(args, flags...) - run.Cmd.Dir = t.Runner.Testdir - if serr := run.Cmd.Start(); serr != nil { - return nil, serr - } - return run, nil -} - -func (t *TestGroup) Fail(v ...interface{}) { - panic(fmt.Sprintln(v...)) -} - -func (t *TestGroup) writeFifo(srcfile string, read io.Reader) *Goroutine { - return t.Go("compare", func(g *Goroutine) { - fifo, err := os.OpenFile(srcfile, os.O_WRONLY, 0600) - if err != nil { - fifo.Close() - g.Panic(err) - } - if _, err := io.Copy(fifo, read); err != nil { - fifo.Close() - g.Panic(err) - } - if err := fifo.Close(); err != nil { - g.Panic(err) - } - g.OK() - }) -} diff --git a/go/src/xdelta/tgroup.go b/go/src/xdelta/tgroup.go deleted file mode 100644 index 602b1e1..0000000 --- a/go/src/xdelta/tgroup.go +++ /dev/null @@ -1,97 +0,0 @@ -package xdelta - -import ( - "fmt" - "runtime" - "sync" -) - -type TestGroup struct { - *Runner - main *Goroutine - sync.Mutex - sync.WaitGroup - running []*Goroutine - errors []error - nonerrors []error // For tolerated / expected conditions -} - -type Goroutine struct { - *TestGroup - name string - done bool -} - -func (g *Goroutine) String() string { - return fmt.Sprint("[", g.name, "]") -} - -func (g *Goroutine) finish(err error) { - wait := false - tg := g.TestGroup - sbuf := make([]byte, 4096) - sbuf = sbuf[0:runtime.Stack(sbuf, false)] - if err != nil { - err = fmt.Errorf("%v:%v:%v", g.name, err, string(sbuf)) - } - tg.Lock() - if g.done { - if err != nil { - tg.nonerrors = append(tg.nonerrors, err) - } - } else { - wait = true - g.done = true - if err != nil { - tg.errors = append(tg.errors, err) - } - } - tg.Unlock() - if wait { - tg.WaitGroup.Done() - } -} - -func (g *Goroutine) OK() { - g.finish(nil) -} - -func (g *Goroutine) Panic(err error) { - g.finish(err) - if g != g.TestGroup.main { - runtime.Goexit() - } -} - -func (t *TestGroup) Main() *Goroutine { return t.main } - -func (t *TestGroup) Panic(err error) { t.Main().Panic(err) } - -func (t *TestGroup) Go(name string, f func(*Goroutine)) *Goroutine { - g := &Goroutine{t, name, false} - t.Lock() - t.WaitGroup.Add(1) - t.running = append(t.running, g) - t.Unlock() - go f(g) - return g -} - -func (t *TestGroup) Wait(procs... *Run) { - t.Main().OK() - t.WaitGroup.Wait() - for _, p := range procs { - if err := p.Wait(); err != nil { - t.errors = append(t.errors, err) - } - } - for _, err := range t.errors { - fmt.Println(":ERROR:", err) - } - for _, err := range t.nonerrors { - fmt.Println("(ERROR)", err) - } - if len(t.errors) != 0 { - t.Fail("Test failed with", len(t.errors), "errors") - } -} |