1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
8	"testing"
9)
10
11func checkDistribution(t *testing.T, data []*SRV, margin float64) {
12	sum := 0
13	for _, srv := range data {
14		sum += int(srv.Weight)
15	}
16
17	results := make(map[string]int)
18
19	count := 10000
20	for j := 0; j < count; j++ {
21		d := make([]*SRV, len(data))
22		copy(d, data)
23		byPriorityWeight(d).shuffleByWeight()
24		key := d[0].Target
25		results[key] = results[key] + 1
26	}
27
28	actual := results[data[0].Target]
29	expected := float64(count) * float64(data[0].Weight) / float64(sum)
30	diff := float64(actual) - expected
31	t.Logf("actual: %v diff: %v e: %v m: %v", actual, diff, expected, margin)
32	if diff < 0 {
33		diff = -diff
34	}
35	if diff > (expected * margin) {
36		t.Errorf("missed target weight: expected %v, %v", expected, actual)
37	}
38}
39
40func testUniformity(t *testing.T, size int, margin float64) {
41	data := make([]*SRV, size)
42	for i := 0; i < size; i++ {
43		data[i] = &SRV{Target: string('a' + rune(i)), Weight: 1}
44	}
45	checkDistribution(t, data, margin)
46}
47
48func TestDNSSRVUniformity(t *testing.T) {
49	testUniformity(t, 2, 0.05)
50	testUniformity(t, 3, 0.10)
51	testUniformity(t, 10, 0.20)
52	testWeighting(t, 0.05)
53}
54
55func testWeighting(t *testing.T, margin float64) {
56	data := []*SRV{
57		{Target: "a", Weight: 60},
58		{Target: "b", Weight: 30},
59		{Target: "c", Weight: 10},
60	}
61	checkDistribution(t, data, margin)
62}
63
64func TestWeighting(t *testing.T) {
65	testWeighting(t, 0.05)
66}
67