// Test sync/copy/move package sync import ( "context" "fmt" "runtime" "strings" "testing" "time" "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/all" // import all backends "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fstest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/text/unicode/norm") // Some times used in the testsvar ( t1 = fstest.Time("2001-02-03T04:05:06.499999999Z") t2 = fstest.Time("2011-12-25T12:59:59.123456789Z") t3 = fstest.Time("2011-12-30T12:59:59.000000000Z")) // TestMain drives the testsfunc TestMain(m *testing.M) { fstest.TestMain(m)} // Check dry run is workingfunc TestCopyWithDryRun(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) r.Mkdir(ctx, r.Fremote) ci.DryRun = true err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote)} // Now without dry runfunc TestCopy(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) r.Mkdir(ctx, r.Fremote) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1)} func TestCopyMissingDirectory(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() r.Mkdir(ctx, r.Fremote) nonExistingFs, err := fs.NewFs(ctx, "/non-existing") if err != nil { t.Fatal(err) } err = CopyDir(ctx, r.Fremote, nonExistingFs, false) require.Error(t, err)} // Now with --no-traversefunc TestCopyNoTraverse(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.NoTraverse = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1)} // Now with --check-firstfunc TestCopyCheckFirst(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.CheckFirst = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1)} // Now with --no-traversefunc TestSyncNoTraverse(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.NoTraverse = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1)} // Test copy with depthfunc TestCopyWithDepth(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) file2 := r.WriteFile("hello world2", "hello world2", t2) // Check the MaxDepth too ci.MaxDepth = 1 err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1, file2) fstest.CheckItems(t, r.Fremote, file2)} // Test copy with files fromfunc testCopyWithFilesFrom(t *testing.T, noTraverse bool) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("potato2", "hello world", t1) file2 := r.WriteFile("hello world2", "hello world2", t2) // Set the --files-from equivalent f, err := filter.NewFilter(nil) require.NoError(t, err) require.NoError(t, f.AddFile("potato2")) require.NoError(t, f.AddFile("notfound")) // Change the active filter ctx = filter.ReplaceConfig(ctx, f) ci.NoTraverse = noTraverse err = CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1, file2) fstest.CheckItems(t, r.Fremote, file1)}func TestCopyWithFilesFrom(t *testing.T) { testCopyWithFilesFrom(t, false) }func TestCopyWithFilesFromAndNoTraverse(t *testing.T) { testCopyWithFilesFrom(t, true) } // Test copy empty directoriesfunc TestCopyEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = CopyDir(ctx, r.Fremote, r.Flocal, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), )} // Test move empty directoriesfunc TestMoveEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = MoveDir(ctx, r.Fremote, r.Flocal, false, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), )} // Test sync empty directoriesfunc TestSyncEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = Sync(ctx, r.Fremote, r.Flocal, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), )} // Test a server-side copy if possible, or the backup path if notfunc TestServerSideCopy(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Fremote, file1) FremoteCopy, _, finaliseCopy, err := fstest.RandomRemote() require.NoError(t, err) defer finaliseCopy() t.Logf("Server side copy (if possible) %v -> %v", r.Fremote, FremoteCopy) err = CopyDir(ctx, FremoteCopy, r.Fremote, false) require.NoError(t, err) fstest.CheckItems(t, FremoteCopy, file1)} // Check that if the local file doesn't exist when we copy it up,// nothing happens to the remote filefunc TestCopyAfterDelete(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Flocal) fstest.CheckItems(t, r.Fremote, file1) err := operations.Mkdir(ctx, r.Flocal, "") require.NoError(t, err) err = CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal) fstest.CheckItems(t, r.Fremote, file1)} // Check the copy downloading a filefunc TestCopyRedownload(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Fremote, file1) err := CopyDir(ctx, r.Flocal, r.Fremote, false) require.NoError(t, err) // Test with combined precision of local and remote as we copied it there and back fstest.CheckListingWithPrecision(t, r.Flocal, []fstest.Item{file1}, nil, fs.GetModifyWindow(ctx, r.Flocal, r.Fremote))} // Create a file and sync it. Change the last modified date and resync.// If we're only doing sync by size and checksum, we expect nothing to// to be transferred on the second sync.func TestSyncBasedOnCheckSum(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.CheckSum = true file1 := r.WriteFile("check sum", "-", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Change last modified date only file2 := r.WriteFile("check sum", "-", t2) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1)} // Create a file and sync it. Change the last modified date and the// file contents but not the size. If we're only doing sync by size// only, we expect nothing to to be transferred on the second sync.func TestSyncSizeOnly(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.SizeOnly = true file1 := r.WriteFile("sizeonly", "potato", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Update mtime, md5sum but not length of file file2 := r.WriteFile("sizeonly", "POTATO", t2) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1)} // Create a file and sync it. Keep the last modified date but change// the size. With --ignore-size we expect nothing to to be// transferred on the second sync.func TestSyncIgnoreSize(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.IgnoreSize = true file1 := r.WriteFile("ignore-size", "contents", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Update size but not date of file file2 := r.WriteFile("ignore-size", "longer contents but same date", t1) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1)} func TestSyncIgnoreTimes(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteBoth(ctx, "existing", "potato", t1) fstest.CheckItems(t, r.Fremote, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly 0 files because the // files were identical. assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) ci.IgnoreTimes = true accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file even though the // files were identical. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1)} func TestSyncIgnoreExisting(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("existing", "potato", t1) ci.IgnoreExisting = true accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) // Change everything r.WriteFile("existing", "newpotatoes", t2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // Items should not change fstest.CheckItems(t, r.Fremote, file1)} func TestSyncIgnoreErrors(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) ci.IgnoreErrors = true defer r.Finalise() file1 := r.WriteFile("a/potato2", "------------------------------------------------------------", t1) file2 := r.WriteObject(ctx, "b/potato", "SMALLER BUT SAME DATE", t2) file3 := r.WriteBoth(ctx, "c/non empty space", "AhHa!", t2) require.NoError(t, operations.Mkdir(ctx, r.Fremote, "d")) fstest.CheckListingWithPrecision( t, r.Flocal, []fstest.Item{ file1, file3, },Lines 1–500 of 1965. Load more
// Test sync/copy/move package sync import ( "context" "fmt" "runtime" "strings" "testing" "time" "github.com/pkg/errors" _ "github.com/rclone/rclone/backend/all" // import all backends "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/filter" "github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fstest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/text/unicode/norm" ) // Some times used in the tests var ( t1 = fstest.Time("2001-02-03T04:05:06.499999999Z") t2 = fstest.Time("2011-12-25T12:59:59.123456789Z") t3 = fstest.Time("2011-12-30T12:59:59.000000000Z") ) // TestMain drives the tests func TestMain(m *testing.M) { fstest.TestMain(m) } // Check dry run is working func TestCopyWithDryRun(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) r.Mkdir(ctx, r.Fremote) ci.DryRun = true err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote) } // Now without dry run func TestCopy(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) r.Mkdir(ctx, r.Fremote) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) } func TestCopyMissingDirectory(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() r.Mkdir(ctx, r.Fremote) nonExistingFs, err := fs.NewFs(ctx, "/non-existing") if err != nil { t.Fatal(err) } err = CopyDir(ctx, r.Fremote, nonExistingFs, false) require.Error(t, err) } // Now with --no-traverse func TestCopyNoTraverse(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.NoTraverse = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) } // Now with --check-first func TestCopyCheckFirst(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.CheckFirst = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) } // Now with --no-traverse func TestSyncNoTraverse(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.NoTraverse = true file1 := r.WriteFile("sub dir/hello world", "hello world", t1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) } // Test copy with depth func TestCopyWithDepth(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) file2 := r.WriteFile("hello world2", "hello world2", t2) // Check the MaxDepth too ci.MaxDepth = 1 err := CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1, file2) fstest.CheckItems(t, r.Fremote, file2) } // Test copy with files from func testCopyWithFilesFrom(t *testing.T, noTraverse bool) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("potato2", "hello world", t1) file2 := r.WriteFile("hello world2", "hello world2", t2) // Set the --files-from equivalent f, err := filter.NewFilter(nil) require.NoError(t, err) require.NoError(t, f.AddFile("potato2")) require.NoError(t, f.AddFile("notfound")) // Change the active filter ctx = filter.ReplaceConfig(ctx, f) ci.NoTraverse = noTraverse err = CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1, file2) fstest.CheckItems(t, r.Fremote, file1) } func TestCopyWithFilesFrom(t *testing.T) { testCopyWithFilesFrom(t, false) } func TestCopyWithFilesFromAndNoTraverse(t *testing.T) { testCopyWithFilesFrom(t, true) } // Test copy empty directories func TestCopyEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = CopyDir(ctx, r.Fremote, r.Flocal, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), ) } // Test move empty directories func TestMoveEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = MoveDir(ctx, r.Fremote, r.Flocal, false, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), ) } // Test sync empty directories func TestSyncEmptyDirectories(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("sub dir/hello world", "hello world", t1) err := operations.Mkdir(ctx, r.Flocal, "sub dir2") require.NoError(t, err) r.Mkdir(ctx, r.Fremote) err = Sync(ctx, r.Fremote, r.Flocal, true) require.NoError(t, err) fstest.CheckListingWithPrecision( t, r.Fremote, []fstest.Item{ file1, }, []string{ "sub dir", "sub dir2", }, fs.GetModifyWindow(ctx, r.Fremote), ) } // Test a server-side copy if possible, or the backup path if not func TestServerSideCopy(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Fremote, file1) FremoteCopy, _, finaliseCopy, err := fstest.RandomRemote() require.NoError(t, err) defer finaliseCopy() t.Logf("Server side copy (if possible) %v -> %v", r.Fremote, FremoteCopy) err = CopyDir(ctx, FremoteCopy, r.Fremote, false) require.NoError(t, err) fstest.CheckItems(t, FremoteCopy, file1) } // Check that if the local file doesn't exist when we copy it up, // nothing happens to the remote file func TestCopyAfterDelete(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Flocal) fstest.CheckItems(t, r.Fremote, file1) err := operations.Mkdir(ctx, r.Flocal, "") require.NoError(t, err) err = CopyDir(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal) fstest.CheckItems(t, r.Fremote, file1) } // Check the copy downloading a file func TestCopyRedownload(t *testing.T) { ctx := context.Background() r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteObject(ctx, "sub dir/hello world", "hello world", t1) fstest.CheckItems(t, r.Fremote, file1) err := CopyDir(ctx, r.Flocal, r.Fremote, false) require.NoError(t, err) // Test with combined precision of local and remote as we copied it there and back fstest.CheckListingWithPrecision(t, r.Flocal, []fstest.Item{file1}, nil, fs.GetModifyWindow(ctx, r.Flocal, r.Fremote)) } // Create a file and sync it. Change the last modified date and resync. // If we're only doing sync by size and checksum, we expect nothing to // to be transferred on the second sync. func TestSyncBasedOnCheckSum(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.CheckSum = true file1 := r.WriteFile("check sum", "-", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Change last modified date only file2 := r.WriteFile("check sum", "-", t2) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1) } // Create a file and sync it. Change the last modified date and the // file contents but not the size. If we're only doing sync by size // only, we expect nothing to to be transferred on the second sync. func TestSyncSizeOnly(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.SizeOnly = true file1 := r.WriteFile("sizeonly", "potato", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Update mtime, md5sum but not length of file file2 := r.WriteFile("sizeonly", "POTATO", t2) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1) } // Create a file and sync it. Keep the last modified date but change // the size. With --ignore-size we expect nothing to to be // transferred on the second sync. func TestSyncIgnoreSize(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() ci.IgnoreSize = true file1 := r.WriteFile("ignore-size", "contents", t1) fstest.CheckItems(t, r.Flocal, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Fremote, file1) // Update size but not date of file file2 := r.WriteFile("ignore-size", "longer contents but same date", t1) fstest.CheckItems(t, r.Flocal, file2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred no files assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file2) fstest.CheckItems(t, r.Fremote, file1) } func TestSyncIgnoreTimes(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteBoth(ctx, "existing", "potato", t1) fstest.CheckItems(t, r.Fremote, file1) accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly 0 files because the // files were identical. assert.Equal(t, int64(0), accounting.GlobalStats().GetTransfers()) ci.IgnoreTimes = true accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // We should have transferred exactly one file even though the // files were identical. assert.Equal(t, toyFileTransfers(r), accounting.GlobalStats().GetTransfers()) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) } func TestSyncIgnoreExisting(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) defer r.Finalise() file1 := r.WriteFile("existing", "potato", t1) ci.IgnoreExisting = true accounting.GlobalStats().ResetCounters() err := Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) fstest.CheckItems(t, r.Flocal, file1) fstest.CheckItems(t, r.Fremote, file1) // Change everything r.WriteFile("existing", "newpotatoes", t2) accounting.GlobalStats().ResetCounters() err = Sync(ctx, r.Fremote, r.Flocal, false) require.NoError(t, err) // Items should not change fstest.CheckItems(t, r.Fremote, file1) } func TestSyncIgnoreErrors(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx) r := fstest.NewRun(t) ci.IgnoreErrors = true defer r.Finalise() file1 := r.WriteFile("a/potato2", "------------------------------------------------------------", t1) file2 := r.WriteObject(ctx, "b/potato", "SMALLER BUT SAME DATE", t2) file3 := r.WriteBoth(ctx, "c/non empty space", "AhHa!", t2) require.NoError(t, operations.Mkdir(ctx, r.Fremote, "d")) fstest.CheckListingWithPrecision( t, r.Flocal, []fstest.Item{ file1, file3, },