// This file is part of the uutils coreutils package. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use std::fs; use tempfile::tempdir; use uutests::new_ucmd; #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } #[test] fn test_sync_default() { new_ucmd!().succeeds(); } #[test] fn test_sync_incorrect_arg() { new_ucmd!().arg("--foo").fails(); } #[test] fn test_sync_fs() { let temporary_directory = tempdir().unwrap(); let temporary_path = fs::canonicalize(temporary_directory.path()).unwrap(); new_ucmd!() .arg("--file-system") .arg(&temporary_path) .succeeds(); } #[test] fn test_sync_fs_without_files_falls_back_to_full_sync() { new_ucmd!().arg("--file-system").succeeds(); } #[test] fn test_sync_data() { // Todo add a second arg let temporary_directory = tempdir().unwrap(); let temporary_path = fs::canonicalize(temporary_directory.path()).unwrap(); new_ucmd!().arg("--data").arg(&temporary_path).succeeds(); } #[test] fn test_sync_no_existing_files() { new_ucmd!() .arg("--data") .arg("do-no-exist") .fails() .stderr_contains("error opening"); } #[test] fn test_sync_data_but_not_file() { new_ucmd!() .arg("--data") .fails() .stderr_contains("sync: --data needs at least one argument"); } #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(feature = "chmod")] #[test] fn test_sync_no_permission_dir() { use uutests::util::TestScenario; use uutests::util_name; let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; let dir = "foo"; at.mkdir_all(dir); ts.ccmd("chmod").arg("0").arg(dir).succeeds(); let result = ts.ucmd().arg("--data").arg(dir).fails(); result.stderr_contains("sync: error opening 'foo': Permission denied"); let result = ts.ucmd().arg(dir).fails(); result.stderr_contains("sync: error opening 'foo': Permission denied"); } #[cfg(not(target_os = "windows"))] #[cfg(feature = "chmod")] #[test] fn test_sync_no_permission_file() { use uutests::util::TestScenario; use uutests::util_name; let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; let f = "file"; at.touch(f); ts.ccmd("chmod").arg("0200").arg(f).succeeds(); ts.ucmd().arg(f).succeeds(); } #[cfg(any(target_os = "linux", target_os = "android"))] #[test] fn test_sync_data_nonblock_flag_reset() { // Test that O_NONBLOCK flag is properly reset when syncing files use uutests::util::TestScenario; use uutests::util_name; let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; let test_file = "test_file.txt"; // Create a test file at.write(test_file, "test content"); // Run sync --data with the file - should succeed ts.ucmd().arg("--data").arg(test_file).succeeds(); } #[cfg(any(target_os = "linux", target_os = "android"))] #[test] fn test_sync_fs_nonblock_flag_reset() { // Test that O_NONBLOCK flag is properly reset when syncing filesystems use std::fs; use tempfile::tempdir; let temporary_directory = tempdir().unwrap(); let temporary_path = fs::canonicalize(temporary_directory.path()).unwrap(); // Run sync --file-system with the path - should succeed new_ucmd!() .arg("--file-system") .arg(&temporary_path) .succeeds(); } #[cfg(any(target_os = "linux", target_os = "android"))] #[test] fn test_sync_fdatasync_error_handling() { // Test that fdatasync properly handles file opening errors new_ucmd!() .arg("--data") .arg("/nonexistent/path/to/file") .fails() .stderr_contains("error opening"); } #[cfg(target_os = "macos")] #[test] fn test_sync_syncfs_error_handling_macos() { // Test that syncfs properly handles invalid paths on macOS new_ucmd!() .arg("--file-system") .arg("/nonexistent/path/to/file") .fails() .stderr_contains("error opening"); } #[test] fn test_sync_multiple_files() { // Test syncing multiple files at once use std::fs; use tempfile::tempdir; let temporary_directory = tempdir().unwrap(); let temp_path = temporary_directory.path(); // Create multiple test files let file1 = temp_path.join("file1.txt"); let file2 = temp_path.join("file2.txt"); fs::write(&file1, "content1").unwrap(); fs::write(&file2, "content2").unwrap(); // Sync both files new_ucmd!().arg("--data").arg(&file1).arg(&file2).succeeds(); } #[test] fn test_sync_multiple_nonexistent_files() { let result = new_ucmd!().arg("--data").arg("bad1").arg("bad2").fails(); result.stderr_contains("sync: error opening 'bad1': No such file or directory"); result.stderr_contains("sync: error opening 'bad2': No such file or directory"); } #[cfg(any(target_os = "linux", target_os = "android"))] #[test] fn test_sync_data_fifo_fails_immediately() { use std::time::Duration; use uutests::util::TestScenario; use uutests::util_name; let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; at.mkfifo("test-fifo"); ts.ucmd() .arg("--data") .arg(at.plus_as_string("test-fifo")) .timeout(Duration::from_secs(2)) .fails() .stderr_contains("error syncing") .stderr_contains("test-fifo") .stderr_contains("Invalid input"); }