mirror of
https://github.com/rclone/rclone.git
synced 2024-11-23 00:43:49 +01:00
mounttest: fix unreliable tests on Windows CI
The failure is this which is not reproducable locally, only on the CI servers. --- FAIL: TestMount/CacheMode=minimal/TestWriteFileOverwrite (1.01s) fs.go:351: Error Trace: fs.go:351 write.go:65 Error: Received unexpected error: open E:testwrite: The request could not be performed because of an I/O device error. Test: TestMount/CacheMode=minimal/TestWriteFileOverwrite The corresponding ERROR from the log is this: ERROR : IO error: truncate C:\Users\runneradmin\AppData\Local\rclone\vfs\local\C\Users\RUNNER~1\AppData\Local\Temp\rclone298719627\testwrite: Access is denied. Instead of using ioutil.WriteFile this fix uses an equivalent based on rclone's lib/file which doesn't set the exclusive flag on Windows. This allows files to be deleted that are open. It also deletes existing files if an error is received and retries.
This commit is contained in:
parent
51dca8c8d4
commit
a4bc4daf30
@ -6,6 +6,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@ -22,6 +23,7 @@ import (
|
|||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/walk"
|
"github.com/rclone/rclone/fs/walk"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
|
"github.com/rclone/rclone/lib/file"
|
||||||
"github.com/rclone/rclone/vfs"
|
"github.com/rclone/rclone/vfs"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -345,9 +347,36 @@ func (r *Run) waitForWriters() {
|
|||||||
run.vfs.WaitForWriters(10 * time.Second)
|
run.vfs.WaitForWriters(10 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeFile writes data to a file named by filename.
|
||||||
|
// If the file does not exist, WriteFile creates it with permissions perm;
|
||||||
|
// otherwise writeFile truncates it before writing.
|
||||||
|
// If there is an error writing then writeFile
|
||||||
|
// deletes it an existing file and tries again.
|
||||||
|
func writeFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
|
f, err := file.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||||
|
if err != nil {
|
||||||
|
err = os.Remove(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f, err = file.OpenFile(filename, os.O_WRONLY|os.O_CREATE, perm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err := f.Write(data)
|
||||||
|
if err == nil && n < len(data) {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
}
|
||||||
|
if err1 := f.Close(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Run) createFile(t *testing.T, filepath string, contents string) {
|
func (r *Run) createFile(t *testing.T, filepath string, contents string) {
|
||||||
filepath = r.path(filepath)
|
filepath = r.path(filepath)
|
||||||
err := ioutil.WriteFile(filepath, []byte(contents), 0600)
|
err := writeFile(filepath, []byte(contents), 0600)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r.waitForWriters()
|
r.waitForWriters()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user