ClickHouse/programs/diagnostics/internal/runner_test.go
2022-11-25 08:52:49 +01:00

131 lines
4.6 KiB
Go

//go:build !no_docker
package internal_test
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"testing"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/collectors"
_ "github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/collectors/clickhouse"
_ "github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/collectors/system"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/outputs"
_ "github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/outputs/file"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/config"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/test"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/utils"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
// Execute a full default capture, with simple output, and check if a bundle is produced and it's not empty
func TestCapture(t *testing.T) {
// create a ClickHouse container
ctx := context.Background()
cwd, err := os.Getwd()
if err != nil {
// can't test without container
panic(err)
}
// for now, we test against a hardcoded database-server version but we should make this a property
req := testcontainers.ContainerRequest{
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
ExposedPorts: []string{"9000/tcp"},
WaitingFor: wait.ForLog("Ready for connections"),
Mounts: testcontainers.ContainerMounts{
{
Source: testcontainers.GenericBindMountSource{
HostPath: path.Join(cwd, "../testdata/docker/custom.xml"),
},
Target: "/etc/clickhouse-server/config.d/custom.xml",
},
{
Source: testcontainers.GenericBindMountSource{
HostPath: path.Join(cwd, "../testdata/docker/admin.xml"),
},
Target: "/etc/clickhouse-server/users.d/admin.xml",
},
},
}
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
// can't test without container
panic(err)
}
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
t.Setenv("CLICKHOUSE_DB_PORT", p.Port())
defer clickhouseContainer.Terminate(ctx) //nolint
tmrDir := t.TempDir()
port := p.Int()
// test a simple output exists
_, err = outputs.GetOutputByName("simple")
require.Nil(t, err)
// this relies on the simple out not changing its params - test will likely fail if so
outputConfig := config.Configuration{
Params: []config.ConfigParam{
config.StringParam{
Value: tmrDir,
Param: config.NewParam("directory", "Directory in which to create dump. Defaults to the current directory.", false),
},
config.StringOptions{
Value: "csv",
Options: []string{"csv"},
Param: config.NewParam("format", "Format of exported files", false),
},
config.BoolParam{
Value: true,
Param: config.NewParam("skip_archive", "Don't compress output to an archive", false),
},
},
}
// test default collectors
collectorNames := collectors.GetCollectorNames(true)
// grab all configs - only default will be used because of collectorNames
collectorConfigs, err := collectors.BuildConfigurationOptions()
require.Nil(t, err)
conf := internal.NewRunConfiguration("random", "localhost", uint16(port), "", "", "simple", outputConfig, collectorNames, collectorConfigs)
internal.Capture(conf)
outputDir := path.Join(tmrDir, "random")
_, err = os.Stat(outputDir)
require.Nil(t, err)
require.True(t, !os.IsNotExist(err))
files, err := ioutil.ReadDir(outputDir)
require.Nil(t, err)
require.Len(t, files, 1)
outputDir = path.Join(outputDir, files[0].Name())
// check we have a folder per collector i.e. collectorNames + diag_trace
files, err = ioutil.ReadDir(outputDir)
require.Nil(t, err)
require.Len(t, files, len(collectorNames)+1)
expectedFolders := append(collectorNames, "diag_trace")
for _, file := range files {
require.True(t, file.IsDir())
utils.Contains(expectedFolders, file.Name())
}
// we don't test the specific collector outputs but make sure something was written to system
systemFolder := path.Join(outputDir, "system")
files, err = ioutil.ReadDir(systemFolder)
require.Nil(t, err)
require.Greater(t, len(files), 0)
// test diag_trace
diagFolder := path.Join(outputDir, "diag_trace")
files, err = ioutil.ReadDir(diagFolder)
require.Nil(t, err)
require.Equal(t, 1, len(files))
require.FileExists(t, path.Join(diagFolder, "errors.csv"))
}