151 lines
3.0 KiB
Go
151 lines
3.0 KiB
Go
package verify_wal
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/influxdata/influxdb/v2/tsdb"
|
|
"github.com/influxdata/influxdb/v2/tsdb/engine/tsm1"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type testInfo struct {
|
|
t *testing.T
|
|
path string
|
|
expectedOut string
|
|
expectErr bool
|
|
withStdErr bool
|
|
}
|
|
|
|
func TestVerifies_InvalidFileType(t *testing.T) {
|
|
path := t.TempDir()
|
|
|
|
f, err := os.CreateTemp(path, "verifywaltest*"+".txt")
|
|
require.NoError(t, err)
|
|
require.NoError(t, f.Close())
|
|
|
|
runCommand(testInfo{
|
|
t: t,
|
|
path: path,
|
|
expectedOut: "no WAL files found in directory",
|
|
expectErr: true,
|
|
})
|
|
}
|
|
|
|
func TestVerifies_InvalidNotDir(t *testing.T) {
|
|
_, file := newTempWALInvalid(t, true)
|
|
|
|
runCommand(testInfo{
|
|
t: t,
|
|
path: file.Name(),
|
|
expectedOut: "is not a directory",
|
|
expectErr: true,
|
|
})
|
|
}
|
|
|
|
func TestVerifies_InvalidEmptyFile(t *testing.T) {
|
|
path, _ := newTempWALInvalid(t, true)
|
|
|
|
runCommand(testInfo{
|
|
t: t,
|
|
path: path,
|
|
expectedOut: "no WAL entries found",
|
|
withStdErr: true,
|
|
})
|
|
}
|
|
|
|
func TestVerifies_Invalid(t *testing.T) {
|
|
path, _ := newTempWALInvalid(t, false)
|
|
|
|
runCommand(testInfo{
|
|
t: t,
|
|
path: path,
|
|
expectedOut: "corrupt entry found at position",
|
|
withStdErr: true,
|
|
})
|
|
}
|
|
|
|
func TestVerifies_Valid(t *testing.T) {
|
|
path := newTempWALValid(t)
|
|
|
|
runCommand(testInfo{
|
|
t: t,
|
|
path: path,
|
|
expectedOut: "clean",
|
|
withStdErr: true,
|
|
})
|
|
}
|
|
|
|
func runCommand(args testInfo) {
|
|
verify := NewVerifyWALCommand()
|
|
verify.SetArgs([]string{"--wal-path", args.path, "--verbose"})
|
|
|
|
b := bytes.NewBufferString("")
|
|
verify.SetOut(b)
|
|
if args.withStdErr {
|
|
verify.SetErr(b)
|
|
}
|
|
|
|
if args.expectErr {
|
|
require.Error(args.t, verify.Execute())
|
|
} else {
|
|
require.NoError(args.t, verify.Execute())
|
|
}
|
|
|
|
out, err := io.ReadAll(b)
|
|
require.NoError(args.t, err)
|
|
require.Contains(args.t, string(out), args.expectedOut)
|
|
}
|
|
|
|
func newTempWALValid(t *testing.T) string {
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
|
|
w := tsm1.NewWAL(dir, 0, 0, tsdb.EngineTags{})
|
|
require.NoError(t, w.Open())
|
|
t.Cleanup(func() {
|
|
require.NoError(t, w.Close())
|
|
})
|
|
|
|
p1 := tsm1.NewValue(1, 1.1)
|
|
p2 := tsm1.NewValue(1, int64(1))
|
|
p3 := tsm1.NewValue(1, true)
|
|
p4 := tsm1.NewValue(1, "string")
|
|
p5 := tsm1.NewValue(1, ^uint64(0))
|
|
|
|
values := map[string][]tsm1.Value{
|
|
"cpu,host=A#!~#float": {p1},
|
|
"cpu,host=A#!~#int": {p2},
|
|
"cpu,host=A#!~#bool": {p3},
|
|
"cpu,host=A#!~#string": {p4},
|
|
"cpu,host=A#!~#unsigned": {p5},
|
|
}
|
|
|
|
_, err := w.WriteMulti(context.Background(), values)
|
|
require.NoError(t, err)
|
|
|
|
return dir
|
|
}
|
|
|
|
func newTempWALInvalid(t *testing.T, empty bool) (string, *os.File) {
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
|
|
file, err := os.CreateTemp(dir, "verifywaltest*."+tsm1.WALFileExtension)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { file.Close() })
|
|
|
|
if !empty {
|
|
written, err := file.Write([]byte("foobar"))
|
|
require.NoError(t, err)
|
|
require.Equal(t, 6, written)
|
|
}
|
|
|
|
return dir, file
|
|
}
|