mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-10-15 07:18:04 +00:00
* Prevent file corruption when writing tar backup to stdout FB-1794 Tar backups written to stdout were coming out corrupt. This turned out to be due to log messages getting written to stdout and ending up in the tar file. We now check to see if the tar file and the log are both going to stdout, and if they are, send the logs to stderr instead. Testing did not have any kind of consistency or validity check. We now compare a tar file sent to a file and a tar file sent to stdout to make sure they're the same. This does not guarantee correctness but does at least catch this form of corruption. * trying different index name Co-authored-by: tgruben <tgruben@gmail.com> Co-authored-by: Todd Gruben <todd@molecula.com>
68 lines
2 KiB
Go
68 lines
2 KiB
Go
package ctl
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
pilosa "github.com/molecula/featurebase/v3"
|
|
"github.com/molecula/featurebase/v3/test"
|
|
)
|
|
|
|
func TestBackupTarCommand_Run(t *testing.T) {
|
|
cluster := test.MustRunCluster(t, 1)
|
|
defer cluster.Close()
|
|
cmd := cluster.GetNode(0)
|
|
indexName := "backuptar"
|
|
|
|
// this might produce some annoying spam in tests but we need to make sure log messages to
|
|
// stdout are being redirected properly when the tarfile is also going to stdout
|
|
cm := NewBackupTarCommand(os.Stdout)
|
|
hostport := cmd.API.Node().URI.HostPort()
|
|
cm.Host = hostport
|
|
dir := t.TempDir()
|
|
cm.OutputPath = filepath.Join(dir, "backuptest.tar")
|
|
|
|
_, err := cmd.API.CreateIndex(context.Background(), indexName, pilosa.IndexOptions{Keys: true, TrackExistence: true})
|
|
if err != nil {
|
|
t.Fatalf("creating test index: %v", err)
|
|
}
|
|
_, err = cmd.API.CreateField(context.Background(), indexName, "f", pilosa.OptFieldKeys())
|
|
if err != nil {
|
|
t.Fatalf("creating test field: %v", err)
|
|
}
|
|
|
|
cm.Index = indexName
|
|
if err := cm.Run(context.Background()); err != nil {
|
|
t.Fatalf("BackupTarCommand Run error: %s", err)
|
|
}
|
|
|
|
oldpath := cm.OutputPath
|
|
cm.OutputPath = "-"
|
|
cfpath := filepath.Join(dir, "stdouttest.tar") //capture file
|
|
cf, err := os.Create(cfpath)
|
|
if err != nil {
|
|
t.Fatalf("opening file to compare file and stdout outputs: %v", err)
|
|
}
|
|
defer cf.Close()
|
|
// I don't like this at all but it's all i'm really finding for capturing os.Stdout
|
|
old := os.Stdout
|
|
defer func() { os.Stdout = old }()
|
|
os.Stdout = cf
|
|
if err := cm.Run(context.Background()); err != nil {
|
|
t.Fatalf("BackupTarCommand Run error: %s", err)
|
|
}
|
|
fdata, err := os.ReadFile(oldpath)
|
|
if err != nil {
|
|
t.Fatalf("unable to read from direct-to-file backup: %v", err)
|
|
}
|
|
cdata, err := os.ReadFile(cfpath)
|
|
if err != nil {
|
|
t.Fatalf("unable to read from captured stdout backup: %v", err)
|
|
}
|
|
if !bytes.Equal(fdata, cdata) {
|
|
t.Fatalf("backing up to file and to stdout produced different results")
|
|
}
|
|
}
|