test: add test for mysql gatherGlobalVariables using sql-mock (#10987)
This commit is contained in:
parent
df6d4e7972
commit
1d659f5fbe
|
|
@ -82,7 +82,6 @@
|
|||
|
||||
- [#10462](https://github.com/influxdata/telegraf/pull/10462) `external.psi` Add psi plugin
|
||||
|
||||
|
||||
## v1.22.0
|
||||
|
||||
### Influx Line Protocol Parser
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -188,6 +188,7 @@ require (
|
|||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0
|
||||
github.com/Microsoft/go-winio v0.4.17 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.24 // indirect
|
||||
github.com/alecthomas/participle v0.4.1 // indirect
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -167,6 +167,8 @@ github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV
|
|||
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
|
|
|
|||
|
|
@ -629,7 +629,7 @@ func (m *Mysql) gatherSlaveStatuses(db *sql.DB, serv string, acc telegraf.Accumu
|
|||
continue
|
||||
}
|
||||
|
||||
if colValue == nil || len(colValue) == 0 {
|
||||
if len(colValue) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
|
|
@ -21,6 +22,7 @@ func TestMysqlDefaultsToLocalIntegration(t *testing.T) {
|
|||
var acc testutil.Accumulator
|
||||
err := m.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, acc.Errors)
|
||||
|
||||
require.True(t, acc.HasMeasurement("mysql"))
|
||||
}
|
||||
|
|
@ -42,6 +44,7 @@ func TestMysqlMultipleInstancesIntegration(t *testing.T) {
|
|||
var acc, acc2 testutil.Accumulator
|
||||
err := m.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, acc.Errors)
|
||||
require.True(t, acc.HasMeasurement("mysql"))
|
||||
// acc should have global variables
|
||||
require.True(t, acc.HasMeasurement("mysql_variables"))
|
||||
|
|
@ -52,6 +55,7 @@ func TestMysqlMultipleInstancesIntegration(t *testing.T) {
|
|||
}
|
||||
err = m2.Gather(&acc2)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, acc.Errors)
|
||||
require.True(t, acc2.HasMeasurement("mysql"))
|
||||
// acc2 should not have global variables
|
||||
require.False(t, acc2.HasMeasurement("mysql_variables"))
|
||||
|
|
@ -178,6 +182,142 @@ func TestMysqlDNSAddTimeout(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGatherGlobalVariables(t *testing.T) {
|
||||
db, mock, err := sqlmock.New()
|
||||
require.NoError(t, err)
|
||||
defer db.Close()
|
||||
|
||||
m := Mysql{
|
||||
Log: testutil.Logger{},
|
||||
MetricVersion: 2,
|
||||
}
|
||||
m.InitMysql()
|
||||
|
||||
columns := []string{"Variable_name", "Value"}
|
||||
measurement := "mysql_variables"
|
||||
|
||||
type fields []struct {
|
||||
key string
|
||||
rawValue string
|
||||
parsedValue interface{}
|
||||
}
|
||||
type tags map[string]string
|
||||
testCases := []struct {
|
||||
name string
|
||||
fields fields
|
||||
tags tags
|
||||
}{
|
||||
{
|
||||
"basic variables",
|
||||
fields{
|
||||
{"__test__string_variable", "text", "text"},
|
||||
{"__test__int_variable", "5", int64(5)},
|
||||
{"__test__off_variable", "OFF", int64(0)},
|
||||
{"__test__on_variable", "ON", int64(1)},
|
||||
{"__test__empty_variable", "", nil},
|
||||
},
|
||||
tags{"server": "127.0.0.1:3306"},
|
||||
},
|
||||
{
|
||||
"version tag is present",
|
||||
fields{
|
||||
{"__test__string_variable", "text", "text"},
|
||||
{"version", "8.0.27-0ubuntu0.20.04.1", "8.0.27-0ubuntu0.20.04.1"},
|
||||
},
|
||||
tags{"server": "127.0.0.1:3306", "version": "8.0.27-0ubuntu0.20.04.1"},
|
||||
},
|
||||
|
||||
{"", fields{{"delay_key_write", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"delay_key_write", "ON", "ON"}}, nil},
|
||||
{"", fields{{"delay_key_write", "ALL", "ALL"}}, nil},
|
||||
{"", fields{{"enforce_gtid_consistency", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"enforce_gtid_consistency", "ON", "ON"}}, nil},
|
||||
{"", fields{{"enforce_gtid_consistency", "WARN", "WARN"}}, nil},
|
||||
{"", fields{{"event_scheduler", "NO", "NO"}}, nil},
|
||||
{"", fields{{"event_scheduler", "YES", "YES"}}, nil},
|
||||
{"", fields{{"event_scheduler", "DISABLED", "DISABLED"}}, nil},
|
||||
{"", fields{{"have_ssl", "DISABLED", int64(0)}}, nil},
|
||||
{"", fields{{"have_ssl", "YES", int64(1)}}, nil},
|
||||
{"", fields{{"have_symlink", "NO", int64(0)}}, nil},
|
||||
{"", fields{{"have_symlink", "DISABLED", int64(0)}}, nil},
|
||||
{"", fields{{"have_symlink", "YES", int64(1)}}, nil},
|
||||
{"", fields{{"session_track_gtids", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"session_track_gtids", "OWN_GTID", "OWN_GTID"}}, nil},
|
||||
{"", fields{{"session_track_gtids", "ALL_GTIDS", "ALL_GTIDS"}}, nil},
|
||||
{"", fields{{"session_track_transaction_info", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"session_track_transaction_info", "STATE", "STATE"}}, nil},
|
||||
{"", fields{{"session_track_transaction_info", "CHARACTERISTICS", "CHARACTERISTICS"}}, nil},
|
||||
{"", fields{{"ssl_fips_mode", "0", "0"}}, nil}, // TODO: map this to OFF or vice versa using integers
|
||||
{"", fields{{"ssl_fips_mode", "1", "1"}}, nil}, // TODO: map this to ON or vice versa using integers
|
||||
{"", fields{{"ssl_fips_mode", "2", "2"}}, nil}, // TODO: map this to STRICT or vice versa using integers
|
||||
{"", fields{{"ssl_fips_mode", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"ssl_fips_mode", "ON", "ON"}}, nil},
|
||||
{"", fields{{"ssl_fips_mode", "STRICT", "STRICT"}}, nil},
|
||||
{"", fields{{"use_secondary_engine", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"use_secondary_engine", "ON", "ON"}}, nil},
|
||||
{"", fields{{"use_secondary_engine", "FORCED", "FORCED"}}, nil},
|
||||
{"", fields{{"transaction_write_set_extraction", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"transaction_write_set_extraction", "MURMUR32", "MURMUR32"}}, nil},
|
||||
{"", fields{{"transaction_write_set_extraction", "XXHASH64", "XXHASH64"}}, nil},
|
||||
{"", fields{{"slave_skip_errors", "OFF", "OFF"}}, nil},
|
||||
{"", fields{{"slave_skip_errors", "0", "0"}}, nil},
|
||||
{"", fields{{"slave_skip_errors", "1007,1008,1050", "1007,1008,1050"}}, nil},
|
||||
{"", fields{{"slave_skip_errors", "all", "all"}}, nil},
|
||||
{"", fields{{"slave_skip_errors", "ddl_exist_errors", "ddl_exist_errors"}}, nil},
|
||||
{"", fields{{"gtid_mode", "OFF", int64(0)}}, nil},
|
||||
{"", fields{{"gtid_mode", "OFF_PERMISSIVE", int64(0)}}, nil},
|
||||
{"", fields{{"gtid_mode", "ON", int64(1)}}, nil},
|
||||
{"", fields{{"gtid_mode", "ON_PERMISSIVE", int64(1)}}, nil},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
if testCase.name == "" {
|
||||
testCase.name = fmt.Sprintf("#%d", i)
|
||||
}
|
||||
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
rows := sqlmock.NewRows(columns)
|
||||
for _, field := range testCase.fields {
|
||||
rows.AddRow(field.key, field.rawValue)
|
||||
}
|
||||
|
||||
mock.ExpectQuery(globalVariablesQuery).WillReturnRows(rows).RowsWillBeClosed()
|
||||
|
||||
acc := &testutil.Accumulator{}
|
||||
|
||||
err = m.gatherGlobalVariables(db, "test", acc)
|
||||
require.NoErrorf(t, err, "err on gatherGlobalVariables (test case %q)", testCase.name)
|
||||
|
||||
foundFields := map[string]bool{}
|
||||
|
||||
for _, metric := range acc.Metrics {
|
||||
require.Equalf(t, measurement, metric.Measurement, "wrong measurement (test case %q)", testCase.name)
|
||||
|
||||
if testCase.tags != nil {
|
||||
require.Equalf(t, testCase.tags, tags(metric.Tags), "wrong tags (test case %q)", testCase.name)
|
||||
}
|
||||
|
||||
for key, value := range metric.Fields {
|
||||
for _, field := range testCase.fields {
|
||||
if field.key == key {
|
||||
require.Falsef(t, foundFields[key], "field %s observed multiple times (test case %q)", key, testCase.name)
|
||||
require.Equalf(t, field.parsedValue, value, "wrong value for field %s (test case %q)", key, testCase.name)
|
||||
foundFields[key] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.Truef(t, foundFields[key], "unexpected field %s=%v (test case %q)", key, value, testCase.name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, field := range testCase.fields {
|
||||
require.Truef(t, foundFields[field.key], "missing field %s=%v (test case %q)", field.key, field.parsedValue, testCase.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewNamespace(t *testing.T) {
|
||||
testCases := []struct {
|
||||
words []string
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ func ParseGTIDMode(value sql.RawBytes) (interface{}, error) {
|
|||
|
||||
func ParseValue(value sql.RawBytes) (interface{}, error) {
|
||||
if bytes.EqualFold(value, []byte("YES")) || bytes.Equal(value, []byte("ON")) {
|
||||
return 1, nil
|
||||
return int64(1), nil
|
||||
}
|
||||
|
||||
if bytes.EqualFold(value, []byte("NO")) || bytes.Equal(value, []byte("OFF")) {
|
||||
return 0, nil
|
||||
return int64(0), nil
|
||||
}
|
||||
|
||||
if val, err := strconv.ParseInt(string(value), 10, 64); err == nil {
|
||||
|
|
@ -99,19 +99,28 @@ var GlobalStatusConversions = map[string]ConversionFunc{
|
|||
var GlobalVariableConversions = map[string]ConversionFunc{
|
||||
// see https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
|
||||
// see https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
|
||||
"delay_key_write": ParseString, // ON, OFF, ALL
|
||||
"enforce_gtid_consistency": ParseString, // ON, OFF, WARN
|
||||
"event_scheduler": ParseString, // YES, NO, DISABLED
|
||||
"gtid_mode": ParseGTIDMode,
|
||||
"have_openssl": ParseBoolAsInteger, // alias for have_ssl
|
||||
"have_ssl": ParseBoolAsInteger, // YES, DISABLED
|
||||
"have_symlink": ParseBoolAsInteger, // YES, NO, DISABLED
|
||||
"session_track_gtids": ParseString,
|
||||
"session_track_transaction_info": ParseString,
|
||||
"slave_skip_errors": ParseString,
|
||||
"ssl_fips_mode": ParseString,
|
||||
"delay_key_write": ParseString, // ON, OFF, ALL
|
||||
"enforce_gtid_consistency": ParseString, // ON, OFF, WARN
|
||||
"event_scheduler": ParseString, // YES, NO, DISABLED
|
||||
"have_openssl": ParseBoolAsInteger, // alias for have_ssl
|
||||
"have_ssl": ParseBoolAsInteger, // YES, DISABLED
|
||||
"have_symlink": ParseBoolAsInteger, // YES, NO, DISABLED
|
||||
"session_track_gtids": ParseString,
|
||||
"session_track_transaction_info": ParseString,
|
||||
"ssl_fips_mode": ParseString,
|
||||
"use_secondary_engine": ParseString,
|
||||
|
||||
// https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html
|
||||
// https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html
|
||||
"transaction_write_set_extraction": ParseString,
|
||||
"use_secondary_engine": ParseString,
|
||||
|
||||
// https://dev.mysql.com/doc/refman/5.7/en/replication-options-replica.html
|
||||
// https://dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html
|
||||
"slave_skip_errors": ParseString,
|
||||
|
||||
// https://dev.mysql.com/doc/refman/5.7/en/replication-options-gtids.html
|
||||
// https://dev.mysql.com/doc/refman/8.0/en/replication-options-gtids.html
|
||||
"gtid_mode": ParseGTIDMode,
|
||||
}
|
||||
|
||||
func ConvertGlobalStatus(key string, value sql.RawBytes) (interface{}, error) {
|
||||
|
|
|
|||
|
|
@ -95,12 +95,12 @@ func TestParseValue(t *testing.T) {
|
|||
{sql.RawBytes("123"), int64(123), ""},
|
||||
{sql.RawBytes("abc"), "abc", ""},
|
||||
{sql.RawBytes("10.1"), 10.1, ""},
|
||||
{sql.RawBytes("ON"), 1, ""},
|
||||
{sql.RawBytes("OFF"), 0, ""},
|
||||
{sql.RawBytes("NO"), 0, ""},
|
||||
{sql.RawBytes("YES"), 1, ""},
|
||||
{sql.RawBytes("No"), 0, ""},
|
||||
{sql.RawBytes("Yes"), 1, ""},
|
||||
{sql.RawBytes("ON"), int64(1), ""},
|
||||
{sql.RawBytes("OFF"), int64(0), ""},
|
||||
{sql.RawBytes("NO"), int64(0), ""},
|
||||
{sql.RawBytes("YES"), int64(1), ""},
|
||||
{sql.RawBytes("No"), int64(0), ""},
|
||||
{sql.RawBytes("Yes"), int64(1), ""},
|
||||
{sql.RawBytes("-794"), int64(-794), ""},
|
||||
{sql.RawBytes("2147483647"), int64(2147483647), ""}, // max int32
|
||||
{sql.RawBytes("2147483648"), int64(2147483648), ""}, // too big for int32
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Azure Monitor Output Plugin
|
||||
|
||||
__The Azure Monitor custom metrics service is currently in preview and not
|
||||
available in a subset of Azure regions.__
|
||||
**The Azure Monitor custom metrics service is currently in preview and not
|
||||
available in a subset of Azure regions.**
|
||||
|
||||
This plugin will send custom metrics to Azure Monitor. Azure Monitor has a
|
||||
metric resolution of one minute. To handle this in Telegraf, the Azure Monitor
|
||||
|
|
|
|||
Loading…
Reference in New Issue