211 lines
4.5 KiB
Go
211 lines
4.5 KiB
Go
package dump_tsm
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/influxdata/influxdb/v2/tsdb/engine/tsm1"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var argsKeys = []string{"index", "blocks", "all", "filter-key"}
|
|
|
|
func Test_DumpTSM_NoFile(t *testing.T) {
|
|
runCommand(t, cmdParams{
|
|
file: "",
|
|
expectOut: "TSM File not specified",
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_EmptyFile(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
expectErr: true,
|
|
expectOut: "error opening TSM file",
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_WrongExt(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{
|
|
wrongExt: true,
|
|
})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
expectErr: true,
|
|
expectOut: "is not a TSM file",
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_NotFile(t *testing.T) {
|
|
dir, _ := makeTSMFile(t, tsmParams{})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: dir,
|
|
expectErr: true,
|
|
expectOut: "is a directory",
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_Valid(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{
|
|
keys: []string{"cpu"},
|
|
})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
expectOuts: makeExpectOut(
|
|
[]string{"Summary:", "Index:", "Total: 1", "Size: 34"},
|
|
[]string{"Summary:", "Blocks:", "float64", "9/19", "s8b/gor"},
|
|
[]string{"Summary:", "Index:", "Blocks:", "Points:", "Encoding:", "Compression:"},
|
|
),
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_Invalid(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{
|
|
invalid: true,
|
|
keys: []string{"cpu"},
|
|
})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
expectErr: true,
|
|
expectOut: "error opening TSM file",
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_ManyKeys(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{
|
|
keys: []string{"cpu", "foobar", "mem"},
|
|
})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
expectOuts: makeExpectOut(
|
|
[]string{"Total: 3", "Size: 102"},
|
|
[]string{"Blocks:", "float64", "s8b/gor", "9/19"},
|
|
// TODO https://github.com/influxdata/influxdb/issues/22145
|
|
//[]string{"cpu", "foobar", "mem", "float64"},
|
|
),
|
|
})
|
|
}
|
|
|
|
func Test_DumpTSM_FilterKey(t *testing.T) {
|
|
_, file := makeTSMFile(t, tsmParams{
|
|
keys: []string{"cpu", "foobar", "mem"},
|
|
})
|
|
|
|
runCommand(t, cmdParams{
|
|
file: file,
|
|
filter: "cpu",
|
|
expectOuts: makeExpectOut(
|
|
[]string{"Total: 3", "Size: 102"},
|
|
[]string{"Blocks:", "float64", "s8b/gor", "9/19"},
|
|
// TODO https://github.com/influxdata/influxdb/issues/22145
|
|
//[]string{"cpu", "foobar", "mem", "float64"},
|
|
//[]string{"Points:\n Total: 1", "s8b: 1 (33%)", "gor: 1 (33%)"},
|
|
),
|
|
})
|
|
}
|
|
|
|
func makeExpectOut(outs ...[]string) (m map[string][]string) {
|
|
m = make(map[string][]string)
|
|
for i, value := range outs {
|
|
m[argsKeys[i]] = value
|
|
}
|
|
return
|
|
}
|
|
|
|
type cmdParams struct {
|
|
file string
|
|
expectErr bool
|
|
expectOuts map[string][]string
|
|
expectOut string
|
|
filter string
|
|
}
|
|
|
|
func runCommand(t *testing.T, params cmdParams) {
|
|
cmd := NewDumpTSMCommand()
|
|
|
|
b := bytes.NewBufferString("")
|
|
cmd.SetOut(b)
|
|
cmd.SetErr(b)
|
|
|
|
m := makeArgs(params.file, params.filter)
|
|
|
|
for argsKey, args := range m {
|
|
cmd.SetArgs(args)
|
|
if params.expectErr {
|
|
require.Error(t, cmd.Execute())
|
|
} else {
|
|
require.NoError(t, cmd.Execute())
|
|
}
|
|
|
|
out, err := io.ReadAll(b)
|
|
require.NoError(t, err)
|
|
|
|
if params.expectOut != "" {
|
|
require.Contains(t, string(out), params.expectOut)
|
|
} else {
|
|
for _, value := range params.expectOuts[argsKey] {
|
|
require.Contains(t, string(out), value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func makeArgs(path string, meas string) (args map[string][]string) {
|
|
args = make(map[string][]string)
|
|
args[argsKeys[0]] = []string{"--file-path", path, "--index"}
|
|
args[argsKeys[1]] = []string{"--file-path", path, "--blocks"}
|
|
args[argsKeys[2]] = []string{"--file-path", path, "--all"}
|
|
if meas != "" {
|
|
args[argsKeys[3]] = []string{"--file-path", path, "--filter-key", meas, "--all"}
|
|
}
|
|
return
|
|
}
|
|
|
|
type tsmParams struct {
|
|
wrongExt bool
|
|
invalid bool
|
|
keys []string
|
|
}
|
|
|
|
func makeTSMFile(t *testing.T, params tsmParams) (string, string) {
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
|
|
ext := tsm1.TSMFileExtension
|
|
if params.wrongExt {
|
|
ext = "txt"
|
|
}
|
|
file, err := os.CreateTemp(dir, "*."+ext)
|
|
require.NoError(t, err)
|
|
|
|
w, err := tsm1.NewTSMWriter(file)
|
|
require.NoError(t, err)
|
|
|
|
for _, key := range params.keys {
|
|
values := []tsm1.Value{tsm1.NewValue(0, 1.0)}
|
|
require.NoError(t, w.Write([]byte(key), values))
|
|
require.NoError(t, w.Flush())
|
|
}
|
|
if len(params.keys) != 0 {
|
|
require.NoError(t, w.WriteIndex())
|
|
}
|
|
|
|
if params.invalid {
|
|
require.NoError(t, binary.Write(file, binary.BigEndian, []byte("foobar\n")))
|
|
}
|
|
require.NoError(t, w.Close())
|
|
|
|
return dir, file.Name()
|
|
}
|