about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-10-21 14:12:19 +0200
committerRalf Jung <post@ralfj.de>2022-10-21 14:22:12 +0200
commit7300aac798d033df973f595063c77ecd986e6d4e (patch)
tree8438183004b1d362489f59758c2d8fe862b79e17
parent9a1edc3c061021a48ffbd149340d7ce059faa97c (diff)
downloadrust-7300aac798d033df973f595063c77ecd986e6d4e.tar.gz
rust-7300aac798d033df973f595063c77ecd986e6d4e.zip
split libc tests from stdlib tests
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs28
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr6
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs.rs137
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs.stderr (renamed from src/tools/miri/tests/pass-dep/shims/fs.stderr)0
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs.stdout (renamed from src/tools/miri/tests/pass-dep/shims/fs.stdout)0
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout1
-rw-r--r--src/tools/miri/tests/pass/shims/fs-with-isolation.rs (renamed from src/tools/miri/tests/pass-dep/shims/fs_with_isolation.rs)19
-rw-r--r--src/tools/miri/tests/pass/shims/fs-with-isolation.stderr (renamed from src/tools/miri/tests/pass-dep/shims/fs_with_isolation.stderr)4
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs (renamed from src/tools/miri/tests/pass-dep/shims/fs.rs)101
9 files changed, 176 insertions, 120 deletions
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
new file mode 100644
index 00000000000..f1838cf64f7
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
@@ -0,0 +1,28 @@
+//@ignore-target-windows: no libc on Windows
+//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
+//@normalize-stderr-test: "(stat(x)?)" -> "$$STAT"
+
+use std::ffi::CString;
+use std::fs;
+use std::io::{Error, ErrorKind};
+
+fn main() {
+    // test `fcntl`
+    unsafe {
+        assert_eq!(libc::fcntl(1, libc::F_DUPFD, 0), -1);
+        assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
+    }
+
+    // test `readlink`
+    let symlink_c_str = CString::new("foo.txt").unwrap();
+    let mut buf = vec![0; "foo_link.txt".len() + 1];
+    unsafe {
+        assert_eq!(libc::readlink(symlink_c_str.as_ptr(), buf.as_mut_ptr(), buf.len()), -1);
+        assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES));
+    }
+
+    // test `stat`
+    assert_eq!(fs::metadata("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
+    // check that it is the right kind of `PermissionDenied`
+    assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES));
+}
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr
new file mode 100644
index 00000000000..21fcb65243e
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr
@@ -0,0 +1,6 @@
+warning: `fcntl` was made to return an error due to isolation
+
+warning: `readlink` was made to return an error due to isolation
+
+warning: `$STAT` was made to return an error due to isolation
+
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
new file mode 100644
index 00000000000..acf16ecb7e0
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs
@@ -0,0 +1,137 @@
+//@ignore-target-windows: no libc on Windows
+//@compile-flags: -Zmiri-disable-isolation
+
+#![feature(io_error_more)]
+#![feature(io_error_uncategorized)]
+
+use std::convert::TryInto;
+use std::ffi::CString;
+use std::fs::{canonicalize, remove_file, File};
+use std::io::{Error, ErrorKind, Write};
+use std::os::unix::ffi::OsStrExt;
+use std::path::PathBuf;
+
+fn main() {
+    test_dup_stdout_stderr();
+    test_canonicalize_too_long();
+    test_readlink();
+    test_file_open_unix_allow_two_args();
+    test_file_open_unix_needs_three_args();
+    test_file_open_unix_extra_third_arg();
+}
+
+fn tmp() -> PathBuf {
+    std::env::var("MIRI_TEMP")
+        .map(|tmp| {
+            // MIRI_TEMP is set outside of our emulated
+            // program, so it may have path separators that don't
+            // correspond to our target platform. We normalize them here
+            // before constructing a `PathBuf`
+
+            #[cfg(windows)]
+            return PathBuf::from(tmp.replace("/", "\\"));
+
+            #[cfg(not(windows))]
+            return PathBuf::from(tmp.replace("\\", "/"));
+        })
+        .unwrap_or_else(|_| std::env::temp_dir())
+}
+
+/// Prepare: compute filename and make sure the file does not exist.
+fn prepare(filename: &str) -> PathBuf {
+    let path = tmp().join(filename);
+    // Clean the paths for robustness.
+    remove_file(&path).ok();
+    path
+}
+
+/// Prepare like above, and also write some initial content to the file.
+fn prepare_with_content(filename: &str, content: &[u8]) -> PathBuf {
+    let path = prepare(filename);
+    let mut file = File::create(&path).unwrap();
+    file.write(content).unwrap();
+    path
+}
+
+fn test_file_open_unix_allow_two_args() {
+    let path = prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]);
+
+    let mut name = path.into_os_string();
+    name.push("\0");
+    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
+    let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY) };
+}
+
+fn test_file_open_unix_needs_three_args() {
+    let path = prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]);
+
+    let mut name = path.into_os_string();
+    name.push("\0");
+    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
+    let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT, 0o666) };
+}
+
+fn test_file_open_unix_extra_third_arg() {
+    let path = prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]);
+
+    let mut name = path.into_os_string();
+    name.push("\0");
+    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
+    let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 42) };
+}
+
+fn test_dup_stdout_stderr() {
+    let bytes = b"hello dup fd\n";
+    unsafe {
+        let new_stdout = libc::fcntl(1, libc::F_DUPFD, 0);
+        let new_stderr = libc::fcntl(2, libc::F_DUPFD, 0);
+        libc::write(new_stdout, bytes.as_ptr() as *const libc::c_void, bytes.len());
+        libc::write(new_stderr, bytes.as_ptr() as *const libc::c_void, bytes.len());
+    }
+}
+
+fn test_canonicalize_too_long() {
+    // Make sure we get an error for long paths.
+    let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap());
+    assert!(canonicalize(too_long).is_err());
+}
+
+fn test_readlink() {
+    let bytes = b"Hello, World!\n";
+    let path = prepare_with_content("miri_test_fs_link_target.txt", bytes);
+    let expected_path = path.as_os_str().as_bytes();
+
+    let symlink_path = prepare("miri_test_fs_symlink.txt");
+    std::os::unix::fs::symlink(&path, &symlink_path).unwrap();
+
+    // Test that the expected string gets written to a buffer of proper
+    // length, and that a trailing null byte is not written.
+    let symlink_c_str = CString::new(symlink_path.as_os_str().as_bytes()).unwrap();
+    let symlink_c_ptr = symlink_c_str.as_ptr();
+
+    // Make the buf one byte larger than it needs to be,
+    // and check that the last byte is not overwritten.
+    let mut large_buf = vec![0xFF; expected_path.len() + 1];
+    let res =
+        unsafe { libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) };
+    // Check that the resovled path was properly written into the buf.
+    assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path);
+    assert_eq!(large_buf.last(), Some(&0xFF));
+    assert_eq!(res, large_buf.len() as isize - 1);
+
+    // Test that the resolved path is truncated if the provided buffer
+    // is too small.
+    let mut small_buf = [0u8; 2];
+    let res =
+        unsafe { libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) };
+    assert_eq!(small_buf, &expected_path[..small_buf.len()]);
+    assert_eq!(res, small_buf.len() as isize);
+
+    // Test that we report a proper error for a missing path.
+    let bad_path = CString::new("MIRI_MISSING_FILE_NAME").unwrap();
+    let res = unsafe {
+        libc::readlink(bad_path.as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len())
+    };
+    assert_eq!(res, -1);
+    assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound);
+}
diff --git a/src/tools/miri/tests/pass-dep/shims/fs.stderr b/src/tools/miri/tests/pass-dep/shims/libc-fs.stderr
index b6fa69e3d5d..b6fa69e3d5d 100644
--- a/src/tools/miri/tests/pass-dep/shims/fs.stderr
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.stderr
diff --git a/src/tools/miri/tests/pass-dep/shims/fs.stdout b/src/tools/miri/tests/pass-dep/shims/libc-fs.stdout
index b6fa69e3d5d..b6fa69e3d5d 100644
--- a/src/tools/miri/tests/pass-dep/shims/fs.stdout
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs.stdout
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout b/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout
new file mode 100644
index 00000000000..b6fa69e3d5d
--- /dev/null
+++ b/src/tools/miri/tests/pass-dep/shims/libc-rsfs.stdout
@@ -0,0 +1 @@
+hello dup fd
diff --git a/src/tools/miri/tests/pass-dep/shims/fs_with_isolation.rs b/src/tools/miri/tests/pass/shims/fs-with-isolation.rs
index f5420dbc553..8fa683085b9 100644
--- a/src/tools/miri/tests/pass-dep/shims/fs_with_isolation.rs
+++ b/src/tools/miri/tests/pass/shims/fs-with-isolation.rs
@@ -2,21 +2,14 @@
 //@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
 //@normalize-stderr-test: "(stat(x)?)" -> "$$STAT"
 
