github.com/thanos-io/thanos@v0.32.5/pkg/discovery/dns/provider_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package dns 5 6 import ( 7 "context" 8 "sort" 9 "testing" 10 11 "github.com/go-kit/log" 12 promtestutil "github.com/prometheus/client_golang/prometheus/testutil" 13 14 "github.com/efficientgo/core/testutil" 15 ) 16 17 func TestProvider(t *testing.T) { 18 ips := []string{ 19 "127.0.0.1:19091", 20 "127.0.0.2:19092", 21 "127.0.0.3:19093", 22 "127.0.0.4:19094", 23 "127.0.0.5:19095", 24 } 25 26 prv := NewProvider(log.NewNopLogger(), nil, "") 27 prv.resolver = &mockResolver{ 28 res: map[string][]string{ 29 "a": ips[:2], 30 "b": ips[2:4], 31 "c": {ips[4]}, 32 }, 33 } 34 ctx := context.TODO() 35 36 err := prv.Resolve(ctx, []string{"any+x"}) 37 testutil.Ok(t, err) 38 result := prv.Addresses() 39 sort.Strings(result) 40 testutil.Equals(t, []string(nil), result) 41 testutil.Equals(t, 1, promtestutil.CollectAndCount(prv.resolverAddrs)) 42 testutil.Equals(t, float64(0), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+x"))) 43 44 err = prv.Resolve(ctx, []string{"any+a", "any+b", "any+c"}) 45 testutil.Ok(t, err) 46 result = prv.Addresses() 47 sort.Strings(result) 48 testutil.Equals(t, ips, result) 49 testutil.Equals(t, 3, promtestutil.CollectAndCount(prv.resolverAddrs)) 50 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+a"))) 51 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+b"))) 52 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+c"))) 53 54 err = prv.Resolve(ctx, []string{"any+b", "any+c"}) 55 testutil.Ok(t, err) 56 result = prv.Addresses() 57 sort.Strings(result) 58 testutil.Equals(t, ips[2:], result) 59 testutil.Equals(t, 2, promtestutil.CollectAndCount(prv.resolverAddrs)) 60 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+b"))) 61 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+c"))) 62 63 err = prv.Resolve(ctx, []string{"any+x"}) 64 testutil.Ok(t, err) 65 result = prv.Addresses() 66 sort.Strings(result) 67 testutil.Equals(t, []string(nil), result) 68 testutil.Equals(t, 1, promtestutil.CollectAndCount(prv.resolverAddrs)) 69 testutil.Equals(t, float64(0), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+x"))) 70 71 err = prv.Resolve(ctx, []string{"any+a", "any+b", "any+c"}) 72 testutil.Ok(t, err) 73 result = prv.Addresses() 74 sort.Strings(result) 75 testutil.Equals(t, ips, result) 76 testutil.Equals(t, 3, promtestutil.CollectAndCount(prv.resolverAddrs)) 77 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+a"))) 78 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+b"))) 79 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+c"))) 80 81 err = prv.Resolve(ctx, []string{"any+b", "example.com:90", "any+c"}) 82 testutil.Ok(t, err) 83 result = prv.Addresses() 84 sort.Strings(result) 85 testutil.Equals(t, append(ips[2:], "example.com:90"), result) 86 testutil.Equals(t, 3, promtestutil.CollectAndCount(prv.resolverAddrs)) 87 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+b"))) 88 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("example.com:90"))) 89 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+c"))) 90 91 err = prv.Resolve(ctx, []string{"any+b", "any+c"}) 92 testutil.Ok(t, err) 93 result = prv.Addresses() 94 sort.Strings(result) 95 testutil.Equals(t, ips[2:], result) 96 testutil.Equals(t, 2, promtestutil.CollectAndCount(prv.resolverAddrs)) 97 testutil.Equals(t, float64(2), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+b"))) 98 testutil.Equals(t, float64(1), promtestutil.ToFloat64(prv.resolverAddrs.WithLabelValues("any+c"))) 99 100 } 101 102 type mockResolver struct { 103 res map[string][]string 104 err error 105 } 106 107 func (d *mockResolver) Resolve(_ context.Context, name string, _ QType) ([]string, error) { 108 if d.err != nil { 109 return nil, d.err 110 } 111 return d.res[name], nil 112 } 113 114 // TestIsDynamicNode tests whether we properly catch dynamically defined nodes. 115 func TestIsDynamicNode(t *testing.T) { 116 for _, tcase := range []struct { 117 node string 118 isDynamic bool 119 }{ 120 { 121 node: "1.2.3.4", 122 isDynamic: false, 123 }, 124 { 125 node: "gibberish+1.1.1.1+noa", 126 isDynamic: true, 127 }, 128 { 129 node: "", 130 isDynamic: false, 131 }, 132 { 133 node: "dns+aaa", 134 isDynamic: true, 135 }, 136 { 137 node: "dnssrv+asdasdsa", 138 isDynamic: true, 139 }, 140 } { 141 isDynamic := IsDynamicNode(tcase.node) 142 testutil.Equals(t, tcase.isDynamic, isDynamic, "mismatch between results") 143 } 144 }