vitess.io/vitess@v0.16.2/go/vt/vtadmin/cluster/discovery/discovery_static_file_test.go (about) 1 /* 2 Copyright 2020 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package discovery 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/require" 25 26 "vitess.io/vitess/go/vt/proto/vtadmin" 27 vtadminpb "vitess.io/vitess/go/vt/proto/vtadmin" 28 ) 29 30 func TestDiscoverVTGate(t *testing.T) { 31 t.Parallel() 32 33 tests := []struct { 34 name string 35 contents []byte 36 expected *vtadminpb.VTGate 37 tags []string 38 shouldErr bool 39 }{ 40 { 41 name: "empty config", 42 contents: []byte(`{}`), 43 expected: nil, 44 shouldErr: true, 45 }, 46 { 47 name: "one gate", 48 contents: []byte(` 49 { 50 "vtgates": [{ 51 "host": { 52 "hostname": "127.0.0.1:12345" 53 } 54 }] 55 } 56 `), 57 expected: &vtadmin.VTGate{ 58 Hostname: "127.0.0.1:12345", 59 }, 60 }, 61 { 62 name: "filtered by tags (one match)", 63 contents: []byte(` 64 { 65 "vtgates": [ 66 { 67 "host": { 68 "hostname": "127.0.0.1:11111" 69 }, 70 "tags": ["cell:cellA"] 71 }, 72 { 73 "host": { 74 "hostname": "127.0.0.1:22222" 75 }, 76 "tags": ["cell:cellB"] 77 }, 78 { 79 "host": { 80 "hostname": "127.0.0.1:33333" 81 }, 82 "tags": ["cell:cellA"] 83 } 84 ] 85 } 86 `), 87 expected: &vtadminpb.VTGate{ 88 Hostname: "127.0.0.1:22222", 89 }, 90 tags: []string{"cell:cellB"}, 91 }, 92 } 93 94 ctx := context.Background() 95 96 for _, tt := range tests { 97 tt := tt 98 99 t.Run(tt.name, func(t *testing.T) { 100 t.Parallel() 101 102 disco := &StaticFileDiscovery{} 103 err := disco.parseConfig(tt.contents) 104 require.NoError(t, err) 105 106 gate, err := disco.DiscoverVTGate(ctx, tt.tags) 107 if tt.shouldErr { 108 assert.Error(t, err) 109 return 110 } 111 112 assert.NoError(t, err) 113 assert.Equal(t, tt.expected, gate) 114 }) 115 } 116 } 117 118 func TestDiscoverVTGates(t *testing.T) { 119 t.Parallel() 120 121 tests := []struct { 122 name string 123 contents []byte 124 tags []string 125 expected []*vtadminpb.VTGate 126 // True if the test should produce an error on the DiscoverVTGates call 127 shouldErr bool 128 // True if the test should produce an error on the disco.parseConfig step 129 shouldErrConfig bool 130 }{ 131 { 132 name: "empty config", 133 contents: []byte(`{}`), 134 expected: []*vtadminpb.VTGate{}, 135 shouldErr: false, 136 }, 137 { 138 name: "no tags", 139 contents: []byte(` 140 { 141 "vtgates": [ 142 { 143 "host": { 144 "hostname": "127.0.0.1:12345" 145 } 146 }, 147 { 148 "host": { 149 "hostname": "127.0.0.1:67890" 150 } 151 } 152 ] 153 } 154 `), 155 expected: []*vtadminpb.VTGate{ 156 {Hostname: "127.0.0.1:12345"}, 157 {Hostname: "127.0.0.1:67890"}, 158 }, 159 shouldErr: false, 160 }, 161 { 162 name: "filtered by tags", 163 contents: []byte(` 164 { 165 "vtgates": [ 166 { 167 "host": { 168 "hostname": "127.0.0.1:11111" 169 }, 170 "tags": ["cell:cellA"] 171 }, 172 { 173 "host": { 174 "hostname": "127.0.0.1:22222" 175 }, 176 "tags": ["cell:cellB"] 177 }, 178 { 179 "host": { 180 "hostname": "127.0.0.1:33333" 181 }, 182 "tags": ["cell:cellA"] 183 } 184 ] 185 } 186 `), 187 tags: []string{"cell:cellA"}, 188 expected: []*vtadminpb.VTGate{ 189 {Hostname: "127.0.0.1:11111"}, 190 {Hostname: "127.0.0.1:33333"}, 191 }, 192 shouldErr: false, 193 }, 194 { 195 name: "filtered by multiple tags", 196 contents: []byte(` 197 { 198 "vtgates": [ 199 { 200 "host": { 201 "hostname": "127.0.0.1:11111" 202 }, 203 "tags": ["cell:cellA"] 204 }, 205 { 206 "host": { 207 "hostname": "127.0.0.1:22222" 208 }, 209 "tags": ["cell:cellA", "pool:poolZ"] 210 }, 211 { 212 "host": { 213 "hostname": "127.0.0.1:33333" 214 }, 215 "tags": ["pool:poolZ"] 216 } 217 ] 218 } 219 `), 220 tags: []string{"cell:cellA", "pool:poolZ"}, 221 expected: []*vtadminpb.VTGate{ 222 {Hostname: "127.0.0.1:22222"}, 223 }, 224 shouldErr: false, 225 }, 226 { 227 name: "invalid json", 228 contents: []byte(` 229 { 230 "vtgates": "malformed" 231 } 232 `), 233 tags: []string{}, 234 shouldErr: false, 235 shouldErrConfig: true, 236 }, 237 } 238 239 ctx := context.Background() 240 241 for _, tt := range tests { 242 tt := tt 243 244 t.Run(tt.name, func(t *testing.T) { 245 t.Parallel() 246 247 disco := &StaticFileDiscovery{} 248 249 err := disco.parseConfig(tt.contents) 250 if tt.shouldErrConfig { 251 assert.Error(t, err) 252 } else { 253 require.NoError(t, err) 254 } 255 256 gates, err := disco.DiscoverVTGates(ctx, tt.tags) 257 if tt.shouldErr { 258 assert.Error(t, err) 259 return 260 } 261 262 assert.NoError(t, err) 263 assert.ElementsMatch(t, tt.expected, gates) 264 }) 265 } 266 } 267 268 func TestDiscoverVtctld(t *testing.T) { 269 t.Parallel() 270 271 tests := []struct { 272 name string 273 contents []byte 274 expected *vtadminpb.Vtctld 275 tags []string 276 shouldErr bool 277 }{ 278 { 279 name: "empty config", 280 contents: []byte(`{}`), 281 expected: nil, 282 shouldErr: true, 283 }, 284 { 285 name: "one vtctld", 286 contents: []byte(` 287 { 288 "vtctlds": [{ 289 "host": { 290 "hostname": "127.0.0.1:12345" 291 } 292 }] 293 } 294 `), 295 expected: &vtadmin.Vtctld{ 296 Hostname: "127.0.0.1:12345", 297 }, 298 }, 299 { 300 name: "filtered by tags (one match)", 301 contents: []byte(` 302 { 303 "vtctlds": [ 304 { 305 "host": { 306 "hostname": "127.0.0.1:11111" 307 }, 308 "tags": ["cell:cellA"] 309 }, 310 { 311 "host": { 312 "hostname": "127.0.0.1:22222" 313 }, 314 "tags": ["cell:cellB"] 315 }, 316 { 317 "host": { 318 "hostname": "127.0.0.1:33333" 319 }, 320 "tags": ["cell:cellA"] 321 } 322 ] 323 } 324 `), 325 expected: &vtadminpb.Vtctld{ 326 Hostname: "127.0.0.1:22222", 327 }, 328 tags: []string{"cell:cellB"}, 329 }, 330 } 331 332 ctx := context.Background() 333 334 for _, tt := range tests { 335 tt := tt 336 337 t.Run(tt.name, func(t *testing.T) { 338 t.Parallel() 339 340 disco := &StaticFileDiscovery{} 341 err := disco.parseConfig(tt.contents) 342 require.NoError(t, err) 343 344 vtctld, err := disco.DiscoverVtctld(ctx, tt.tags) 345 if tt.shouldErr { 346 assert.Error(t, err) 347 return 348 } 349 350 assert.NoError(t, err) 351 assert.Equal(t, tt.expected, vtctld) 352 }) 353 } 354 } 355 356 func TestDiscoverVtctlds(t *testing.T) { 357 t.Parallel() 358 359 tests := []struct { 360 name string 361 contents []byte 362 tags []string 363 expected []*vtadminpb.Vtctld 364 // True if the test should produce an error on the DiscoverVTGates call 365 shouldErr bool 366 // True if the test should produce an error on the disco.parseConfig step 367 shouldErrConfig bool 368 }{ 369 { 370 name: "empty config", 371 contents: []byte(`{}`), 372 expected: []*vtadminpb.Vtctld{}, 373 shouldErr: false, 374 }, 375 { 376 name: "no tags", 377 contents: []byte(` 378 { 379 "vtctlds": [ 380 { 381 "host": { 382 "hostname": "127.0.0.1:12345" 383 } 384 }, 385 { 386 "host": { 387 "hostname": "127.0.0.1:67890" 388 } 389 } 390 ] 391 } 392 `), 393 expected: []*vtadminpb.Vtctld{ 394 {Hostname: "127.0.0.1:12345"}, 395 {Hostname: "127.0.0.1:67890"}, 396 }, 397 shouldErr: false, 398 }, 399 { 400 name: "filtered by tags", 401 contents: []byte(` 402 { 403 "vtctlds": [ 404 { 405 "host": { 406 "hostname": "127.0.0.1:11111" 407 }, 408 "tags": ["cell:cellA"] 409 }, 410 { 411 "host": { 412 "hostname": "127.0.0.1:22222" 413 }, 414 "tags": ["cell:cellB"] 415 }, 416 { 417 "host": { 418 "hostname": "127.0.0.1:33333" 419 }, 420 "tags": ["cell:cellA"] 421 } 422 ] 423 } 424 `), 425 tags: []string{"cell:cellA"}, 426 expected: []*vtadminpb.Vtctld{ 427 {Hostname: "127.0.0.1:11111"}, 428 {Hostname: "127.0.0.1:33333"}, 429 }, 430 shouldErr: false, 431 }, 432 { 433 name: "filtered by multiple tags", 434 contents: []byte(` 435 { 436 "vtctlds": [ 437 { 438 "host": { 439 "hostname": "127.0.0.1:11111" 440 }, 441 "tags": ["cell:cellA"] 442 }, 443 { 444 "host": { 445 "hostname": "127.0.0.1:22222" 446 }, 447 "tags": ["cell:cellA", "pool:poolZ"] 448 }, 449 { 450 "host": { 451 "hostname": "127.0.0.1:33333" 452 }, 453 "tags": ["pool:poolZ"] 454 } 455 ] 456 } 457 `), 458 tags: []string{"cell:cellA", "pool:poolZ"}, 459 expected: []*vtadminpb.Vtctld{ 460 {Hostname: "127.0.0.1:22222"}, 461 }, 462 shouldErr: false, 463 }, 464 { 465 name: "invalid json", 466 contents: []byte(` 467 { 468 "vtctlds": "malformed" 469 } 470 `), 471 tags: []string{}, 472 shouldErr: false, 473 shouldErrConfig: true, 474 }, 475 } 476 477 ctx := context.Background() 478 479 for _, tt := range tests { 480 tt := tt 481 482 t.Run(tt.name, func(t *testing.T) { 483 t.Parallel() 484 485 disco := &StaticFileDiscovery{} 486 487 err := disco.parseConfig(tt.contents) 488 if tt.shouldErrConfig { 489 assert.Error(t, err) 490 } else { 491 require.NoError(t, err) 492 } 493 494 vtctlds, err := disco.DiscoverVtctlds(ctx, tt.tags) 495 if tt.shouldErr { 496 assert.Error(t, err) 497 return 498 } 499 500 assert.NoError(t, err) 501 assert.ElementsMatch(t, tt.expected, vtctlds) 502 }) 503 } 504 }