github.com/netdata/go.d.plugin@v0.58.1/modules/consul/consul_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package consul
     4  
     5  import (
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/netdata/go.d.plugin/pkg/web"
    15  )
    16  
    17  var (
    18  	datav1132Checks, _                        = os.ReadFile("testdata/v1.13.2/v1-agent-checks.json")
    19  	dataV1132ClientSelf, _                    = os.ReadFile("testdata/v1.13.2/client_v1-agent-self.json")
    20  	dataV1132ClientPromMetrics, _             = os.ReadFile("testdata/v1.13.2/client_v1-agent-metrics.txt")
    21  	dataV1132ServerSelf, _                    = os.ReadFile("testdata/v1.13.2/server_v1-agent-self.json")
    22  	dataV1132ServerSelfDisabledPrometheus, _  = os.ReadFile("testdata/v1.13.2/server_v1-agent-self_disabled_prom.json")
    23  	dataV1132ServerSelfWithHostname, _        = os.ReadFile("testdata/v1.13.2/server_v1-agent-self_with_hostname.json")
    24  	dataV1132ServerPromMetrics, _             = os.ReadFile("testdata/v1.13.2/server_v1-agent-metrics.txt")
    25  	dataV1132ServerPromMetricsWithHostname, _ = os.ReadFile("testdata/v1.13.2/server_v1-agent-metrics_with_hostname.txt")
    26  	dataV1132ServerOperatorAutopilotHealth, _ = os.ReadFile("testdata/v1.13.2/server_v1-operator-autopilot-health.json")
    27  	dataV1132ServerCoordinateNodes, _         = os.ReadFile("testdata/v1.13.2/server_v1-coordinate-nodes.json")
    28  
    29  	dataV1143CloudServerPromMetrics, _     = os.ReadFile("testdata/v1.14.3-cloud/server_v1-agent-metrics.txt")
    30  	dataV1143CloudServerSelf, _            = os.ReadFile("testdata/v1.14.3-cloud/server_v1-agent-self.json")
    31  	dataV1143CloudServerCoordinateNodes, _ = os.ReadFile("testdata/v1.14.3-cloud/server_v1-coordinate-nodes.json")
    32  	dataV1143CloudChecks, _                = os.ReadFile("testdata/v1.14.3-cloud/v1-agent-checks.json")
    33  )
    34  
    35  func Test_testDataIsValid(t *testing.T) {
    36  	for name, data := range map[string][]byte{
    37  		"datav1132Checks":                        datav1132Checks,
    38  		"dataV1132ClientSelf":                    dataV1132ClientSelf,
    39  		"dataV1132ClientPromMetrics":             dataV1132ClientPromMetrics,
    40  		"dataV1132ServerSelf":                    dataV1132ServerSelf,
    41  		"dataV1132ServerSelfWithHostname":        dataV1132ServerSelfWithHostname,
    42  		"dataV1132ServerSelfDisabledPrometheus":  dataV1132ServerSelfDisabledPrometheus,
    43  		"dataV1132ServerPromMetrics":             dataV1132ServerPromMetrics,
    44  		"dataV1132ServerPromMetricsWithHostname": dataV1132ServerPromMetricsWithHostname,
    45  		"dataV1132ServerOperatorAutopilotHealth": dataV1132ServerOperatorAutopilotHealth,
    46  		"dataV1132ServerCoordinateNodes":         dataV1132ServerCoordinateNodes,
    47  		"dataV1143CloudServerPromMetrics":        dataV1143CloudServerPromMetrics,
    48  		"dataV1143CloudServerSelf":               dataV1143CloudServerSelf,
    49  		"dataV1143CloudServerCoordinateNodes":    dataV1143CloudServerCoordinateNodes,
    50  		"dataV1143CloudChecks":                   dataV1143CloudChecks,
    51  	} {
    52  		require.NotNilf(t, data, name)
    53  	}
    54  }
    55  
    56  func TestConsul_Init(t *testing.T) {
    57  	tests := map[string]struct {
    58  		wantFail bool
    59  		config   Config
    60  	}{
    61  		"success with default": {
    62  			wantFail: false,
    63  			config:   New().Config,
    64  		},
    65  		"fail when URL not set": {
    66  			wantFail: true,
    67  			config: Config{
    68  				HTTP: web.HTTP{
    69  					Request: web.Request{URL: ""},
    70  				},
    71  			},
    72  		},
    73  	}
    74  
    75  	for name, test := range tests {
    76  		t.Run(name, func(t *testing.T) {
    77  			consul := New()
    78  			consul.Config = test.config
    79  
    80  			if test.wantFail {
    81  				assert.False(t, consul.Init())
    82  			} else {
    83  				assert.True(t, consul.Init())
    84  			}
    85  		})
    86  	}
    87  }
    88  
    89  func TestConsul_Check(t *testing.T) {
    90  	tests := map[string]struct {
    91  		wantFail bool
    92  		prepare  func(t *testing.T) (consul *Consul, cleanup func())
    93  	}{
    94  		"success on response from Consul v1.13.2 server": {
    95  			wantFail: false,
    96  			prepare:  caseConsulV1132ServerResponse,
    97  		},
    98  		"success on response from Consul v1.14.3 server cloud managed": {
    99  			wantFail: false,
   100  			prepare:  caseConsulV1143CloudServerResponse,
   101  		},
   102  		"success on response from Consul v1.13.2 server with enabled hostname": {
   103  			wantFail: false,
   104  			prepare:  caseConsulV1132ServerWithHostnameResponse,
   105  		},
   106  		"success on response from Consul v1.13.2 server with disabled prometheus": {
   107  			wantFail: false,
   108  			prepare:  caseConsulV1132ServerWithDisabledPrometheus,
   109  		},
   110  		"success on response from Consul v1.13.2 client": {
   111  			wantFail: false,
   112  			prepare:  caseConsulV1132ClientResponse,
   113  		},
   114  		"fail on invalid data response": {
   115  			wantFail: true,
   116  			prepare:  caseInvalidDataResponse,
   117  		},
   118  		"fail on connection refused": {
   119  			wantFail: true,
   120  			prepare:  caseConnectionRefused,
   121  		},
   122  		"fail on 404 response": {
   123  			wantFail: true,
   124  			prepare:  case404,
   125  		},
   126  	}
   127  
   128  	for name, test := range tests {
   129  		t.Run(name, func(t *testing.T) {
   130  			consul, cleanup := test.prepare(t)
   131  			defer cleanup()
   132  
   133  			if test.wantFail {
   134  				assert.False(t, consul.Check())
   135  			} else {
   136  				assert.True(t, consul.Check())
   137  			}
   138  		})
   139  	}
   140  }
   141  
   142  func TestConsul_Collect(t *testing.T) {
   143  	tests := map[string]struct {
   144  		prepare         func(t *testing.T) (consul *Consul, cleanup func())
   145  		wantNumOfCharts int
   146  		wantMetrics     map[string]int64
   147  	}{
   148  		"success on response from Consul v1.13.2 server": {
   149  			prepare: caseConsulV1132ServerResponse,
   150  			// 3 node, 1 service check, no license
   151  			wantNumOfCharts: len(serverCommonCharts) + len(serverAutopilotHealthCharts) + len(serverLeaderCharts) + 3 + 1 - 1,
   152  			wantMetrics: map[string]int64{
   153  				"autopilot_failure_tolerance":               1,
   154  				"autopilot_healthy_no":                      0,
   155  				"autopilot_healthy_yes":                     1,
   156  				"autopilot_server_healthy_no":               0,
   157  				"autopilot_server_healthy_yes":              1,
   158  				"autopilot_server_lastContact_leader":       13,
   159  				"autopilot_server_sefStatus_alive":          1,
   160  				"autopilot_server_sefStatus_failed":         0,
   161  				"autopilot_server_sefStatus_left":           0,
   162  				"autopilot_server_sefStatus_none":           0,
   163  				"autopilot_server_stable_time":              265849,
   164  				"autopilot_server_voter_no":                 0,
   165  				"autopilot_server_voter_yes":                1,
   166  				"client_rpc":                                6838,
   167  				"client_rpc_exceeded":                       0,
   168  				"client_rpc_failed":                         0,
   169  				"health_check_chk1_critical_status":         0,
   170  				"health_check_chk1_maintenance_status":      0,
   171  				"health_check_chk1_passing_status":          1,
   172  				"health_check_chk1_warning_status":          0,
   173  				"health_check_chk2_critical_status":         1,
   174  				"health_check_chk2_maintenance_status":      0,
   175  				"health_check_chk2_passing_status":          0,
   176  				"health_check_chk2_warning_status":          0,
   177  				"health_check_chk3_critical_status":         1,
   178  				"health_check_chk3_maintenance_status":      0,
   179  				"health_check_chk3_passing_status":          0,
   180  				"health_check_chk3_warning_status":          0,
   181  				"health_check_mysql_critical_status":        1,
   182  				"health_check_mysql_maintenance_status":     0,
   183  				"health_check_mysql_passing_status":         0,
   184  				"health_check_mysql_warning_status":         0,
   185  				"kvs_apply_count":                           0,
   186  				"kvs_apply_quantile=0.5":                    0,
   187  				"kvs_apply_quantile=0.9":                    0,
   188  				"kvs_apply_quantile=0.99":                   0,
   189  				"kvs_apply_sum":                             0,
   190  				"network_lan_rtt_avg":                       737592,
   191  				"network_lan_rtt_count":                     2,
   192  				"network_lan_rtt_max":                       991168,
   193  				"network_lan_rtt_min":                       484017,
   194  				"network_lan_rtt_sum":                       1475185,
   195  				"raft_apply":                                10681000,
   196  				"raft_boltdb_freelistBytes":                 11264,
   197  				"raft_boltdb_logsPerBatch_count":            12360,
   198  				"raft_boltdb_logsPerBatch_quantile=0.5":     1000000,
   199  				"raft_boltdb_logsPerBatch_quantile=0.9":     1000000,
   200  				"raft_boltdb_logsPerBatch_quantile=0.99":    1000000,
   201  				"raft_boltdb_logsPerBatch_sum":              12362000,
   202  				"raft_boltdb_storeLogs_count":               12360,
   203  				"raft_boltdb_storeLogs_quantile=0.5":        13176624,
   204  				"raft_boltdb_storeLogs_quantile=0.9":        13176624,
   205  				"raft_boltdb_storeLogs_quantile=0.99":       13176624,
   206  				"raft_boltdb_storeLogs_sum":                 651888027,
   207  				"raft_commitTime_count":                     12345,
   208  				"raft_commitTime_quantile=0.5":              41146488,
   209  				"raft_commitTime_quantile=0.9":              41146488,
   210  				"raft_commitTime_quantile=0.99":             41146488,
   211  				"raft_commitTime_sum":                       955781149,
   212  				"raft_fsm_lastRestoreDuration":              2,
   213  				"raft_leader_lastContact_count":             80917,
   214  				"raft_leader_lastContact_quantile=0.5":      33000000,
   215  				"raft_leader_lastContact_quantile=0.9":      68000000,
   216  				"raft_leader_lastContact_quantile=0.99":     68000000,
   217  				"raft_leader_lastContact_sum":               3066900000,
   218  				"raft_leader_oldestLogAge":                  166046464,
   219  				"raft_rpc_installSnapshot_count":            0,
   220  				"raft_rpc_installSnapshot_quantile=0.5":     0,
   221  				"raft_rpc_installSnapshot_quantile=0.9":     0,
   222  				"raft_rpc_installSnapshot_quantile=0.99":    0,
   223  				"raft_rpc_installSnapshot_sum":              0,
   224  				"raft_state_candidate":                      1,
   225  				"raft_state_leader":                         1,
   226  				"raft_thread_fsm_saturation_count":          11923,
   227  				"raft_thread_fsm_saturation_quantile=0.5":   0,
   228  				"raft_thread_fsm_saturation_quantile=0.9":   0,
   229  				"raft_thread_fsm_saturation_quantile=0.99":  0,
   230  				"raft_thread_fsm_saturation_sum":            90,
   231  				"raft_thread_main_saturation_count":         43067,
   232  				"raft_thread_main_saturation_quantile=0.5":  0,
   233  				"raft_thread_main_saturation_quantile=0.9":  0,
   234  				"raft_thread_main_saturation_quantile=0.99": 0,
   235  				"raft_thread_main_saturation_sum":           205409,
   236  				"runtime_alloc_bytes":                       53065368,
   237  				"runtime_sys_bytes":                         84955160,
   238  				"runtime_total_gc_pause_ns":                 1372001280,
   239  				"server_isLeader_no":                        0,
   240  				"server_isLeader_yes":                       1,
   241  				"txn_apply_count":                           0,
   242  				"txn_apply_quantile=0.5":                    0,
   243  				"txn_apply_quantile=0.9":                    0,
   244  				"txn_apply_quantile=0.99":                   0,
   245  				"txn_apply_sum":                             0,
   246  			},
   247  		},
   248  		"success on response from Consul v1.14.3 server cloud managed": {
   249  			prepare: caseConsulV1143CloudServerResponse,
   250  			// 3 node, 1 service check, license
   251  			wantNumOfCharts: len(serverCommonCharts) + len(serverLeaderCharts) + 3 + 1,
   252  			wantMetrics: map[string]int64{
   253  				"autopilot_failure_tolerance":               0,
   254  				"autopilot_healthy_no":                      0,
   255  				"autopilot_healthy_yes":                     1,
   256  				"client_rpc":                                438718,
   257  				"client_rpc_exceeded":                       0,
   258  				"client_rpc_failed":                         0,
   259  				"health_check_chk1_critical_status":         0,
   260  				"health_check_chk1_maintenance_status":      0,
   261  				"health_check_chk1_passing_status":          1,
   262  				"health_check_chk1_warning_status":          0,
   263  				"health_check_chk2_critical_status":         1,
   264  				"health_check_chk2_maintenance_status":      0,
   265  				"health_check_chk2_passing_status":          0,
   266  				"health_check_chk2_warning_status":          0,
   267  				"health_check_chk3_critical_status":         1,
   268  				"health_check_chk3_maintenance_status":      0,
   269  				"health_check_chk3_passing_status":          0,
   270  				"health_check_chk3_warning_status":          0,
   271  				"health_check_mysql_critical_status":        1,
   272  				"health_check_mysql_maintenance_status":     0,
   273  				"health_check_mysql_passing_status":         0,
   274  				"health_check_mysql_warning_status":         0,
   275  				"kvs_apply_count":                           2,
   276  				"kvs_apply_quantile=0.5":                    0,
   277  				"kvs_apply_quantile=0.9":                    0,
   278  				"kvs_apply_quantile=0.99":                   0,
   279  				"kvs_apply_sum":                             18550,
   280  				"network_lan_rtt_avg":                       1321107,
   281  				"network_lan_rtt_count":                     1,
   282  				"network_lan_rtt_max":                       1321107,
   283  				"network_lan_rtt_min":                       1321107,
   284  				"network_lan_rtt_sum":                       1321107,
   285  				"raft_apply":                                115252000,
   286  				"raft_boltdb_freelistBytes":                 26008,
   287  				"raft_boltdb_logsPerBatch_count":            122794,
   288  				"raft_boltdb_logsPerBatch_quantile=0.5":     1000000,
   289  				"raft_boltdb_logsPerBatch_quantile=0.9":     1000000,
   290  				"raft_boltdb_logsPerBatch_quantile=0.99":    1000000,
   291  				"raft_boltdb_logsPerBatch_sum":              122856000,
   292  				"raft_boltdb_storeLogs_count":               122794,
   293  				"raft_boltdb_storeLogs_quantile=0.5":        1673303,
   294  				"raft_boltdb_storeLogs_quantile=0.9":        2210979,
   295  				"raft_boltdb_storeLogs_quantile=0.99":       2210979,
   296  				"raft_boltdb_storeLogs_sum":                 278437403,
   297  				"raft_commitTime_count":                     122785,
   298  				"raft_commitTime_quantile=0.5":              1718204,
   299  				"raft_commitTime_quantile=0.9":              2262192,
   300  				"raft_commitTime_quantile=0.99":             2262192,
   301  				"raft_commitTime_sum":                       284260428,
   302  				"raft_fsm_lastRestoreDuration":              0,
   303  				"raft_leader_lastContact_count":             19,
   304  				"raft_leader_lastContact_quantile=0.5":      0,
   305  				"raft_leader_lastContact_quantile=0.9":      0,
   306  				"raft_leader_lastContact_quantile=0.99":     0,
   307  				"raft_leader_lastContact_sum":               598000,
   308  				"raft_leader_oldestLogAge":                  68835264,
   309  				"raft_rpc_installSnapshot_count":            1,
   310  				"raft_rpc_installSnapshot_quantile=0.5":     0,
   311  				"raft_rpc_installSnapshot_quantile=0.9":     0,
   312  				"raft_rpc_installSnapshot_quantile=0.99":    0,
   313  				"raft_rpc_installSnapshot_sum":              473038,
   314  				"raft_state_candidate":                      1,
   315  				"raft_state_leader":                         1,
   316  				"raft_thread_fsm_saturation_count":          44326,
   317  				"raft_thread_fsm_saturation_quantile=0.5":   0,
   318  				"raft_thread_fsm_saturation_quantile=0.9":   0,
   319  				"raft_thread_fsm_saturation_quantile=0.99":  0,
   320  				"raft_thread_fsm_saturation_sum":            729,
   321  				"raft_thread_main_saturation_count":         451221,
   322  				"raft_thread_main_saturation_quantile=0.5":  0,
   323  				"raft_thread_main_saturation_quantile=0.9":  0,
   324  				"raft_thread_main_saturation_quantile=0.99": 9999,
   325  				"raft_thread_main_saturation_sum":           213059,
   326  				"runtime_alloc_bytes":                       51729856,
   327  				"runtime_sys_bytes":                         160156960,
   328  				"runtime_total_gc_pause_ns":                 832754048,
   329  				"server_isLeader_no":                        0,
   330  				"server_isLeader_yes":                       1,
   331  				"system_licenseExpiration":                  2949945,
   332  				"txn_apply_count":                           0,
   333  				"txn_apply_quantile=0.5":                    0,
   334  				"txn_apply_quantile=0.9":                    0,
   335  				"txn_apply_quantile=0.99":                   0,
   336  				"txn_apply_sum":                             0,
   337  			},
   338  		},
   339  		"success on response from Consul v1.13.2 server with enabled hostname": {
   340  			prepare: caseConsulV1132ServerResponse,
   341  			// 3 node, 1 service check, no license
   342  			wantNumOfCharts: len(serverCommonCharts) + len(serverAutopilotHealthCharts) + len(serverLeaderCharts) + 3 + 1 - 1,
   343  			wantMetrics: map[string]int64{
   344  				"autopilot_failure_tolerance":               1,
   345  				"autopilot_healthy_no":                      0,
   346  				"autopilot_healthy_yes":                     1,
   347  				"autopilot_server_healthy_no":               0,
   348  				"autopilot_server_healthy_yes":              1,
   349  				"autopilot_server_lastContact_leader":       13,
   350  				"autopilot_server_sefStatus_alive":          1,
   351  				"autopilot_server_sefStatus_failed":         0,
   352  				"autopilot_server_sefStatus_left":           0,
   353  				"autopilot_server_sefStatus_none":           0,
   354  				"autopilot_server_stable_time":              265825,
   355  				"autopilot_server_voter_no":                 0,
   356  				"autopilot_server_voter_yes":                1,
   357  				"client_rpc":                                6838,
   358  				"client_rpc_exceeded":                       0,
   359  				"client_rpc_failed":                         0,
   360  				"health_check_chk1_critical_status":         0,
   361  				"health_check_chk1_maintenance_status":      0,
   362  				"health_check_chk1_passing_status":          1,
   363  				"health_check_chk1_warning_status":          0,
   364  				"health_check_chk2_critical_status":         1,
   365  				"health_check_chk2_maintenance_status":      0,
   366  				"health_check_chk2_passing_status":          0,
   367  				"health_check_chk2_warning_status":          0,
   368  				"health_check_chk3_critical_status":         1,
   369  				"health_check_chk3_maintenance_status":      0,
   370  				"health_check_chk3_passing_status":          0,
   371  				"health_check_chk3_warning_status":          0,
   372  				"health_check_mysql_critical_status":        1,
   373  				"health_check_mysql_maintenance_status":     0,
   374  				"health_check_mysql_passing_status":         0,
   375  				"health_check_mysql_warning_status":         0,
   376  				"kvs_apply_count":                           0,
   377  				"kvs_apply_quantile=0.5":                    0,
   378  				"kvs_apply_quantile=0.9":                    0,
   379  				"kvs_apply_quantile=0.99":                   0,
   380  				"kvs_apply_sum":                             0,
   381  				"network_lan_rtt_avg":                       737592,
   382  				"network_lan_rtt_count":                     2,
   383  				"network_lan_rtt_max":                       991168,
   384  				"network_lan_rtt_min":                       484017,
   385  				"network_lan_rtt_sum":                       1475185,
   386  				"raft_apply":                                10681000,
   387  				"raft_boltdb_freelistBytes":                 11264,
   388  				"raft_boltdb_logsPerBatch_count":            12360,
   389  				"raft_boltdb_logsPerBatch_quantile=0.5":     1000000,
   390  				"raft_boltdb_logsPerBatch_quantile=0.9":     1000000,
   391  				"raft_boltdb_logsPerBatch_quantile=0.99":    1000000,
   392  				"raft_boltdb_logsPerBatch_sum":              12362000,
   393  				"raft_boltdb_storeLogs_count":               12360,
   394  				"raft_boltdb_storeLogs_quantile=0.5":        13176624,
   395  				"raft_boltdb_storeLogs_quantile=0.9":        13176624,
   396  				"raft_boltdb_storeLogs_quantile=0.99":       13176624,
   397  				"raft_boltdb_storeLogs_sum":                 651888027,
   398  				"raft_commitTime_count":                     12345,
   399  				"raft_commitTime_quantile=0.5":              41146488,
   400  				"raft_commitTime_quantile=0.9":              41146488,
   401  				"raft_commitTime_quantile=0.99":             41146488,
   402  				"raft_commitTime_sum":                       955781149,
   403  				"raft_fsm_lastRestoreDuration":              2,
   404  				"raft_leader_lastContact_count":             80917,
   405  				"raft_leader_lastContact_quantile=0.5":      33000000,
   406  				"raft_leader_lastContact_quantile=0.9":      68000000,
   407  				"raft_leader_lastContact_quantile=0.99":     68000000,
   408  				"raft_leader_lastContact_sum":               3066900000,
   409  				"raft_leader_oldestLogAge":                  166046464,
   410  				"raft_rpc_installSnapshot_count":            0,
   411  				"raft_rpc_installSnapshot_quantile=0.5":     0,
   412  				"raft_rpc_installSnapshot_quantile=0.9":     0,
   413  				"raft_rpc_installSnapshot_quantile=0.99":    0,
   414  				"raft_rpc_installSnapshot_sum":              0,
   415  				"raft_state_candidate":                      1,
   416  				"raft_state_leader":                         1,
   417  				"raft_thread_fsm_saturation_count":          11923,
   418  				"raft_thread_fsm_saturation_quantile=0.5":   0,
   419  				"raft_thread_fsm_saturation_quantile=0.9":   0,
   420  				"raft_thread_fsm_saturation_quantile=0.99":  0,
   421  				"raft_thread_fsm_saturation_sum":            90,
   422  				"raft_thread_main_saturation_count":         43067,
   423  				"raft_thread_main_saturation_quantile=0.5":  0,
   424  				"raft_thread_main_saturation_quantile=0.9":  0,
   425  				"raft_thread_main_saturation_quantile=0.99": 0,
   426  				"raft_thread_main_saturation_sum":           205409,
   427  				"runtime_alloc_bytes":                       53065368,
   428  				"runtime_sys_bytes":                         84955160,
   429  				"runtime_total_gc_pause_ns":                 1372001280,
   430  				"server_isLeader_no":                        0,
   431  				"server_isLeader_yes":                       1,
   432  				"txn_apply_count":                           0,
   433  				"txn_apply_quantile=0.5":                    0,
   434  				"txn_apply_quantile=0.9":                    0,
   435  				"txn_apply_quantile=0.99":                   0,
   436  				"txn_apply_sum":                             0,
   437  			},
   438  		},
   439  		"success on response from Consul v1.13.2 server with disabled prometheus": {
   440  			prepare: caseConsulV1132ServerWithDisabledPrometheus,
   441  			// 3 node, 1 service check, no license
   442  			wantNumOfCharts: len(serverAutopilotHealthCharts) + 3 + 1,
   443  			wantMetrics: map[string]int64{
   444  				"autopilot_server_healthy_no":           0,
   445  				"autopilot_server_healthy_yes":          1,
   446  				"autopilot_server_lastContact_leader":   13,
   447  				"autopilot_server_sefStatus_alive":      1,
   448  				"autopilot_server_sefStatus_failed":     0,
   449  				"autopilot_server_sefStatus_left":       0,
   450  				"autopilot_server_sefStatus_none":       0,
   451  				"autopilot_server_stable_time":          265805,
   452  				"autopilot_server_voter_no":             0,
   453  				"autopilot_server_voter_yes":            1,
   454  				"health_check_chk1_critical_status":     0,
   455  				"health_check_chk1_maintenance_status":  0,
   456  				"health_check_chk1_passing_status":      1,
   457  				"health_check_chk1_warning_status":      0,
   458  				"health_check_chk2_critical_status":     1,
   459  				"health_check_chk2_maintenance_status":  0,
   460  				"health_check_chk2_passing_status":      0,
   461  				"health_check_chk2_warning_status":      0,
   462  				"health_check_chk3_critical_status":     1,
   463  				"health_check_chk3_maintenance_status":  0,
   464  				"health_check_chk3_passing_status":      0,
   465  				"health_check_chk3_warning_status":      0,
   466  				"health_check_mysql_critical_status":    1,
   467  				"health_check_mysql_maintenance_status": 0,
   468  				"health_check_mysql_passing_status":     0,
   469  				"health_check_mysql_warning_status":     0,
   470  				"network_lan_rtt_avg":                   737592,
   471  				"network_lan_rtt_count":                 2,
   472  				"network_lan_rtt_max":                   991168,
   473  				"network_lan_rtt_min":                   484017,
   474  				"network_lan_rtt_sum":                   1475185,
   475  			},
   476  		},
   477  		"success on response from Consul v1.13.2 client": {
   478  			prepare: caseConsulV1132ClientResponse,
   479  			// 3 node, 1 service check, no license
   480  			wantNumOfCharts: len(clientCharts) + 3 + 1 - 1,
   481  			wantMetrics: map[string]int64{
   482  				"client_rpc":                            34,
   483  				"client_rpc_exceeded":                   0,
   484  				"client_rpc_failed":                     0,
   485  				"health_check_chk1_critical_status":     0,
   486  				"health_check_chk1_maintenance_status":  0,
   487  				"health_check_chk1_passing_status":      1,
   488  				"health_check_chk1_warning_status":      0,
   489  				"health_check_chk2_critical_status":     1,
   490  				"health_check_chk2_maintenance_status":  0,
   491  				"health_check_chk2_passing_status":      0,
   492  				"health_check_chk2_warning_status":      0,
   493  				"health_check_chk3_critical_status":     1,
   494  				"health_check_chk3_maintenance_status":  0,
   495  				"health_check_chk3_passing_status":      0,
   496  				"health_check_chk3_warning_status":      0,
   497  				"health_check_mysql_critical_status":    1,
   498  				"health_check_mysql_maintenance_status": 0,
   499  				"health_check_mysql_passing_status":     0,
   500  				"health_check_mysql_warning_status":     0,
   501  				"runtime_alloc_bytes":                   26333408,
   502  				"runtime_sys_bytes":                     51201032,
   503  				"runtime_total_gc_pause_ns":             4182423,
   504  			},
   505  		},
   506  		"fail on invalid data response": {
   507  			prepare:         caseInvalidDataResponse,
   508  			wantNumOfCharts: 0,
   509  			wantMetrics:     nil,
   510  		},
   511  		"fail on connection refused": {
   512  			prepare:         caseConnectionRefused,
   513  			wantNumOfCharts: 0,
   514  			wantMetrics:     nil,
   515  		},
   516  		"fail on 404 response": {
   517  			prepare:         case404,
   518  			wantNumOfCharts: 0,
   519  			wantMetrics:     nil,
   520  		},
   521  	}
   522  
   523  	for name, test := range tests {
   524  		t.Run(name, func(t *testing.T) {
   525  			consul, cleanup := test.prepare(t)
   526  			defer cleanup()
   527  
   528  			mx := consul.Collect()
   529  
   530  			delete(mx, "autopilot_server_stable_time")
   531  			delete(test.wantMetrics, "autopilot_server_stable_time")
   532  
   533  			require.Equal(t, test.wantMetrics, mx)
   534  			if len(test.wantMetrics) > 0 {
   535  				assert.Equal(t, test.wantNumOfCharts, len(*consul.Charts()))
   536  			}
   537  		})
   538  	}
   539  }
   540  
   541  func caseConsulV1143CloudServerResponse(t *testing.T) (*Consul, func()) {
   542  	t.Helper()
   543  	srv := httptest.NewServer(http.HandlerFunc(
   544  		func(w http.ResponseWriter, r *http.Request) {
   545  			switch {
   546  			case r.URL.Path == urlPathAgentSelf:
   547  				_, _ = w.Write(dataV1143CloudServerSelf)
   548  			case r.URL.Path == urlPathAgentChecks:
   549  				_, _ = w.Write(dataV1143CloudChecks)
   550  			case r.URL.Path == urlPathAgentMetrics && r.URL.RawQuery == "format=prometheus":
   551  				_, _ = w.Write(dataV1143CloudServerPromMetrics)
   552  			case r.URL.Path == urlPathOperationAutopilotHealth:
   553  				w.WriteHeader(http.StatusForbidden)
   554  			case r.URL.Path == urlPathCoordinateNodes:
   555  				_, _ = w.Write(dataV1143CloudServerCoordinateNodes)
   556  			default:
   557  				w.WriteHeader(http.StatusNotFound)
   558  			}
   559  		}))
   560  
   561  	consul := New()
   562  	consul.URL = srv.URL
   563  
   564  	require.True(t, consul.Init())
   565  
   566  	return consul, srv.Close
   567  }
   568  
   569  func caseConsulV1132ServerResponse(t *testing.T) (*Consul, func()) {
   570  	t.Helper()
   571  	srv := httptest.NewServer(http.HandlerFunc(
   572  		func(w http.ResponseWriter, r *http.Request) {
   573  			switch {
   574  			case r.URL.Path == urlPathAgentSelf:
   575  				_, _ = w.Write(dataV1132ServerSelf)
   576  			case r.URL.Path == urlPathAgentChecks:
   577  				_, _ = w.Write(datav1132Checks)
   578  			case r.URL.Path == urlPathAgentMetrics && r.URL.RawQuery == "format=prometheus":
   579  				_, _ = w.Write(dataV1132ServerPromMetrics)
   580  			case r.URL.Path == urlPathOperationAutopilotHealth:
   581  				_, _ = w.Write(dataV1132ServerOperatorAutopilotHealth)
   582  			case r.URL.Path == urlPathCoordinateNodes:
   583  				_, _ = w.Write(dataV1132ServerCoordinateNodes)
   584  			default:
   585  				w.WriteHeader(http.StatusNotFound)
   586  			}
   587  		}))
   588  
   589  	consul := New()
   590  	consul.URL = srv.URL
   591  
   592  	require.True(t, consul.Init())
   593  
   594  	return consul, srv.Close
   595  }
   596  
   597  func caseConsulV1132ServerWithHostnameResponse(t *testing.T) (*Consul, func()) {
   598  	t.Helper()
   599  	srv := httptest.NewServer(http.HandlerFunc(
   600  		func(w http.ResponseWriter, r *http.Request) {
   601  			switch {
   602  			case r.URL.Path == urlPathAgentSelf:
   603  				_, _ = w.Write(dataV1132ServerSelfWithHostname)
   604  			case r.URL.Path == urlPathAgentChecks:
   605  				_, _ = w.Write(datav1132Checks)
   606  			case r.URL.Path == urlPathAgentMetrics && r.URL.RawQuery == "format=prometheus":
   607  				_, _ = w.Write(dataV1132ServerPromMetricsWithHostname)
   608  			case r.URL.Path == urlPathOperationAutopilotHealth:
   609  				_, _ = w.Write(dataV1132ServerOperatorAutopilotHealth)
   610  			case r.URL.Path == urlPathCoordinateNodes:
   611  				_, _ = w.Write(dataV1132ServerCoordinateNodes)
   612  			default:
   613  				w.WriteHeader(http.StatusNotFound)
   614  			}
   615  		}))
   616  
   617  	consul := New()
   618  	consul.URL = srv.URL
   619  
   620  	require.True(t, consul.Init())
   621  
   622  	return consul, srv.Close
   623  }
   624  
   625  func caseConsulV1132ServerWithDisabledPrometheus(t *testing.T) (*Consul, func()) {
   626  	t.Helper()
   627  	srv := httptest.NewServer(http.HandlerFunc(
   628  		func(w http.ResponseWriter, r *http.Request) {
   629  			switch r.URL.Path {
   630  			case urlPathAgentSelf:
   631  				_, _ = w.Write(dataV1132ServerSelfDisabledPrometheus)
   632  			case urlPathAgentChecks:
   633  				_, _ = w.Write(datav1132Checks)
   634  			case urlPathOperationAutopilotHealth:
   635  				_, _ = w.Write(dataV1132ServerOperatorAutopilotHealth)
   636  			case urlPathCoordinateNodes:
   637  				_, _ = w.Write(dataV1132ServerCoordinateNodes)
   638  			default:
   639  				w.WriteHeader(http.StatusNotFound)
   640  			}
   641  		}))
   642  
   643  	consul := New()
   644  	consul.URL = srv.URL
   645  
   646  	require.True(t, consul.Init())
   647  
   648  	return consul, srv.Close
   649  }
   650  
   651  func caseConsulV1132ClientResponse(t *testing.T) (*Consul, func()) {
   652  	t.Helper()
   653  	srv := httptest.NewServer(http.HandlerFunc(
   654  		func(w http.ResponseWriter, r *http.Request) {
   655  			switch {
   656  			case r.URL.Path == urlPathAgentSelf:
   657  				_, _ = w.Write(dataV1132ClientSelf)
   658  			case r.URL.Path == urlPathAgentChecks:
   659  				_, _ = w.Write(datav1132Checks)
   660  			case r.URL.Path == urlPathAgentMetrics && r.URL.RawQuery == "format=prometheus":
   661  				_, _ = w.Write(dataV1132ClientPromMetrics)
   662  			default:
   663  				w.WriteHeader(http.StatusNotFound)
   664  			}
   665  		}))
   666  
   667  	consul := New()
   668  	consul.URL = srv.URL
   669  
   670  	require.True(t, consul.Init())
   671  
   672  	return consul, srv.Close
   673  }
   674  
   675  func caseInvalidDataResponse(t *testing.T) (*Consul, func()) {
   676  	t.Helper()
   677  	srv := httptest.NewServer(http.HandlerFunc(
   678  		func(w http.ResponseWriter, r *http.Request) {
   679  			_, _ = w.Write([]byte("hello and\n goodbye"))
   680  		}))
   681  
   682  	consul := New()
   683  	consul.URL = srv.URL
   684  
   685  	require.True(t, consul.Init())
   686  
   687  	return consul, srv.Close
   688  }
   689  
   690  func caseConnectionRefused(t *testing.T) (*Consul, func()) {
   691  	t.Helper()
   692  	consul := New()
   693  	consul.URL = "http://127.0.0.1:65535/"
   694  	require.True(t, consul.Init())
   695  
   696  	return consul, func() {}
   697  }
   698  
   699  func case404(t *testing.T) (*Consul, func()) {
   700  	t.Helper()
   701  	srv := httptest.NewServer(http.HandlerFunc(
   702  		func(w http.ResponseWriter, r *http.Request) {
   703  			w.WriteHeader(http.StatusNotFound)
   704  		}))
   705  
   706  	consul := New()
   707  	consul.URL = srv.URL
   708  	require.True(t, consul.Init())
   709  
   710  	return consul, srv.Close
   711  }