github.com/google/cloudprober@v0.11.3/probes/options/options_test.go (about) 1 // Copyright 2017-2020 The Cloudprober Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package options 16 17 import ( 18 "errors" 19 "net" 20 "testing" 21 "time" 22 23 "github.com/golang/protobuf/proto" 24 "github.com/google/cloudprober/common/iputils" 25 "github.com/google/cloudprober/logger" 26 configpb "github.com/google/cloudprober/probes/proto" 27 targetspb "github.com/google/cloudprober/targets/proto" 28 ) 29 30 type intf struct { 31 addrs []net.Addr 32 } 33 34 func (i *intf) Addrs() ([]net.Addr, error) { 35 return i.addrs, nil 36 } 37 38 func mockInterfaceByName(iname string, addrs []string) { 39 ips := make([]net.Addr, len(addrs)) 40 for i, a := range addrs { 41 ips[i] = &net.IPAddr{IP: net.ParseIP(a)} 42 } 43 i := &intf{addrs: ips} 44 iputils.InterfaceByName = func(name string) (iputils.Addr, error) { 45 if name != iname { 46 return nil, errors.New("device not found") 47 } 48 return i, nil 49 } 50 } 51 52 var ipVersionToEnum = map[int]*configpb.ProbeDef_IPVersion{ 53 4: configpb.ProbeDef_IPV4.Enum(), 54 6: configpb.ProbeDef_IPV6.Enum(), 55 } 56 57 func TestGetSourceIPFromConfig(t *testing.T) { 58 rows := []struct { 59 name string 60 sourceIP string 61 sourceIntf string 62 intf string 63 intfAddrs []string 64 ipVer int 65 want string 66 wantError bool 67 }{ 68 { 69 name: "Use IP", 70 sourceIP: "1.1.1.1", 71 want: "1.1.1.1", 72 }, 73 { 74 name: "Source IP doesn't match IP version", 75 sourceIP: "1.1.1.1", 76 ipVer: 6, 77 wantError: true, 78 }, 79 { 80 name: "Use IPv6", 81 sourceIP: "::1", 82 ipVer: 6, 83 want: "::1", 84 }, 85 { 86 name: "Invalid IP", 87 sourceIP: "12ab", 88 wantError: true, 89 }, 90 { 91 name: "Interface with no adders fails", 92 sourceIntf: "eth1", 93 intf: "eth1", 94 wantError: true, 95 }, 96 { 97 name: "Unknown interface fails", 98 sourceIntf: "eth1", 99 intf: "eth0", 100 wantError: true, 101 }, 102 { 103 name: "Uses first addr for interface", 104 sourceIntf: "eth1", 105 intf: "eth1", 106 intfAddrs: []string{"1.1.1.1", "2.2.2.2"}, 107 want: "1.1.1.1", 108 }, 109 { 110 name: "Uses first IPv6 addr for interface", 111 sourceIntf: "eth1", 112 intf: "eth1", 113 intfAddrs: []string{"1.1.1.1", "::1"}, 114 ipVer: 6, 115 want: "::1", 116 }, 117 } 118 119 for _, r := range rows { 120 p := &configpb.ProbeDef{ 121 IpVersion: ipVersionToEnum[r.ipVer], 122 } 123 124 if r.sourceIP != "" { 125 p.SourceIpConfig = &configpb.ProbeDef_SourceIp{r.sourceIP} 126 } else if r.sourceIntf != "" { 127 p.SourceIpConfig = &configpb.ProbeDef_SourceInterface{r.sourceIntf} 128 mockInterfaceByName(r.intf, r.intfAddrs) 129 } 130 131 source, err := getSourceIPFromConfig(p, &logger.Logger{}) 132 133 if (err != nil) != r.wantError { 134 t.Errorf("Row %q: getSourceIPFromConfig() gave error %q, want error is %v", r.name, err, r.wantError) 135 continue 136 } 137 if r.wantError { 138 continue 139 } 140 if source.String() != r.want { 141 t.Errorf("Row %q: source= %q, want %q", r.name, source, r.want) 142 } 143 } 144 } 145 146 var testTargets = &targetspb.TargetsDef{ 147 Type: &targetspb.TargetsDef_HostNames{HostNames: "testHost"}, 148 } 149 150 func TestIPVersionFromSourceIP(t *testing.T) { 151 rows := []struct { 152 name string 153 sourceIP string 154 ipVer int 155 }{ 156 { 157 name: "No source IP", 158 ipVer: 0, 159 }, 160 { 161 name: "IPv4 from source IP", 162 sourceIP: "1.1.1.1", 163 ipVer: 4, 164 }, 165 { 166 name: "IPv6 from source IP", 167 sourceIP: "::1", 168 ipVer: 6, 169 }, 170 } 171 172 for _, r := range rows { 173 p := &configpb.ProbeDef{ 174 Targets: testTargets, 175 } 176 177 if r.sourceIP != "" { 178 p.SourceIpConfig = &configpb.ProbeDef_SourceIp{r.sourceIP} 179 } 180 181 opts, err := BuildProbeOptions(p, nil, nil, nil) 182 if err != nil { 183 t.Errorf("got unexpected error: %v", err) 184 continue 185 } 186 187 if opts.IPVersion != r.ipVer { 188 t.Errorf("Unexpected IPVersion (test case: %s) want=%d, got=%d", r.name, r.ipVer, opts.IPVersion) 189 } 190 } 191 } 192 193 func TestStatsExportInterval(t *testing.T) { 194 rows := []struct { 195 name string 196 pType *configpb.ProbeDef_Type 197 interval int32 198 timeout int32 199 configured int32 200 want int 201 wantError bool 202 }{ 203 { 204 name: "Interval bigger than default", 205 interval: 15, 206 timeout: 10, 207 want: 15, 208 }, 209 { 210 name: "Timeout bigger than interval", 211 interval: 10, 212 timeout: 12, 213 want: 12, 214 }, 215 { 216 name: "Interval and timeout less than default", 217 interval: 2, 218 timeout: 1, 219 want: int(defaultStatsExtportIntv.Seconds()), 220 }, 221 { 222 name: "UDP probe: default twice of timeout- I", 223 interval: 10, 224 timeout: 12, 225 pType: configpb.ProbeDef_UDP.Enum(), 226 want: 24, 227 }, 228 { 229 name: "UDP probe: default twice of timeout - II", 230 interval: 5, 231 timeout: 6, 232 pType: configpb.ProbeDef_UDP.Enum(), 233 want: 12, 234 }, 235 { 236 name: "Error: stats export interval smaller than interval", 237 interval: 2, 238 timeout: 1, 239 configured: 1, 240 wantError: true, 241 }, 242 { 243 name: "Configured value is good", 244 interval: 2, 245 timeout: 1, 246 configured: 10, 247 want: 10, 248 }, 249 } 250 251 for _, r := range rows { 252 p := &configpb.ProbeDef{ 253 Targets: testTargets, 254 IntervalMsec: proto.Int32(r.interval * 1000), 255 TimeoutMsec: proto.Int32(r.timeout * 1000), 256 } 257 258 if r.pType != nil { 259 p.Type = r.pType 260 } 261 262 if r.configured != 0 { 263 p.StatsExportIntervalMsec = proto.Int32(r.configured * 1000) 264 } 265 266 opts, err := BuildProbeOptions(p, nil, nil, nil) 267 if (err != nil) != r.wantError { 268 t.Errorf("Row %q: BuildProbeOptions() gave error %q, want error is %v", r.name, err, r.wantError) 269 continue 270 } 271 if r.wantError { 272 continue 273 } 274 275 want := time.Duration(r.want) * time.Second 276 if opts.StatsExportInterval != want { 277 t.Errorf("Unexpected stats export interval (test case: %s): want=%s, got=%s", r.name, want, opts.StatsExportInterval) 278 } 279 } 280 } 281 282 func TestDefaultOptions(t *testing.T) { 283 // Most of all, it verifies that DefaultOptions() doesn't generate panic. 284 opts := DefaultOptions() 285 if opts == nil { 286 t.Errorf("Got nil default options") 287 } 288 }