From 7a1a5e285fe1fd4e031b89738f2a934936bb9604 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:59:12 +0100 Subject: [PATCH] chunkenc: add extra tests Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- tsdb/chunkenc/varbit_test.go | 38 ++++++++++++++++++-- tsdb/chunkenc/xor2_test.go | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/tsdb/chunkenc/varbit_test.go b/tsdb/chunkenc/varbit_test.go index dcb43f08df..b0c776bc47 100644 --- a/tsdb/chunkenc/varbit_test.go +++ b/tsdb/chunkenc/varbit_test.go @@ -20,8 +20,8 @@ import ( "github.com/stretchr/testify/require" ) -func TestVarbitInt(t *testing.T) { - numbers := []int64{ +func testVarbitIntBoundaryValues() []int64 { + return []int64{ math.MinInt64, -36028797018963968, -36028797018963967, -16777216, -16777215, @@ -40,6 +40,10 @@ func TestVarbitInt(t *testing.T) { 36028797018963968, 36028797018963969, math.MaxInt64, } +} + +func TestVarbitInt(t *testing.T) { + numbers := testVarbitIntBoundaryValues() bs := bstream{} @@ -56,6 +60,36 @@ func TestVarbitInt(t *testing.T) { } } +func TestVarbitIntFast(t *testing.T) { + numbers := testVarbitIntBoundaryValues() + + bs := bstream{} + + for _, n := range numbers { + putVarbitIntFast(&bs, n) + } + + bsr := newBReader(bs.bytes()) + + for _, want := range numbers { + got, err := readVarbitInt(&bsr) + require.NoError(t, err) + require.Equal(t, want, got) + } +} + +func TestVarbitIntAndFastProduceIdenticalOutput(t *testing.T) { + numbers := testVarbitIntBoundaryValues() + + var slow, fast bstream + for _, n := range numbers { + putVarbitInt(&slow, n) + putVarbitIntFast(&fast, n) + } + + require.Equal(t, slow.bytes(), fast.bytes()) +} + func TestVarbitUint(t *testing.T) { numbers := []uint64{ 0, 1, diff --git a/tsdb/chunkenc/xor2_test.go b/tsdb/chunkenc/xor2_test.go index c0c1af8a1b..c6cb35d99f 100644 --- a/tsdb/chunkenc/xor2_test.go +++ b/tsdb/chunkenc/xor2_test.go @@ -116,6 +116,29 @@ func BenchmarkXor2Read(b *testing.B) { } } +func requireXOR2Samples(t *testing.T, samples []triple) { + t.Helper() + + chunk := NewXOR2Chunk() + app, err := chunk.Appender() + require.NoError(t, err) + + for _, sample := range samples { + app.Append(sample.st, sample.t, sample.v) + } + + it := chunk.Iterator(nil) + for _, want := range samples { + require.Equal(t, ValFloat, it.Next()) + require.Equal(t, want.st, it.AtST()) + ts, v := it.At() + require.Equal(t, want.t, ts) + require.Equal(t, want.v, v) + } + require.Equal(t, ValNone, it.Next()) + require.NoError(t, it.Err()) +} + func TestXOR2Basic(t *testing.T) { c := NewXOR2Chunk() app, err := c.Appender() @@ -268,6 +291,53 @@ func TestXOR2LargeDod(t *testing.T) { require.Equal(t, ValNone, it.Next()) } +func TestXOR2LargeDodWithActiveST(t *testing.T) { + requireXOR2Samples(t, []triple{ + {st: 0, t: 0, v: 1.0}, + {st: 900, t: 1000, v: 2.0}, + {st: 1000, t: 2000, v: 3.0}, + {st: 1047576, t: 1050576, v: 4.0}, + }) +} + +func TestXOR2ActiveSTFastPathBoundaries(t *testing.T) { + requireXOR2Samples(t, []triple{ + {st: 0, t: 1000, v: 1.0}, + {st: 1990, t: 2000, v: 1.0}, + {st: 2986, t: 3000, v: 1.0}, + {st: 3954, t: 4000, v: 1.0}, + {st: 4698, t: 5000, v: 1.0}, + }) +} + +func TestXOR2EncodeJointValueUnchangedThenChanged(t *testing.T) { + requireXOR2Samples(t, []triple{ + {st: 0, t: 1000, v: 1.0}, + {st: 0, t: 2000, v: 2.0}, + {st: 0, t: 7096, v: 2.0}, + {st: 0, t: 12192, v: 3.0}, + }) +} + +func TestXOR2ConstantNonZeroSTFastPath(t *testing.T) { + requireXOR2Samples(t, []triple{ + {st: 500, t: 1000, v: 1.0}, + {st: 500, t: 2000, v: 2.0}, + {st: 500, t: 3000, v: 2.0}, + {st: 500, t: 4050, v: 2.0}, + {st: 500, t: 5100, v: 3.0}, + }) +} + +func TestXOR2ActiveSTDodZeroValueChange(t *testing.T) { + requireXOR2Samples(t, []triple{ + {st: 0, t: 1000, v: 1.0}, + {st: 500, t: 2000, v: 2.0}, + {st: 500, t: 3000, v: 3.0}, // dod=0, value changed. + {st: 500, t: 4000, v: 4.0}, // dod=0, value changed. + }) +} + func TestXOR2ChunkST(t *testing.T) { testChunkSTHandling(t, ValFloat, func() Chunk { return NewXOR2Chunk()