63 lines
2.0 KiB
Go
63 lines
2.0 KiB
Go
//go:build linux || freebsd
|
|||
|
|
// +build linux freebsd
|
||
|
|
|
||
|
|
package ftp
|
||
|
|
|
||
|
|
import (
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"codeberg.org/petrbalvin/goget/internal/output"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TestSaveFTPResume verifies the helper persists partial FTP progress
|
||
|
|
// to a .goget.meta sidecar and that the sidecar is suitable for a
|
||
|
|
// subsequent goget --resume invocation. The function is called from
|
||
|
|
// Client.DownloadFile when ctx is cancelled mid-transfer; without a
|
||
|
|
// working sidecar the user's interrupted download cannot be continued.
|
||
|
|
func TestSaveFTPResume(t *testing.T) {
|
||
|
|
tmp := t.TempDir()
|
||
|
|
out := filepath.Join(tmp, "file.bin")
|
||
|
|
|
||
|
|
// 1. First call records partial progress.
|
||
|
|
if err := saveFTPResume("ftp://example.com/file.bin", out, 4096, 1<<20); err != nil {
|
||
|
|
t.Fatalf("saveFTPResume: %v", err)
|
||
|
|
}
|
||
|
|
meta, err := output.LoadResumeMetadata(out)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("LoadResumeMetadata: %v", err)
|
||
|
|
}
|
||
|
|
if meta == nil {
|
||
|
|
t.Fatal("expected resume metadata, got nil")
|
||
|
|
}
|
||
|
|
if meta.URL != "ftp://example.com/file.bin" {
|
||
|
|
t.Errorf("URL = %q, want ftp://example.com/file.bin", meta.URL)
|
||
|
|
}
|
||
|
|
if meta.Downloaded != 4096 {
|
||
|
|
t.Errorf("Downloaded = %d, want 4096", meta.Downloaded)
|
||
|
|
}
|
||
|
|
if meta.Total != 1<<20 {
|
||
|
|
t.Errorf("Total = %d, want %d", meta.Total, 1<<20)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. Second call overwrites the sidecar with a later snapshot.
|
||
|
|
if err := saveFTPResume("ftp://example.com/file.bin", out, 8192, 1<<20); err != nil {
|
||
|
|
t.Fatalf("saveFTPResume (2): %v", err)
|
||
|
|
}
|
||
|
|
meta2, _ := output.LoadResumeMetadata(out)
|
||
|
|
if meta2 == nil || meta2.Downloaded != 8192 {
|
||
|
|
t.Errorf("second call did not update sidecar: %+v", meta2)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. Zero-byte save is a no-op (no point persisting a sidecar
|
||
|
|
// for an empty transfer).
|
||
|
|
out2 := filepath.Join(tmp, "empty.bin")
|
||
|
|
if err := saveFTPResume("ftp://x", out2, 0, 100); err != nil {
|
||
|
|
t.Errorf("zero-byte save returned error: %v", err)
|
||
|
|
}
|
||
|
|
if _, err := os.Stat(out2 + output.ResumeMetaFileSuffix); !os.IsNotExist(err) {
|
||
|
|
t.Errorf("expected no sidecar for zero-byte save, got one")
|
||
|
|
}
|
||
|
|
}
|