prometheus/util/compression/compression_test.go
Bartlomiej Plotka 7a7bc65237
Add util/compression package to consolidate snappy/zstd use in Prometheus. (#16156)
# Conflicts:
#	tsdb/db_test.go

Apply suggestions from code review




tmp



Addressed comments.



Update util/compression/buffers.go

Signed-off-by: Bartlomiej Plotka <bwplotka@gmail.com>
Co-authored-by: Arthur Silva Sens <arthursens2005@gmail.com>
2025-03-10 10:36:26 +00:00

193 lines
5.6 KiB
Go

// Copyright 2025 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compression
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
const compressible = `ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
fsfsdfsfddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa2
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa12
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa1
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa121
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa324
ddddddddddsfpgjsdoadjgfpajdspfgjasfjapddddddddddaaaaaaaa145
`
func TestEncodeDecode(t *testing.T) {
for _, tcase := range []struct {
name string
src string
types []Type
encBuf EncodeBuffer
decBuf DecodeBuffer
expectCompression bool
expectEncErr error
}{
{
name: "empty src; no buffers",
types: Types(),
src: "",
expectCompression: false,
},
{
name: "empty src; sync buffers",
types: Types(),
encBuf: NewSyncEncodeBuffer(), decBuf: NewSyncDecodeBuffer(),
src: "",
expectCompression: false,
},
{
name: "empty src; concurrent buffers",
types: Types(),
encBuf: NewConcurrentEncodeBuffer(), decBuf: NewConcurrentDecodeBuffer(),
src: "",
expectCompression: false,
},
{
name: "no buffers",
types: []Type{None},
src: compressible,
expectCompression: false,
},
{
name: "no buffers",
types: []Type{Snappy},
src: compressible,
expectCompression: true,
},
{
name: "no buffers",
types: []Type{Zstd},
src: compressible,
expectEncErr: errors.New("zstd requested but EncodeBuffer was not provided"),
},
{
name: "sync buffers",
types: []Type{None},
encBuf: NewSyncEncodeBuffer(), decBuf: NewSyncDecodeBuffer(),
src: compressible,
expectCompression: false,
},
{
name: "sync buffers",
types: Types()[1:], // All but none
encBuf: NewSyncEncodeBuffer(), decBuf: NewSyncDecodeBuffer(),
src: compressible,
expectCompression: true,
},
{
name: "concurrent buffers",
types: []Type{None},
encBuf: NewConcurrentEncodeBuffer(), decBuf: NewConcurrentDecodeBuffer(),
src: compressible,
expectCompression: false,
},
{
name: "concurrent buffers",
types: Types()[1:], // All but none
encBuf: NewConcurrentEncodeBuffer(), decBuf: NewConcurrentDecodeBuffer(),
src: compressible,
expectCompression: true,
},
} {
require.NotEmpty(t, tcase.types, "must specify at least one type")
for _, typ := range tcase.types {
t.Run(fmt.Sprintf("case=%v/type=%v", tcase.name, typ), func(t *testing.T) {
res, err := Encode(typ, []byte(tcase.src), tcase.encBuf)
if tcase.expectEncErr != nil {
require.ErrorContains(t, err, tcase.expectEncErr.Error())
return
}
require.NoError(t, err)
if tcase.expectCompression {
require.Less(t, len(res), len(tcase.src))
}
// Decode back.
got, err := Decode(typ, res, tcase.decBuf)
require.NoError(t, err)
require.Equal(t, tcase.src, string(got))
})
}
}
}
/*
export bench=encode-v1 && go test ./util/compression/... \
-run '^$' -bench '^BenchmarkEncode' \
-benchtime 5s -count 6 -cpu 2 -timeout 999m \
| tee ${bench}.txt
*/
func BenchmarkEncode(b *testing.B) {
for _, typ := range Types() {
b.Run(fmt.Sprintf("type=%v", typ), func(b *testing.B) {
var buf EncodeBuffer
compressible := []byte(compressible)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if buf == nil {
buf = NewSyncEncodeBuffer()
}
res, err := Encode(typ, compressible, buf)
require.NoError(b, err)
b.ReportMetric(float64(len(res)), "B")
}
})
}
}
/*
export bench=decode-v1 && go test ./util/compression/... \
-run '^$' -bench '^BenchmarkDecode' \
-benchtime 5s -count 6 -cpu 2 -timeout 999m \
| tee ${bench}.txt
*/
func BenchmarkDecode(b *testing.B) {
for _, typ := range Types() {
b.Run(fmt.Sprintf("type=%v", typ), func(b *testing.B) {
var buf DecodeBuffer
res, err := Encode(typ, []byte(compressible), NewConcurrentEncodeBuffer())
require.NoError(b, err)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if buf == nil {
buf = NewSyncDecodeBuffer()
}
_, err := Decode(typ, res, buf)
require.NoError(b, err)
}
})
}
}