bsdaily/internal/bsdaily/verify.go
2026-02-09 00:42:06 -08:00

64 lines
1.5 KiB
Go

package bsdaily
import (
"fmt"
"log/slog"
"os/exec"
"strings"
)
func VerifyOutput(path string) error {
slog.Info("running zstdmt integrity check")
testCmd := exec.Command("zstdmt", "--test", path)
var testStderr strings.Builder
testCmd.Stderr = &testStderr
if err := testCmd.Run(); err != nil {
return fmt.Errorf("zstdmt --test failed: %w; stderr: %s", err, testStderr.String())
}
slog.Info("zstdmt integrity check passed")
slog.Info("verifying SQL content")
catCmd := exec.Command("zstdcat", path)
headCmd := exec.Command("head", "-20")
pipe, err := catCmd.StdoutPipe()
if err != nil {
return fmt.Errorf("creating zstdcat pipe: %w", err)
}
headCmd.Stdin = pipe
var headOut strings.Builder
headCmd.Stdout = &headOut
if err := headCmd.Start(); err != nil {
return fmt.Errorf("starting head: %w", err)
}
if err := catCmd.Start(); err != nil {
return fmt.Errorf("starting zstdcat: %w", err)
}
// head closes pipe early, zstdcat gets SIGPIPE - expected
_ = headCmd.Wait()
_ = catCmd.Wait()
content := headOut.String()
if len(content) == 0 {
return fmt.Errorf("decompressed content is empty")
}
hasSQLMarker := false
for _, marker := range []string{"BEGIN TRANSACTION", "CREATE TABLE", "INSERT INTO", "PRAGMA"} {
if strings.Contains(content, marker) {
hasSQLMarker = true
break
}
}
if !hasSQLMarker {
return fmt.Errorf("decompressed content does not look like SQL; first 200 bytes: %s",
content[:min(200, len(content))])
}
slog.Info("SQL content verification passed")
return nil
}