-use std::ffi::CString;
 use std::fs::{self, File};
-use std::io::{Error, ErrorKind};
+use std::io::ErrorKind;
 use std::os::unix;
 
 fn main() {
     // test `open`
     assert_eq!(File::create("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
 
-    // test `fcntl`
-    unsafe {
-        assert_eq!(libc::fcntl(1, libc::F_DUPFD, 0), -1);
-        assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM));
-    }
-
     // test `unlink`
     assert_eq!(fs::remove_file("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
 
@@ -26,17 +19,8 @@ fn main() {
         ErrorKind::PermissionDenied
     );
 
-    // test `readlink`
-    let symlink_c_str = CString::new("foo.txt").unwrap();
-    let mut buf = vec![0; "foo_link.txt".len() + 1];
-    unsafe {
-        assert_eq!(libc::readlink(symlink_c_str.as_ptr(), buf.as_mut_ptr(), buf.len()), -1);
-        assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES));
-    }
-
     // test `stat`
     assert_eq!(fs::metadata("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
-    assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES));
 
     // test `rename`
     assert_eq!(fs::rename("a.txt", "b.txt").unwrap_err().kind(), ErrorKind::PermissionDenied);
@@ -49,5 +33,4 @@ fn main() {
 
     // test `opendir`
     assert_eq!(fs::read_dir("foo/bar").unwrap_err().kind(), ErrorKind::PermissionDenied);
-    assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES));
 }
