package rand import ( "sync" "testing" "time" ) func TestNew(t *testing.T) { tests := []struct { name string seed int64 }{ { name: "positive seed", seed: 12345, }, { name: "zero seed", seed: 0, }, { name: "negative seed", seed: -12345, }, { name: "current time seed", seed: time.Now().UnixNano(), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { r := New(test.seed) if r.r == nil { t.Error("internal rand.Rand is nil") } }) } } func TestIntDeterministic(t *testing.T) { seed := int64(42) // Create two generators with the same seed r1 := New(seed) r2 := New(seed) // They should produce the same sequence for i := range 10 { val1 := r1.Int() val2 := r2.Int() if val1 != val2 { t.Errorf("generators with same seed produced different values at iteration %d: %d != %d", i, val1, val2) } } } func TestPerm(t *testing.T) { r := New(12345) tests := []struct { name string n int }{ { name: "empty permutation", n: 0, }, { name: "single element", n: 1, }, { name: "small permutation", n: 5, }, { name: "larger permutation", n: 20, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { perm := r.Perm(test.n) if len(perm) != test.n { t.Errorf("Perm(%d) returned slice of length %d", test.n, len(perm)) } }) } } func TestPermDeterministic(t *testing.T) { seed := int64(42) n := 10 // Create two generators with the same seed r1 := New(seed) r2 := New(seed) perm1 := r1.Perm(n) perm2 := r2.Perm(n) // They should produce the same permutation if len(perm1) != len(perm2) { t.Errorf("permutations have different lengths: %d != %d", len(perm1), len(perm2)) } for i := 0; i < len(perm1) && i < len(perm2); i++ { if perm1[i] != perm2[i] { t.Errorf("permutations differ at index %d: %d != %d", i, perm1[i], perm2[i]) } } } func TestConcurrentAccess(t *testing.T) { r := New(12345) numGoroutines := 10 numOperations := 100 var wg sync.WaitGroup errors := make(chan error, numGoroutines*numOperations) // Test concurrent Int() calls for range numGoroutines { wg.Add(1) go func() { defer wg.Done() for range numOperations { val := r.Int() if val < 0 { errors <- nil } } }() } // Test concurrent Perm() calls for range numGoroutines { wg.Add(1) go func() { defer wg.Done() for range numOperations { perm := r.Perm(5) if len(perm) != 5 { errors <- nil } } }() } wg.Wait() close(errors) errorCount := 0 for range errors { errorCount++ } if errorCount > 0 { t.Errorf("concurrent access resulted in %d errors", errorCount) } } func TestConcurrentMixedOperations(t *testing.T) { r := New(time.Now().UnixNano()) numGoroutines := 5 numOperations := 50 var wg sync.WaitGroup errors := make(chan error, numGoroutines*numOperations) // Mix of Int() and Perm() operations running concurrently for i := range numGoroutines { wg.Add(1) go func(id int) { defer wg.Done() for j := range numOperations { if j%2 == 0 { val := r.Int() if val < 0 { errors <- nil } } else { perm := r.Perm(3) if len(perm) != 3 { errors <- nil } } } }(i) } wg.Wait() close(errors) errorCount := 0 for range errors { errorCount++ } if errorCount > 0 { t.Errorf("concurrent mixed operations resulted in %d errors", errorCount) } }