refactor: retry file remove/rename when a file is busy and clean up os detection (#38588)

Rename functions "util.Remove" (remove.go) to "util.RemoveWithRetry"
(file_retry.go) and add comments to clarify their behaviors, also add
tests.

Refactor callers: when no concurrent access (cmd cli, migration, app
init, test), use "os.Xxx" directly.

More details are in `modules/util/file_retry.go`

By the way, clean up OS (windows) detection, make FileURLToPath test
always run
This commit is contained in:
wxiaoguang
2026-07-23 22:31:29 +08:00
committed by GitHub
parent c4fc4d363b
commit e992b0a7cc
32 changed files with 225 additions and 225 deletions
+22 -20
View File
@@ -7,7 +7,6 @@ import (
"net/url"
"os"
"path/filepath"
"runtime"
"testing"
"github.com/stretchr/testify/assert"
@@ -18,43 +17,46 @@ func TestFileURLToPath(t *testing.T) {
cases := []struct {
url string
expected string
haserror bool
invalid bool
windows bool
}{
// case 0
{
url: "",
haserror: true,
url: "",
invalid: true,
},
// case 1
{
url: "http://test.io",
haserror: true,
url: "http://test.io",
invalid: true,
},
// case 2
{
url: "file:///path",
expected: "/path",
},
// case 3
{
url: "file:///C:/path",
expected: "C:/path",
windows: true,
},
{
url: "file:///z:/path",
expected: "z:/path",
windows: true,
},
{
url: "file:///path",
expected: "/path",
windows: true,
},
}
for n, c := range cases {
if c.windows && runtime.GOOS != "windows" {
continue
}
for _, c := range cases {
u, _ := url.Parse(c.url)
p, err := FileURLToPath(u)
if c.haserror {
assert.Error(t, err, "case %d: should return error", n)
p, err := fileURLToPathInternal(u, c.windows)
if c.invalid {
assert.Error(t, err, "case %s: should return error", c.url)
} else {
assert.NoError(t, err, "case %d: should not return error", n)
assert.Equal(t, c.expected, p, "case %d: should be equal", n)
assert.NoError(t, err, "case %s: should not return error", c.url)
assert.Equal(t, c.expected, p, "case %s: should be equal", c.url)
}
}
}
@@ -180,7 +182,7 @@ func TestCleanPath(t *testing.T) {
}
// for POSIX only, but the result is similar on Windows, because the first element must be an absolute path
if isOSWindows() {
if isOSWindows {
cases = []struct {
elems []string
expected string