mirror of
https://github.com/rancher/steve.git
synced 2025-09-23 12:29:09 +00:00
163
pkg/sqlcache/db/encoding_test.go
Normal file
163
pkg/sqlcache/db/encoding_test.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var random = rand.New(rand.NewSource(0))
|
||||
|
||||
func TestEquality(t *testing.T) {
|
||||
testObject := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
Annotations: map[string]string{"annotation": "test"},
|
||||
Labels: map[string]string{"label": "test"},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{{
|
||||
Name: "test",
|
||||
Image: "testimage",
|
||||
VolumeMounts: []corev1.VolumeMount{{
|
||||
Name: "test",
|
||||
MountPath: "/test",
|
||||
}},
|
||||
}},
|
||||
Volumes: []corev1.Volume{{
|
||||
Name: "test",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
encoding encoding
|
||||
}{
|
||||
{name: "gob", encoding: &gobEncoding{}},
|
||||
{name: "json", encoding: &jsonEncoding{}},
|
||||
{name: "gob+gz", encoding: gzipped(&gobEncoding{})},
|
||||
{name: "json+gz", encoding: gzipped(&jsonEncoding{})},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
if err := tt.encoding.Encode(&buf, testObject); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var dest *corev1.Pod
|
||||
if err := tt.encoding.Decode(bytes.NewReader(buf.Bytes()), &dest); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, testObject, dest)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncodings(b *testing.B) {
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
// a single entry map with 10K zero characters should account for ~10KB ConfigMap size,
|
||||
Data: generateTestData(10000),
|
||||
}
|
||||
pod := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
Annotations: map[string]string{"annotation": "test"},
|
||||
Labels: map[string]string{"label": "test"},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{{
|
||||
Name: "test",
|
||||
Image: "testimage",
|
||||
VolumeMounts: []corev1.VolumeMount{{
|
||||
Name: "test",
|
||||
MountPath: "/test",
|
||||
}},
|
||||
}},
|
||||
Volumes: []corev1.Volume{{
|
||||
Name: "test",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
encoding encoding
|
||||
testObject any
|
||||
}{
|
||||
{name: "gob", encoding: &gobEncoding{}},
|
||||
{name: "json", encoding: &jsonEncoding{}},
|
||||
{name: "gob+gzip", encoding: gzipped(&gobEncoding{})},
|
||||
{name: "json+gzip", encoding: gzipped(&jsonEncoding{})},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
for objType, testObject := range map[string]any{
|
||||
"10KB-configmap": cm,
|
||||
"pod": pod,
|
||||
} {
|
||||
b.Run(tt.name+"-"+objType, func(b *testing.B) {
|
||||
b.Run("encoding", func(b *testing.B) {
|
||||
for b.Loop() {
|
||||
w := new(discardWriter)
|
||||
if err := tt.encoding.Encode(w, testObject); err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
b.ReportMetric(float64(w.count), "bytes")
|
||||
}
|
||||
})
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := tt.encoding.Encode(&buf, testObject); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
serialized := buf.Bytes()
|
||||
b.Run("decoding", func(b *testing.B) {
|
||||
var dest corev1.ConfigMap
|
||||
for b.Loop() {
|
||||
if err := tt.encoding.Decode(bytes.NewReader(serialized), &dest); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type discardWriter struct {
|
||||
count int
|
||||
}
|
||||
|
||||
func (d *discardWriter) Write(p []byte) (int, error) {
|
||||
n, err := io.Discard.Write(p)
|
||||
d.count += n
|
||||
return n, err
|
||||
}
|
||||
|
||||
// single-entry map, whose value is a randomly-generated string of n size
|
||||
func generateTestData(n int) map[string]string {
|
||||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letters[random.Int63()%int64(len(letters))]
|
||||
}
|
||||
return map[string]string{
|
||||
"data": string(b),
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user