diff --git a/src/tools/miri/tests/pass-dep/shims/fs_with_isolation.stderr b/src/tools/miri/tests/pass/shims/fs-with-isolation.stderr
index ad75e42831b..452c5b9b772 100644
--- a/src/tools/miri/tests/pass-dep/shims/fs_with_isolation.stderr
+++ b/src/tools/miri/tests/pass/shims/fs-with-isolation.stderr
@@ -1,13 +1,9 @@
 warning: `open` was made to return an error due to isolation
 
-warning: `fcntl` was made to return an error due to isolation
-
 warning: `unlink` was made to return an error due to isolation
 
 warning: `symlink` was made to return an error due to isolation
 
-warning: `readlink` was made to return an error due to isolation
-
 warning: `$STAT` was made to return an error due to isolation
 
 warning: `rename` was made to return an error due to isolation
diff --git a/src/tools/miri/tests/pass-dep/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index e573d330aa4..1758e486ac3 100644
--- a/src/tools/miri/tests/pass-dep/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -5,10 +5,10 @@
 #![feature(io_error_uncategorized)]
 
 use std::collections::HashMap;
-use std::ffi::{CString, OsString};
+use std::ffi::OsString;
 use std::fs::{
-    create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename, File,
-    OpenOptions,
+    canonicalize, create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename,
+    File, OpenOptions,
 };
 use std::io::{Error, ErrorKind, Read, Result, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
@@ -26,13 +26,7 @@ fn main() {
     test_rename();
     test_directory();
     test_canonicalize();
-    test_dup_stdout_stderr();
     test_from_raw_os_error();
-
-    // These all require unix, if the test is changed to no longer `ignore-windows`, move these to a unix test
-    test_file_open_unix_allow_two_args();
-    test_file_open_unix_needs_three_args();
-    test_file_open_unix_extra_third_arg();
 }
 
 fn tmp() -> PathBuf {
@@ -101,39 +95,6 @@ fn test_file() {
     remove_file(&path).unwrap();
 }
 
-fn test_file_open_unix_allow_two_args() {
-    use std::os::unix::ffi::OsStrExt;
-
-    let path = prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]);
-
-    let mut name = path.into_os_string();
-    name.push("\0");
-    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
-    let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY) };
-}
-
-fn test_file_open_unix_needs_three_args() {
-    use std::os::unix::ffi::OsStrExt;
-
-    let path = prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]);
-
-    let mut name = path.into_os_string();
-    name.push("\0");
-    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
-    let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT, 0o666) };
-}
-
-fn test_file_open_unix_extra_third_arg() {
-    use std::os::unix::ffi::OsStrExt;
-
-    let path = prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]);
-
-    let mut name = path.into_os_string();
-    name.push("\0");
-    let name_ptr = name.as_bytes().as_ptr().cast::<libc::c_char>();
-    let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 42) };
-}
-
 fn test_file_clone() {
     let bytes = b"Hello, World!\n";
     let path = prepare_with_content("miri_test_fs_file_clone.txt", bytes);
@@ -279,46 +240,6 @@ fn test_symlink() {
     symlink_file.read_to_end(&mut contents).unwrap();
     assert_eq!(bytes, contents.as_slice());
 
-    #[cfg(unix)]
-    {
-        use std::os::unix::ffi::OsStrExt;
-
-        let expected_path = path.as_os_str().as_bytes();
-
-        // Test that the expected string gets written to a buffer of proper
-        // length, and that a trailing null byte is not written.
-        let symlink_c_str = CString::new(symlink_path.as_os_str().as_bytes()).unwrap();
-        let symlink_c_ptr = symlink_c_str.as_ptr();
-
-        // Make the buf one byte larger than it needs to be,
-        // and check that the last byte is not overwritten.
-        let mut large_buf = vec![0xFF; expected_path.len() + 1];
-        let res = unsafe {
-            libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len())
-        };
-        // Check that the resovled path was properly written into the buf.
-        assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path);
-        assert_eq!(large_buf.last(), Some(&0xFF));
-        assert_eq!(res, large_buf.len() as isize - 1);
-
-        // Test that the resolved path is truncated if the provided buffer
-        // is too small.
-        let mut small_buf = [0u8; 2];
-        let res = unsafe {
-            libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len())
-        };
-        assert_eq!(small_buf, &expected_path[..small_buf.len()]);
-        assert_eq!(res, small_buf.len() as isize);
-
-        // Test that we report a proper error for a missing path.
-        let bad_path = CString::new("MIRI_MISSING_FILE_NAME").unwrap();
-        let res = unsafe {
-            libc::readlink(bad_path.as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len())
-        };
-        assert_eq!(res, -1);
-        assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound);
-    }
-
     // Test that metadata of a symbolic link (i.e., the file it points to) is correct.
     check_metadata(bytes, &symlink_path).unwrap();
     // Test that the metadata of a symbolic link is correct when not following it.
