github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/compress/zlib/writer_test.go (about)

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