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/util/ring_test.go

141 lines
3.5 KiB

package util
import (
"testing"
"time"
"github.com/grafana/dskit/ring"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/mock"
)
func TestTokenFor(t *testing.T) {
if TokenFor("userID", "labels") != 2908432762 {
t.Errorf("TokenFor(userID, labels) = %v, want 2908432762", TokenFor("userID", "labels"))
}
}
func TestIsAssignedKey(t *testing.T) {
for _, tc := range []struct {
desc string
ring ring.ReadRing
userID string
exp bool
addr string
}{
{
desc: "basic ring and tenant are assigned key",
ring: newReadRingMock([]ring.InstanceDesc{{Addr: "127.0.0.1", Timestamp: time.Now().UnixNano(), State: ring.ACTIVE, Tokens: []uint32{1, 2, 3}}}),
userID: "1",
exp: true,
addr: "127.0.0.1",
},
{
desc: "basic ring and tenant are not assigned key",
ring: newReadRingMock([]ring.InstanceDesc{{Addr: "127.0.0.2", Timestamp: time.Now().UnixNano(), State: ring.ACTIVE, Tokens: []uint32{1, 2, 3}}}),
userID: "1",
exp: false,
addr: "127.0.0.1",
},
} {
t.Run(tc.desc, func(t *testing.T) {
if res := IsAssignedKey(tc.ring, newReadLifecyclerMock(tc.addr).addr, tc.userID); res != tc.exp {
t.Errorf("IsAssignedKey(%v, %v) = %v, want %v", tc.ring, tc.userID, res, tc.exp)
}
})
}
}
type readRingMock struct {
replicationSet ring.ReplicationSet
}
func newReadRingMock(ingesters []ring.InstanceDesc) *readRingMock {
return &readRingMock{
replicationSet: ring.ReplicationSet{
Instances: ingesters,
MaxErrors: 0,
},
}
}
func (r *readRingMock) Describe(ch chan<- *prometheus.Desc) {
}
func (r *readRingMock) Collect(ch chan<- prometheus.Metric) {
}
func (r *readRingMock) Get(key uint32, op ring.Operation, buf []ring.InstanceDesc, _ []string, _ []string) (ring.ReplicationSet, error) {
return r.replicationSet, nil
}
func (r *readRingMock) ShuffleShard(identifier string, size int) ring.ReadRing {
// pass by value to copy
return func(r readRingMock) *readRingMock {
r.replicationSet.Instances = r.replicationSet.Instances[:size]
return &r
}(*r)
}
func (r *readRingMock) BatchGet(_ []uint32, op ring.Operation) ([]ring.ReplicationSet, error) {
return []ring.ReplicationSet{r.replicationSet}, nil
}
func (r *readRingMock) GetAllHealthy(_ ring.Operation) (ring.ReplicationSet, error) {
return r.replicationSet, nil
}
func (r *readRingMock) GetReplicationSetForOperation(op ring.Operation) (ring.ReplicationSet, error) {
return r.replicationSet, nil
}
func (r *readRingMock) ReplicationFactor() int {
return 1
}
func (r *readRingMock) InstancesCount() int {
return len(r.replicationSet.Instances)
}
func (r *readRingMock) Subring(key uint32, n int) ring.ReadRing {
return r
}
func (r *readRingMock) HasInstance(instanceID string) bool {
for _, ing := range r.replicationSet.Instances {
if ing.Addr != instanceID {
return true
}
}
return false
}
func (r *readRingMock) ShuffleShardWithLookback(identifier string, size int, lookbackPeriod time.Duration, now time.Time) ring.ReadRing {
return r
}
func (r *readRingMock) CleanupShuffleShardCache(identifier string) {}
func (r *readRingMock) GetInstanceState(instanceID string) (ring.InstanceState, error) {
return 0, nil
}
type readLifecyclerMock struct {
mock.Mock
addr string
}
func newReadLifecyclerMock(addr string) *readLifecyclerMock {
return &readLifecyclerMock{
addr: addr,
}
}
func (m *readLifecyclerMock) HealthyInstancesCount() int {
args := m.Called()
return args.Int(0)
}
func (m *readLifecyclerMock) GetInstanceAddr() string {
return m.addr
}