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