internal/sampler/random/random_test.go

package random_test

import (
	"testing"
	"time"

	"mercemay.top/src/lambdalog/internal/sampler"
	"mercemay.top/src/lambdalog/internal/sampler/random"
)

func TestRate_Zero_AlwaysDrops(t *testing.T) {
	s := &random.Sampler{Rate: 0}
	for i := 0; i < 100; i++ {
		if got := s.Sample(sampler.Input{Now: time.Unix(0, int64(i))}); got != sampler.Drop {
			t.Fatalf("i=%d: got %v, want Drop", i, got)
		}
	}
}

func TestRate_One_AlwaysEmits(t *testing.T) {
	s := &random.Sampler{Rate: 1}
	for i := 0; i < 100; i++ {
		if got := s.Sample(sampler.Input{Now: time.Unix(0, int64(i))}); got != sampler.Emit {
			t.Fatalf("i=%d: got %v, want Emit", i, got)
		}
	}
}

func TestRate_One_WithTag(t *testing.T) {
	s := &random.Sampler{Rate: 1, Tag: true}
	if got := s.Sample(sampler.Input{}); got != sampler.Tag {
		t.Fatalf("got %v, want Tag", got)
	}
}

func TestRate_Half_ApproximatelyFifty(t *testing.T) {
	s := &random.Sampler{Rate: 0.5}
	s.SeedFixed(42)
	var emits int
	const n = 10_000
	for i := 0; i < n; i++ {
		if s.Sample(sampler.Input{Now: time.Unix(0, int64(i))}) == sampler.Emit {
			emits++
		}
	}
	frac := float64(emits) / float64(n)
	if frac < 0.45 || frac > 0.55 {
		t.Fatalf("rate 0.5 produced fraction %.3f", frac)
	}
}

func TestSampler_Deterministic(t *testing.T) {
	s1 := &random.Sampler{Rate: 0.3}
	s1.SeedFixed(1)
	s2 := &random.Sampler{Rate: 0.3}
	s2.SeedFixed(1)
	for i := 0; i < 500; i++ {
		if s1.Sample(sampler.Input{}) != s2.Sample(sampler.Input{}) {
			t.Fatalf("divergence at i=%d", i)
		}
	}
}

func TestNewPercent_Clamps(t *testing.T) {
	for _, pct := range []int{-5, 0, 50, 100, 150} {
		pct := pct
		t.Run("pct", func(t *testing.T) {
			t.Helper()
			s := random.NewPercent(pct)
			if pct <= 0 && s.Sample(sampler.Input{}) != sampler.Drop {
				t.Fatalf("pct<=0 should drop")
			}
			if pct >= 100 && s.Sample(sampler.Input{}) != sampler.Emit {
				t.Fatalf("pct>=100 should emit")
			}
		})
	}
}

func TestName(t *testing.T) {
	if got := (&random.Sampler{}).Name(); got != "random" {
		t.Fatalf("got %q", got)
	}
}