check / check (push) Waiting to run
One progress reporter spans every path of a snapshot. Its counts of files and bytes processed run across all the paths, while the totals they were divided by were reset to each path's own, so a second path smaller than the first showed more than 100% and an ETA of `unknown`. The totals now add up over the paths scanned so far, and the processing start time the rate is measured from is the first path's. SetTotalSize is renamed AddTotalSize because it now adds. The issue says the ETA went negative; it was computed negative and printed as `unknown`. Model: opus-5-5
95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
package snapshot_test
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/spf13/afero"
|
|
"sneak.berlin/go/vaultik/internal/database"
|
|
"sneak.berlin/go/vaultik/internal/snapshot"
|
|
)
|
|
|
|
// TestProgressPercentWithSecondPathSmaller backs up two paths with one
|
|
// scanner, as a snapshot with two paths does, the second path smaller
|
|
// than the first. The progress line divides the bytes processed by the
|
|
// total size, so both must count both paths to stay within 100%.
|
|
func TestProgressPercentWithSecondPathSmaller(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
files := map[string]string{
|
|
"/large/one.txt": strings.Repeat("1", 4000),
|
|
"/large/two.txt": strings.Repeat("2", 4000),
|
|
"/small/three.txt": strings.Repeat("3", 1000),
|
|
}
|
|
|
|
for path, content := range files {
|
|
err := fs.MkdirAll(filepath.Dir(path), 0755)
|
|
if err != nil {
|
|
t.Fatalf("mkdir: %v", err)
|
|
}
|
|
|
|
err = afero.WriteFile(fs, path, []byte(content), 0644)
|
|
if err != nil {
|
|
t.Fatalf("write %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
db, err := database.NewTestDB()
|
|
if err != nil {
|
|
t.Fatalf("create test db: %v", err)
|
|
}
|
|
|
|
t.Cleanup(func() {
|
|
cerr := db.Close()
|
|
if cerr != nil {
|
|
t.Errorf("close db: %v", cerr)
|
|
}
|
|
})
|
|
|
|
repos := database.NewRepositories(db)
|
|
|
|
scanner := snapshot.NewScanner(snapshot.ScannerConfig{
|
|
FS: fs,
|
|
ChunkSize: int64(1024 * 16),
|
|
Repositories: repos,
|
|
MaxBlobSize: int64(1024 * 1024),
|
|
CompressionLevel: 3,
|
|
AgeRecipients: []string{testAgePublicKey},
|
|
EnableProgress: true,
|
|
})
|
|
|
|
// Never started, but Stop releases its tickers and signal handler.
|
|
progress := scanner.GetProgress()
|
|
defer progress.Stop()
|
|
|
|
ctx := context.Background()
|
|
snapshotID := "test-snapshot-progress"
|
|
createTestSnapshotRecord(ctx, t, repos, snapshotID)
|
|
|
|
for _, path := range []string{"/large", "/small"} {
|
|
_, err := scanner.Scan(ctx, path, snapshotID)
|
|
if err != nil {
|
|
t.Fatalf("scanning %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
stats := progress.GetStats()
|
|
|
|
// Directories count toward the total size but produce no chunks, so
|
|
// the percentage ends just under 100%.
|
|
percent := float64(stats.BytesProcessed.Load()) /
|
|
float64(stats.TotalSize.Load()) * 100
|
|
if percent > 100 {
|
|
t.Errorf("progress after both paths is %.1f%%, want at most 100%%",
|
|
percent)
|
|
}
|
|
|
|
if stats.FilesProcessed.Load() != stats.TotalFiles.Load() {
|
|
t.Errorf("progress after both paths is %d of %d files, want all",
|
|
stats.FilesProcessed.Load(), stats.TotalFiles.Load())
|
|
}
|
|
}
|