blob: 1b5d5f2658c51bcc02bdd10029aa3121c87213ba [file] [log] [blame] [edit]
package zstd
import (
"bytes"
"io"
"testing"
)
func failOnError(t *testing.T, msg string, err error) {
if err != nil {
t.Fatalf("%s: %s", msg, err)
}
}
func testCompressionDecompression(t *testing.T, dict []byte, payload []byte) {
var w bytes.Buffer
writer := NewWriterLevelDict(&w, DefaultCompression, dict)
_, err := writer.Write(payload)
failOnError(t, "Failed writing to compress object", err)
failOnError(t, "Failed to close compress object", writer.Close())
out := w.Bytes()
t.Logf("Compressed %v -> %v bytes", len(payload), len(out))
failOnError(t, "Failed compressing", err)
rr := bytes.NewReader(out)
// Check that we can decompress with Decompress()
decompressed, err := Decompress(nil, out)
failOnError(t, "Failed to decompress with Decompress()", err)
if string(payload) != string(decompressed) {
t.Fatalf("Payload did not match, lengths: %v & %v", len(payload), len(decompressed))
}
// Decompress
r := NewReaderDict(rr, dict)
dst := make([]byte, len(payload))
n, err := r.Read(dst)
if err != nil {
failOnError(t, "Failed to read for decompression", err)
}
dst = dst[:n]
if string(payload) != string(dst) { // Only print if we can print
if len(payload) < 100 && len(dst) < 100 {
t.Fatalf("Cannot compress and decompress: %s != %s", payload, dst)
} else {
t.Fatalf("Cannot compress and decompress (lengths: %v bytes & %v bytes)", len(payload), len(dst))
}
}
// Check EOF
n, err = r.Read(dst)
if err != io.EOF && len(dst) > 0 { // If we want 0 bytes, that should work
t.Fatalf("Error should have been EOF, was %s instead: (%v bytes read: %s)", err, n, dst[:n])
}
failOnError(t, "Failed to close decompress object", r.Close())
}
func TestResize(t *testing.T) {
if len(resize(nil, 129)) != 129 {
t.Fatalf("Cannot allocate new slice")
}
a := make([]byte, 1, 200)
b := resize(a, 129)
if &a[0] != &b[0] {
t.Fatalf("Address changed")
}
if len(b) != 129 {
t.Fatalf("Wrong size")
}
c := make([]byte, 5, 10)
d := resize(c, 129)
if len(d) != 129 {
t.Fatalf("Cannot allocate a new slice")
}
}
func TestStreamSimpleCompressionDecompression(t *testing.T) {
testCompressionDecompression(t, nil, []byte("Hello world!"))
}
func TestStreamEmptySlice(t *testing.T) {
testCompressionDecompression(t, nil, []byte{})
}
func TestZstdReaderLong(t *testing.T) {
var long bytes.Buffer
for i := 0; i < 10000; i++ {
long.Write([]byte("Hellow World!"))
}
testCompressionDecompression(t, nil, long.Bytes())
}
func TestStreamCompressionDecompression(t *testing.T) {
payload := []byte("Hello World!")
repeat := 10000
var intermediate bytes.Buffer
w := NewWriterLevel(&intermediate, 4)
for i := 0; i < repeat; i++ {
_, err := w.Write(payload)
failOnError(t, "Failed writing to compress object", err)
}
w.Close()
// Decompress
r := NewReader(&intermediate)
dst := make([]byte, len(payload))
for i := 0; i < repeat; i++ {
n, err := r.Read(dst)
failOnError(t, "Failed to decompress", err)
if n != len(payload) {
t.Fatalf("Did not read enough bytes: %v != %v", n, len(payload))
}
if string(dst) != string(payload) {
t.Fatalf("Did not read the same %s != %s", string(dst), string(payload))
}
}
// Check EOF
n, err := r.Read(dst)
if err != io.EOF {
t.Fatalf("Error should have been EOF, was %s instead: (%v bytes read: %s)", err, n, dst[:n])
}
failOnError(t, "Failed to close decompress object", r.Close())
}
func TestStreamRealPayload(t *testing.T) {
if raw == nil {
t.Skip(ErrNoPayloadEnv)
}
testCompressionDecompression(t, nil, raw)
}
func BenchmarkStreamCompression(b *testing.B) {
if raw == nil {
b.Fatal(ErrNoPayloadEnv)
}
var intermediate bytes.Buffer
w := NewWriter(&intermediate)
defer w.Close()
b.SetBytes(int64(len(raw)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := w.Write(raw)
if err != nil {
b.Fatalf("Failed writing to compress object: %s", err)
}
}
}
func BenchmarkStreamDecompression(b *testing.B) {
if raw == nil {
b.Fatal(ErrNoPayloadEnv)
}
compressed, err := Compress(nil, raw)
if err != nil {
b.Fatalf("Failed to compress: %s", err)
}
_, err = Decompress(nil, compressed)
if err != nil {
b.Fatalf("Problem: %s", err)
}
dst := make([]byte, len(raw))
b.SetBytes(int64(len(raw)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
rr := bytes.NewReader(compressed)
r := NewReader(rr)
_, err := r.Read(dst)
if err != nil {
b.Fatalf("Failed to decompress: %s", err)
}
}
}