gcc/ChangeLog:
[official-gcc.git] / libgo / go / compress / zlib / writer_test.go
blobd5019740783f16b4a5864d04b721489d43ba068b
1 // Copyright 2009 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 zlib
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "io"
12 "io/ioutil"
13 "os"
14 "testing"
17 var filenames = []string{
18 "../testdata/gettysburg.txt",
19 "../testdata/e.txt",
20 "../testdata/pi.txt",
23 var data = []string{
24 "test a reasonable sized string that can be compressed",
27 // Tests that compressing and then decompressing the given file at the given compression level and dictionary
28 // yields equivalent bytes to the original file.
29 func testFileLevelDict(t *testing.T, fn string, level int, d string) {
30 // Read the file, as golden output.
31 golden, err := os.Open(fn)
32 if err != nil {
33 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
34 return
36 defer golden.Close()
37 b0, err0 := ioutil.ReadAll(golden)
38 if err0 != nil {
39 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err0)
40 return
42 testLevelDict(t, fn, b0, level, d)
45 func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) {
46 // Make dictionary, if given.
47 var dict []byte
48 if d != "" {
49 dict = []byte(d)
52 // Push data through a pipe that compresses at the write end, and decompresses at the read end.
53 piper, pipew := io.Pipe()
54 defer piper.Close()
55 go func() {
56 defer pipew.Close()
57 zlibw, err := NewWriterLevelDict(pipew, level, dict)
58 if err != nil {
59 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
60 return
62 defer zlibw.Close()
63 _, err = zlibw.Write(b0)
64 if err != nil {
65 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
66 return
68 }()
69 zlibr, err := NewReaderDict(piper, dict)
70 if err != nil {
71 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
72 return
74 defer zlibr.Close()
76 // Compare the decompressed data.
77 b1, err1 := ioutil.ReadAll(zlibr)
78 if err1 != nil {
79 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err1)
80 return
82 if len(b0) != len(b1) {
83 t.Errorf("%s (level=%d, dict=%q): length mismatch %d versus %d", fn, level, d, len(b0), len(b1))
84 return
86 for i := 0; i < len(b0); i++ {
87 if b0[i] != b1[i] {
88 t.Errorf("%s (level=%d, dict=%q): mismatch at %d, 0x%02x versus 0x%02x\n", fn, level, d, i, b0[i], b1[i])
89 return
94 func testFileLevelDictReset(t *testing.T, fn string, level int, dict []byte) {
95 var b0 []byte
96 var err error
97 if fn != "" {
98 b0, err = ioutil.ReadFile(fn)
99 if err != nil {
100 t.Errorf("%s (level=%d): %v", fn, level, err)
101 return
105 // Compress once.
106 buf := new(bytes.Buffer)
107 var zlibw *Writer
108 if dict == nil {
109 zlibw, err = NewWriterLevel(buf, level)
110 } else {
111 zlibw, err = NewWriterLevelDict(buf, level, dict)
113 if err == nil {
114 _, err = zlibw.Write(b0)
116 if err == nil {
117 err = zlibw.Close()
119 if err != nil {
120 t.Errorf("%s (level=%d): %v", fn, level, err)
121 return
123 out := buf.String()
125 // Reset and compress again.
126 buf2 := new(bytes.Buffer)
127 zlibw.Reset(buf2)
128 _, err = zlibw.Write(b0)
129 if err == nil {
130 err = zlibw.Close()
132 if err != nil {
133 t.Errorf("%s (level=%d): %v", fn, level, err)
134 return
136 out2 := buf2.String()
138 if out2 != out {
139 t.Errorf("%s (level=%d): different output after reset (got %d bytes, expected %d",
140 fn, level, len(out2), len(out))
144 func TestWriter(t *testing.T) {
145 for i, s := range data {
146 b := []byte(s)
147 tag := fmt.Sprintf("#%d", i)
148 testLevelDict(t, tag, b, DefaultCompression, "")
149 testLevelDict(t, tag, b, NoCompression, "")
150 testLevelDict(t, tag, b, HuffmanOnly, "")
151 for level := BestSpeed; level <= BestCompression; level++ {
152 testLevelDict(t, tag, b, level, "")
157 func TestWriterBig(t *testing.T) {
158 for i, fn := range filenames {
159 testFileLevelDict(t, fn, DefaultCompression, "")
160 testFileLevelDict(t, fn, NoCompression, "")
161 testFileLevelDict(t, fn, HuffmanOnly, "")
162 for level := BestSpeed; level <= BestCompression; level++ {
163 testFileLevelDict(t, fn, level, "")
164 if level >= 1 && testing.Short() && testenv.Builder() == "" {
165 break
168 if i == 0 && testing.Short() && testenv.Builder() == "" {
169 break
174 func TestWriterDict(t *testing.T) {
175 const dictionary = "0123456789."
176 for i, fn := range filenames {
177 testFileLevelDict(t, fn, DefaultCompression, dictionary)
178 testFileLevelDict(t, fn, NoCompression, dictionary)
179 testFileLevelDict(t, fn, HuffmanOnly, dictionary)
180 for level := BestSpeed; level <= BestCompression; level++ {
181 testFileLevelDict(t, fn, level, dictionary)
182 if level >= 1 && testing.Short() && testenv.Builder() == "" {
183 break
186 if i == 0 && testing.Short() && testenv.Builder() == "" {
187 break
192 func TestWriterReset(t *testing.T) {
193 const dictionary = "0123456789."
194 for _, fn := range filenames {
195 testFileLevelDictReset(t, fn, NoCompression, nil)
196 testFileLevelDictReset(t, fn, DefaultCompression, nil)
197 testFileLevelDictReset(t, fn, HuffmanOnly, nil)
198 testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary))
199 testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary))
200 testFileLevelDictReset(t, fn, HuffmanOnly, []byte(dictionary))
201 if testing.Short() {
202 break
204 for level := BestSpeed; level <= BestCompression; level++ {
205 testFileLevelDictReset(t, fn, level, nil)
210 func TestWriterDictIsUsed(t *testing.T) {
211 var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
212 var buf bytes.Buffer
213 compressor, err := NewWriterLevelDict(&buf, BestCompression, input)
214 if err != nil {
215 t.Errorf("error in NewWriterLevelDict: %s", err)
216 return
218 compressor.Write(input)
219 compressor.Close()
220 const expectedMaxSize = 25
221 output := buf.Bytes()
222 if len(output) > expectedMaxSize {
223 t.Errorf("result too large (got %d, want <= %d bytes). Is the dictionary being used?", len(output), expectedMaxSize)