1package crr 2 3import ( 4 "net/url" 5 "reflect" 6 "testing" 7) 8 9func urlParse(uri string) *url.URL { 10 u, _ := url.Parse(uri) 11 return u 12} 13 14func TestCacheAdd(t *testing.T) { 15 cases := []struct { 16 limit int64 17 endpoints []Endpoint 18 validKeys map[string]Endpoint 19 expectedSize int 20 }{ 21 { 22 limit: 5, 23 endpoints: []Endpoint{ 24 { 25 Key: "foo", 26 Addresses: []WeightedAddress{ 27 { 28 URL: urlParse("http://0"), 29 }, 30 }, 31 }, 32 { 33 Key: "bar", 34 Addresses: []WeightedAddress{ 35 { 36 URL: urlParse("http://1"), 37 }, 38 }, 39 }, 40 { 41 Key: "baz", 42 Addresses: []WeightedAddress{ 43 { 44 URL: urlParse("http://2"), 45 }, 46 }, 47 }, 48 { 49 Key: "qux", 50 Addresses: []WeightedAddress{ 51 { 52 URL: urlParse("http://3"), 53 }, 54 }, 55 }, 56 { 57 Key: "moo", 58 Addresses: []WeightedAddress{ 59 { 60 URL: urlParse("http://4"), 61 }, 62 }, 63 }, 64 }, 65 validKeys: map[string]Endpoint{ 66 "foo": { 67 Key: "foo", 68 Addresses: []WeightedAddress{ 69 { 70 URL: urlParse("http://0"), 71 }, 72 }, 73 }, 74 "bar": { 75 Key: "bar", 76 Addresses: []WeightedAddress{ 77 { 78 URL: urlParse("http://1"), 79 }, 80 }, 81 }, 82 "baz": { 83 Key: "baz", 84 Addresses: []WeightedAddress{ 85 { 86 URL: urlParse("http://2"), 87 }, 88 }, 89 }, 90 "qux": { 91 Key: "qux", 92 Addresses: []WeightedAddress{ 93 { 94 URL: urlParse("http://3"), 95 }, 96 }, 97 }, 98 "moo": { 99 Key: "moo", 100 Addresses: []WeightedAddress{ 101 { 102 URL: urlParse("http://4"), 103 }, 104 }, 105 }, 106 }, 107 expectedSize: 5, 108 }, 109 { 110 limit: 2, 111 endpoints: []Endpoint{ 112 { 113 Key: "bar", 114 Addresses: []WeightedAddress{ 115 { 116 URL: urlParse("http://1"), 117 }, 118 }, 119 }, 120 { 121 Key: "foo", 122 Addresses: []WeightedAddress{ 123 { 124 URL: urlParse("http://0"), 125 }, 126 }, 127 }, 128 { 129 Key: "baz", 130 Addresses: []WeightedAddress{ 131 { 132 URL: urlParse("http://2"), 133 }, 134 }, 135 }, 136 { 137 Key: "qux", 138 Addresses: []WeightedAddress{ 139 { 140 URL: urlParse("http://3"), 141 }, 142 }, 143 }, 144 { 145 Key: "moo", 146 Addresses: []WeightedAddress{ 147 { 148 URL: urlParse("http://4"), 149 }, 150 }, 151 }, 152 }, 153 validKeys: map[string]Endpoint{ 154 "foo": { 155 Key: "foo", 156 Addresses: []WeightedAddress{ 157 { 158 URL: urlParse("http://0"), 159 }, 160 }, 161 }, 162 "bar": { 163 Key: "bar", 164 Addresses: []WeightedAddress{ 165 { 166 URL: urlParse("http://1"), 167 }, 168 }, 169 }, 170 "baz": { 171 Key: "baz", 172 Addresses: []WeightedAddress{ 173 { 174 URL: urlParse("http://2"), 175 }, 176 }, 177 }, 178 "qux": { 179 Key: "qux", 180 Addresses: []WeightedAddress{ 181 { 182 URL: urlParse("http://3"), 183 }, 184 }, 185 }, 186 "moo": { 187 Key: "moo", 188 Addresses: []WeightedAddress{ 189 { 190 URL: urlParse("http://4"), 191 }, 192 }, 193 }, 194 }, 195 expectedSize: 2, 196 }, 197 } 198 199 for _, c := range cases { 200 cache := NewEndpointCache(c.limit) 201 202 for _, endpoint := range c.endpoints { 203 cache.Add(endpoint) 204 } 205 206 count := 0 207 endpoints := map[string]Endpoint{} 208 cache.endpoints.Range(func(key, value interface{}) bool { 209 count++ 210 211 endpoints[key.(string)] = value.(Endpoint) 212 return true 213 }) 214 215 if e, a := c.expectedSize, cache.size; int64(e) != a { 216 t.Errorf("expected %v, but received %v", e, a) 217 } 218 219 if e, a := c.expectedSize, count; e != a { 220 t.Errorf("expected %v, but received %v", e, a) 221 } 222 223 for k, ep := range endpoints { 224 endpoint, ok := c.validKeys[k] 225 if !ok { 226 t.Errorf("unrecognized key %q in cache", k) 227 } 228 if e, a := endpoint, ep; !reflect.DeepEqual(e, a) { 229 t.Errorf("expected %v, but received %v", e, a) 230 } 231 } 232 } 233} 234 235func TestCacheGet(t *testing.T) { 236 cases := []struct { 237 addEndpoints []Endpoint 238 validKeys map[string]Endpoint 239 limit int64 240 }{ 241 { 242 limit: 5, 243 addEndpoints: []Endpoint{ 244 { 245 Key: "foo", 246 Addresses: []WeightedAddress{ 247 { 248 URL: urlParse("http://0"), 249 }, 250 }, 251 }, 252 { 253 Key: "bar", 254 Addresses: []WeightedAddress{ 255 { 256 URL: urlParse("http://1"), 257 }, 258 }, 259 }, 260 { 261 Key: "baz", 262 Addresses: []WeightedAddress{ 263 { 264 URL: urlParse("http://2"), 265 }, 266 }, 267 }, 268 { 269 Key: "qux", 270 Addresses: []WeightedAddress{ 271 { 272 URL: urlParse("http://3"), 273 }, 274 }, 275 }, 276 { 277 Key: "moo", 278 Addresses: []WeightedAddress{ 279 { 280 URL: urlParse("http://4"), 281 }, 282 }, 283 }, 284 }, 285 validKeys: map[string]Endpoint{ 286 "foo": { 287 Key: "foo", 288 Addresses: []WeightedAddress{ 289 { 290 URL: urlParse("http://0"), 291 }, 292 }, 293 }, 294 "bar": { 295 Key: "bar", 296 Addresses: []WeightedAddress{ 297 { 298 URL: urlParse("http://1"), 299 }, 300 }, 301 }, 302 "baz": { 303 Key: "baz", 304 Addresses: []WeightedAddress{ 305 { 306 URL: urlParse("http://2"), 307 }, 308 }, 309 }, 310 "qux": { 311 Key: "qux", 312 Addresses: []WeightedAddress{ 313 { 314 URL: urlParse("http://3"), 315 }, 316 }, 317 }, 318 "moo": { 319 Key: "moo", 320 Addresses: []WeightedAddress{ 321 { 322 URL: urlParse("http://4"), 323 }, 324 }, 325 }, 326 }, 327 }, 328 { 329 limit: 2, 330 addEndpoints: []Endpoint{ 331 { 332 Key: "bar", 333 Addresses: []WeightedAddress{ 334 { 335 URL: urlParse("http://1"), 336 }, 337 }, 338 }, 339 { 340 Key: "foo", 341 Addresses: []WeightedAddress{ 342 { 343 URL: urlParse("http://0"), 344 }, 345 }, 346 }, 347 { 348 Key: "baz", 349 Addresses: []WeightedAddress{ 350 { 351 URL: urlParse("http://2"), 352 }, 353 }, 354 }, 355 { 356 Key: "qux", 357 Addresses: []WeightedAddress{ 358 { 359 URL: urlParse("http://3"), 360 }, 361 }, 362 }, 363 { 364 Key: "moo", 365 Addresses: []WeightedAddress{ 366 { 367 URL: urlParse("http://4"), 368 }, 369 }, 370 }, 371 }, 372 validKeys: map[string]Endpoint{ 373 "foo": { 374 Key: "foo", 375 Addresses: []WeightedAddress{ 376 { 377 URL: urlParse("http://0"), 378 }, 379 }, 380 }, 381 "bar": { 382 Key: "bar", 383 Addresses: []WeightedAddress{ 384 { 385 URL: urlParse("http://1"), 386 }, 387 }, 388 }, 389 "baz": { 390 Key: "baz", 391 Addresses: []WeightedAddress{ 392 { 393 URL: urlParse("http://2"), 394 }, 395 }, 396 }, 397 "qux": { 398 Key: "qux", 399 Addresses: []WeightedAddress{ 400 { 401 URL: urlParse("http://3"), 402 }, 403 }, 404 }, 405 "moo": { 406 Key: "moo", 407 Addresses: []WeightedAddress{ 408 { 409 URL: urlParse("http://4"), 410 }, 411 }, 412 }, 413 }, 414 }, 415 } 416 417 for _, c := range cases { 418 cache := NewEndpointCache(c.limit) 419 420 for _, endpoint := range c.addEndpoints { 421 cache.Add(endpoint) 422 } 423 424 keys := []string{} 425 cache.endpoints.Range(func(key, value interface{}) bool { 426 a := value.(Endpoint) 427 e, ok := c.validKeys[key.(string)] 428 if !ok { 429 t.Errorf("unrecognized key %q in cache", key.(string)) 430 } 431 432 if !reflect.DeepEqual(e, a) { 433 t.Errorf("expected %v, but received %v", e, a) 434 } 435 436 keys = append(keys, key.(string)) 437 return true 438 }) 439 440 for _, key := range keys { 441 a, ok := cache.get(key) 442 if !ok { 443 t.Errorf("expected key to be present: %q", key) 444 } 445 446 e := c.validKeys[key] 447 if !reflect.DeepEqual(e, a) { 448 t.Errorf("expected %v, but received %v", e, a) 449 } 450 } 451 } 452} 453