func benchmarkEncode(b *testing.B, enc func() io.WriteCloser, bs []byte) {
	size := int64(len(bs))
	b.SetBytes(size)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		w := enc()
		n, err := io.Copy(w, dummyBytesReader(bs))
		if err != nil {
			b.Fatal(err)
		}
		if n != size {
			b.Fatalf("wrote wrong amount %d != %d", n, size)
		}
		err = w.Close()
		if err != nil {
			b.Fatalf("close: %v", err)
		}
	}
	b.StopTimer()
}
benchmarkEncode benchmarks the speed at which bytes can be copied from
bs into writers created by enc.
package snappystream
import (
	"bytes"
	"crypto/rand"
	"io"
	"io/ioutil"
	"testing"
)
const TestFileSize = 10 << 20  
func dummyBytesReader(p []byte) io.Reader {
	return ioutil.NopCloser(bytes.NewReader(p))
}
func testWriteThenRead(t *testing.T, name string, bs []byte) {
	var buf bytes.Buffer
	w := NewWriter(&buf)
	n, err := io.Copy(w, dummyBytesReader(bs))
	if err != nil {
		t.Errorf("write %v: %v", name, err)
		return
	}
	if n != int64(len(bs)) {
		t.Errorf("write %v: wrote %d bytes (!= %d)", name, n, len(bs))
		return
	}
	enclen := buf.Len()
	r := NewReader(&buf, true)
	gotbs, err := ioutil.ReadAll(r)
	if err != nil {
		t.Errorf("read %v: %v", name, err)
		return
	}
	n = int64(len(gotbs))
	if n != int64(len(bs)) {
		t.Errorf("read %v: read %d bytes (!= %d)", name, n, len(bs))
		return
	}
	if !bytes.Equal(gotbs, bs) {
		t.Errorf("%v: unequal decompressed content", name)
		return
	}
	c := float64(len(bs)) / float64(enclen)
	t.Logf("%v compression ratio %.03g (%d byte reduction)", name, c, len(bs)-enclen)
}
func testBufferedWriteThenRead(t *testing.T, name string, bs []byte) {
	var buf bytes.Buffer
	w := NewBufferedWriter(&buf)
	n, err := io.Copy(w, dummyBytesReader(bs))
	if err != nil {
		t.Errorf("write %v: %v", name, err)
		return
	}
	if n != int64(len(bs)) {
		t.Errorf("write %v: wrote %d bytes (!= %d)", name, n, len(bs))
		return
	}
	err = w.Close()
	if err != nil {
		t.Errorf("close %v: %v", name, err)
		return
	}
	enclen := buf.Len()
	r := NewReader(&buf, true)
	gotbs, err := ioutil.ReadAll(r)
	if err != nil {
		t.Errorf("read %v: %v", name, err)
		return
	}
	n = int64(len(gotbs))
	if n != int64(len(bs)) {
		t.Errorf("read %v: read %d bytes (!= %d)", name, n, len(bs))
		return
	}
	if !bytes.Equal(gotbs, bs) {
		t.Errorf("%v: unequal decompressed content", name)
		return
	}
	c := float64(len(bs)) / float64(enclen)
	t.Logf("%v compression ratio %.03g (%d byte reduction)", name, c, len(bs)-enclen)
}
func TestWriterReader(t *testing.T) {
	testWriteThenRead(t, "simple", []byte("test"))
	testWriteThenRead(t, "manpage", testDataMan)
	testWriteThenRead(t, "json", testDataJSON)
	p := make([]byte, TestFileSize)
	testWriteThenRead(t, "constant", p)
	_, err := rand.Read(p)
	if err != nil {
		t.Fatal(err)
	}
	testWriteThenRead(t, "random", p)
}
func TestBufferedWriterReader(t *testing.T) {
	testBufferedWriteThenRead(t, "simple", []byte("test"))
	testBufferedWriteThenRead(t, "manpage", testDataMan)
	testBufferedWriteThenRead(t, "json", testDataJSON)
	p := make([]byte, TestFileSize)
	testBufferedWriteThenRead(t, "constant", p)
	_, err := rand.Read(p)
	if err != nil {
		t.Fatal(err)
	}
	testBufferedWriteThenRead(t, "random", p)
}
func TestWriterChunk(t *testing.T) {
	var buf bytes.Buffer
	in := make([]byte, 128000)
	w := NewWriter(&buf)
	r := NewReader(&buf, VerifyChecksum)
	n, err := w.Write(in)
	if err != nil {
		t.Fatalf(err.Error())
	}
	if n != len(in) {
		t.Fatalf("wrote wrong amount %d != %d", n, len(in))
	}
	out := make([]byte, len(in))
	n, err = io.ReadFull(r, out)
	if err != nil {
		t.Fatal(err)
	}
	if n != len(in) {
		t.Fatalf("read wrong amount %d != %d", n, len(in))
	}
	if !bytes.Equal(out, in) {
		t.Fatalf("bytes not equal %v != %v", out, in)
	}
}
func BenchmarkWriterManpage(b *testing.B) {
	benchmarkWriterBytes(b, testDataMan)
}
func BenchmarkBufferedWriterManpage(b *testing.B) {
	benchmarkBufferedWriterBytes(b, testDataMan)
}
func BenchmarkBufferedWriterManpageNoCopy(b *testing.B) {
	benchmarkBufferedWriterBytesNoCopy(b, testDataMan)
}
func BenchmarkWriterJSON(b *testing.B) {
	benchmarkWriterBytes(b, testDataJSON)
}
func BenchmarkBufferedWriterJSON(b *testing.B) {
	benchmarkBufferedWriterBytes(b, testDataJSON)
}
func BenchmarkBufferedWriterJSONNoCopy(b *testing.B) {
	benchmarkBufferedWriterBytesNoCopy(b, testDataJSON)
}
func BenchmarkWriterRandom(b *testing.B) {
	benchmarkWriterBytes(b, randBytes(b, TestFileSize))
}
func BenchmarkBufferedWriterRandom(b *testing.B) {
	benchmarkBufferedWriterBytes(b, randBytes(b, TestFileSize))
}
func BenchmarkBufferedWriterRandomNoCopy(b *testing.B) {
	benchmarkBufferedWriterBytesNoCopy(b, randBytes(b, TestFileSize))
}
func BenchmarkWriterConstant(b *testing.B) {
	benchmarkWriterBytes(b, make([]byte, TestFileSize))
}
func BenchmarkBufferedWriterConstant(b *testing.B) {
	benchmarkBufferedWriterBytes(b, make([]byte, TestFileSize))
}
func BenchmarkBufferedWriterConstantNoCopy(b *testing.B) {
	benchmarkBufferedWriterBytesNoCopy(b, make([]byte, TestFileSize))
}
func benchmarkWriterBytes(b *testing.B, p []byte) {
	enc := func() io.WriteCloser {
		return &nopWriteCloser{NewWriter(ioutil.Discard)}
	}
	benchmarkEncode(b, enc, p)
}
func benchmarkBufferedWriterBytes(b *testing.B, p []byte) {
	enc := func() io.WriteCloser {
		return NewBufferedWriter(ioutil.Discard)
	}
	benchmarkEncode(b, enc, p)
}
func benchmarkBufferedWriterBytesNoCopy(b *testing.B, p []byte) {
	enc := func() io.WriteCloser {
		return &writeCloserNoCopy{NewBufferedWriter(ioutil.Discard)}
	}
	benchmarkEncode(b, enc, p)
}