Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/pkg/memory/buffer/buffer_test.go

124 lines
3.4 KiB

package buffer_test
import (
"slices"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/loki/v3/pkg/memory"
"github.com/grafana/loki/v3/pkg/memory/buffer"
)
func TestBuffer_Push(t *testing.T) {
var alloc memory.Allocator
defer alloc.Reset()
buf := buffer.Make[int32](&alloc)
buf.Grow(10)
require.Equal(t, (64 / 4), buf.Cap(), "capacity should be 64-byte aligned") // Capacity should be padded to 64-byte alignment.
require.NotPanics(t, func() {
for range int32(buf.Cap()) {
buf.Push(5)
}
})
require.Panics(t, func() {
buf.Push(99)
}, "should not be able to push past capacity")
// Grow the capacity and try some more.
buf.Grow(5)
require.NotPanics(t, func() {
for range int32(buf.Cap() - buf.Len()) {
buf.Push(5)
}
})
require.Panics(t, func() {
buf.Push(99)
}, "should not be able to push past capacity")
expect := slices.Repeat([]int32{5}, buf.Cap())
actual := buf.Data()[:buf.Len()]
require.Equal(t, expect, actual)
}
func TestBuffer_Append(t *testing.T) {
var alloc memory.Allocator
defer alloc.Reset()
buf := buffer.Make[int32](&alloc)
buf.Grow(10)
require.NotPanics(t, func() {
buf.Append(slices.Repeat([]int32{5}, buf.Cap()-buf.Len())...)
})
require.Panics(t, func() {
buf.Append(make([]int32, 1)...)
}, "should not be able to push past capacity")
// Grow the capacity and try some more.
buf.Grow(5)
require.NotPanics(t, func() {
buf.Append(slices.Repeat([]int32{5}, buf.Cap()-buf.Len())...)
})
require.Panics(t, func() {
buf.Append(make([]int32, 1)...)
}, "should not be able to push past capacity")
expect := slices.Repeat([]int32{5}, buf.Cap())
actual := buf.Data()[:buf.Len()]
require.Equal(t, expect, actual)
}
func TestBuffer_Set_Get(t *testing.T) {
var alloc memory.Allocator
defer alloc.Reset()
buf := buffer.Make[int32](&alloc)
buf.Grow(10)
require.Equal(t, 0, buf.Len())
require.Panics(t, func() { buf.Set(0, 15) }, "cannot call set past length")
buf.Resize(5)
require.Equal(t, 5, buf.Len())
require.Equal(t, (64 / 4), buf.Cap(), "capacity should be 64-byte aligned")
require.NotPanics(t, func() { buf.Set(3, 15) }, "cannot call set past length")
require.Panics(t, func() { buf.Set(5, 15) }, "cannot call set past length")
require.Equal(t, int32(15), buf.Get(3))
}
func TestBuffer_Grow(t *testing.T) {
var alloc memory.Allocator
defer alloc.Reset()
buf := buffer.Make[int32](&alloc)
buf.Grow(10) // Set initial capacity
buf.Grow(buf.Cap() * 2) // Double the capacity
// Our allocator should be tracking both the original memory and the
// expanded memory. However, it should not consider the expanded memory as
// free, since there may be copies of the original memory still being used.
require.Equal(t, 192, alloc.AllocatedBytes(), "expected allocated bytes to be 64-byte aligned")
require.Equal(t, 0, alloc.FreeBytes(), "recently expanded memory should not be marked free")
alloc.Reset()
buf = buffer.Make[int32](&alloc)
buf.Grow(20)
require.Equal(t, 192, alloc.AllocatedBytes(), "no additional memory should be allocated")
require.Equal(t, 64, alloc.FreeBytes(), "recently expanded memory should be free")
// Resetting one more time should cause the unused free memory to be released.
alloc.Reset()
buf = buffer.Make[int32](&alloc)
buf.Grow(20)
require.Equal(t, 128, alloc.AllocatedBytes(), "expected unused memory to be released")
require.Equal(t, 0, alloc.FreeBytes(), "expected unused memory to be released")
}