blob: e4bf92d0e73fbfcbf38ef600b0fbd707a166938d [file] [edit]
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2026 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
package zstd
import (
"bytes"
"crypto/rand"
"os/exec"
"strings"
"testing"
)
func TestCodecRoundtrip(t *testing.T) {
random := make([]byte, 32768)
if _, err := rand.Read(random); err != nil {
t.Fatal(err)
}
for _, tc := range []struct {
name string
data []byte
}{
{"empty", nil},
{"small", []byte("hello world")},
{"compressible", bytes.Repeat([]byte("mysql row contents"), 65536)},
{"incompressible", random},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
c := codec{}
encoded := c.Encode(tc.data, nil)
decoded, err := c.Decode(encoded, make([]byte, 0, len(tc.data)))
if err != nil || !bytes.Equal(decoded, tc.data) {
t.Fatalf("roundtrip error = %v, output length = %d", err, len(decoded))
}
})
}
}
func TestDriverDependencyBoundary(t *testing.T) {
goPath, err := exec.LookPath("go")
if err != nil {
t.Skipf("go toolchain unavailable: %v", err)
}
dependencies, err := exec.Command(goPath, "list", "-deps", "github.com/go-sql-driver/mysql").CombinedOutput()
if err != nil {
t.Fatalf("go list: %v\n%s", err, dependencies)
}
if strings.Contains(string(dependencies), "github.com/klauspost/compress") {
t.Fatal("importing the driver alone must not build klauspost/compress")
}
}
func TestCodecRejectsInvalidInput(t *testing.T) {
c := codec{}
data := bytes.Repeat([]byte("mysql"), 10000)
encoded := c.Encode(data, nil)
for _, tc := range []struct {
name string
src []byte
size int
}{
{"too much output", encoded, len(data) - 1},
{"truncated frame", encoded[:len(encoded)-1], len(data)},
{"invalid frame", []byte("invalid zstd frame"), len(data)},
} {
t.Run(tc.name, func(t *testing.T) {
if _, err := c.Decode(tc.src, make([]byte, 0, tc.size)); err == nil {
t.Fatal("invalid input was accepted")
}
// A decoder returned to the pool after failure must remain reusable.
decoded, err := c.Decode(encoded, make([]byte, 0, len(data)))
if err != nil || !bytes.Equal(decoded, data) {
t.Fatalf("reuse after failure: %v", err)
}
})
}
}