github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/klauspost/compress/flate/deflate_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Copyright (c) 2015 Klaus Post
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package flate
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"io"
    12  	"io/ioutil"
    13  	"reflect"
    14  	"strings"
    15  	"sync"
    16  	"testing"
    17  )
    18  
    19  type deflateTest struct {
    20  	in    []byte
    21  	level int
    22  	out   []byte
    23  }
    24  
    25  type deflateInflateTest struct {
    26  	in []byte
    27  }
    28  
    29  type reverseBitsTest struct {
    30  	in       uint16
    31  	bitCount uint8
    32  	out      uint16
    33  }
    34  
    35  var deflateTests = []*deflateTest{
    36  	{[]byte{}, 0, []byte{1, 0, 0, 255, 255}},
    37  	{[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
    38  	{[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
    39  	{[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
    40  
    41  	{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
    42  	{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
    43  	{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
    44  		[]byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255},
    45  	},
    46  	{[]byte{}, 1, []byte{1, 0, 0, 255, 255}},
    47  	{[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
    48  	{[]byte{0x11, 0x12}, BestCompression, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
    49  	{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, BestCompression, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
    50  	{[]byte{}, 9, []byte{1, 0, 0, 255, 255}},
    51  	{[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}},
    52  	{[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
    53  	{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
    54  }
    55  
    56  var deflateInflateTests = []*deflateInflateTest{
    57  	{[]byte{}},
    58  	{[]byte{0x11}},
    59  	{[]byte{0x11, 0x12}},
    60  	{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
    61  	{[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}},
    62  	{largeDataChunk()},
    63  }
    64  
    65  var reverseBitsTests = []*reverseBitsTest{
    66  	{1, 1, 1},
    67  	{1, 2, 2},
    68  	{1, 3, 4},
    69  	{1, 4, 8},
    70  	{1, 5, 16},
    71  	{17, 5, 17},
    72  	{257, 9, 257},
    73  	{29, 5, 23},
    74  }
    75  
    76  func largeDataChunk() []byte {
    77  	result := make([]byte, 100000)
    78  	for i := range result {
    79  		result[i] = byte(i * i & 0xFF)
    80  	}
    81  	return result
    82  }
    83  
    84  func TestCRCBulkOld(t *testing.T) {
    85  	for _, x := range deflateTests {
    86  		y := x.out
    87  		if len(y) >= minMatchLength {
    88  			y = append(y, y...)
    89  			for j := 4; j < len(y); j++ {
    90  				y := y[:j]
    91  				dst := make([]hash, len(y)-minMatchLength+1)
    92  				for i := range dst {
    93  					dst[i] = hash(i + 100)
    94  				}
    95  				oldBulkHash(y, dst)
    96  				for i, val := range dst {
    97  					got := val & hashMask
    98  					expect := oldHash(y[i:]) & hashMask
    99  					if got != expect && got == hash(i)+100 {
   100  						t.Errorf("Len:%d Index:%d, expected 0x%08x but not modified", len(y), i, expect)
   101  					} else if got != expect {
   102  						t.Errorf("Len:%d Index:%d, got 0x%08x expected:0x%08x", len(y), i, got, expect)
   103  					} else {
   104  						//t.Logf("Len:%d Index:%d OK (0x%08x)", len(y), i, got)
   105  					}
   106  				}
   107  			}
   108  		}
   109  	}
   110  }
   111  
   112  func TestDeflate(t *testing.T) {
   113  	for _, h := range deflateTests {
   114  		var buf bytes.Buffer
   115  		w, err := NewWriter(&buf, h.level)
   116  		if err != nil {
   117  			t.Errorf("NewWriter: %v", err)
   118  			continue
   119  		}
   120  		w.Write(h.in)
   121  		w.Close()
   122  		if !bytes.Equal(buf.Bytes(), h.out) {
   123  			t.Errorf("Deflate(%d, %x) = \n%#v, want \n%#v", h.level, h.in, buf.Bytes(), h.out)
   124  		}
   125  	}
   126  }
   127  
   128  // A sparseReader returns a stream consisting of 0s followed by 1<<16 1s.
   129  // This tests missing hash references in a very large input.
   130  type sparseReader struct {
   131  	l   int64
   132  	cur int64
   133  }
   134  
   135  func (r *sparseReader) Read(b []byte) (n int, err error) {
   136  	if r.cur >= r.l {
   137  		return 0, io.EOF
   138  	}
   139  	n = len(b)
   140  	cur := r.cur + int64(n)
   141  	if cur > r.l {
   142  		n -= int(cur - r.l)
   143  		cur = r.l
   144  	}
   145  	for i := range b[0:n] {
   146  		if r.cur+int64(i) >= r.l-1<<16 {
   147  			b[i] = 1
   148  		} else {
   149  			b[i] = 0
   150  		}
   151  	}
   152  	r.cur = cur
   153  	return
   154  }
   155  
   156  func TestVeryLongSparseChunk(t *testing.T) {
   157  	if testing.Short() {
   158  		t.Skip("skipping sparse chunk during short test")
   159  	}
   160  	w, err := NewWriter(ioutil.Discard, 1)
   161  	if err != nil {
   162  		t.Errorf("NewWriter: %v", err)
   163  		return
   164  	}
   165  	if _, err = io.Copy(w, &sparseReader{l: 23E8}); err != nil {
   166  		t.Errorf("Compress failed: %v", err)
   167  		return
   168  	}
   169  }
   170  
   171  type syncBuffer struct {
   172  	buf    bytes.Buffer
   173  	mu     sync.RWMutex
   174  	closed bool
   175  	ready  chan bool
   176  }
   177  
   178  func newSyncBuffer() *syncBuffer {
   179  	return &syncBuffer{ready: make(chan bool, 1)}
   180  }
   181  
   182  func (b *syncBuffer) Read(p []byte) (n int, err error) {
   183  	for {
   184  		b.mu.RLock()
   185  		n, err = b.buf.Read(p)
   186  		b.mu.RUnlock()
   187  		if n > 0 || b.closed {
   188  			return
   189  		}
   190  		<-b.ready
   191  	}
   192  }
   193  
   194  func (b *syncBuffer) signal() {
   195  	select {
   196  	case b.ready <- true:
   197  	default:
   198  	}
   199  }
   200  
   201  func (b *syncBuffer) Write(p []byte) (n int, err error) {
   202  	n, err = b.buf.Write(p)
   203  	b.signal()
   204  	return
   205  }
   206  
   207  func (b *syncBuffer) WriteMode() {
   208  	b.mu.Lock()
   209  }
   210  
   211  func (b *syncBuffer) ReadMode() {
   212  	b.mu.Unlock()
   213  	b.signal()
   214  }
   215  
   216  func (b *syncBuffer) Close() error {
   217  	b.closed = true
   218  	b.signal()
   219  	return nil
   220  }
   221  
   222  func testSync(t *testing.T, level int, input []byte, name string) {
   223  	if len(input) == 0 {
   224  		return
   225  	}
   226  
   227  	t.Logf("--testSync %d, %d, %s", level, len(input), name)
   228  	buf := newSyncBuffer()
   229  	buf1 := new(bytes.Buffer)
   230  	buf.WriteMode()
   231  	w, err := NewWriter(io.MultiWriter(buf, buf1), level)
   232  	if err != nil {
   233  		t.Errorf("NewWriter: %v", err)
   234  		return
   235  	}
   236  	r := NewReader(buf)
   237  
   238  	// Write half the input and read back.
   239  	for i := 0; i < 2; i++ {
   240  		var lo, hi int
   241  		if i == 0 {
   242  			lo, hi = 0, (len(input)+1)/2
   243  		} else {
   244  			lo, hi = (len(input)+1)/2, len(input)
   245  		}
   246  		t.Logf("#%d: write %d-%d", i, lo, hi)
   247  		if _, err := w.Write(input[lo:hi]); err != nil {
   248  			t.Errorf("testSync: write: %v", err)
   249  			return
   250  		}
   251  		if i == 0 {
   252  			if err := w.Flush(); err != nil {
   253  				t.Errorf("testSync: flush: %v", err)
   254  				return
   255  			}
   256  		} else {
   257  			if err := w.Close(); err != nil {
   258  				t.Errorf("testSync: close: %v", err)
   259  			}
   260  		}
   261  		buf.ReadMode()
   262  		out := make([]byte, hi-lo+1)
   263  		m, err := io.ReadAtLeast(r, out, hi-lo)
   264  		t.Logf("#%d: read %d", i, m)
   265  		if m != hi-lo || err != nil {
   266  			t.Errorf("testSync/%d (%d, %d, %s): read %d: %d, %v (%d left)", i, level, len(input), name, hi-lo, m, err, buf.buf.Len())
   267  			return
   268  		}
   269  		if !bytes.Equal(input[lo:hi], out[:hi-lo]) {
   270  			t.Errorf("testSync/%d: read wrong bytes: %x vs %x", i, input[lo:hi], out[:hi-lo])
   271  			return
   272  		}
   273  		// This test originally checked that after reading
   274  		// the first half of the input, there was nothing left
   275  		// in the read buffer (buf.buf.Len() != 0) but that is
   276  		// not necessarily the case: the write Flush may emit
   277  		// some extra framing bits that are not necessary
   278  		// to process to obtain the first half of the uncompressed
   279  		// data.  The test ran correctly most of the time, because
   280  		// the background goroutine had usually read even
   281  		// those extra bits by now, but it's not a useful thing to
   282  		// check.
   283  		buf.WriteMode()
   284  	}
   285  	buf.ReadMode()
   286  	out := make([]byte, 10)
   287  	if n, err := r.Read(out); n > 0 || err != io.EOF {
   288  		t.Errorf("testSync (%d, %d, %s): final Read: %d, %v (hex: %x)", level, len(input), name, n, err, out[0:n])
   289  	}
   290  	if buf.buf.Len() != 0 {
   291  		t.Errorf("testSync (%d, %d, %s): extra data at end", level, len(input), name)
   292  	}
   293  	r.Close()
   294  
   295  	// stream should work for ordinary reader too
   296  	r = NewReader(buf1)
   297  	out, err = ioutil.ReadAll(r)
   298  	if err != nil {
   299  		t.Errorf("testSync: read: %s", err)
   300  		return
   301  	}
   302  	r.Close()
   303  	if !bytes.Equal(input, out) {
   304  		t.Errorf("testSync: decompress(compress(data)) != data: level=%d input=%s", level, name)
   305  	}
   306  }
   307  
   308  func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) {
   309  	var buffer bytes.Buffer
   310  	w, err := NewWriter(&buffer, level)
   311  	if err != nil {
   312  		t.Errorf("NewWriter: %v", err)
   313  		return
   314  	}
   315  	w.Write(input)
   316  	w.Close()
   317  	if limit > 0 && buffer.Len() > limit {
   318  		t.Errorf("level: %d, len(compress(data)) = %d > limit = %d", level, buffer.Len(), limit)
   319  		return
   320  	}
   321  	if limit > 0 {
   322  		t.Logf("level: %d - Size:%.2f%%, %d b\n", level, float64(buffer.Len()*100)/float64(limit), buffer.Len())
   323  	}
   324  	r := NewReader(&buffer)
   325  	out, err := ioutil.ReadAll(r)
   326  	if err != nil {
   327  		t.Errorf("read: %s", err)
   328  		return
   329  	}
   330  	r.Close()
   331  	if !bytes.Equal(input, out) {
   332  		t.Errorf("decompress(compress(data)) != data: level=%d input=%s", level, name)
   333  		return
   334  	}
   335  	testSync(t, level, input, name)
   336  }
   337  
   338  func testToFromWithLimit(t *testing.T, input []byte, name string, limit [11]int) {
   339  	for i := 0; i < 10; i++ {
   340  		testToFromWithLevelAndLimit(t, i, input, name, limit[i])
   341  	}
   342  	testToFromWithLevelAndLimit(t, -2, input, name, limit[10])
   343  }
   344  
   345  func TestDeflateInflate(t *testing.T) {
   346  	for i, h := range deflateInflateTests {
   347  		testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [11]int{})
   348  	}
   349  }
   350  
   351  func TestReverseBits(t *testing.T) {
   352  	for _, h := range reverseBitsTests {
   353  		if v := reverseBits(h.in, h.bitCount); v != h.out {
   354  			t.Errorf("reverseBits(%v,%v) = %v, want %v",
   355  				h.in, h.bitCount, v, h.out)
   356  		}
   357  	}
   358  }
   359  
   360  type deflateInflateStringTest struct {
   361  	filename string
   362  	label    string
   363  	limit    [11]int // Number 11 is ConstantCompression
   364  }
   365  
   366  var deflateInflateStringTests = []deflateInflateStringTest{
   367  	{
   368  		"../testdata/e.txt",
   369  		"2.718281828...",
   370  		[...]int{100018, 67900, 50960, 51150, 50930, 50790, 50790, 50790, 50790, 50790, 43683 + 100},
   371  	},
   372  	{
   373  		"../testdata/Mark.Twain-Tom.Sawyer.txt",
   374  		"Mark.Twain-Tom.Sawyer",
   375  		[...]int{407330, 195000, 185361, 180974, 169160, 164476, 162936, 160506, 160295, 160295, 233460 + 100},
   376  	},
   377  }
   378  
   379  func TestDeflateInflateString(t *testing.T) {
   380  	for _, test := range deflateInflateStringTests {
   381  		gold, err := ioutil.ReadFile(test.filename)
   382  		if err != nil {
   383  			t.Error(err)
   384  		}
   385  		// Remove returns that may be present on Windows
   386  		neutral := strings.Map(func(r rune) rune {
   387  			if r != '\r' {
   388  				return r
   389  			}
   390  			return -1
   391  		}, string(gold))
   392  
   393  		testToFromWithLimit(t, []byte(neutral), test.label, test.limit)
   394  
   395  		if testing.Short() {
   396  			break
   397  		}
   398  	}
   399  }
   400  
   401  func TestReaderDict(t *testing.T) {
   402  	const (
   403  		dict = "hello world"
   404  		text = "hello again world"
   405  	)
   406  	var b bytes.Buffer
   407  	w, err := NewWriter(&b, 5)
   408  	if err != nil {
   409  		t.Fatalf("NewWriter: %v", err)
   410  	}
   411  	w.Write([]byte(dict))
   412  	w.Flush()
   413  	b.Reset()
   414  	w.Write([]byte(text))
   415  	w.Close()
   416  
   417  	r := NewReaderDict(&b, []byte(dict))
   418  	data, err := ioutil.ReadAll(r)
   419  	if err != nil {
   420  		t.Fatal(err)
   421  	}
   422  	if string(data) != "hello again world" {
   423  		t.Fatalf("read returned %q want %q", string(data), text)
   424  	}
   425  }
   426  
   427  func TestWriterDict(t *testing.T) {
   428  	const (
   429  		dict = "hello world Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
   430  		text = "hello world Lorem ipsum dolor sit amet"
   431  	)
   432  	// This test is sensitive to algorithm changes that skip
   433  	// data in favour of speed. Higher levels are less prone to this
   434  	// so we test level 4-9.
   435  	for l := 4; l < 9; l++ {
   436  		var b bytes.Buffer
   437  		w, err := NewWriter(&b, l)
   438  		if err != nil {
   439  			t.Fatalf("level %d, NewWriter: %v", l, err)
   440  		}
   441  		w.Write([]byte(dict))
   442  		w.Flush()
   443  		b.Reset()
   444  		w.Write([]byte(text))
   445  		w.Close()
   446  
   447  		var b1 bytes.Buffer
   448  		w, _ = NewWriterDict(&b1, l, []byte(dict))
   449  		w.Write([]byte(text))
   450  		w.Close()
   451  
   452  		if !bytes.Equal(b1.Bytes(), b.Bytes()) {
   453  			t.Errorf("level %d, writer wrote\n%v\n want\n%v", l, b1.Bytes(), b.Bytes())
   454  		}
   455  	}
   456  }
   457  
   458  // See http://code.google.com/p/go/issues/detail?id=2508
   459  func TestRegression2508(t *testing.T) {
   460  	if testing.Short() {
   461  		t.Logf("test disabled with -short")
   462  		return
   463  	}
   464  	w, err := NewWriter(ioutil.Discard, 1)
   465  	if err != nil {
   466  		t.Fatalf("NewWriter: %v", err)
   467  	}
   468  	buf := make([]byte, 1024)
   469  	for i := 0; i < 131072; i++ {
   470  		if _, err := w.Write(buf); err != nil {
   471  			t.Fatalf("writer failed: %v", err)
   472  		}
   473  	}
   474  	w.Close()
   475  }
   476  
   477  func TestWriterReset(t *testing.T) {
   478  	for level := -2; level <= 9; level++ {
   479  		if level == -1 {
   480  			level++
   481  		}
   482  		if testing.Short() && level > 1 {
   483  			break
   484  		}
   485  		w, err := NewWriter(ioutil.Discard, level)
   486  		if err != nil {
   487  			t.Fatalf("NewWriter: %v", err)
   488  		}
   489  		buf := []byte("hello world")
   490  		for i := 0; i < 1024; i++ {
   491  			w.Write(buf)
   492  		}
   493  		w.Reset(ioutil.Discard)
   494  
   495  		wref, err := NewWriter(ioutil.Discard, level)
   496  		if err != nil {
   497  			t.Fatalf("NewWriter: %v", err)
   498  		}
   499  
   500  		// DeepEqual doesn't compare functions.
   501  		w.d.fill, wref.d.fill = nil, nil
   502  		w.d.step, wref.d.step = nil, nil
   503  		w.d.bulkHasher, wref.d.bulkHasher = nil, nil
   504  		w.d.snap, wref.d.snap = nil, nil
   505  
   506  		// hashMatch is always overwritten when used.
   507  		copy(w.d.hashMatch[:], wref.d.hashMatch[:])
   508  		if w.d.tokens.n != 0 {
   509  			t.Errorf("level %d Writer not reset after Reset. %d tokens were present", level, w.d.tokens.n)
   510  		}
   511  		// As long as the length is 0, we don't care about the content.
   512  		w.d.tokens = wref.d.tokens
   513  
   514  		// We don't care if there are values in the window, as long as it is at d.index is 0
   515  		w.d.window = wref.d.window
   516  		if !reflect.DeepEqual(w, wref) {
   517  			t.Errorf("level %d Writer not reset after Reset", level)
   518  		}
   519  	}
   520  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, NoCompression) })
   521  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, DefaultCompression) })
   522  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, BestCompression) })
   523  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, ConstantCompression) })
   524  	dict := []byte("we are the world")
   525  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, NoCompression, dict) })
   526  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, DefaultCompression, dict) })
   527  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, BestCompression, dict) })
   528  	testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, ConstantCompression, dict) })
   529  }
   530  
   531  func testResetOutput(t *testing.T, newWriter func(w io.Writer) (*Writer, error)) {
   532  	buf := new(bytes.Buffer)
   533  	w, err := newWriter(buf)
   534  	if err != nil {
   535  		t.Fatalf("NewWriter: %v", err)
   536  	}
   537  	b := []byte("hello world")
   538  	for i := 0; i < 1024; i++ {
   539  		w.Write(b)
   540  	}
   541  	w.Close()
   542  	out1 := buf.Bytes()
   543  
   544  	buf2 := new(bytes.Buffer)
   545  	w.Reset(buf2)
   546  	for i := 0; i < 1024; i++ {
   547  		w.Write(b)
   548  	}
   549  	w.Close()
   550  	out2 := buf2.Bytes()
   551  
   552  	if len(out1) != len(out2) {
   553  		t.Errorf("got %d, expected %d bytes", len(out2), len(out1))
   554  	}
   555  	if bytes.Compare(out1, out2) != 0 {
   556  		mm := 0
   557  		for i, b := range out1[:len(out2)] {
   558  			if b != out2[i] {
   559  				t.Errorf("mismatch index %d: %02x, expected %02x", i, out2[i], b)
   560  			}
   561  			mm++
   562  			if mm == 10 {
   563  				t.Fatal("Stopping")
   564  			}
   565  		}
   566  	}
   567  	t.Logf("got %d bytes", len(out1))
   568  }
   569  
   570  // A writer that fails after N writes.
   571  type errorWriter struct {
   572  	N int
   573  }
   574  
   575  func (e *errorWriter) Write(b []byte) (int, error) {
   576  	if e.N <= 0 {
   577  		return 0, io.ErrClosedPipe
   578  	}
   579  	e.N--
   580  	return len(b), nil
   581  }
   582  
   583  // Test if errors from the underlying writer is passed upwards.
   584  func TestWriteError(t *testing.T) {
   585  	buf := new(bytes.Buffer)
   586  	for i := 0; i < 1024*1024; i++ {
   587  		buf.WriteString(fmt.Sprintf("asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i))
   588  	}
   589  	in := buf.Bytes()
   590  	for l := -2; l < 10; l++ {
   591  		for fail := 1; fail <= 512; fail *= 2 {
   592  			// Fail after 2 writes
   593  			ew := &errorWriter{N: fail}
   594  			w, err := NewWriter(ew, l)
   595  			if err != nil {
   596  				t.Errorf("NewWriter: level %d: %v", l, err)
   597  			}
   598  			n, err := io.Copy(w, bytes.NewBuffer(in))
   599  			if err == nil {
   600  				t.Errorf("Level %d: Expected an error, writer was %#v", l, ew)
   601  			}
   602  			n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5})
   603  			if n2 != 0 {
   604  				t.Error("Level", l, "Expected 0 length write, got", n)
   605  			}
   606  			if err == nil {
   607  				t.Error("Level", l, "Expected an error")
   608  			}
   609  			err = w.Flush()
   610  			if err == nil {
   611  				t.Error("Level", l, "Expected an error on close")
   612  			}
   613  			err = w.Close()
   614  			if err == nil {
   615  				t.Error("Level", l, "Expected an error on close")
   616  			}
   617  
   618  			w.Reset(ioutil.Discard)
   619  			n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6})
   620  			if err != nil {
   621  				t.Error("Level", l, "Got unexpected error after reset:", err)
   622  			}
   623  			if n2 == 0 {
   624  				t.Error("Level", l, "Got 0 length write, expected > 0")
   625  			}
   626  			if testing.Short() {
   627  				return
   628  			}
   629  		}
   630  	}
   631  
   632  }