chore: switch to math/rand/v2

This commit is contained in:
Vincent Bernat
2025-10-26 12:14:20 +01:00
parent dd8ef6abcc
commit ee6e197e8e
12 changed files with 115 additions and 100 deletions

View File

@@ -11,7 +11,7 @@ import (
"image/draw" "image/draw"
"image/png" "image/png"
"io/fs" "io/fs"
"math/rand" "math/rand/v2"
"net/http" "net/http"
"akvorado/common/embed" "akvorado/common/embed"
@@ -31,7 +31,7 @@ func (c *Component) UserAvatarHandlerFunc(gc *gin.Context) {
info := gc.MustGet("user").(UserInformation) info := gc.MustGet("user").(UserInformation)
hash := fnv.New64() hash := fnv.New64()
hash.Write([]byte(info.Login)) hash.Write([]byte(info.Login))
randSource := rand.New(rand.NewSource(int64(hash.Sum64()))) randSource := rand.New(rand.NewPCG(hash.Sum64(), 0))
etag := fmt.Sprintf(`"%x"`, hash.Sum64()) etag := fmt.Sprintf(`"%x"`, hash.Sum64())
// Do we have a If-None-Match header? // Do we have a If-None-Match header?
@@ -70,7 +70,7 @@ func (c *Component) UserAvatarHandlerFunc(gc *gin.Context) {
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Cannot build avatar."}) gc.JSON(http.StatusInternalServerError, gin.H{"message": "Cannot build avatar."})
return return
} }
parts[idx] = p[randSource.Intn(len(p))] parts[idx] = p[randSource.IntN(len(p))]
} }
// Compose the images // Compose the images

View File

