mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
fs: add more tests for filesystem functionality (#5493)
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn canonicalize_root_dir_unix() {
|
||||||
|
assert_eq!(fs::canonicalize("/.").await.unwrap().to_str().unwrap(), "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn canonicalize_root_dir_windows() {
|
||||||
|
// 2-step let bindings due to Rust memory semantics
|
||||||
|
let dir_path = fs::canonicalize("C:\\.\\").await.unwrap();
|
||||||
|
|
||||||
|
let dir_name = dir_path.to_str().unwrap();
|
||||||
|
|
||||||
|
assert!(dir_name.starts_with("\\\\"));
|
||||||
|
assert!(dir_name.ends_with("C:\\"));
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|||||||
+40
-1
@@ -1,5 +1,5 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support directory operations
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio_test::{assert_err, assert_ok};
|
use tokio_test::{assert_err, assert_ok};
|
||||||
@@ -45,6 +45,27 @@ async fn build_dir() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn build_dir_mode_read_only() {
|
||||||
|
let base_dir = tempdir().unwrap();
|
||||||
|
let new_dir = base_dir.path().join("abc");
|
||||||
|
|
||||||
|
assert_ok!(
|
||||||
|
fs::DirBuilder::new()
|
||||||
|
.recursive(true)
|
||||||
|
.mode(0o444)
|
||||||
|
.create(&new_dir)
|
||||||
|
.await
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(fs::metadata(new_dir)
|
||||||
|
.await
|
||||||
|
.expect("metadata result")
|
||||||
|
.permissions()
|
||||||
|
.readonly());
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn remove() {
|
async fn remove() {
|
||||||
let base_dir = tempdir().unwrap();
|
let base_dir = tempdir().unwrap();
|
||||||
@@ -85,3 +106,21 @@ async fn read_inherent() {
|
|||||||
vec!["aa".to_string(), "bb".to_string(), "cc".to_string()]
|
vec!["aa".to_string(), "bb".to_string(), "cc".to_string()]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn read_dir_entry_info() {
|
||||||
|
let temp_dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let file_path = temp_dir.path().join("a.txt");
|
||||||
|
|
||||||
|
fs::write(&file_path, b"Hello File!").await.unwrap();
|
||||||
|
|
||||||
|
let mut dir = fs::read_dir(temp_dir.path()).await.unwrap();
|
||||||
|
|
||||||
|
let first_entry = dir.next_entry().await.unwrap().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(first_entry.path(), file_path);
|
||||||
|
assert_eq!(first_entry.file_name(), "a.txt");
|
||||||
|
assert!(first_entry.metadata().await.unwrap().is_file());
|
||||||
|
assert!(first_entry.file_type().await.unwrap().is_file());
|
||||||
|
}
|
||||||
|
|||||||
+103
-2
@@ -1,5 +1,5 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
@@ -87,13 +87,93 @@ async fn coop() {
|
|||||||
panic!("did not yield");
|
panic!("did not yield");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn write_to_clone() {
|
||||||
|
let tempfile = tempfile();
|
||||||
|
|
||||||
|
let file = File::create(tempfile.path()).await.unwrap();
|
||||||
|
let mut clone = file.try_clone().await.unwrap();
|
||||||
|
|
||||||
|
clone.write_all(HELLO).await.unwrap();
|
||||||
|
clone.flush().await.unwrap();
|
||||||
|
|
||||||
|
let contents = std::fs::read(tempfile.path()).unwrap();
|
||||||
|
assert_eq!(contents, HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn write_into_std() {
|
||||||
|
let tempfile = tempfile();
|
||||||
|
|
||||||
|
let file = File::create(tempfile.path()).await.unwrap();
|
||||||
|
let mut std_file = file.into_std().await;
|
||||||
|
|
||||||
|
std_file.write_all(HELLO).unwrap();
|
||||||
|
|
||||||
|
let contents = std::fs::read(tempfile.path()).unwrap();
|
||||||
|
assert_eq!(contents, HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn write_into_std_immediate() {
|
||||||
|
let tempfile = tempfile();
|
||||||
|
|
||||||
|
let file = File::create(tempfile.path()).await.unwrap();
|
||||||
|
let mut std_file = file.try_into_std().unwrap();
|
||||||
|
|
||||||
|
std_file.write_all(HELLO).unwrap();
|
||||||
|
|
||||||
|
let contents = std::fs::read(tempfile.path()).unwrap();
|
||||||
|
assert_eq!(contents, HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn read_file_from_std() {
|
||||||
|
let mut tempfile = tempfile();
|
||||||
|
tempfile.write_all(HELLO).unwrap();
|
||||||
|
|
||||||
|
let std_file = std::fs::File::open(tempfile.path()).unwrap();
|
||||||
|
let mut file = File::from(std_file);
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
let n = file.read(&mut buf).await.unwrap();
|
||||||
|
assert_eq!(n, HELLO.len());
|
||||||
|
assert_eq!(&buf[..n], HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
fn tempfile() -> NamedTempFile {
|
fn tempfile() -> NamedTempFile {
|
||||||
NamedTempFile::new().unwrap()
|
NamedTempFile::new().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
async fn unix_fd() {
|
async fn file_debug_fmt() {
|
||||||
|
let tempfile = tempfile();
|
||||||
|
|
||||||
|
let file = File::open(tempfile.path()).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
&format!("{:?}", file)[0..33],
|
||||||
|
"tokio::fs::File { std: File { fd:"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn file_debug_fmt() {
|
||||||
|
let tempfile = tempfile();
|
||||||
|
|
||||||
|
let file = File::open(tempfile.path()).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
&format!("{:?}", file)[0..37],
|
||||||
|
"tokio::fs::File { std: File { handle:"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn unix_fd_is_valid() {
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
let tempfile = tempfile();
|
let tempfile = tempfile();
|
||||||
|
|
||||||
@@ -101,6 +181,27 @@ async fn unix_fd() {
|
|||||||
assert!(file.as_raw_fd() as u64 > 0);
|
assert!(file.as_raw_fd() as u64 > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn read_file_from_unix_fd() {
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
use std::os::unix::io::FromRawFd;
|
||||||
|
|
||||||
|
let mut tempfile = tempfile();
|
||||||
|
tempfile.write_all(HELLO).unwrap();
|
||||||
|
|
||||||
|
let file1 = File::open(tempfile.path()).await.unwrap();
|
||||||
|
let raw_fd = file1.as_raw_fd();
|
||||||
|
assert!(raw_fd > 0);
|
||||||
|
|
||||||
|
let mut file2 = unsafe { File::from_raw_fd(raw_fd) };
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
let n = file2.read(&mut buf).await.unwrap();
|
||||||
|
assert_eq!(n, HELLO.len());
|
||||||
|
assert_eq!(&buf[..n], HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
async fn windows_handle() {
|
async fn windows_handle() {
|
||||||
|
|||||||
+26
-33
@@ -1,10 +1,9 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use std::io::prelude::*;
|
use std::io::Write;
|
||||||
use std::io::BufReader;
|
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -13,24 +12,23 @@ async fn test_hard_link() {
|
|||||||
let src = dir.path().join("src.txt");
|
let src = dir.path().join("src.txt");
|
||||||
let dst = dir.path().join("dst.txt");
|
let dst = dir.path().join("dst.txt");
|
||||||
|
|
||||||
{
|
std::fs::File::create(&src)
|
||||||
let mut file = std::fs::File::create(&src).unwrap();
|
.unwrap()
|
||||||
file.write_all(b"hello").unwrap();
|
.write_all(b"hello")
|
||||||
}
|
.unwrap();
|
||||||
|
|
||||||
let dst_2 = dst.clone();
|
fs::hard_link(&src, &dst).await.unwrap();
|
||||||
|
|
||||||
assert!(fs::hard_link(src, dst_2.clone()).await.is_ok());
|
std::fs::File::create(&src)
|
||||||
|
.unwrap()
|
||||||
|
.write_all(b"new-data")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut content = String::new();
|
let content = fs::read(&dst).await.unwrap();
|
||||||
|
assert_eq!(content, b"new-data");
|
||||||
|
|
||||||
{
|
// test that this is not a symlink:
|
||||||
let file = std::fs::File::open(dst).unwrap();
|
assert!(fs::read_link(&dst).await.is_err());
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
reader.read_to_string(&mut content).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(content == "hello");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@@ -40,25 +38,20 @@ async fn test_symlink() {
|
|||||||
let src = dir.path().join("src.txt");
|
let src = dir.path().join("src.txt");
|
||||||
let dst = dir.path().join("dst.txt");
|
let dst = dir.path().join("dst.txt");
|
||||||
|
|
||||||
{
|
std::fs::File::create(&src)
|
||||||
let mut file = std::fs::File::create(&src).unwrap();
|
.unwrap()
|
||||||
file.write_all(b"hello").unwrap();
|
.write_all(b"hello")
|
||||||
}
|
.unwrap();
|
||||||
|
|
||||||
let src_2 = src.clone();
|
fs::symlink(&src, &dst).await.unwrap();
|
||||||
let dst_2 = dst.clone();
|
|
||||||
|
|
||||||
assert!(fs::symlink(src_2.clone(), dst_2.clone()).await.is_ok());
|
std::fs::File::create(&src)
|
||||||
|
.unwrap()
|
||||||
|
.write_all(b"new-data")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut content = String::new();
|
let content = fs::read(&dst).await.unwrap();
|
||||||
|
assert_eq!(content, b"new-data");
|
||||||
{
|
|
||||||
let file = std::fs::File::open(dst.clone()).unwrap();
|
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
reader.read_to_string(&mut content).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(content == "hello");
|
|
||||||
|
|
||||||
let read = fs::read_link(dst.clone()).await.unwrap();
|
let read = fs::read_link(dst.clone()).await.unwrap();
|
||||||
assert!(read == src);
|
assert!(read == src);
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
use tokio::fs::OpenOptions;
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
|
const HELLO: &[u8] = b"hello world...";
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_with_open_options_and_read() {
|
||||||
|
let mut tempfile = NamedTempFile::new().unwrap();
|
||||||
|
tempfile.write_all(HELLO).unwrap();
|
||||||
|
|
||||||
|
let mut file = OpenOptions::new().read(true).open(tempfile).await.unwrap();
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
let n = file.read(&mut buf).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(n, HELLO.len());
|
||||||
|
assert_eq!(&buf[..n], HELLO);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_options_write() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().write(true)).contains("write: true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_options_append() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().append(true)).contains("append: true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_options_truncate() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().truncate(true)).contains("truncate: true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_options_create() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().create(true)).contains("create: true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn open_options_create_new() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().create_new(true)).contains("create_new: true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn open_options_mode() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().mode(0o644)).contains("mode: 420 "));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
async fn open_options_custom_flags_linux() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(
|
||||||
|
format!("{:?}", OpenOptions::new().custom_flags(libc::O_TRUNC))
|
||||||
|
.contains("custom_flags: 512,")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
|
||||||
|
async fn open_options_custom_flags_bsd_family() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(
|
||||||
|
format!("{:?}", OpenOptions::new().custom_flags(libc::O_NOFOLLOW))
|
||||||
|
.contains("custom_flags: 256,")
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
#![cfg(windows)]
|
||||||
|
|
||||||
|
use tokio::fs::OpenOptions;
|
||||||
|
use windows_sys::Win32::Storage::FileSystem;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn open_options_windows_access_mode() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().access_mode(0)).contains("access_mode: Some(0)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn open_options_windows_share_mode() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!("{:?}", OpenOptions::new().share_mode(0)).contains("share_mode: 0,"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn open_options_windows_custom_flags() {
|
||||||
|
// TESTING HACK: use Debug output to check the stored data
|
||||||
|
assert!(format!(
|
||||||
|
"{:?}",
|
||||||
|
OpenOptions::new().custom_flags(FileSystem::FILE_FLAG_DELETE_ON_CLOSE)
|
||||||
|
)
|
||||||
|
.contains("custom_flags: 67108864,"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn open_options_windows_attributes() {
|
||||||
|
assert!(format!(
|
||||||
|
"{:?}",
|
||||||
|
OpenOptions::new().attributes(FileSystem::FILE_ATTRIBUTE_HIDDEN)
|
||||||
|
)
|
||||||
|
.contains("attributes: 2,"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(windows)]
|
||||||
|
async fn open_options_windows_security_qos_flags() {
|
||||||
|
assert!(format!(
|
||||||
|
"{:?}",
|
||||||
|
OpenOptions::new().security_qos_flags(FileSystem::SECURITY_IDENTIFICATION)
|
||||||
|
)
|
||||||
|
.contains("security_qos_flags: 1114112,"));
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn remove_dir_all() {
|
||||||
|
let temp_dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let test_dir = temp_dir.path().join("test");
|
||||||
|
fs::create_dir(&test_dir).await.unwrap();
|
||||||
|
|
||||||
|
let file_path = test_dir.as_path().join("a.txt");
|
||||||
|
|
||||||
|
fs::write(&file_path, b"Hello File!").await.unwrap();
|
||||||
|
|
||||||
|
fs::remove_dir_all(test_dir.as_path()).await.unwrap();
|
||||||
|
|
||||||
|
// test dir should no longer exist
|
||||||
|
match fs::try_exists(test_dir).await {
|
||||||
|
Ok(exists) => assert!(!exists),
|
||||||
|
Err(_) => println!("ignored try_exists error after remove_dir_all"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// contents should no longer exist
|
||||||
|
match fs::try_exists(file_path).await {
|
||||||
|
Ok(exists) => assert!(!exists),
|
||||||
|
Err(_) => println!("ignored try_exists error after remove_dir_all"),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn remove_file() {
|
||||||
|
let temp_dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let file_path = temp_dir.path().join("a.txt");
|
||||||
|
|
||||||
|
fs::write(&file_path, b"Hello File!").await.unwrap();
|
||||||
|
|
||||||
|
assert!(fs::try_exists(&file_path).await.unwrap());
|
||||||
|
|
||||||
|
fs::remove_file(&file_path).await.unwrap();
|
||||||
|
|
||||||
|
// should no longer exist
|
||||||
|
match fs::try_exists(file_path).await {
|
||||||
|
Ok(exists) => assert!(!exists),
|
||||||
|
Err(_) => println!("ignored try_exists error after remove_file"),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn rename_file() {
|
||||||
|
let temp_dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let file_path = temp_dir.path().join("a.txt");
|
||||||
|
|
||||||
|
fs::write(&file_path, b"Hello File!").await.unwrap();
|
||||||
|
|
||||||
|
assert!(fs::try_exists(&file_path).await.unwrap());
|
||||||
|
|
||||||
|
let new_file_path = temp_dir.path().join("b.txt");
|
||||||
|
|
||||||
|
fs::rename(&file_path, &new_file_path).await.unwrap();
|
||||||
|
|
||||||
|
assert!(fs::try_exists(new_file_path).await.unwrap());
|
||||||
|
|
||||||
|
// original file should no longer exist
|
||||||
|
match fs::try_exists(file_path).await {
|
||||||
|
Ok(exists) => assert!(!exists),
|
||||||
|
Err(_) => println!("ignored try_exists error after rename"),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
#![cfg(windows)]
|
||||||
|
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn symlink_file_windows() {
|
||||||
|
const FILE_NAME: &str = "abc.txt";
|
||||||
|
|
||||||
|
let temp_dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let dir1 = temp_dir.path().join("a");
|
||||||
|
fs::create_dir(&dir1).await.unwrap();
|
||||||
|
|
||||||
|
let file1 = dir1.as_path().join(FILE_NAME);
|
||||||
|
fs::write(&file1, b"Hello File!").await.unwrap();
|
||||||
|
|
||||||
|
let dir2 = temp_dir.path().join("b");
|
||||||
|
fs::symlink_dir(&dir1, &dir2).await.unwrap();
|
||||||
|
|
||||||
|
fs::write(&file1, b"new data!").await.unwrap();
|
||||||
|
|
||||||
|
let file2 = dir2.as_path().join(FILE_NAME);
|
||||||
|
|
||||||
|
let from = fs::read(&file1).await.unwrap();
|
||||||
|
let to = fs::read(&file2).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(from, to);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
#![cfg(windows)]
|
||||||
|
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn symlink_file_windows() {
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
|
||||||
|
let source_path = dir.path().join("foo.txt");
|
||||||
|
let dest_path = dir.path().join("bar.txt");
|
||||||
|
|
||||||
|
fs::write(&source_path, b"Hello File!").await.unwrap();
|
||||||
|
fs::symlink_file(&source_path, &dest_path).await.unwrap();
|
||||||
|
|
||||||
|
fs::write(&source_path, b"new data!").await.unwrap();
|
||||||
|
|
||||||
|
let from = fs::read(&source_path).await.unwrap();
|
||||||
|
let to = fs::read(&dest_path).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(from, to);
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations
|
#![cfg(all(feature = "full", not(tokio_wasi)))] // WASI does not support all fs operations
|
||||||
|
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|||||||
Reference in New Issue
Block a user