2021-05-30 05:10:54 +00:00
|
|
|
// spell-checker:ignore (words) gpghome
|
|
|
|
|
2020-05-25 17:05:26 +00:00
|
|
|
use crate::common::util::*;
|
2020-06-09 09:30:19 +00:00
|
|
|
|
2022-05-05 22:05:16 +00:00
|
|
|
use uucore::display::Quotable;
|
|
|
|
|
2021-02-10 23:03:23 +00:00
|
|
|
use std::path::PathBuf;
|
2022-05-22 03:31:12 +00:00
|
|
|
#[cfg(not(windows))]
|
|
|
|
use std::path::MAIN_SEPARATOR;
|
2021-01-19 07:15:53 +00:00
|
|
|
use tempfile::tempdir;
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2022-05-16 18:05:59 +00:00
|
|
|
#[cfg(unix)]
|
|
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
|
2021-05-29 12:32:35 +00:00
|
|
|
static TEST_TEMPLATE1: &str = "tempXXXXXX";
|
|
|
|
static TEST_TEMPLATE2: &str = "temp";
|
|
|
|
static TEST_TEMPLATE3: &str = "tempX";
|
|
|
|
static TEST_TEMPLATE4: &str = "tempXX";
|
|
|
|
static TEST_TEMPLATE5: &str = "tempXXX";
|
2021-05-31 03:55:28 +00:00
|
|
|
static TEST_TEMPLATE6: &str = "tempXXXlate"; // spell-checker:disable-line
|
|
|
|
static TEST_TEMPLATE7: &str = "XXXtemplate"; // spell-checker:disable-line
|
2016-01-03 10:10:47 +00:00
|
|
|
#[cfg(unix)]
|
2021-05-29 12:32:35 +00:00
|
|
|
static TEST_TEMPLATE8: &str = "tempXXXl/ate";
|
2016-01-03 10:10:47 +00:00
|
|
|
#[cfg(windows)]
|
2021-05-29 12:32:35 +00:00
|
|
|
static TEST_TEMPLATE8: &str = "tempXXXl\\ate";
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2021-06-22 15:36:56 +00:00
|
|
|
#[cfg(not(windows))]
|
2021-05-29 12:32:35 +00:00
|
|
|
const TMPDIR: &str = "TMPDIR";
|
2021-06-22 15:36:56 +00:00
|
|
|
#[cfg(windows)]
|
|
|
|
const TMPDIR: &str = "TMP";
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2022-05-27 01:02:12 +00:00
|
|
|
/// An assertion that uses [`matches_template`] and adds a helpful error message.
|
|
|
|
macro_rules! assert_matches_template {
|
|
|
|
($template:expr, $s:expr) => {{
|
|
|
|
assert!(
|
|
|
|
matches_template($template, $s),
|
|
|
|
"\"{}\" != \"{}\"",
|
|
|
|
$template,
|
|
|
|
$s
|
|
|
|
);
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2022-05-22 03:31:12 +00:00
|
|
|
/// Like [`assert_matches_template`] but for the suffix of a string.
|
|
|
|
#[cfg(windows)]
|
|
|
|
macro_rules! assert_suffix_matches_template {
|
|
|
|
($template:expr, $s:expr) => {{
|
|
|
|
let n = ($s).len();
|
|
|
|
let m = ($template).len();
|
|
|
|
let suffix = &$s[n - m..n];
|
|
|
|
assert!(
|
|
|
|
matches_template($template, suffix),
|
|
|
|
"\"{}\" does not end with \"{}\"",
|
|
|
|
$template,
|
|
|
|
suffix
|
|
|
|
);
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2016-01-03 10:10:47 +00:00
|
|
|
#[test]
|
|
|
|
fn test_mktemp_mktemp() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let pathname = scene.fixtures.as_string();
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg(TEST_TEMPLATE8)
|
|
|
|
.fails();
|
2016-01-03 10:10:47 +00:00
|
|
|
}
|
|
|
|
|
2021-01-02 08:53:47 +00:00
|
|
|
#[test]
|
|
|
|
fn test_mktemp_mktemp_t() {
|
|
|
|
let scene = TestScenario::new(util_name!());
|
|
|
|
|
|
|
|
let pathname = scene.fixtures.as_string();
|
|
|
|
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.succeeds();
|
2021-04-17 12:14:49 +00:00
|
|
|
scene
|
2021-01-02 08:53:47 +00:00
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-t")
|
|
|
|
.arg(TEST_TEMPLATE8)
|
2021-04-17 12:14:49 +00:00
|
|
|
.fails()
|
|
|
|
.no_stdout()
|
2021-06-28 11:45:15 +00:00
|
|
|
.stderr_contains("invalid suffix")
|
|
|
|
.stderr_contains("contains directory separator");
|
2021-01-02 08:53:47 +00:00
|
|
|
}
|
|
|
|
|
2016-06-18 09:44:07 +00:00
|
|
|
#[test]
|
|
|
|
fn test_mktemp_make_temp_dir() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2016-06-18 09:44:07 +00:00
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let pathname = scene.fixtures.as_string();
|
2016-06-18 09:44:07 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-d")
|
|
|
|
.arg(TEST_TEMPLATE8)
|
|
|
|
.fails();
|
2016-06-18 09:44:07 +00:00
|
|
|
}
|
2016-01-03 17:11:15 +00:00
|
|
|
|
2016-01-03 10:10:47 +00:00
|
|
|
#[test]
|
|
|
|
fn test_mktemp_dry_run() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let pathname = scene.fixtures.as_string();
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("-u")
|
|
|
|
.arg(TEST_TEMPLATE8)
|
|
|
|
.fails();
|
2016-01-03 10:10:47 +00:00
|
|
|
}
|
|
|
|
|
2016-06-18 09:44:07 +00:00
|
|
|
#[test]
|
|
|
|
fn test_mktemp_quiet() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2016-06-18 09:44:07 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg("/definitely/not/exist/I/promise")
|
|
|
|
.arg("-q")
|
|
|
|
.fails()
|
|
|
|
.no_stdout()
|
|
|
|
.no_stderr();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-d")
|
|
|
|
.arg("-p")
|
|
|
|
.arg("/definitely/not/exist/I/promise")
|
|
|
|
.arg("-q")
|
|
|
|
.fails()
|
|
|
|
.no_stdout()
|
|
|
|
.no_stderr();
|
2016-06-18 09:44:07 +00:00
|
|
|
}
|
2016-01-03 10:10:47 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mktemp_suffix() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2016-01-03 10:10:47 +00:00
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let pathname = scene.fixtures.as_string();
|
2016-01-03 17:11:15 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env(TMPDIR, &pathname)
|
|
|
|
.arg("--suffix")
|
|
|
|
.arg("suf")
|
|
|
|
.arg(TEST_TEMPLATE8)
|
|
|
|
.fails();
|
2016-01-03 10:10:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mktemp_tmpdir() {
|
2016-08-23 11:52:43 +00:00
|
|
|
let scene = TestScenario::new(util_name!());
|
2020-06-09 09:30:19 +00:00
|
|
|
let dir = tempdir().unwrap();
|
|
|
|
let path = dir.path().join(scene.fixtures.as_string());
|
|
|
|
let pathname = path.as_os_str();
|
2016-08-13 21:59:21 +00:00
|
|
|
|
2020-04-13 18:36:03 +00:00
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE1)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE2)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE3)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE4)
|
|
|
|
.fails();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE5)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE6)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE7)
|
|
|
|
.succeeds();
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.arg("-p")
|
|
|
|
.arg(pathname)
|
|
|
|
.arg(TEST_TEMPLATE8)
|
|
|
|
.fails();
|
2016-01-03 10:10:47 +00:00
|
|
|
}
|
2021-02-10 23:03:23 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mktemp_tmpdir_one_arg() {
|
|
|
|
let scene = TestScenario::new(util_name!());
|
|
|
|
|
|
|
|
let result = scene
|
2021-06-21 19:13:40 +00:00
|
|
|
.ucmd_keepenv()
|
2021-02-10 23:03:23 +00:00
|
|
|
.arg("--tmpdir")
|
|
|
|
.arg("apt-key-gpghome.XXXXXXXXXX")
|
|
|
|
.succeeds();
|
2021-04-17 23:33:52 +00:00
|
|
|
result.no_stderr().stdout_contains("apt-key-gpghome.");
|
2021-04-17 12:14:49 +00:00
|
|
|
assert!(PathBuf::from(result.stdout_str().trim()).is_file());
|
2021-02-10 23:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mktemp_directory_tmpdir() {
|
|
|
|
let scene = TestScenario::new(util_name!());
|
|
|
|
|
|
|
|
let result = scene
|
2021-06-21 19:13:40 +00:00
|
|
|
.ucmd_keepenv()
|
2021-02-10 23:03:23 +00:00
|
|
|
.arg("--directory")
|
|
|
|
.arg("--tmpdir")
|
|
|
|
.arg("apt-key-gpghome.XXXXXXXXXX")
|
|
|
|
.succeeds();
|
2021-04-17 12:14:49 +00:00
|
|
|
result.no_stderr().stdout_contains("apt-key-gpghome.");
|
|
|
|
assert!(PathBuf::from(result.stdout_str().trim()).is_dir());
|
2021-02-10 23:03:23 +00:00
|
|
|
}
|
2022-05-01 16:03:02 +00:00
|
|
|
|
2022-05-27 01:02:12 +00:00
|
|
|
/// Test for combining `--tmpdir` and a template with a subdirectory.
|
|
|
|
#[test]
|
|
|
|
fn test_tmpdir_template_has_subdirectory() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
at.mkdir("a");
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
let (template, joined) = ("a/bXXXX", "./a/bXXXX");
|
|
|
|
#[cfg(windows)]
|
|
|
|
let (template, joined) = (r"a\bXXXX", r".\a\bXXXX");
|
|
|
|
let result = ucmd.args(&["--tmpdir=.", template]).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_matches_template!(joined, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|
|
|
|
|
2022-05-12 02:31:09 +00:00
|
|
|
/// Test that an absolute path is disallowed when --tmpdir is provided.
|
|
|
|
#[test]
|
|
|
|
fn test_tmpdir_absolute_path() {
|
|
|
|
#[cfg(windows)]
|
|
|
|
let path = r"C:\XXX";
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
let path = "/XXX";
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["--tmpdir=a", path])
|
|
|
|
.fails()
|
|
|
|
.stderr_only(format!(
|
|
|
|
"mktemp: invalid template, '{}'; with --tmpdir, it may not be absolute\n",
|
|
|
|
path
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2022-05-01 16:03:02 +00:00
|
|
|
/// Decide whether a string matches a given template.
|
|
|
|
///
|
|
|
|
/// In the template, the character `'X'` is treated as a wildcard,
|
|
|
|
/// that is, it matches anything. All other characters in `template`
|
|
|
|
/// and `s` must match exactly.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust,ignore
|
|
|
|
/// # These all match.
|
|
|
|
/// assert!(matches_template("abc", "abc"));
|
|
|
|
/// assert!(matches_template("aXc", "abc"));
|
|
|
|
/// assert!(matches_template("XXX", "abc"));
|
|
|
|
///
|
|
|
|
/// # None of these match
|
|
|
|
/// assert!(matches_template("abc", "abcd"));
|
|
|
|
/// assert!(matches_template("abc", "ab"));
|
|
|
|
/// assert!(matches_template("aXc", "abd"));
|
|
|
|
/// assert!(matches_template("XXX", "abcd"));
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
fn matches_template(template: &str, s: &str) -> bool {
|
|
|
|
if template.len() != s.len() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (a, b) in template.chars().zip(s.chars()) {
|
|
|
|
if !(a == 'X' || a == b) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Test that the file is created in the directory given by the template.
|
|
|
|
#[test]
|
|
|
|
fn test_respect_template() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let template = "XXX";
|
|
|
|
let result = ucmd.arg(template).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_matches_template!(template, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Test that the file is created in the directory given by the template.
|
|
|
|
#[test]
|
|
|
|
fn test_respect_template_directory() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
at.mkdir("d");
|
2022-05-01 20:51:25 +00:00
|
|
|
#[cfg(not(windows))]
|
2022-05-01 16:03:02 +00:00
|
|
|
let template = "d/XXX";
|
2022-05-01 20:51:25 +00:00
|
|
|
#[cfg(windows)]
|
|
|
|
let template = r"d\XXX";
|
2022-05-01 16:03:02 +00:00
|
|
|
let result = ucmd.arg(template).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_matches_template!(template, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|
2022-05-05 22:05:16 +00:00
|
|
|
|
2022-05-16 18:05:59 +00:00
|
|
|
#[cfg(unix)]
|
|
|
|
#[test]
|
|
|
|
fn test_directory_permissions() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let result = ucmd.args(&["-d", "XXX"]).succeeds();
|
|
|
|
let dirname = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_matches_template!("XXX", dirname);
|
|
|
|
let metadata = at.metadata(dirname);
|
|
|
|
assert!(metadata.is_dir());
|
|
|
|
assert_eq!(metadata.permissions().mode(), 0o40700);
|
|
|
|
}
|
2022-05-16 18:07:18 +00:00
|
|
|
|
2022-05-05 22:05:16 +00:00
|
|
|
/// Test that a template with a path separator is invalid.
|
|
|
|
#[test]
|
|
|
|
fn test_template_path_separator() {
|
2022-05-28 22:35:34 +00:00
|
|
|
#[cfg(not(windows))]
|
2022-05-05 22:05:16 +00:00
|
|
|
new_ucmd!()
|
|
|
|
.args(&["-t", "a/bXXX"])
|
|
|
|
.fails()
|
|
|
|
.stderr_only(format!(
|
|
|
|
"mktemp: invalid template, {}, contains directory separator\n",
|
|
|
|
"a/bXXX".quote()
|
|
|
|
));
|
2022-05-28 22:35:34 +00:00
|
|
|
#[cfg(windows)]
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["-t", r"a\bXXX"])
|
|
|
|
.fails()
|
|
|
|
.stderr_only(format!(
|
|
|
|
"mktemp: invalid template, {}, contains directory separator\n",
|
|
|
|
r"a\bXXX".quote()
|
|
|
|
));
|
2022-05-05 22:05:16 +00:00
|
|
|
}
|
2022-05-18 22:33:53 +00:00
|
|
|
|
|
|
|
/// Test that a suffix with a path separator is invalid.
|
|
|
|
#[test]
|
|
|
|
fn test_suffix_path_separator() {
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
new_ucmd!()
|
|
|
|
.arg("aXXX/b")
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: invalid suffix '/b', contains directory separator\n");
|
|
|
|
#[cfg(windows)]
|
|
|
|
new_ucmd!()
|
|
|
|
.arg(r"aXXX\b")
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: invalid suffix '\\b', contains directory separator\n");
|
2022-05-27 01:02:12 +00:00
|
|
|
#[cfg(not(windows))]
|
|
|
|
new_ucmd!()
|
|
|
|
.arg("XXX/..")
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: invalid suffix '/..', contains directory separator\n");
|
|
|
|
#[cfg(windows)]
|
|
|
|
new_ucmd!()
|
|
|
|
.arg(r"XXX\..")
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: invalid suffix '\\..', contains directory separator\n");
|
2022-05-18 22:33:53 +00:00
|
|
|
}
|
2022-05-22 01:58:38 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_too_few_xs_suffix() {
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["--suffix=X", "aXX"])
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: too few X's in template 'aXXX'\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_too_few_xs_suffix_directory() {
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["-d", "--suffix=X", "aXX"])
|
|
|
|
.fails()
|
|
|
|
.stderr_only("mktemp: too few X's in template 'aXXX'\n");
|
|
|
|
}
|
2022-05-30 13:30:47 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_too_many_arguments() {
|
|
|
|
new_ucmd!().args(&["-q", "a", "b"]).fails().code_is(1);
|
|
|
|
}
|
2022-06-01 13:35:31 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_two_contiguous_wildcard_blocks() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let template = "XXX_XXX";
|
|
|
|
let result = ucmd.arg(template).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_eq!(&filename[..4], "XXX_");
|
|
|
|
assert_matches_template!(template, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_three_contiguous_wildcard_blocks() {
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let template = "XXX_XXX_XXX";
|
|
|
|
let result = ucmd.arg(template).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
assert_eq!(&filename[..8], "XXX_XXX_");
|
|
|
|
assert_matches_template!(template, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|
2022-06-06 13:46:15 +00:00
|
|
|
|
|
|
|
/// Test that template must end in X even if `--suffix` is the empty string.
|
|
|
|
#[test]
|
|
|
|
fn test_suffix_must_end_in_x() {
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["--suffix=", "aXXXb"])
|
|
|
|
.fails()
|
|
|
|
.stderr_is("mktemp: with --suffix, template 'aXXXb' must end in X\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_suffix_empty_template() {
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["--suffix=aXXXb", ""])
|
|
|
|
.fails()
|
|
|
|
.stderr_is("mktemp: with --suffix, template '' must end in X\n");
|
|
|
|
|
|
|
|
new_ucmd!()
|
|
|
|
.args(&["-d", "--suffix=aXXXb", ""])
|
|
|
|
.fails()
|
|
|
|
.stderr_is("mktemp: with --suffix, template '' must end in X\n");
|
|
|
|
}
|
2022-06-09 06:48:05 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mktemp_with_posixly_correct() {
|
|
|
|
let scene = TestScenario::new(util_name!());
|
|
|
|
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env("POSIXLY_CORRECT", "1")
|
|
|
|
.args(&["aXXXX", "--suffix=b"])
|
|
|
|
.fails()
|
|
|
|
.stderr_is(&format!(
|
|
|
|
"mktemp: too many templates\nTry '{} {} --help' for more information.\n",
|
|
|
|
scene.bin_path.to_string_lossy(),
|
|
|
|
scene.util_name
|
|
|
|
));
|
|
|
|
|
|
|
|
scene
|
|
|
|
.ucmd()
|
|
|
|
.env("POSIXLY_CORRECT", "1")
|
|
|
|
.args(&["--suffix=b", "aXXXX"])
|
|
|
|
.succeeds();
|
|
|
|
}
|
2022-05-22 03:31:12 +00:00
|
|
|
|
|
|
|
/// Test that files are created relative to `TMPDIR` environment variable.
|
|
|
|
#[test]
|
|
|
|
fn test_tmpdir_env_var() {
|
|
|
|
// `TMPDIR=. mktemp`
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let result = ucmd.env(TMPDIR, ".").succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
{
|
|
|
|
let template = format!(".{}tmp.XXXXXXXXXX", MAIN_SEPARATOR);
|
|
|
|
assert_matches_template!(&template, filename);
|
|
|
|
}
|
|
|
|
// On Windows, `env::temp_dir()` seems to give an absolute path
|
|
|
|
// regardless of the value of `TMPDIR`; see
|
|
|
|
// * https://github.com/uutils/coreutils/pull/3552#issuecomment-1211804981
|
|
|
|
// * https://doc.rust-lang.org/std/env/fn.temp_dir.html
|
|
|
|
// * https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2w
|
|
|
|
#[cfg(windows)]
|
|
|
|
assert_suffix_matches_template!("tmp.XXXXXXXXXX", filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
|
|
|
|
// FIXME This is not working because --tmpdir is configured to
|
|
|
|
// require a value.
|
|
|
|
//
|
|
|
|
// // `TMPDIR=. mktemp --tmpdir`
|
|
|
|
// let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
// let result = ucmd.env(TMPDIR, ".").arg("--tmpdir").succeeds();
|
|
|
|
// let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
// let template = format!(".{}tmp.XXXXXXXXXX", MAIN_SEPARATOR);
|
|
|
|
// assert_matches_template!(&template, filename);
|
|
|
|
// assert!(at.file_exists(filename));
|
|
|
|
|
|
|
|
// `TMPDIR=. mktemp --tmpdir XXX`
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let result = ucmd.env(TMPDIR, ".").args(&["--tmpdir", "XXX"]).succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
#[cfg(not(windows))]
|
|
|
|
{
|
|
|
|
let template = format!(".{}XXX", MAIN_SEPARATOR);
|
|
|
|
assert_matches_template!(&template, filename);
|
|
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
|
|
assert_suffix_matches_template!("XXX", filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
|
|
|
|
// `TMPDIR=. mktemp XXX` - in this case `TMPDIR` is ignored.
|
|
|
|
let (at, mut ucmd) = at_and_ucmd!();
|
|
|
|
let result = ucmd.env(TMPDIR, ".").arg("XXX").succeeds();
|
|
|
|
let filename = result.no_stderr().stdout_str().trim_end();
|
|
|
|
let template = "XXX";
|
|
|
|
assert_matches_template!(template, filename);
|
|
|
|
assert!(at.file_exists(filename));
|
|
|
|
}
|