@@ -8,7 +8,7 @@ import (
"hash/fnv" "hash/fnv"
"math" "math"
"math/bits" "math/bits"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"time" "time"
@@ -39,11 +39,8 @@ func randomIP(prefix netip.Prefix, r *rand.Rand) netip.Addr {
result[i] = prefix.Addr().AsSlice()[i] result[i] = prefix.Addr().AsSlice()[i]
continue continue
} }
shiftMask := prefix.Bits() - i*8 shiftMask := max(0, prefix.Bits()-i*8)
if shiftMask < 0 { randomByte := byte(r.IntN(256))
shiftMask = 0
}
randomByte := byte(int(r.Int31n(256)))
randomByte = randomByte & ^bits.Reverse8(byte((1<<shiftMask)-1)) randomByte = randomByte & ^bits.Reverse8(byte((1<<shiftMask)-1))
result[i] = randomByte | prefix.Addr().AsSlice()[i] result[i] = randomByte | prefix.Addr().AsSlice()[i]
} }
@@ -69,7 +66,7 @@ func chooseRandom[T any](r *rand.Rand, slice []T) T {
if len(slice) == 1 { if len(slice) == 1 {
return slice[0] return slice[0]
} }
return slice[r.Intn(len(slice))] return slice[r.IntN(len(slice))]
} }
// generateFlows generate a set of flows using the provided // generateFlows generate a set of flows using the provided
@@ -83,7 +80,7 @@ func generateFlows(flowConfigs []FlowConfiguration, seed int64, now time.Time) [
// Initialize the random number generator to a known state // Initialize the random number generator to a known state
hash := fnv.New64() hash := fnv.New64()
fmt.Fprintf(hash, "%d %d", now.Unix(), seed) fmt.Fprintf(hash, "%d %d", now.Unix(), seed)
r := rand.New(rand.NewSource(int64(hash.Sum64()))) r := rand.New(rand.NewPCG(hash.Sum64(), 0))
nowTime := now.Sub(now.Truncate(time.Hour * 24)) nowTime := now.Sub(now.Truncate(time.Hour * 24))
for _, flowConfig := range flowConfigs { for _, flowConfig := range flowConfigs {
@@ -104,7 +101,7 @@ func generateFlows(flowConfigs []FlowConfiguration, seed int64, now time.Time) [
}, },
} }
if flowConfig.Size == 0 { if flowConfig.Size == 0 {
flow.Octets = uint32(r.Int31n(1200) + 300) flow.Octets = uint32(r.Int32N(1200) + 300)
} else { } else {
flow.Octets = uint32(float64(flowConfig.Size) * (r.NormFloat64()*0.3 + 1)) flow.Octets = uint32(float64(flowConfig.Size) * (r.NormFloat64()*0.3 + 1))
if flow.Octets > 9000 { if flow.Octets > 9000 {
@@ -122,12 +119,12 @@ func generateFlows(flowConfigs []FlowConfiguration, seed int64, now time.Time) [
if srcPort := chooseRandom(r, flowConfig.SrcPort); srcPort != 0 { if srcPort := chooseRandom(r, flowConfig.SrcPort); srcPort != 0 {
flow.SrcPort = srcPort flow.SrcPort = srcPort
} else { } else {
flow.SrcPort = uint16(r.Int31n(2000) + 33000) flow.SrcPort = uint16(r.Int32N(2000) + 33000)
} }
if dstPort := chooseRandom(r, flowConfig.DstPort); dstPort != 0 { if dstPort := chooseRandom(r, flowConfig.DstPort); dstPort != 0 {
flow.DstPort = dstPort flow.DstPort = dstPort
} else { } else {
flow.DstPort = uint16(r.Int31n(2000) + 33000) flow.DstPort = uint16(r.Int32N(2000) + 33000)
} }
} }
if flow.SrcAddr.Is4() { if flow.SrcAddr.Is4() {

View File

@@ -6,7 +6,7 @@ package flows
import ( import (
"fmt" "fmt"
"math" "math"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"testing" "testing"
"time" "time"
@@ -41,7 +41,7 @@ func TestRandomIP(t *testing.T) {
"2001:db8:a:b::/64", "2001:db8:a:b::/64",
"2001:db8:a:c:d::1/128", "2001:db8:a:c:d::1/128",
} }
r := rand.New(rand.NewSource(0)) r := rand.New(rand.NewPCG(0, 0))
for _, p := range prefixes { for _, p := range prefixes {
prefix := netip.MustParsePrefix(p) prefix := netip.MustParsePrefix(p)
for range 1000 { for range 1000 {
@@ -89,7 +89,7 @@ func TestChooseRandom(t *testing.T) {
{6}, {6},
{1, 2, 3, 4, 10, 12}, {1, 2, 3, 4, 10, 12},
} }
r := rand.New(rand.NewSource(0)) r := rand.New(rand.NewPCG(0, 0))
for _, tc := range cases { for _, tc := range cases {
t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) { t.Run(fmt.Sprintf("%v", tc), func(t *testing.T) {
results := map[int]bool{} results := map[int]bool{}
@@ -146,15 +146,15 @@ func TestGenerateFlows(t *testing.T) {
}, },
Expected: []generatedFlow{ Expected: []generatedFlow{
{ {
SrcAddr: netip.MustParseAddr("192.0.2.36"), SrcAddr: netip.MustParseAddr("192.0.2.155"),
DstAddr: netip.MustParseAddr("203.0.113.91"), DstAddr: netip.MustParseAddr("203.0.113.59"),
EType: 0x800, EType: 0x800,
IPFlow: IPFlow{ IPFlow: IPFlow{
Octets: 1365, Octets: 1011,
Packets: 1, Packets: 1,
Proto: 6, Proto: 6,
SrcPort: 443, SrcPort: 443,
DstPort: 34905, DstPort: 33550,
InputInt: 10, InputInt: 10,
OutputInt: 21, OutputInt: 21,
SrcAS: 65201, SrcAS: 65201,
@@ -164,17 +164,35 @@ func TestGenerateFlows(t *testing.T) {
DstMask: 24, DstMask: 24,
}, },
}, { }, {
SrcAddr: netip.MustParseAddr("192.0.2.30"), SrcAddr: netip.MustParseAddr("192.0.2.3"),
DstAddr: netip.MustParseAddr("203.0.113.220"), DstAddr: netip.MustParseAddr("203.0.113.52"),
EType: 0x800, EType: 0x800,
IPFlow: IPFlow{ IPFlow: IPFlow{
Octets: 1500, Octets: 1478,
Packets: 1, Packets: 1,
Proto: 6, Proto: 6,
SrcPort: 443, SrcPort: 443,
DstPort: 33618, DstPort: 33200,
InputInt: 10, InputInt: 10,
OutputInt: 21, OutputInt: 20,
SrcAS: 65201,
DstAS: 65202,
ForwardStatus: 64,
SrcMask: 24,
DstMask: 24,
},
}, {
SrcAddr: netip.MustParseAddr("192.0.2.151"),
DstAddr: netip.MustParseAddr("203.0.113.245"),
EType: 2048,
IPFlow: IPFlow{
Packets: 1,
Octets: 1311,
Proto: 6,
InputInt: 10,
OutputInt: 20,
SrcPort: 443,
DstPort: 33389,
SrcAS: 65201, SrcAS: 65201,
DstAS: 65202, DstAS: 65202,
ForwardStatus: 64, ForwardStatus: 64,
@@ -202,13 +220,13 @@ func TestGenerateFlows(t *testing.T) {
Expected: []generatedFlow{ Expected: []generatedFlow{
{ {
SrcAddr: netip.MustParseAddr("2001:db8::1"), SrcAddr: netip.MustParseAddr("2001:db8::1"),
DstAddr: netip.MustParseAddr("2001:db8:2:0:245b:11f7:351e:dc1a"), DstAddr: netip.MustParseAddr("2001:db8:2:0:9b3b:48ac:f003:34f4"),
EType: 0x86dd, EType: 0x86dd,
IPFlow: IPFlow{ IPFlow: IPFlow{
Octets: 1170, Octets: 866,
Packets: 1, Packets: 1,
Proto: 6, Proto: 6,
SrcPort: 34045, SrcPort: 33820,
DstPort: 443, DstPort: 443,
InputInt: 20, InputInt: 20,
OutputInt: 11, OutputInt: 11,
@@ -240,13 +258,13 @@ func TestGenerateFlows(t *testing.T) {
Expected: []generatedFlow{ Expected: []generatedFlow{
{ {
SrcAddr: netip.MustParseAddr("2001:db8::1"), SrcAddr: netip.MustParseAddr("2001:db8::1"),
DstAddr: netip.MustParseAddr("2001:db8:2:0:245b:11f7:351e:dc1a"), DstAddr: netip.MustParseAddr("2001:db8:2:0:9b3b:48ac:f003:34f4"),
EType: 0x86dd, EType: 0x86dd,
IPFlow: IPFlow{ IPFlow: IPFlow{
Octets: 1170, Octets: 866,
Packets: 1, Packets: 1,
Proto: 6, Proto: 6,
SrcPort: 34045, SrcPort: 33820,
DstPort: 443, DstPort: 443,
InputInt: 20, InputInt: 20,
OutputInt: 11, OutputInt: 11,
@@ -258,13 +276,13 @@ func TestGenerateFlows(t *testing.T) {
}, },
}, { }, {
DstAddr: netip.MustParseAddr("2001:db8::1"), DstAddr: netip.MustParseAddr("2001:db8::1"),
SrcAddr: netip.MustParseAddr("2001:db8:2:0:245b:11f7:351e:dc1a"), SrcAddr: netip.MustParseAddr("2001:db8:2:0:9b3b:48ac:f003:34f4"),
EType: 0x86dd, EType: 0x86dd,
IPFlow: IPFlow{ IPFlow: IPFlow{
Octets: 1170 / 10, Octets: 866 / 10,
Packets: 1, Packets: 1,
Proto: 6, Proto: 6,
DstPort: 34045, DstPort: 33820,
SrcPort: 443, SrcPort: 443,
OutputInt: 20, OutputInt: 20,
InputInt: 11, InputInt: 11,

View File

@@ -6,7 +6,7 @@ package kafka
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"sync" "sync"
"testing" "testing"
"time" "time"
@@ -49,10 +49,10 @@ func TestFakeKafka(t *testing.T) {
msg1 := make([]byte, 50) msg1 := make([]byte, 50)
msg2 := make([]byte, 50) msg2 := make([]byte, 50)
for i := range msg1 { for i := range msg1 {
msg1[i] = letters[rand.Intn(len(letters))] msg1[i] = letters[rand.IntN(len(letters))]
} }
for i := range msg2 { for i := range msg2 {
msg2[i] = letters[rand.Intn(len(letters))] msg2[i] = letters[rand.IntN(len(letters))]
} }
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)

View File

@@ -8,7 +8,7 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"strings" "strings"
"time" "time"

View File

@@ -6,7 +6,7 @@ package kafka
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"testing" "testing"
"time" "time"

View File

@@ -6,7 +6,7 @@ package clickhouse
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"strconv" "strconv"
"time" "time"

View File

@@ -6,7 +6,7 @@ package kafka
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"strconv" "strconv"
"strings" "strings"
"sync/atomic" "sync/atomic"

View File

@@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"io/fs" "io/fs"
"math" "math"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"path/filepath" "path/filepath"
"slices" "slices"
@@ -419,8 +419,8 @@ func TestConcurrentOperations(t *testing.T) {
nowLock.RLock() nowLock.RLock()
now := now now := now
nowLock.RUnlock() nowLock.RUnlock()
ip := rand.Intn(10) ip := rand.IntN(10)
iface := rand.Intn(100) iface := rand.IntN(100)
sc.Put(now, provider.Query{ sc.Put(now, provider.Query{
ExporterIP: netip.MustParseAddr(fmt.Sprintf("::ffff:127.0.0.%d", ip)), ExporterIP: netip.MustParseAddr(fmt.Sprintf("::ffff:127.0.0.%d", ip)),
IfIndex: uint(iface), IfIndex: uint(iface),
@@ -443,8 +443,8 @@ func TestConcurrentOperations(t *testing.T) {
nowLock.RLock() nowLock.RLock()
now := now now := now
nowLock.RUnlock() nowLock.RUnlock()
ip := rand.Intn(10) ip := rand.IntN(10)
iface := rand.Intn(100) iface := rand.IntN(100)
sc.Lookup(now, provider.Query{ sc.Lookup(now, provider.Query{
ExporterIP: netip.MustParseAddr(fmt.Sprintf("::ffff:127.0.0.%d", ip)), ExporterIP: netip.MustParseAddr(fmt.Sprintf("::ffff:127.0.0.%d", ip)),
IfIndex: uint(iface), IfIndex: uint(iface),

View File

@@ -8,7 +8,7 @@ import (
"crypto/tls" "crypto/tls"
"errors" "errors"
"fmt" "fmt"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"sync" "sync"
"time" "time"
@@ -244,7 +244,7 @@ func (p *Provider) chooseRouter(agent netip.Addr) (netip.Addr, *RISInstanceRunti
// Randomly select a ris providing the router ID we selected earlier. // Randomly select a ris providing the router ID we selected earlier.
// In the future, we might also want to exclude currently unavailable ris instances // In the future, we might also want to exclude currently unavailable ris instances
chosenRis = p.routers[chosenRouterID][rand.Intn(len(p.routers[chosenRouterID]))] chosenRis = p.routers[chosenRouterID][rand.IntN(len(p.routers[chosenRouterID]))]
if chosenRis == nil || chosenRouterID.IsUnspecified() { if chosenRis == nil || chosenRouterID.IsUnspecified() {
return chosenRouterID, nil, errNoInstance return chosenRouterID, nil, errNoInstance

View File

@@ -6,7 +6,7 @@ package bmp
import ( import (
"fmt" "fmt"
"iter" "iter"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"runtime" "runtime"
"slices" "slices"
@@ -30,7 +30,7 @@ var prefixSizeDistribution = [33]int{
} }
func init() { func init() {
prng := rand.New(rand.NewSource(0)) prng := rand.New(rand.NewPCG(0, 0))
// Data from https://bgp.potaroo.net/as2.0/bgp-asbyhop-vector.txt // Data from https://bgp.potaroo.net/as2.0/bgp-asbyhop-vector.txt
asDistanceDistribution := []int{ asDistanceDistribution := []int{
1, 2, 366, 9645, 29251, 28984, 7340, 1423, 383, 63, 14, 2, 4, 4, 4, 4, 1, 0, 1, 2, 366, 9645, 29251, 28984, 7340, 1423, 383, 63, 14, 2, 4, 4, 4, 4, 1, 0,
@@ -46,7 +46,7 @@ func init() {
for i := range uniqueASPaths { for i := range uniqueASPaths {
// Generate AS path length based on distribution // Generate AS path length based on distribution
asPathLen := 1 asPathLen := 1
r := prng.Intn(totalAS) r := prng.IntN(totalAS)
cumulative := 0 cumulative := 0
for len, count := range asDistanceDistribution { for len, count := range asDistanceDistribution {
cumulative += count cumulative += count
@@ -62,7 +62,7 @@ func init() {
// Generate unique AS path // Generate unique AS path
asPath := make([]uint32, asPathLen) asPath := make([]uint32, asPathLen)
for j := 0; j < asPathLen; j++ { for j := 0; j < asPathLen; j++ {
asPath[j] = uint32(prng.Intn(64494) + 1) asPath[j] = uint32(prng.IntN(64494) + 1)
} }
asPathCache[i] = asPath asPathCache[i] = asPath
} }
@@ -87,7 +87,7 @@ func randomRealWorldRoutes4(prngPrefixes, prngASPaths *rand.Rand, n int) iter.Se
for range n { for range n {
// Generate prefix length based on distribution // Generate prefix length based on distribution
prefixLen := 0 prefixLen := 0
r := prngPrefixes.Intn(totalRoutes) r := prngPrefixes.IntN(totalRoutes)
cumulative := 0 cumulative := 0
for len, count := range prefixSizeDistribution { for len, count := range prefixSizeDistribution {
cumulative += count cumulative += count
@@ -99,34 +99,34 @@ func randomRealWorldRoutes4(prngPrefixes, prngASPaths *rand.Rand, n int) iter.Se
// Generate random IPv4 prefix // Generate random IPv4 prefix
ip := netip.AddrFrom4([4]byte{ ip := netip.AddrFrom4([4]byte{
byte(prngPrefixes.Intn(224)), byte(prngPrefixes.IntN(224)),
byte(prngPrefixes.Intn(256)), byte(prngPrefixes.IntN(256)),
byte(prngPrefixes.Intn(256)), byte(prngPrefixes.IntN(256)),
byte(prngPrefixes.Intn(256)), byte(prngPrefixes.IntN(256)),
}) })
prefix := netip.PrefixFrom(ip, prefixLen).Masked() prefix := netip.PrefixFrom(ip, prefixLen).Masked()
// Select a random AS path from the pre-generated cache // Select a random AS path from the pre-generated cache
asPath := asPathCache[prngASPaths.Intn(len(asPathCache))] asPath := asPathCache[prngASPaths.IntN(len(asPathCache))]
// Generate communities (0-5 communities per route) // Generate communities (0-5 communities per route)
numCommunities := max(0, prngASPaths.Intn(10)-4) numCommunities := max(0, prngASPaths.IntN(10)-4)
communities := make([]uint32, numCommunities) communities := make([]uint32, numCommunities)
for j := range numCommunities { for j := range numCommunities {
asFromPath := asPath[prngASPaths.Intn(len(asPath))] asFromPath := asPath[prngASPaths.IntN(len(asPath))]
communities[j] = asFromPath<<16 | uint32(prngASPaths.Intn(3)) communities[j] = asFromPath<<16 | uint32(prngASPaths.IntN(3))
} }
slices.Sort(communities) slices.Sort(communities)
communities = slices.Compact(communities) communities = slices.Compact(communities)
// Generate large communities (0-3 per route, but they are rare) // Generate large communities (0-3 per route, but they are rare)
numLargeCommunities := max(0, prngASPaths.Intn(100)-97) numLargeCommunities := max(0, prngASPaths.IntN(100)-97)
largeCommunities := make([]bgp.LargeCommunity, numLargeCommunities) largeCommunities := make([]bgp.LargeCommunity, numLargeCommunities)
for j := range numLargeCommunities { for j := range numLargeCommunities {
largeCommunities[j] = bgp.LargeCommunity{ largeCommunities[j] = bgp.LargeCommunity{
ASN: asPath[prngASPaths.Intn(len(asPath))], ASN: asPath[prngASPaths.IntN(len(asPath))],
LocalData1: uint32(prngASPaths.Intn(2)) + 1, LocalData1: uint32(prngASPaths.IntN(2)) + 1,
LocalData2: uint32(prngASPaths.Intn(2)) + 1, LocalData2: uint32(prngASPaths.IntN(2)) + 1,
} }
} }
@@ -145,23 +145,23 @@ func randomRealWorldRoutes4(prngPrefixes, prngASPaths *rand.Rand, n int) iter.Se
} }
func TestRandomRealWorldRoutes4(t *testing.T) { func TestRandomRealWorldRoutes4(t *testing.T) {
prng1 := rand.New(rand.NewSource(1)) prng1 := rand.New(rand.NewPCG(1, 1))
prng2 := rand.New(rand.NewSource(2)) prng2 := rand.New(rand.NewPCG(2, 2))
routes := []randomRoute{} routes := []randomRoute{}
for route := range randomRealWorldRoutes4(prng1, prng2, 2) { for route := range randomRealWorldRoutes4(prng1, prng2, 2) {
routes = append(routes, route) routes = append(routes, route)
} }
expectedRoutes := []randomRoute{ expectedRoutes := []randomRoute{
{ {
Prefix: netip.MustParsePrefix("79.199.187.0/24"), Prefix: netip.MustParsePrefix("22.172.220.0/24"),
ASPath: []uint32{29418, 57855, 38297}, ASPath: []uint32{5310, 16496, 48042, 23205},
Communities: []uint32{1927938050, 2509832194}, Communities: []uint32{347996161, 1081081858, 1520762881, 1520762882, 3148480513},
LargeCommunities: []bgp.LargeCommunity{}, LargeCommunities: []bgp.LargeCommunity{},
}, },
{ {
Prefix: netip.MustParsePrefix("185.172.72.0/24"), Prefix: netip.MustParsePrefix("181.109.115.0/24"),
ASPath: []uint32{25258, 9490, 64459, 11892, 37685}, ASPath: []uint32{9514, 53442, 28732, 62632, 53821},
Communities: []uint32{}, Communities: []uint32{623509505, 1882980354, 4104650753},
LargeCommunities: []bgp.LargeCommunity{}, LargeCommunities: []bgp.LargeCommunity{},
}, },
} }
@@ -171,8 +171,8 @@ func TestRandomRealWorldRoutes4(t *testing.T) {
} }
func TestRandomRealWorldRoutes4Distribution(t *testing.T) { func TestRandomRealWorldRoutes4Distribution(t *testing.T) {
prng1 := rand.New(rand.NewSource(42)) prng1 := rand.New(rand.NewPCG(42, 42))
prng2 := rand.New(rand.NewSource(43)) prng2 := rand.New(rand.NewPCG(43, 43))
totalRoutes := 0 totalRoutes := 0
for _, v := range prefixSizeDistribution { for _, v := range prefixSizeDistribution {
@@ -220,10 +220,10 @@ func BenchmarkRIBInsertion(b *testing.B) {
for b.Loop() { for b.Loop() {
rib = newRIB() rib = newRIB()
nh := netip.MustParseAddr("::ffff:198.51.100.0") nh := netip.MustParseAddr("::ffff:198.51.100.0")
prng1 := rand.New(rand.NewSource(10)) prng1 := rand.New(rand.NewPCG(10, 10))
prng2 := make([]*rand.Rand, peers) prng2 := make([]*rand.Rand, peers)
for p := range peers { for p := range peers {
prng2[p] = rand.New(rand.NewSource(int64(p))) prng2[p] = rand.New(rand.NewPCG(uint64(p), uint64(p)))
} }
for p := range peers { for p := range peers {
nh = nh.Next() nh = nh.Next()
@@ -236,7 +236,7 @@ func BenchmarkRIBInsertion(b *testing.B) {
b.StartTimer() b.StartTimer()
for _, r := range randomPrefixes { for _, r := range randomPrefixes {
if prng2[p].Intn(10) == 0 { if prng2[p].IntN(10) == 0 {
continue continue
} }
pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96) pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96)
@@ -272,8 +272,8 @@ func BenchmarkRIBInsertion(b *testing.B) {
func BenchmarkRIBLookup(b *testing.B) { func BenchmarkRIBLookup(b *testing.B) {
for _, routes := range []int{1_000, 10_000, 100_000, 1_000_000} { for _, routes := range []int{1_000, 10_000, 100_000, 1_000_000} {
prng1 := rand.New(rand.NewSource(10)) prng1 := rand.New(rand.NewPCG(10, 10))
prng2 := rand.New(rand.NewSource(0)) prng2 := rand.New(rand.NewPCG(0, 0))
randomPrefixes := []randomRoute{} randomPrefixes := []randomRoute{}
for r := range randomRealWorldRoutes4(prng1, prng2, routes/10) { for r := range randomRealWorldRoutes4(prng1, prng2, routes/10) {
randomPrefixes = append(randomPrefixes, r) randomPrefixes = append(randomPrefixes, r)
@@ -284,15 +284,15 @@ func BenchmarkRIBLookup(b *testing.B) {
b.Run(name, func(b *testing.B) { b.Run(name, func(b *testing.B) {
rib := newRIB() rib := newRIB()
nh := netip.MustParseAddr("::ffff:198.51.100.0") nh := netip.MustParseAddr("::ffff:198.51.100.0")
prng1 := rand.New(rand.NewSource(10)) prng1 := rand.New(rand.NewPCG(10, 10))
prng2 := make([]*rand.Rand, peers) prng2 := make([]*rand.Rand, peers)
for p := range peers { for p := range peers {
prng2[p] = rand.New(rand.NewSource(int64(p))) prng2[p] = rand.New(rand.NewPCG(uint64(p), uint64(p)))
} }
for p := range peers { for p := range peers {
nh = nh.Next() nh = nh.Next()
for r := range randomRealWorldRoutes4(prng1, prng2[p], routes) { for r := range randomRealWorldRoutes4(prng1, prng2[p], routes) {
if prng2[p].Intn(10) == 0 { if prng2[p].IntN(10) == 0 {
continue continue
} }
pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96) pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96)
@@ -333,15 +333,15 @@ func BenchmarkRIBFlush(b *testing.B) {
b.StopTimer() b.StopTimer()
rib := newRIB() rib := newRIB()
nh := netip.MustParseAddr("::ffff:198.51.100.0") nh := netip.MustParseAddr("::ffff:198.51.100.0")
prng1 := rand.New(rand.NewSource(10)) prng1 := rand.New(rand.NewPCG(10, 10))
prng2 := make([]*rand.Rand, peers) prng2 := make([]*rand.Rand, peers)
for p := range peers { for p := range peers {
prng2[p] = rand.New(rand.NewSource(int64(p))) prng2[p] = rand.New(rand.NewPCG(uint64(p), uint64(p)))
} }
for p := range peers { for p := range peers {
nh = nh.Next() nh = nh.Next()
for r := range randomRealWorldRoutes4(prng1, prng2[p], routes) { for r := range randomRealWorldRoutes4(prng1, prng2[p], routes) {
if prng2[p].Intn(10) == 0 { if prng2[p].IntN(10) == 0 {
continue continue
} }
pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96) pfx := netip.PrefixFrom(netip.AddrFrom16(r.Prefix.Addr().As16()), r.Prefix.Bits()+96)

View File

@@ -5,7 +5,7 @@ package bmp
import ( import (
"fmt" "fmt"
"math/rand" "math/rand/v2"
"net/netip" "net/netip"
"testing" "testing"
"unsafe" "unsafe"
@@ -331,7 +331,7 @@ func TestRemoveRoutes(t *testing.T) {
func TestRIBHarness(t *testing.T) { func TestRIBHarness(t *testing.T) {
for run := range 5 { for run := range 5 {
random := rand.New(rand.NewSource(int64(run))) random := rand.New(rand.NewPCG(uint64(run), 0))
run++ run++
// Ramp up the test // Ramp up the test
@@ -378,17 +378,17 @@ func TestRIBHarness(t *testing.T) {
for j := range peerPerExporter { for j := range peerPerExporter {
peer := uint32((i << 16) + int(j)) peer := uint32((i << 16) + int(j))
peers = append(peers, peer) peers = append(peers, peer)
toAdd := random.Intn(maxInitialRoutePerPeer) toAdd := random.IntN(maxInitialRoutePerPeer)
added := 0 added := 0
for range toAdd { for range toAdd {
lookup := lookup{ lookup := lookup{
peer: peer, peer: peer,
addr: netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::", addr: netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::",
random.Intn(300))), random.IntN(300))),
nextHop: netip.MustParseAddr( nextHop: netip.MustParseAddr(
fmt.Sprintf("2001:db8:c::%x", random.Intn(500))), fmt.Sprintf("2001:db8:c::%x", random.IntN(500))),
rd: RD(random.Intn(3)), rd: RD(random.IntN(3)),
asn: uint32(random.Intn(1000)), asn: uint32(random.IntN(1000)),
comment: "added during first pass", comment: "added during first pass",
} }
added += r.AddPrefix(netip.PrefixFrom(lookup.addr, 64), added += r.AddPrefix(netip.PrefixFrom(lookup.addr, 64),
@@ -405,12 +405,12 @@ func TestRIBHarness(t *testing.T) {
} }
t.Logf("Run %d: added = %d/%d", run, added, toAdd) t.Logf("Run %d: added = %d/%d", run, added, toAdd)
toRemove := random.Intn(maxRemovedRoutePerPeer) toRemove := random.IntN(maxRemovedRoutePerPeer)
removed := 0 removed := 0
for range toRemove { for range toRemove {
prefix := netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::", prefix := netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::",
random.Intn(300))) random.IntN(300)))
rd := RD(random.Intn(4)) rd := RD(random.IntN(4))
if nlriRef, ok := r.nlris.Ref(nlri{ if nlriRef, ok := r.nlris.Ref(nlri{
rd: rd, rd: rd,
}); ok { }); ok {
@@ -428,16 +428,16 @@ func TestRIBHarness(t *testing.T) {
} }
t.Logf("Run %d: removed = %d/%d", run, removed, toRemove) t.Logf("Run %d: removed = %d/%d", run, removed, toRemove)
toAdd = random.Intn(maxReaddedRoutePerPeer) toAdd = random.IntN(maxReaddedRoutePerPeer)
added = 0 added = 0
for range toAdd { for range toAdd {
lookup := lookup{ lookup := lookup{
peer: peer, peer: peer,
addr: netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::", addr: netip.MustParseAddr(fmt.Sprintf("2001:db8:f:%x::",
random.Intn(300))), random.IntN(300))),
nextHop: netip.MustParseAddr( nextHop: netip.MustParseAddr(
fmt.Sprintf("2001:db8:c::%x", random.Uint32()%500)), fmt.Sprintf("2001:db8:c::%x", random.Uint32()%500)),
asn: uint32(random.Intn(1010)), asn: uint32(random.IntN(1010)),
comment: "added during third pass", comment: "added during third pass",
} }
added += r.AddPrefix(netip.PrefixFrom(lookup.addr, 64), added += r.AddPrefix(netip.PrefixFrom(lookup.addr, 64),