2021-06-16 03:10:52 +08:00
|
|
|
package sql
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"math/rand"
|
|
|
|
|
"path/filepath"
|
2022-11-09 03:04:12 +08:00
|
|
|
"testing"
|
|
|
|
|
"time"
|
2021-06-16 03:10:52 +08:00
|
|
|
|
2022-06-04 00:29:08 +08:00
|
|
|
"github.com/docker/go-connections/nat"
|
2021-06-16 03:10:52 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
|
|
|
|
|
|
|
|
"github.com/influxdata/telegraf"
|
2022-12-09 00:53:06 +08:00
|
|
|
"github.com/influxdata/telegraf/config"
|
2021-06-16 03:10:52 +08:00
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func pwgen(n int) string {
|
|
|
|
|
charset := []byte("abcdedfghijklmnopqrstABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
|
|
|
|
|
|
|
|
|
nchars := len(charset)
|
|
|
|
|
buffer := make([]byte, n)
|
|
|
|
|
|
|
|
|
|
for i := range buffer {
|
|
|
|
|
buffer[i] = charset[rand.Intn(nchars)]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return string(buffer)
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-04 00:33:28 +08:00
|
|
|
func TestMariaDBIntegration(t *testing.T) {
|
2021-06-16 03:10:52 +08:00
|
|
|
if testing.Short() {
|
|
|
|
|
t.Skip("Skipping integration test in short mode")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger := testutil.Logger{}
|
|
|
|
|
|
|
|
|
|
port := "3306"
|
2022-06-04 00:29:08 +08:00
|
|
|
passwd := pwgen(32)
|
2021-06-16 03:10:52 +08:00
|
|
|
database := "foo"
|
|
|
|
|
|
2022-05-18 04:30:18 +08:00
|
|
|
// Determine the test-data mountpoint
|
|
|
|
|
testdata, err := filepath.Abs("testdata/mariadb")
|
|
|
|
|
require.NoError(t, err, "determining absolute path of test-data failed")
|
2021-06-16 03:10:52 +08:00
|
|
|
|
2022-06-04 00:29:08 +08:00
|
|
|
container := testutil.Container{
|
|
|
|
|
Image: "mariadb",
|
|
|
|
|
ExposedPorts: []string{port},
|
|
|
|
|
Env: map[string]string{
|
|
|
|
|
"MYSQL_ROOT_PASSWORD": passwd,
|
|
|
|
|
"MYSQL_DATABASE": database,
|
|
|
|
|
},
|
|
|
|
|
BindMounts: map[string]string{
|
|
|
|
|
"/docker-entrypoint-initdb.d": testdata,
|
2022-05-18 04:30:18 +08:00
|
|
|
},
|
2022-06-04 00:29:08 +08:00
|
|
|
WaitingFor: wait.ForAll(
|
2022-10-22 04:18:15 +08:00
|
|
|
wait.ForLog("mariadbd: ready for connections.").WithOccurrence(2),
|
2022-06-04 00:29:08 +08:00
|
|
|
wait.ForListeningPort(nat.Port(port)),
|
|
|
|
|
),
|
2021-06-16 03:10:52 +08:00
|
|
|
}
|
2022-06-04 00:29:08 +08:00
|
|
|
err = container.Start()
|
|
|
|
|
require.NoError(t, err, "failed to start container")
|
2022-11-09 03:04:12 +08:00
|
|
|
defer container.Terminate()
|
2022-05-18 04:30:18 +08:00
|
|
|
|
2021-06-16 03:10:52 +08:00
|
|
|
// Define the testset
|
|
|
|
|
var testset = []struct {
|
|
|
|
|
name string
|
|
|
|
|
queries []Query
|
|
|
|
|
expected []telegraf.Metric
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "metric_one",
|
|
|
|
|
queries: []Query{
|
|
|
|
|
{
|
|
|
|
|
Query: "SELECT * FROM metric_one",
|
|
|
|
|
TagColumnsInclude: []string{"tag_*"},
|
|
|
|
|
FieldColumnsExclude: []string{"tag_*", "timestamp"},
|
|
|
|
|
TimeColumn: "timestamp",
|
|
|
|
|
TimeFormat: "2006-01-02 15:04:05",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
expected: []telegraf.Metric{
|
|
|
|
|
testutil.MustMetric(
|
|
|
|
|
"sql",
|
|
|
|
|
map[string]string{
|
|
|
|
|
"tag_one": "tag1",
|
|
|
|
|
"tag_two": "tag2",
|
|
|
|
|
},
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
"int64_one": int64(1234),
|
|
|
|
|
"int64_two": int64(2345),
|
|
|
|
|
},
|
|
|
|
|
time.Date(2021, 5, 17, 22, 4, 45, 0, time.UTC),
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range testset {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
// Setup the plugin-under-test
|
2022-12-09 00:53:06 +08:00
|
|
|
dsn := fmt.Sprintf("root:%s@tcp(%s:%s)/%s", passwd, container.Address, container.Ports[port], database)
|
|
|
|
|
secret := config.NewSecret([]byte(dsn))
|
2021-06-16 03:10:52 +08:00
|
|
|
plugin := &SQL{
|
2022-12-09 00:53:06 +08:00
|
|
|
Driver: "maria",
|
|
|
|
|
Dsn: secret,
|
2021-06-16 03:10:52 +08:00
|
|
|
Queries: tt.queries,
|
|
|
|
|
Log: logger,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
|
|
// Startup the plugin
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Init())
|
|
|
|
|
require.NoError(t, plugin.Start(&acc))
|
2021-06-16 03:10:52 +08:00
|
|
|
|
|
|
|
|
// Gather
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Gather(&acc))
|
2021-06-16 03:10:52 +08:00
|
|
|
require.Len(t, acc.Errors, 0)
|
|
|
|
|
|
|
|
|
|
// Stopping the plugin
|
|
|
|
|
plugin.Stop()
|
|
|
|
|
|
|
|
|
|
// Do the comparison
|
|
|
|
|
testutil.RequireMetricsEqual(t, tt.expected, acc.GetTelegrafMetrics())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-04 00:33:28 +08:00
|
|
|
func TestPostgreSQLIntegration(t *testing.T) {
|
2021-06-16 03:10:52 +08:00
|
|
|
if testing.Short() {
|
|
|
|
|
t.Skip("Skipping integration test in short mode")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger := testutil.Logger{}
|
|
|
|
|
|
|
|
|
|
port := "5432"
|
2022-06-04 00:29:08 +08:00
|
|
|
passwd := pwgen(32)
|
2021-06-16 03:10:52 +08:00
|
|
|
database := "foo"
|
|
|
|
|
|
2022-05-18 04:30:18 +08:00
|
|
|
// Determine the test-data mountpoint
|
|
|
|
|
testdata, err := filepath.Abs("testdata/postgres")
|
|
|
|
|
require.NoError(t, err, "determining absolute path of test-data failed")
|
2021-06-16 03:10:52 +08:00
|
|
|
|
2022-06-04 00:29:08 +08:00
|
|
|
container := testutil.Container{
|
|
|
|
|
Image: "postgres",
|
|
|
|
|
ExposedPorts: []string{port},
|
|
|
|
|
Env: map[string]string{
|
|
|
|
|
"POSTGRES_PASSWORD": passwd,
|
|
|
|
|
"POSTGRES_DB": database,
|
|
|
|
|
},
|
|
|
|
|
BindMounts: map[string]string{
|
|
|
|
|
"/docker-entrypoint-initdb.d": testdata,
|
2022-05-18 04:30:18 +08:00
|
|
|
},
|
2022-06-04 00:29:08 +08:00
|
|
|
WaitingFor: wait.ForAll(
|
2022-10-22 04:18:15 +08:00
|
|
|
wait.ForLog("database system is ready to accept connections").WithOccurrence(2),
|
2022-06-04 00:29:08 +08:00
|
|
|
wait.ForListeningPort(nat.Port(port)),
|
|
|
|
|
),
|
2021-06-16 03:10:52 +08:00
|
|
|
}
|
2022-06-04 00:29:08 +08:00
|
|
|
err = container.Start()
|
|
|
|
|
require.NoError(t, err, "failed to start container")
|
2022-11-09 03:04:12 +08:00
|
|
|
defer container.Terminate()
|
2022-05-18 04:30:18 +08:00
|
|
|
|
2021-06-16 03:10:52 +08:00
|
|
|
// Define the testset
|
|
|
|
|
var testset = []struct {
|
|
|
|
|
name string
|
|
|
|
|
queries []Query
|
|
|
|
|
expected []telegraf.Metric
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "metric_one",
|
|
|
|
|
queries: []Query{
|
|
|
|
|
{
|
|
|
|
|
Query: "SELECT * FROM metric_one",
|
|
|
|
|
TagColumnsInclude: []string{"tag_*"},
|
|
|
|
|
FieldColumnsExclude: []string{"tag_*", "timestamp"},
|
|
|
|
|
TimeColumn: "timestamp",
|
|
|
|
|
TimeFormat: "2006-01-02 15:04:05",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
expected: []telegraf.Metric{
|
|
|
|
|
testutil.MustMetric(
|
|
|
|
|
"sql",
|
|
|
|
|
map[string]string{
|
|
|
|
|
"tag_one": "tag1",
|
|
|
|
|
"tag_two": "tag2",
|
|
|
|
|
},
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
"int64_one": int64(1234),
|
|
|
|
|
"int64_two": int64(2345),
|
|
|
|
|
},
|
|
|
|
|
time.Date(2021, 5, 17, 22, 4, 45, 0, time.UTC),
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range testset {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
// Setup the plugin-under-test
|
2022-12-09 00:53:06 +08:00
|
|
|
dsn := fmt.Sprintf("postgres://postgres:%v@%v:%v/%v", passwd, container.Address, container.Ports[port], database)
|
|
|
|
|
secret := config.NewSecret([]byte(dsn))
|
2021-06-16 03:10:52 +08:00
|
|
|
plugin := &SQL{
|
2022-12-09 00:53:06 +08:00
|
|
|
Driver: "pgx",
|
|
|
|
|
Dsn: secret,
|
2021-06-16 03:10:52 +08:00
|
|
|
Queries: tt.queries,
|
|
|
|
|
Log: logger,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
|
|
// Startup the plugin
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Init())
|
|
|
|
|
require.NoError(t, plugin.Start(&acc))
|
2021-06-16 03:10:52 +08:00
|
|
|
|
|
|
|
|
// Gather
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Gather(&acc))
|
2021-06-16 03:10:52 +08:00
|
|
|
require.Len(t, acc.Errors, 0)
|
|
|
|
|
|
|
|
|
|
// Stopping the plugin
|
|
|
|
|
plugin.Stop()
|
|
|
|
|
|
|
|
|
|
// Do the comparison
|
|
|
|
|
testutil.RequireMetricsEqual(t, tt.expected, acc.GetTelegrafMetrics())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-29 04:35:03 +08:00
|
|
|
|
2022-06-04 00:33:28 +08:00
|
|
|
func TestClickHouseIntegration(t *testing.T) {
|
2022-01-29 04:35:03 +08:00
|
|
|
if testing.Short() {
|
|
|
|
|
t.Skip("Skipping integration test in short mode")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger := testutil.Logger{}
|
|
|
|
|
|
|
|
|
|
port := "9000"
|
|
|
|
|
user := "default"
|
|
|
|
|
|
2022-05-18 04:30:18 +08:00
|
|
|
// Determine the test-data mountpoint
|
|
|
|
|
testdata, err := filepath.Abs("testdata/clickhouse")
|
|
|
|
|
require.NoError(t, err, "determining absolute path of test-data failed")
|
2022-01-29 04:35:03 +08:00
|
|
|
|
2022-06-04 00:29:08 +08:00
|
|
|
container := testutil.Container{
|
|
|
|
|
Image: "yandex/clickhouse-server",
|
|
|
|
|
ExposedPorts: []string{port, "8123"},
|
|
|
|
|
BindMounts: map[string]string{
|
|
|
|
|
"/docker-entrypoint-initdb.d": testdata,
|
2022-05-18 04:30:18 +08:00
|
|
|
},
|
2022-06-04 00:29:08 +08:00
|
|
|
WaitingFor: wait.ForAll(
|
|
|
|
|
wait.NewHTTPStrategy("/").WithPort(nat.Port("8123")),
|
|
|
|
|
wait.ForListeningPort(nat.Port(port)),
|
2022-10-22 04:18:15 +08:00
|
|
|
wait.ForLog("Saved preprocessed configuration to '/var/lib/clickhouse/preprocessed_configs/users.xml'.").WithOccurrence(2),
|
2022-06-04 00:29:08 +08:00
|
|
|
),
|
2022-01-29 04:35:03 +08:00
|
|
|
}
|
2022-06-04 00:29:08 +08:00
|
|
|
err = container.Start()
|
|
|
|
|
require.NoError(t, err, "failed to start container")
|
2022-11-09 03:04:12 +08:00
|
|
|
defer container.Terminate()
|
2022-05-18 04:30:18 +08:00
|
|
|
|
2022-01-29 04:35:03 +08:00
|
|
|
// Define the testset
|
|
|
|
|
var testset = []struct {
|
|
|
|
|
name string
|
|
|
|
|
queries []Query
|
|
|
|
|
expected []telegraf.Metric
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "metric_one",
|
|
|
|
|
queries: []Query{
|
|
|
|
|
{
|
|
|
|
|
Query: "SELECT * FROM default.metric_one",
|
|
|
|
|
TagColumnsInclude: []string{"tag_*"},
|
|
|
|
|
FieldColumnsExclude: []string{"tag_*", "timestamp"},
|
|
|
|
|
TimeColumn: "timestamp",
|
|
|
|
|
TimeFormat: "unix",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
expected: []telegraf.Metric{
|
|
|
|
|
testutil.MustMetric(
|
|
|
|
|
"sql",
|
|
|
|
|
map[string]string{
|
|
|
|
|
"tag_one": "tag1",
|
|
|
|
|
"tag_two": "tag2",
|
|
|
|
|
},
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
"int64_one": int64(1234),
|
|
|
|
|
"int64_two": int64(2345),
|
|
|
|
|
},
|
|
|
|
|
time.Unix(1621289085, 0),
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range testset {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
// Setup the plugin-under-test
|
2022-12-09 00:53:06 +08:00
|
|
|
dsn := fmt.Sprintf("tcp://%v:%v?username=%v", container.Address, container.Ports[port], user)
|
|
|
|
|
secret := config.NewSecret([]byte(dsn))
|
2022-01-29 04:35:03 +08:00
|
|
|
plugin := &SQL{
|
2022-12-09 00:53:06 +08:00
|
|
|
Driver: "clickhouse",
|
|
|
|
|
Dsn: secret,
|
2022-01-29 04:35:03 +08:00
|
|
|
Queries: tt.queries,
|
|
|
|
|
Log: logger,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
|
|
// Startup the plugin
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Init())
|
|
|
|
|
require.NoError(t, plugin.Start(&acc))
|
2022-01-29 04:35:03 +08:00
|
|
|
|
|
|
|
|
// Gather
|
2022-12-09 00:53:06 +08:00
|
|
|
require.NoError(t, plugin.Gather(&acc))
|
2022-01-29 04:35:03 +08:00
|
|
|
require.Len(t, acc.Errors, 0)
|
|
|
|
|
|
|
|
|
|
// Stopping the plugin
|
|
|
|
|
plugin.Stop()
|
|
|
|
|
|
|
|
|
|
// Do the comparison
|
|
|
|
|
testutil.RequireMetricsEqual(t, tt.expected, acc.GetTelegrafMetrics())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|