mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	Enable intrange linter to enforce modern Go range syntax over traditional for loops, by converting: for i := 0; i < n; i++ to: for i := range n Adding type conversions where needed for compatibility with existing uint64 parameters. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
		
			
				
	
	
		
			207 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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)
 | |
| 	}
 | |
| }
 |