aboutsummaryrefslogtreecommitdiff
path: root/src/compress/flate/deflate_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/compress/flate/deflate_test.go')
-rw-r--r--src/compress/flate/deflate_test.go81
1 files changed, 69 insertions, 12 deletions
diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go
index 49a0345fd1..6fc5abf4d5 100644
--- a/src/compress/flate/deflate_test.go
+++ b/src/compress/flate/deflate_test.go
@@ -11,6 +11,7 @@ import (
"internal/testenv"
"io"
"io/ioutil"
+ "math/rand"
"reflect"
"runtime/debug"
"sync"
@@ -156,7 +157,7 @@ func TestVeryLongSparseChunk(t *testing.T) {
if testing.Short() {
t.Skip("skipping sparse chunk during short test")
}
- w, err := NewWriter(ioutil.Discard, 1)
+ w, err := NewWriter(io.Discard, 1)
if err != nil {
t.Errorf("NewWriter: %v", err)
return
@@ -293,7 +294,7 @@ func testSync(t *testing.T, level int, input []byte, name string) {
// stream should work for ordinary reader too
r = NewReader(buf1)
- out, err = ioutil.ReadAll(r)
+ out, err = io.ReadAll(r)
if err != nil {
t.Errorf("testSync: read: %s", err)
return
@@ -321,7 +322,7 @@ func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name str
t.Logf("level: %d, size:%.2f%%, %d b\n", level, float64(buffer.Len()*100)/float64(limit), buffer.Len())
}
r := NewReader(&buffer)
- out, err := ioutil.ReadAll(r)
+ out, err := io.ReadAll(r)
if err != nil {
t.Errorf("read: %s", err)
return
@@ -414,7 +415,7 @@ func TestReaderDict(t *testing.T) {
w.Close()
r := NewReaderDict(&b, []byte(dict))
- data, err := ioutil.ReadAll(r)
+ data, err := io.ReadAll(r)
if err != nil {
t.Fatal(err)
}
@@ -455,7 +456,7 @@ func TestRegression2508(t *testing.T) {
t.Logf("test disabled with -short")
return
}
- w, err := NewWriter(ioutil.Discard, 1)
+ w, err := NewWriter(io.Discard, 1)
if err != nil {
t.Fatalf("NewWriter: %v", err)
}
@@ -474,7 +475,7 @@ func TestWriterReset(t *testing.T) {
if testing.Short() && level > 1 {
break
}
- w, err := NewWriter(ioutil.Discard, level)
+ w, err := NewWriter(io.Discard, level)
if err != nil {
t.Fatalf("NewWriter: %v", err)
}
@@ -486,9 +487,9 @@ func TestWriterReset(t *testing.T) {
for i := 0; i < n; i++ {
w.Write(buf)
}
- w.Reset(ioutil.Discard)
+ w.Reset(io.Discard)
- wref, err := NewWriter(ioutil.Discard, level)
+ wref, err := NewWriter(io.Discard, level)
if err != nil {
t.Fatalf("NewWriter: %v", err)
}
@@ -653,7 +654,7 @@ func TestBestSpeed(t *testing.T) {
}
r := NewReader(buf)
- got, err := ioutil.ReadAll(r)
+ got, err := io.ReadAll(r)
if err != nil {
t.Errorf("i=%d, firstN=%d, flush=%t: ReadAll: %v", i, firstN, flush, err)
continue
@@ -880,7 +881,7 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) {
}
r := NewReader(buf)
- dst, err := ioutil.ReadAll(r)
+ dst, err := io.ReadAll(r)
r.Close()
if err != nil {
report("ReadAll: ", err)
@@ -896,6 +897,62 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) {
}
}
+func TestBestSpeedShiftOffsets(t *testing.T) {
+ // Test if shiftoffsets properly preserves matches and resets out-of-range matches
+ // seen in https://github.com/golang/go/issues/4142
+ enc := newDeflateFast()
+
+ // testData may not generate internal matches.
+ testData := make([]byte, 32)
+ rng := rand.New(rand.NewSource(0))
+ for i := range testData {
+ testData[i] = byte(rng.Uint32())
+ }
+
+ // Encode the testdata with clean state.
+ // Second part should pick up matches from the first block.
+ wantFirstTokens := len(enc.encode(nil, testData))
+ wantSecondTokens := len(enc.encode(nil, testData))
+
+ if wantFirstTokens <= wantSecondTokens {
+ t.Fatalf("test needs matches between inputs to be generated")
+ }
+ // Forward the current indicator to before wraparound.
+ enc.cur = bufferReset - int32(len(testData))
+
+ // Part 1 before wrap, should match clean state.
+ got := len(enc.encode(nil, testData))
+ if wantFirstTokens != got {
+ t.Errorf("got %d, want %d tokens", got, wantFirstTokens)
+ }
+
+ // Verify we are about to wrap.
+ if enc.cur != bufferReset {
+ t.Errorf("got %d, want e.cur to be at bufferReset (%d)", enc.cur, bufferReset)
+ }
+
+ // Part 2 should match clean state as well even if wrapped.
+ got = len(enc.encode(nil, testData))
+ if wantSecondTokens != got {
+ t.Errorf("got %d, want %d token", got, wantSecondTokens)
+ }
+
+ // Verify that we wrapped.
+ if enc.cur >= bufferReset {
+ t.Errorf("want e.cur to be < bufferReset (%d), got %d", bufferReset, enc.cur)
+ }
+
+ // Forward the current buffer, leaving the matches at the bottom.
+ enc.cur = bufferReset
+ enc.shiftOffsets()
+
+ // Ensure that no matches were picked up.
+ got = len(enc.encode(nil, testData))
+ if wantFirstTokens != got {
+ t.Errorf("got %d, want %d tokens", got, wantFirstTokens)
+ }
+}
+
func TestMaxStackSize(t *testing.T) {
// This test must not run in parallel with other tests as debug.SetMaxStack
// affects all goroutines.
@@ -911,7 +968,7 @@ func TestMaxStackSize(t *testing.T) {
wg.Add(1)
go func(level int) {
defer wg.Done()
- zw, err := NewWriter(ioutil.Discard, level)
+ zw, err := NewWriter(io.Discard, level)
if err != nil {
t.Errorf("level %d, NewWriter() = %v, want nil", level, err)
}
@@ -921,7 +978,7 @@ func TestMaxStackSize(t *testing.T) {
if err := zw.Close(); err != nil {
t.Errorf("level %d, Close() = %v, want nil", level, err)
}
- zw.Reset(ioutil.Discard)
+ zw.Reset(io.Discard)
}(level)
}
}