mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-11-11 05:00:47 +08:00
fix(local): preserve completed files on canceled uploads
- Keep completed same-path files during canceled upload cleanup.\n- Add regression coverage for completed replacements. Co-authored-by: LunelleEverdawn <lunelle+suyunmeng@oplist.org>
This commit is contained in:
1 parent
74320ca6db
commit
e90b671e0b
2 files changed
+62
-1
No files matched your search
@@ -420,7 +420,9 @@ func (d *Local) Put(ctx context.Context, dstDir model.Obj, stream model.FileStre
|
||||
defer func() {
|
||||
_ = out.Close()
|
||||
if errors.Is(err, context.Canceled) {
|
||||
_ = os.Remove(fullPath)
|
||||
if info, statErr := os.Stat(fullPath); statErr == nil && info.Size() != stream.GetSize() {
|
||||
_ = os.Remove(fullPath)
|
||||
}
|
||||
}
|
||||
}()
|
||||
err = utils.CopyWithCtx(ctx, out, stream, stream.GetSize(), up)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
)
|
||||
|
||||
type blockedReader struct {
|
||||
started chan struct{}
|
||||
release chan struct{}
|
||||
}
|
||||
|
||||
func (r blockedReader) Read([]byte) (int, error) {
|
||||
close(r.started)
|
||||
<-r.release
|
||||
return 0, context.Canceled
|
||||
}
|
||||
|
||||
func TestPutCancellationPreservesCompletedReplacement(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
const content = "completed replacement"
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
reader := blockedReader{started: make(chan struct{}), release: make(chan struct{})}
|
||||
file := &stream.FileStream{
|
||||
Obj: &model.Object{Name: "test.bin", Size: int64(len(content))},
|
||||
Reader: reader,
|
||||
}
|
||||
|
||||
putDone := make(chan error, 1)
|
||||
go func() {
|
||||
putDone <- (&Local{}).Put(ctx, &model.Object{Path: root}, file, nil)
|
||||
}()
|
||||
<-reader.started
|
||||
|
||||
path := filepath.Join(root, "test.bin")
|
||||
if err := os.WriteFile(path, []byte(content), 0o666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cancel()
|
||||
close(reader.release)
|
||||
if err := <-putDone; !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("Put error = %v, want context.Canceled", err)
|
||||
}
|
||||
|
||||
got, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("completed replacement was removed: %v", err)
|
||||
}
|
||||
if string(got) != content {
|
||||
t.Fatalf("replacement contents = %q, want %q", got, content)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user