@@ -369,7 +290,6 @@ fn test_rename() {
 }
 
 fn test_canonicalize() {
-    use std::fs::canonicalize;
     let dir_path = prepare_dir("miri_test_fs_dir");
     create_dir(&dir_path).unwrap();
     let path = dir_path.join("test_file");
@@ -379,11 +299,6 @@ fn test_canonicalize() {
     assert_eq!(p.to_string_lossy().find('.'), None);
 
     remove_dir_all(&dir_path).unwrap();
-
-    // Make sure we get an error for long paths.
-    use std::convert::TryInto;
-    let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap());
-    assert!(canonicalize(too_long).is_err());
 }
 
 fn test_directory() {
@@ -440,16 +355,6 @@ fn test_directory() {
     remove_dir_all(&dir_path).unwrap();
 }
 
-fn test_dup_stdout_stderr() {
-    let bytes = b"hello dup fd\n";
-    unsafe {
-        let new_stdout = libc::fcntl(1, libc::F_DUPFD, 0);
-        let new_stderr = libc::fcntl(2, libc::F_DUPFD, 0);
-        libc::write(new_stdout, bytes.as_ptr() as *const libc::c_void, bytes.len());
-        libc::write(new_stderr, bytes.as_ptr() as *const libc::c_void, bytes.len());
-    }
-}
-
 fn test_from_raw_os_error() {
     let code = 6; // not a code that std or Miri know
     let error = Error::from_raw_os_error(code);