PR ada/81103
[official-gcc.git] / libgo / go / compress / flate / writer_test.go
blobc4d36aa37e9b6fcb743ddfb840134c7e14ed8363
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package flate
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "io/ioutil"
12 "math/rand"
13 "runtime"
14 "testing"
17 func BenchmarkEncode(b *testing.B) {
18 doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
19 b.StopTimer()
20 b.SetBytes(int64(n))
22 buf1 := make([]byte, n)
23 for i := 0; i < n; i += len(buf0) {
24 if len(buf0) > n-i {
25 buf0 = buf0[:n-i]
27 copy(buf1[i:], buf0)
29 buf0 = nil
30 w, err := NewWriter(ioutil.Discard, level)
31 if err != nil {
32 b.Fatal(err)
34 runtime.GC()
35 b.StartTimer()
36 for i := 0; i < b.N; i++ {
37 w.Reset(ioutil.Discard)
38 w.Write(buf1)
39 w.Close()
44 // errorWriter is a writer that fails after N writes.
45 type errorWriter struct {
46 N int
49 func (e *errorWriter) Write(b []byte) (int, error) {
50 if e.N <= 0 {
51 return 0, io.ErrClosedPipe
53 e.N--
54 return len(b), nil
57 // Test if errors from the underlying writer is passed upwards.
58 func TestWriteError(t *testing.T) {
59 t.Parallel()
60 buf := new(bytes.Buffer)
61 n := 65536
62 if !testing.Short() {
63 n *= 4
65 for i := 0; i < n; i++ {
66 fmt.Fprintf(buf, "asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i)
68 in := buf.Bytes()
69 // We create our own buffer to control number of writes.
70 copyBuffer := make([]byte, 128)
71 for l := 0; l < 10; l++ {
72 for fail := 1; fail <= 256; fail *= 2 {
73 // Fail after 'fail' writes
74 ew := &errorWriter{N: fail}
75 w, err := NewWriter(ew, l)
76 if err != nil {
77 t.Fatalf("NewWriter: level %d: %v", l, err)
79 n, err := io.CopyBuffer(w, struct{ io.Reader }{bytes.NewBuffer(in)}, copyBuffer)
80 if err == nil {
81 t.Fatalf("Level %d: Expected an error, writer was %#v", l, ew)
83 n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5})
84 if n2 != 0 {
85 t.Fatal("Level", l, "Expected 0 length write, got", n)
87 if err == nil {
88 t.Fatal("Level", l, "Expected an error")
90 err = w.Flush()
91 if err == nil {
92 t.Fatal("Level", l, "Expected an error on flush")
94 err = w.Close()
95 if err == nil {
96 t.Fatal("Level", l, "Expected an error on close")
99 w.Reset(ioutil.Discard)
100 n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6})
101 if err != nil {
102 t.Fatal("Level", l, "Got unexpected error after reset:", err)
104 if n2 == 0 {
105 t.Fatal("Level", l, "Got 0 length write, expected > 0")
107 if testing.Short() {
108 return
114 // Test if two runs produce identical results
115 // even when writing different sizes to the Writer.
116 func TestDeterministic(t *testing.T) {
117 t.Parallel()
118 for i := 0; i <= 9; i++ {
119 t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) })
121 t.Run("LM2", func(t *testing.T) { testDeterministic(-2, t) })
124 func testDeterministic(i int, t *testing.T) {
125 t.Parallel()
126 // Test so much we cross a good number of block boundaries.
127 var length = maxStoreBlockSize*30 + 500
128 if testing.Short() {
129 length /= 10
132 // Create a random, but compressible stream.
133 rng := rand.New(rand.NewSource(1))
134 t1 := make([]byte, length)
135 for i := range t1 {
136 t1[i] = byte(rng.Int63() & 7)
139 // Do our first encode.
140 var b1 bytes.Buffer
141 br := bytes.NewBuffer(t1)
142 w, err := NewWriter(&b1, i)
143 if err != nil {
144 t.Fatal(err)
146 // Use a very small prime sized buffer.
147 cbuf := make([]byte, 787)
148 _, err = io.CopyBuffer(w, struct{ io.Reader }{br}, cbuf)
149 if err != nil {
150 t.Fatal(err)
152 w.Close()
154 // We choose a different buffer size,
155 // bigger than a maximum block, and also a prime.
156 var b2 bytes.Buffer
157 cbuf = make([]byte, 81761)
158 br2 := bytes.NewBuffer(t1)
159 w2, err := NewWriter(&b2, i)
160 if err != nil {
161 t.Fatal(err)
163 _, err = io.CopyBuffer(w2, struct{ io.Reader }{br2}, cbuf)
164 if err != nil {
165 t.Fatal(err)
167 w2.Close()
169 b1b := b1.Bytes()
170 b2b := b2.Bytes()
172 if !bytes.Equal(b1b, b2b) {
173 t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b))