ceremonyclient/pebble/tool/data_test.go

137 lines
3.3 KiB
Go
Raw Permalink Normal View History

2024-01-03 07:31:42 +00:00
// Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use
// of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package tool
import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/cockroachdb/datadriven"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/pebble/internal/base"
"github.com/cockroachdb/pebble/internal/testkeys"
"github.com/cockroachdb/pebble/vfs"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
)
func runTests(t *testing.T, path string) {
paths, err := filepath.Glob(path)
require.NoError(t, err)
root := filepath.Dir(path)
for {
next := filepath.Dir(root)
if next == "." {
break
}
root = next
}
normalize := func(name string) string {
if os.PathSeparator == '/' {
return name
}
return strings.Replace(name, "/", string(os.PathSeparator), -1)
}
for _, path := range paths {
name, err := filepath.Rel(root, path)
require.NoError(t, err)
fs := vfs.NewMem()
t.Run(name, func(t *testing.T) {
datadriven.RunTest(t, path, func(t *testing.T, d *datadriven.TestData) string {
args := []string{d.Cmd}
for _, arg := range d.CmdArgs {
args = append(args, arg.String())
}
args = append(args, strings.Fields(d.Input)...)
// The testdata files contain paths with "/" path separators, but we
// might be running on a system with a different path separator
// (e.g. Windows). Copy the input data into a mem filesystem which
// always uses "/" for the path separator.
for i := range args {
src := normalize(args[i])
dest := vfs.Default.PathBase(src)
if ok, err := vfs.Clone(vfs.Default, fs, src, dest); err != nil {
return err.Error()
} else if ok {
args[i] = fs.PathBase(args[i])
}
}
var buf bytes.Buffer
var secs int64
timeNow = func() time.Time { secs++; return time.Unix(secs, 0) }
defer func() {
timeNow = time.Now
}()
// Register a test comparer and merger so that we can check the
// behavior of tools when the comparer and merger do not match.
comparer := func() *Comparer {
c := *base.DefaultComparer
c.Name = "test-comparer"
c.FormatKey = func(key []byte) fmt.Formatter {
return fmtFormatter{
fmt: "test formatter: %s",
v: key,
}
}
c.FormatValue = func(_, value []byte) fmt.Formatter {
return fmtFormatter{
fmt: "test value formatter: %s",
v: value,
}
}
return &c
}()
altComparer := func() *Comparer {
c := *base.DefaultComparer
c.Name = "alt-comparer"
return &c
}()
merger := func() *Merger {
m := *base.DefaultMerger
m.Name = "test-merger"
return &m
}()
openErrEnhancer := func(err error) error {
if errors.Is(err, base.ErrCorruption) {
return base.CorruptionErrorf("%v\nCustom message in case of corruption error.", err)
}
return err
}
tool := New(
DefaultComparer(comparer),
Comparers(altComparer, testkeys.Comparer),
Mergers(merger),
FS(fs),
OpenErrEnhancer(openErrEnhancer),
)
c := &cobra.Command{}
c.AddCommand(tool.Commands...)
c.SetArgs(args)
c.SetOut(&buf)
c.SetErr(&buf)
if err := c.Execute(); err != nil {
return err.Error()
}
return buf.String()
})
})
}
}