github.com/m3db/m3@v1.5.0/src/cmd/services/m3dbnode/config/config_test.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package config 22 23 import ( 24 "fmt" 25 "io/ioutil" 26 "os" 27 "testing" 28 29 "github.com/m3db/m3/src/dbnode/client" 30 "github.com/m3db/m3/src/dbnode/environment" 31 "github.com/m3db/m3/src/dbnode/storage" 32 "github.com/m3db/m3/src/dbnode/storage/bootstrap/bootstrapper/commitlog" 33 "github.com/m3db/m3/src/dbnode/storage/bootstrap/result" 34 "github.com/m3db/m3/src/dbnode/topology" 35 xconfig "github.com/m3db/m3/src/x/config" 36 "github.com/m3db/m3/src/x/instrument" 37 xtest "github.com/m3db/m3/src/x/test" 38 39 "github.com/golang/mock/gomock" 40 "github.com/stretchr/testify/assert" 41 "github.com/stretchr/testify/require" 42 yaml "gopkg.in/yaml.v2" 43 ) 44 45 const testBaseConfig = ` 46 db: 47 logging: 48 level: info 49 file: /var/log/m3dbnode.log 50 51 cache: 52 postingsList: 53 size: 100 54 cacheRegexp: false 55 cacheTerms: false 56 cacheSearch: null 57 58 metrics: 59 prometheus: 60 handlerPath: /metrics 61 sanitization: prometheus 62 samplingRate: 1.0 63 extended: detailed 64 65 listenAddress: 0.0.0.0:9000 66 clusterListenAddress: 0.0.0.0:9001 67 httpNodeListenAddress: 0.0.0.0:9002 68 httpClusterListenAddress: 0.0.0.0:9003 69 debugListenAddress: 0.0.0.0:9004 70 71 hostID: 72 resolver: config 73 value: host1 74 75 client: 76 writeConsistencyLevel: majority 77 readConsistencyLevel: unstrict_majority 78 connectConsistencyLevel: any 79 writeTimeout: 10s 80 fetchTimeout: 15s 81 connectTimeout: 20s 82 writeRetry: 83 initialBackoff: 500ms 84 backoffFactor: 3 85 maxRetries: 2 86 jitter: true 87 fetchRetry: 88 initialBackoff: 500ms 89 backoffFactor: 2 90 maxRetries: 3 91 jitter: true 92 backgroundHealthCheckFailLimit: 4 93 backgroundHealthCheckFailThrottleFactor: 0.5 94 hashing: 95 seed: 42 96 97 gcPercentage: 100 98 99 bootstrap: 100 filesystem: 101 numProcessorsPerCPU: 0.42 102 commitlog: 103 returnUnfulfilledForCorruptCommitLogFiles: false 104 105 commitlog: 106 flushMaxBytes: 524288 107 flushEvery: 1s 108 queue: 109 calculationType: fixed 110 size: 2097152 111 112 filesystem: 113 filePathPrefix: /var/lib/m3db 114 writeBufferSize: 65536 115 dataReadBufferSize: 65536 116 infoReadBufferSize: 128 117 seekReadBufferSize: 4096 118 throughputLimitMbps: 100.0 119 throughputCheckEvery: 128 120 force_index_summaries_mmap_memory: true 121 force_bloom_filter_mmap_memory: true 122 123 repair: 124 enabled: false 125 throttle: 2m 126 checkInterval: 1m 127 128 pooling: 129 blockAllocSize: 16 130 thriftBytesPoolAllocSize: 2048 131 type: simple 132 seriesPool: 133 size: 5242880 134 lowWatermark: 0.01 135 highWatermark: 0.02 136 blockPool: 137 size: 4194304 138 lowWatermark: 0.01 139 highWatermark: 0.02 140 encoderPool: 141 size: 25165824 142 lowWatermark: 0.01 143 highWatermark: 0.02 144 checkedBytesWrapperPool: 145 size: 65536 146 lowWatermark: 0.01 147 highWatermark: 0.02 148 closersPool: 149 size: 104857 150 lowWatermark: 0.01 151 highWatermark: 0.02 152 contextPool: 153 size: 524288 154 lowWatermark: 0.01 155 highWatermark: 0.02 156 segmentReaderPool: 157 size: 16384 158 lowWatermark: 0.01 159 highWatermark: 0.02 160 iteratorPool: 161 size: 2048 162 lowWatermark: 0.01 163 highWatermark: 0.02 164 fetchBlockMetadataResultsPool: 165 size: 65536 166 capacity: 32 167 lowWatermark: 0.01 168 highWatermark: 0.02 169 fetchBlocksMetadataResultsPool: 170 size: 32 171 lowWatermark: 0.01 172 highWatermark: 0.02 173 capacity: 4096 174 replicaMetadataSlicePool: 175 size: 131072 176 capacity: 3 177 lowWatermark: 0.01 178 highWatermark: 0.02 179 blockMetadataPool: 180 size: 65536 181 lowWatermark: 0.01 182 highWatermark: 0.02 183 blockMetadataSlicePool: 184 size: 65536 185 capacity: 32 186 lowWatermark: 0.01 187 highWatermark: 0.02 188 blocksMetadataPool: 189 size: 65536 190 lowWatermark: 0.01 191 highWatermark: 0.02 192 blocksMetadataSlicePool: 193 size: 32 194 capacity: 4096 195 lowWatermark: 0.01 196 highWatermark: 0.02 197 tagsPool: 198 size: 65536 199 capacity: 8 200 maxCapacity: 32 201 lowWatermark: 0.01 202 highWatermark: 0.02 203 tagIteratorPool: 204 size: 8192 205 lowWatermark: 0.01 206 highWatermark: 0.02 207 indexResultsPool: 208 size: 8192 209 lowWatermark: 0.01 210 highWatermark: 0.02 211 tagEncoderPool: 212 size: 8192 213 lowWatermark: 0.01 214 highWatermark: 0.02 215 tagDecoderPool: 216 size: 8192 217 lowWatermark: 0.01 218 highWatermark: 0.02 219 writeBatchPool: 220 size: 8192 221 initialBatchSize: 128 222 maxBatchSize: 100000 223 postingsListPool: 224 size: 8 225 lowWatermark: 0 226 highWatermark: 0 227 identifierPool: 228 size: 9437184 229 lowWatermark: 0.01 230 highWatermark: 0.02 231 bufferBucketPool: 232 size: 65536 233 lowWatermark: 0.01 234 highWatermark: 0.02 235 bufferBucketVersionsPool: 236 size: 65536 237 lowWatermark: 0.01 238 highWatermark: 0.02 239 retrieveRequestPool: 240 size: 65536 241 lowWatermark: 0.01 242 highWatermark: 0.02 243 bytesPool: 244 buckets: 245 - capacity: 16 246 size: 6291456 247 lowWatermark: 0.10 248 highWatermark: 0.12 249 - capacity: 32 250 size: 3145728 251 lowWatermark: 0.10 252 highWatermark: 0.12 253 - capacity: 64 254 size: 3145728 255 lowWatermark: 0.10 256 highWatermark: 0.12 257 - capacity: 128 258 size: 3145728 259 lowWatermark: 0.10 260 highWatermark: 0.12 261 - capacity: 256 262 size: 3145728 263 lowWatermark: 0.10 264 highWatermark: 0.12 265 - capacity: 1440 266 size: 524288 267 lowWatermark: 0.10 268 highWatermark: 0.12 269 - capacity: 4096 270 size: 524288 271 lowWatermark: 0.01 272 highWatermark: 0.02 273 - capacity: 8192 274 size: 32768 275 lowWatermark: 0.01 276 highWatermark: 0.02 277 278 discovery: 279 config: 280 service: 281 env: production 282 zone: embedded 283 service: m3db 284 cacheDir: /var/lib/m3kv 285 etcdClusters: 286 - zone: embedded 287 endpoints: 288 - 1.1.1.1:2379 289 - 1.1.1.2:2379 290 - 1.1.1.3:2379 291 292 seedNodes: 293 listenPeerUrls: 294 - http://0.0.0.0:2380 295 listenClientUrls: 296 - http://0.0.0.0:2379 297 rootDir: /var/lib/etcd 298 initialAdvertisePeerUrls: 299 - http://1.1.1.1:2380 300 advertiseClientUrls: 301 - http://1.1.1.1:2379 302 initialCluster: 303 - hostID: host1 304 endpoint: http://1.1.1.1:2380 305 clusterState: existing 306 - hostID: host2 307 endpoint: http://1.1.1.2:2380 308 - hostID: host3 309 endpoint: http://1.1.1.3:2380 310 hashing: 311 seed: 42 312 writeNewSeriesAsync: true 313 writeNewSeriesBackoffDuration: 2ms 314 tracing: 315 backend: jaeger 316 ` 317 318 func TestConfiguration(t *testing.T) { 319 fd, err := ioutil.TempFile("", "config.yaml") 320 require.NoError(t, err) 321 defer func() { 322 assert.NoError(t, fd.Close()) 323 assert.NoError(t, os.Remove(fd.Name())) 324 }() 325 326 _, err = fd.Write([]byte(testBaseConfig)) 327 require.NoError(t, err) 328 329 // Verify is valid 330 var cfg Configuration 331 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 332 require.NoError(t, err) 333 334 // Verify a reverse output of the data matches what we expect 335 data, err := yaml.Marshal(cfg) 336 require.NoError(t, err) 337 338 expected := `db: 339 index: 340 maxQueryIDsConcurrency: 0 341 maxWorkerTime: 0s 342 regexpDFALimit: null 343 regexpFSALimit: null 344 forwardIndexProbability: 0 345 forwardIndexThreshold: 0 346 transforms: 347 truncateBy: 0 348 forceValue: null 349 logging: 350 file: /var/log/m3dbnode.log 351 level: info 352 fields: {} 353 metrics: 354 scope: null 355 m3: null 356 prometheus: 357 handlerPath: /metrics 358 listenAddress: "" 359 timerType: "" 360 defaultHistogramBuckets: [] 361 defaultSummaryObjectives: [] 362 onError: "" 363 samplingRate: 1 364 extended: 3 365 sanitization: 2 366 listenAddress: 0.0.0.0:9000 367 clusterListenAddress: 0.0.0.0:9001 368 httpNodeListenAddress: 0.0.0.0:9002 369 httpClusterListenAddress: 0.0.0.0:9003 370 debugListenAddress: 0.0.0.0:9004 371 hostID: 372 resolver: config 373 value: host1 374 envVarName: null 375 file: null 376 hostname: null 377 client: 378 config: null 379 writeConsistencyLevel: 2 380 readConsistencyLevel: 2 381 connectConsistencyLevel: 0 382 writeTimeout: 10s 383 fetchTimeout: 15s 384 connectTimeout: 20s 385 writeRetry: 386 initialBackoff: 500ms 387 backoffFactor: 3 388 maxBackoff: 0s 389 maxRetries: 2 390 forever: null 391 jitter: true 392 fetchRetry: 393 initialBackoff: 500ms 394 backoffFactor: 2 395 maxBackoff: 0s 396 maxRetries: 3 397 forever: null 398 jitter: true 399 logErrorSampleRate: 0 400 backgroundHealthCheckFailLimit: 4 401 backgroundHealthCheckFailThrottleFactor: 0.5 402 hashing: 403 seed: 42 404 proto: null 405 asyncWriteWorkerPoolSize: null 406 asyncWriteMaxConcurrency: null 407 useV2BatchAPIs: null 408 writeTimestampOffset: null 409 fetchSeriesBlocksBatchConcurrency: null 410 fetchSeriesBlocksBatchSize: null 411 writeShardsInitializing: null 412 shardsLeavingCountTowardsConsistency: null 413 iterateEqualTimestampStrategy: null 414 gcPercentage: 100 415 tick: null 416 bootstrap: 417 mode: null 418 filesystem: 419 numProcessorsPerCPU: 0.42 420 migration: null 421 commitlog: 422 returnUnfulfilledForCorruptCommitLogFiles: false 423 peers: null 424 cacheSeriesMetadata: null 425 indexSegmentConcurrency: null 426 verify: null 427 blockRetrieve: null 428 cache: 429 series: null 430 postingsList: 431 size: 100 432 cacheRegexp: false 433 cacheTerms: false 434 cacheSearch: null 435 regexp: null 436 filesystem: 437 filePathPrefix: /var/lib/m3db 438 writeBufferSize: 65536 439 dataReadBufferSize: 65536 440 infoReadBufferSize: 128 441 seekReadBufferSize: 4096 442 throughputLimitMbps: 100 443 throughputCheckEvery: 128 444 newFileMode: null 445 newDirectoryMode: null 446 mmap: null 447 force_index_summaries_mmap_memory: true 448 force_bloom_filter_mmap_memory: true 449 bloomFilterFalsePositivePercent: null 450 commitlog: 451 flushMaxBytes: 524288 452 flushEvery: 1s 453 queue: 454 calculationType: fixed 455 size: 2097152 456 queueChannel: null 457 repair: 458 enabled: false 459 type: default 460 strategy: default 461 force: false 462 throttle: 2m0s 463 checkInterval: 1m0s 464 concurrency: 0 465 debugShadowComparisonsEnabled: false 466 debugShadowComparisonsPercentage: 0 467 replication: null 468 pooling: 469 blockAllocSize: 16 470 thriftBytesPoolAllocSize: 2048 471 type: simple 472 bytesPool: 473 buckets: 474 - size: 6291456 475 lowWatermark: 0.1 476 highWatermark: 0.12 477 capacity: 16 478 - size: 3145728 479 lowWatermark: 0.1 480 highWatermark: 0.12 481 capacity: 32 482 - size: 3145728 483 lowWatermark: 0.1 484 highWatermark: 0.12 485 capacity: 64 486 - size: 3145728 487 lowWatermark: 0.1 488 highWatermark: 0.12 489 capacity: 128 490 - size: 3145728 491 lowWatermark: 0.1 492 highWatermark: 0.12 493 capacity: 256 494 - size: 524288 495 lowWatermark: 0.1 496 highWatermark: 0.12 497 capacity: 1440 498 - size: 524288 499 lowWatermark: 0.01 500 highWatermark: 0.02 501 capacity: 4096 502 - size: 32768 503 lowWatermark: 0.01 504 highWatermark: 0.02 505 capacity: 8192 506 checkedBytesWrapperPool: 507 size: 65536 508 lowWatermark: 0.01 509 highWatermark: 0.02 510 closersPool: 511 size: 104857 512 lowWatermark: 0.01 513 highWatermark: 0.02 514 contextPool: 515 size: 524288 516 lowWatermark: 0.01 517 highWatermark: 0.02 518 seriesPool: 519 size: 5242880 520 lowWatermark: 0.01 521 highWatermark: 0.02 522 blockPool: 523 size: 4194304 524 lowWatermark: 0.01 525 highWatermark: 0.02 526 encoderPool: 527 size: 25165824 528 lowWatermark: 0.01 529 highWatermark: 0.02 530 iteratorPool: 531 size: 2048 532 lowWatermark: 0.01 533 highWatermark: 0.02 534 segmentReaderPool: 535 size: 16384 536 lowWatermark: 0.01 537 highWatermark: 0.02 538 identifierPool: 539 size: 9437184 540 lowWatermark: 0.01 541 highWatermark: 0.02 542 fetchBlockMetadataResultsPool: 543 size: 65536 544 lowWatermark: 0.01 545 highWatermark: 0.02 546 capacity: 32 547 fetchBlocksMetadataResultsPool: 548 size: 32 549 lowWatermark: 0.01 550 highWatermark: 0.02 551 capacity: 4096 552 replicaMetadataSlicePool: 553 size: 131072 554 lowWatermark: 0.01 555 highWatermark: 0.02 556 capacity: 3 557 blockMetadataPool: 558 size: 65536 559 lowWatermark: 0.01 560 highWatermark: 0.02 561 blockMetadataSlicePool: 562 size: 65536 563 lowWatermark: 0.01 564 highWatermark: 0.02 565 capacity: 32 566 blocksMetadataPool: 567 size: 65536 568 lowWatermark: 0.01 569 highWatermark: 0.02 570 blocksMetadataSlicePool: 571 size: 32 572 lowWatermark: 0.01 573 highWatermark: 0.02 574 capacity: 4096 575 tagsPool: 576 size: 65536 577 lowWatermark: 0.01 578 highWatermark: 0.02 579 capacity: 8 580 maxCapacity: 32 581 tagIteratorPool: 582 size: 8192 583 lowWatermark: 0.01 584 highWatermark: 0.02 585 indexResultsPool: 586 size: 8192 587 lowWatermark: 0.01 588 highWatermark: 0.02 589 tagEncoderPool: 590 size: 8192 591 lowWatermark: 0.01 592 highWatermark: 0.02 593 tagDecoderPool: 594 size: 8192 595 lowWatermark: 0.01 596 highWatermark: 0.02 597 writeBatchPool: 598 size: 8192 599 initialBatchSize: 128 600 maxBatchSize: 100000 601 bufferBucketPool: 602 size: 65536 603 lowWatermark: 0.01 604 highWatermark: 0.02 605 bufferBucketVersionsPool: 606 size: 65536 607 lowWatermark: 0.01 608 highWatermark: 0.02 609 retrieveRequestPool: 610 size: 65536 611 lowWatermark: 0.01 612 highWatermark: 0.02 613 postingsListPool: 614 size: 8 615 lowWatermark: 0 616 highWatermark: 0 617 discovery: 618 type: null 619 m3dbCluster: null 620 m3AggregatorCluster: null 621 config: 622 services: 623 - async: false 624 clientOverrides: 625 hostQueueFlushInterval: null 626 targetHostQueueFlushSize: null 627 service: 628 zone: embedded 629 env: production 630 service: m3db 631 cacheDir: /var/lib/m3kv 632 etcdClusters: 633 - zone: embedded 634 endpoints: 635 - 1.1.1.1:2379 636 - 1.1.1.2:2379 637 - 1.1.1.3:2379 638 keepAlive: null 639 tls: null 640 autoSyncInterval: 0s 641 m3sd: 642 initTimeout: null 643 watchWithRevision: 0 644 newDirectoryMode: null 645 retry: 646 initialBackoff: 0s 647 backoffFactor: 0 648 maxBackoff: 0s 649 maxRetries: 0 650 forever: null 651 jitter: null 652 requestTimeout: 0s 653 watchChanInitTimeout: 0s 654 watchChanCheckInterval: 0s 655 watchChanResetInterval: 0s 656 enableFastGets: false 657 statics: [] 658 seedNodes: 659 rootDir: /var/lib/etcd 660 initialAdvertisePeerUrls: 661 - http://1.1.1.1:2380 662 advertiseClientUrls: 663 - http://1.1.1.1:2379 664 listenPeerUrls: 665 - http://0.0.0.0:2380 666 listenClientUrls: 667 - http://0.0.0.0:2379 668 initialCluster: 669 - hostID: host1 670 endpoint: http://1.1.1.1:2380 671 clusterState: existing 672 - hostID: host2 673 endpoint: http://1.1.1.2:2380 674 clusterState: "" 675 - hostID: host3 676 endpoint: http://1.1.1.3:2380 677 clusterState: "" 678 clientTransportSecurity: 679 caFile: "" 680 certFile: "" 681 keyFile: "" 682 trustedCaFile: "" 683 clientCertAuth: false 684 autoTls: false 685 peerTransportSecurity: 686 caFile: "" 687 certFile: "" 688 keyFile: "" 689 trustedCaFile: "" 690 clientCertAuth: false 691 autoTls: false 692 hashing: 693 seed: 42 694 writeNewSeriesAsync: true 695 writeNewSeriesBackoffDuration: 2ms 696 proto: null 697 tracing: 698 serviceName: "" 699 backend: jaeger 700 opentelemetry: 701 serviceName: "" 702 endpoint: "" 703 insecure: false 704 attributes: {} 705 jaeger: 706 serviceName: "" 707 disabled: false 708 rpc_metrics: false 709 traceid_128bit: false 710 tags: [] 711 sampler: null 712 reporter: null 713 headers: null 714 baggage_restrictions: null 715 throttler: null 716 lightstep: 717 access_token: "" 718 collector: 719 scheme: "" 720 host: "" 721 port: 0 722 plaintext: false 723 custom_ca_cert_file: "" 724 tags: {} 725 lightstep_api: 726 scheme: "" 727 host: "" 728 port: 0 729 plaintext: false 730 custom_ca_cert_file: "" 731 max_buffered_spans: 0 732 max_log_key_len: 0 733 max_log_value_len: 0 734 max_logs_per_span: 0 735 grpc_max_call_send_msg_size_bytes: 0 736 reporting_period: 0s 737 min_reporting_period: 0s 738 report_timeout: 0s 739 drop_span_logs: false 740 verbose: false 741 use_http: false 742 usegrpc: false 743 reconnect_period: 0s 744 meta_event_reporting_enabled: false 745 limits: 746 maxRecentlyQueriedSeriesDiskBytesRead: null 747 maxRecentlyQueriedSeriesDiskRead: null 748 maxRecentlyQueriedSeriesBlocks: null 749 maxRecentlyQueriedMetadata: null 750 maxOutstandingWriteRequests: 0 751 maxOutstandingReadRequests: 0 752 maxOutstandingRepairedBytes: 0 753 maxEncodersPerBlock: 0 754 writeNewSeriesPerSecond: 0 755 tchannel: null 756 debug: 757 mutexProfileFraction: 0 758 blockProfileRate: 0 759 forceColdWritesEnabled: null 760 coordinator: null 761 ` 762 763 actual := string(data) 764 if expected != actual { 765 diff := xtest.Diff(expected, actual) 766 require.FailNow(t, "reverse config did not match:\n"+diff) 767 } 768 } 769 770 func TestInitialClusterEndpoints(t *testing.T) { 771 seedNodes := []environment.SeedNode{ 772 { 773 HostID: "host1", 774 Endpoint: "http://1.1.1.1:2380", 775 }, 776 } 777 endpoints, err := InitialClusterEndpoints(seedNodes) 778 require.NoError(t, err) 779 require.NotNil(t, endpoints) 780 require.Equal(t, 1, len(endpoints)) 781 assert.Equal(t, "http://1.1.1.1:2379", endpoints[0]) 782 783 seedNodes = []environment.SeedNode{ 784 { 785 HostID: "host1", 786 Endpoint: "http://1.1.1.1:2380", 787 }, 788 { 789 HostID: "host2", 790 Endpoint: "http://1.1.1.2:2380", 791 }, 792 { 793 HostID: "host3", 794 Endpoint: "http://1.1.1.3:2380", 795 }, 796 } 797 endpoints, err = InitialClusterEndpoints(seedNodes) 798 require.NoError(t, err) 799 require.NotNil(t, endpoints) 800 require.Equal(t, 3, len(endpoints)) 801 assert.Equal(t, "http://1.1.1.1:2379", endpoints[0]) 802 assert.Equal(t, "http://1.1.1.2:2379", endpoints[1]) 803 assert.Equal(t, "http://1.1.1.3:2379", endpoints[2]) 804 805 seedNodes = []environment.SeedNode{} 806 endpoints, err = InitialClusterEndpoints(seedNodes) 807 assert.NoError(t, err) 808 assert.Equal(t, 0, len(endpoints)) 809 810 seedNodes = []environment.SeedNode{ 811 { 812 HostID: "host1", 813 Endpoint: "", 814 }, 815 } 816 _, err = InitialClusterEndpoints(seedNodes) 817 require.Error(t, err) 818 } 819 820 func TestIsSeedNode(t *testing.T) { 821 seedNodes := []environment.SeedNode{ 822 { 823 HostID: "host1", 824 Endpoint: "http://1.1.1.1:2380", 825 }, 826 } 827 res := IsSeedNode(seedNodes, "host1") 828 assert.Equal(t, true, res) 829 830 seedNodes = []environment.SeedNode{ 831 { 832 HostID: "host1", 833 Endpoint: "http://1.1.1.1:2380", 834 }, 835 { 836 HostID: "host2", 837 Endpoint: "http://1.1.1.2:2380", 838 }, 839 { 840 HostID: "host3", 841 Endpoint: "http://1.1.1.3:2380", 842 }, 843 } 844 res = IsSeedNode(seedNodes, "host2") 845 assert.Equal(t, true, res) 846 847 seedNodes = []environment.SeedNode{ 848 { 849 HostID: "host1", 850 Endpoint: "http://1.1.1.1:2380", 851 }, 852 { 853 HostID: "host2", 854 Endpoint: "http://1.1.1.2:2380", 855 }, 856 } 857 res = IsSeedNode(seedNodes, "host4") 858 assert.Equal(t, false, res) 859 } 860 861 func TestGetHostAndEndpointFromID(t *testing.T) { 862 test2Seeds := []environment.SeedNode{ 863 { 864 HostID: "host1", 865 Endpoint: "http://1.1.1.1:2380", 866 ClusterState: "existing", 867 }, 868 { 869 HostID: "host2", 870 Endpoint: "http://1.1.1.2:2380", 871 }, 872 } 873 874 tests := []struct { 875 initialCluster []environment.SeedNode 876 hostID string 877 expSeedNode environment.SeedNode 878 expEndpoint string 879 expErr bool 880 }{ 881 { 882 initialCluster: test2Seeds, 883 hostID: "host1", 884 expSeedNode: test2Seeds[0], 885 expEndpoint: "http://1.1.1.1", 886 }, 887 { 888 initialCluster: test2Seeds, 889 hostID: "host3", 890 expErr: true, 891 }, 892 { 893 initialCluster: test2Seeds[:0], 894 hostID: "host1", 895 expErr: true, 896 }, 897 } 898 899 for _, test := range tests { 900 node, ep, err := getHostAndEndpointFromID(test.initialCluster, test.hostID) 901 if test.expErr { 902 assert.Error(t, err) 903 continue 904 } 905 906 assert.Equal(t, test.expSeedNode, node) 907 assert.Equal(t, test.expEndpoint, ep) 908 } 909 } 910 911 func TestNewEtcdEmbedConfig(t *testing.T) { 912 fd, err := ioutil.TempFile("", "config2.yaml") 913 require.NoError(t, err) 914 defer func() { 915 assert.NoError(t, fd.Close()) 916 assert.NoError(t, os.Remove(fd.Name())) 917 }() 918 919 _, err = fd.Write([]byte(testBaseConfig)) 920 require.NoError(t, err) 921 922 // Verify is valid 923 var cfg Configuration 924 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 925 require.NoError(t, err) 926 927 embedCfg, err := NewEtcdEmbedConfig(*cfg.DB) 928 require.NoError(t, err) 929 930 assert.Equal(t, "existing", embedCfg.ClusterState) 931 } 932 933 func TestNewJaegerTracer(t *testing.T) { 934 fd, err := ioutil.TempFile("", "config_jaeger.yaml") 935 require.NoError(t, err) 936 defer func() { 937 assert.NoError(t, fd.Close()) 938 assert.NoError(t, os.Remove(fd.Name())) 939 }() 940 941 _, err = fd.Write([]byte(testBaseConfig)) 942 require.NoError(t, err) 943 944 // Verify is valid 945 var cfg Configuration 946 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 947 require.NoError(t, err) 948 949 instrumentOpts := instrument.NewOptions() 950 tracer, closer, err := cfg.DB.Tracing.NewTracer("m3dbnode", 951 instrumentOpts.MetricsScope(), instrumentOpts.Logger()) 952 require.NoError(t, err) 953 defer closer.Close() 954 955 // Verify tracer gets created 956 require.NotNil(t, tracer) 957 } 958 959 func TestProtoConfig(t *testing.T) { 960 testProtoConf := ` 961 db: 962 metrics: 963 samplingRate: 1.0 964 965 listenAddress: 0.0.0.0:9000 966 clusterListenAddress: 0.0.0.0:9001 967 httpNodeListenAddress: 0.0.0.0:9002 968 httpClusterListenAddress: 0.0.0.0:9003 969 970 commitlog: 971 flushMaxBytes: 524288 972 flushEvery: 1s 973 queue: 974 size: 2097152 975 976 proto: 977 enabled: false 978 schema_registry: 979 "ns1:2d": 980 schemaFilePath: "file/path/to/ns1/schema" 981 messageName: "ns1_msg_name" 982 ns2: 983 schemaFilePath: "file/path/to/ns2/schema" 984 messageName: "ns2_msg_name" 985 ` 986 fd, err := ioutil.TempFile("", "config_proto.yaml") 987 require.NoError(t, err) 988 defer func() { 989 assert.NoError(t, fd.Close()) 990 assert.NoError(t, os.Remove(fd.Name())) 991 }() 992 993 _, err = fd.Write([]byte(testProtoConf)) 994 require.NoError(t, err) 995 996 // Verify is valid 997 var cfg Configuration 998 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 999 require.NoError(t, err) 1000 1001 require.NotNil(t, cfg.DB.Proto) 1002 require.False(t, cfg.DB.Proto.Enabled) 1003 1004 require.Len(t, cfg.DB.Proto.SchemaRegistry, 2) 1005 require.EqualValues(t, map[string]NamespaceProtoSchema{ 1006 "ns1:2d": { 1007 SchemaFilePath: "file/path/to/ns1/schema", 1008 MessageName: "ns1_msg_name", 1009 }, 1010 "ns2": { 1011 SchemaFilePath: "file/path/to/ns2/schema", 1012 MessageName: "ns2_msg_name", 1013 }, 1014 }, cfg.DB.Proto.SchemaRegistry) 1015 } 1016 1017 func TestBootstrapCommitLogConfig(t *testing.T) { 1018 ctrl := gomock.NewController(t) 1019 defer ctrl.Finish() 1020 1021 notDefault := !commitlog.DefaultReturnUnfulfilledForCorruptCommitLogFiles 1022 notDefaultStr := fmt.Sprintf("%v", notDefault) 1023 1024 testConf := ` 1025 db: 1026 metrics: 1027 samplingRate: 1.0 1028 1029 listenAddress: 0.0.0.0:9000 1030 clusterListenAddress: 0.0.0.0:9001 1031 httpNodeListenAddress: 0.0.0.0:9002 1032 httpClusterListenAddress: 0.0.0.0:9003 1033 1034 bootstrap: 1035 commitlog: 1036 returnUnfulfilledForCorruptCommitLogFiles: ` + notDefaultStr + ` 1037 1038 commitlog: 1039 flushMaxBytes: 524288 1040 flushEvery: 1s 1041 queue: 1042 size: 2097152 1043 ` 1044 fd, err := ioutil.TempFile("", "config.yaml") 1045 require.NoError(t, err) 1046 defer func() { 1047 assert.NoError(t, fd.Close()) 1048 assert.NoError(t, os.Remove(fd.Name())) 1049 }() 1050 1051 _, err = fd.Write([]byte(testConf)) 1052 require.NoError(t, err) 1053 1054 // Verify is valid 1055 var cfg Configuration 1056 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 1057 require.NoError(t, err) 1058 require.NotNil(t, cfg.DB) 1059 1060 mapProvider := topology.NewMockMapProvider(ctrl) 1061 origin := topology.NewMockHost(ctrl) 1062 adminClient := client.NewMockAdminClient(ctrl) 1063 1064 _, err = cfg.DB.Bootstrap.New( 1065 result.NewOptions(), 1066 storage.DefaultTestOptions(), 1067 mapProvider, 1068 origin, 1069 adminClient, 1070 ) 1071 require.NoError(t, err) 1072 } 1073 1074 func TestConfigurationComponents(t *testing.T) { 1075 testConfDB := ` 1076 db: {} 1077 ` 1078 testConfMultiple := ` 1079 coordinator: {} 1080 db: {} 1081 ` 1082 tests := []struct { 1083 name string 1084 conf string 1085 components int 1086 }{ 1087 { 1088 name: "db configuration", 1089 conf: testConfDB, 1090 components: 1, 1091 }, 1092 { 1093 name: "coordinator and db configuration", 1094 conf: testConfMultiple, 1095 components: 2, 1096 }, 1097 } 1098 1099 for _, tt := range tests { 1100 t.Run(tt.name, func(t *testing.T) { 1101 fd, err := ioutil.TempFile("", "config.yaml") 1102 require.NoError(t, err) 1103 defer func() { 1104 assert.NoError(t, fd.Close()) 1105 assert.NoError(t, os.Remove(fd.Name())) 1106 }() 1107 1108 _, err = fd.Write([]byte(tt.conf)) 1109 require.NoError(t, err) 1110 1111 var cfg Configuration 1112 err = xconfig.LoadFile(&cfg, fd.Name(), xconfig.Options{}) 1113 require.NoError(t, err) 1114 1115 require.Equal(t, tt.components, cfg.Components()) 1116 }) 1117 } 1118 }