mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 09:48:03 +00:00
Merge branch 'unittests-in-ci' of github.com:tertsdiepraam/coreutils into unittests-in-ci
This commit is contained in:
commit
76edba0e1e
12 changed files with 227 additions and 89 deletions
7
.github/workflows/CICD.yml
vendored
7
.github/workflows/CICD.yml
vendored
|
@ -20,6 +20,13 @@ env:
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
cargo-deny:
|
||||||
|
name: Style/cargo-deny
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: EmbarkStudios/cargo-deny-action@v1
|
||||||
|
|
||||||
style_deps:
|
style_deps:
|
||||||
## ToDO: [2021-11-10; rivy] 'Style/deps' needs more informative output and better integration of results into the GHA dashboard
|
## ToDO: [2021-11-10; rivy] 'Style/deps' needs more informative output and better integration of results into the GHA dashboard
|
||||||
name: Style/deps
|
name: Style/deps
|
||||||
|
|
2
.github/workflows/GnuTests.yml
vendored
2
.github/workflows/GnuTests.yml
vendored
|
@ -137,6 +137,8 @@ jobs:
|
||||||
echo "::error ::Failed to find summary of test results (missing '${SUITE_LOG_FILE}'); failing early"
|
echo "::error ::Failed to find summary of test results (missing '${SUITE_LOG_FILE}'); failing early"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# Compress logs before upload (fails otherwise)
|
||||||
|
gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }}
|
||||||
- name: Reserve SHA1/ID of 'test-summary'
|
- name: Reserve SHA1/ID of 'test-summary'
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -94,6 +94,16 @@ uutils: add new utility
|
||||||
gitignore: add temporary files
|
gitignore: add temporary files
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## cargo-deny
|
||||||
|
|
||||||
|
This project uses [cargo-deny](https://github.com/EmbarkStudios/cargo-deny/) to
|
||||||
|
detect duplicate dependencies, checks licenses, etc. To run it locally, first
|
||||||
|
install it and then run with:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo deny --all-features check all
|
||||||
|
```
|
||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
|
|
||||||
uutils is distributed under the terms of the MIT License; see the `LICENSE` file
|
uutils is distributed under the terms of the MIT License; see the `LICENSE` file
|
||||||
|
|
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -877,7 +877,7 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f37978dab2ca789938a83b2f8bc1ef32db6633af9051a6cd409eff72cbaaa79a"
|
checksum = "f37978dab2ca789938a83b2f8bc1ef32db6633af9051a6cd409eff72cbaaa79a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"paste 1.0.6",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1431,31 +1431,12 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "paste"
|
|
||||||
version = "0.1.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
|
||||||
dependencies = [
|
|
||||||
"paste-impl",
|
|
||||||
"proc-macro-hack",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
|
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "paste-impl"
|
|
||||||
version = "0.1.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-hack",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peeking_take_while"
|
name = "peeking_take_while"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -1574,12 +1555,6 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-hack"
|
|
||||||
version = "0.5.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.36"
|
||||||
|
@ -2559,7 +2534,7 @@ dependencies = [
|
||||||
"clap 3.0.10",
|
"clap 3.0.10",
|
||||||
"coz",
|
"coz",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste 0.1.18",
|
"paste",
|
||||||
"quickcheck",
|
"quickcheck",
|
||||||
"rand",
|
"rand",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
|
95
deny.toml
Normal file
95
deny.toml
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# spell-checker:ignore SSLeay RUSTSEC
|
||||||
|
|
||||||
|
# This section is considered when running `cargo deny check advisories`
|
||||||
|
# More documentation for the advisories section can be found here:
|
||||||
|
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
|
||||||
|
[advisories]
|
||||||
|
db-path = "~/.cargo/advisory-db"
|
||||||
|
db-urls = ["https://github.com/rustsec/advisory-db"]
|
||||||
|
vulnerability = "warn"
|
||||||
|
unmaintained = "warn"
|
||||||
|
yanked = "warn"
|
||||||
|
notice = "warn"
|
||||||
|
ignore = [
|
||||||
|
#"RUSTSEC-0000-0000",
|
||||||
|
]
|
||||||
|
|
||||||
|
# This section is considered when running `cargo deny check licenses`
|
||||||
|
# More documentation for the licenses section can be found here:
|
||||||
|
# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
|
||||||
|
[licenses]
|
||||||
|
unlicensed = "deny"
|
||||||
|
allow = [
|
||||||
|
"MIT",
|
||||||
|
"Apache-2.0",
|
||||||
|
"ISC",
|
||||||
|
"BSD-2-Clause",
|
||||||
|
"BSD-2-Clause-FreeBSD",
|
||||||
|
"BSD-3-Clause",
|
||||||
|
"CC0-1.0",
|
||||||
|
"MPL-2.0", # XXX considered copyleft?
|
||||||
|
]
|
||||||
|
copyleft = "deny"
|
||||||
|
allow-osi-fsf-free = "neither"
|
||||||
|
default = "deny"
|
||||||
|
confidence-threshold = 0.8
|
||||||
|
exceptions = [
|
||||||
|
{ allow = ["OpenSSL"], name = "ring" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[licenses.clarify]]
|
||||||
|
name = "ring"
|
||||||
|
# SPDX considers OpenSSL to encompass both the OpenSSL and SSLeay licenses
|
||||||
|
# https://spdx.org/licenses/OpenSSL.html
|
||||||
|
# ISC - Both BoringSSL and ring use this for their new files
|
||||||
|
# MIT - "Files in third_party/ have their own licenses, as described therein. The MIT
|
||||||
|
# license, for third_party/fiat, which, unlike other third_party directories, is
|
||||||
|
# compiled into non-test libraries, is included below."
|
||||||
|
# OpenSSL - Obviously
|
||||||
|
expression = "ISC AND MIT AND OpenSSL"
|
||||||
|
license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }]
|
||||||
|
|
||||||
|
# This section is considered when running `cargo deny check bans`.
|
||||||
|
# More documentation about the 'bans' section can be found here:
|
||||||
|
# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
|
||||||
|
[bans]
|
||||||
|
multiple-versions = "deny"
|
||||||
|
wildcards = "allow"
|
||||||
|
highlight = "all"
|
||||||
|
|
||||||
|
# For each duplicate dependency, indicate the name of the dependency which
|
||||||
|
# introduces it.
|
||||||
|
# spell-checker: disable
|
||||||
|
skip = [
|
||||||
|
# blake2d_simd
|
||||||
|
{ name = "arrayvec", version = "=0.7.2" },
|
||||||
|
# flimit/unix_socket
|
||||||
|
{ name = "cfg-if", version = "=0.1.10" },
|
||||||
|
# ordered-multimap
|
||||||
|
{ name = "hashbrown", version = "=0.9.1" },
|
||||||
|
# kernel32-sys
|
||||||
|
{ name = "winapi", version = "=0.2.8" },
|
||||||
|
# bindgen 0.59.2
|
||||||
|
{ name = "clap", version = "=2.34.0" },
|
||||||
|
{ name = "strsim", version = "=0.8.0" },
|
||||||
|
{ name = "textwrap", version = "=0.11.0" },
|
||||||
|
{ name = "cpp_common", version = "=0.4.0" },
|
||||||
|
# quickcheck
|
||||||
|
{ name = "env_logger", version = "=0.8.4" },
|
||||||
|
# cpp_*
|
||||||
|
{ name = "memchr", version = "=1.0.2" },
|
||||||
|
{ name = "quote", version = "=0.3.15" },
|
||||||
|
{ name = "unicode-xid", version = "=0.0.4" },
|
||||||
|
# exacl
|
||||||
|
{ name = "nix", version = "=0.21.0" },
|
||||||
|
]
|
||||||
|
# spell-checker: enable
|
||||||
|
|
||||||
|
# This section is considered when running `cargo deny check sources`.
|
||||||
|
# More documentation about the 'sources' section can be found here:
|
||||||
|
# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html
|
||||||
|
[sources]
|
||||||
|
unknown-registry = "warn"
|
||||||
|
unknown-git = "warn"
|
||||||
|
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
|
||||||
|
allow-git = []
|
|
@ -23,7 +23,7 @@ smallvec = "1.7" # TODO(nicoo): Use `union` feature, requires Rust 1.49 or late
|
||||||
uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore" }
|
uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
paste = "0.1.18"
|
paste = "1.0.6"
|
||||||
quickcheck = "1.0.3"
|
quickcheck = "1.0.3"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn sleep(args: &[&str]) -> UResult<()> {
|
||||||
args.iter().try_fold(
|
args.iter().try_fold(
|
||||||
Duration::new(0, 0),
|
Duration::new(0, 0),
|
||||||
|result, arg| match uucore::parse_time::from_str(&arg[..]) {
|
|result, arg| match uucore::parse_time::from_str(&arg[..]) {
|
||||||
Ok(m) => Ok(m + result),
|
Ok(m) => Ok(m.saturating_add(result)),
|
||||||
Err(f) => Err(USimpleError::new(1, f)),
|
Err(f) => Err(USimpleError::new(1, f)),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -1162,46 +1162,6 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_into_n_chunks_by_line_round_robin<R>(
|
|
||||||
settings: &Settings,
|
|
||||||
reader: &mut R,
|
|
||||||
num_chunks: u64,
|
|
||||||
) -> UResult<()>
|
|
||||||
where
|
|
||||||
R: BufRead,
|
|
||||||
{
|
|
||||||
// This object is responsible for creating the filename for each chunk.
|
|
||||||
let mut filename_iterator = FilenameIterator::new(
|
|
||||||
&settings.prefix,
|
|
||||||
&settings.additional_suffix,
|
|
||||||
settings.suffix_length,
|
|
||||||
settings.suffix_type,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create one writer for each chunk. This will create each
|
|
||||||
// of the underlying files (if not in `--filter` mode).
|
|
||||||
let mut writers = vec![];
|
|
||||||
for _ in 0..num_chunks {
|
|
||||||
let filename = filename_iterator
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| USimpleError::new(1, "output file suffixes exhausted"))?;
|
|
||||||
let writer = platform::instantiate_current_writer(&settings.filter, filename.as_str());
|
|
||||||
writers.push(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let num_chunks: usize = num_chunks.try_into().unwrap();
|
|
||||||
for (i, line_result) in reader.lines().enumerate() {
|
|
||||||
let line = line_result.unwrap();
|
|
||||||
let maybe_writer = writers.get_mut(i % num_chunks);
|
|
||||||
let writer = maybe_writer.unwrap();
|
|
||||||
let bytes = line.as_bytes();
|
|
||||||
writer.write_all(bytes)?;
|
|
||||||
writer.write_all(b"\n")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn split(settings: &Settings) -> UResult<()> {
|
fn split(settings: &Settings) -> UResult<()> {
|
||||||
let mut reader = BufReader::new(if settings.input == "-" {
|
let mut reader = BufReader::new(if settings.input == "-" {
|
||||||
Box::new(stdin()) as Box<dyn Read>
|
Box::new(stdin()) as Box<dyn Read>
|
||||||
|
@ -1228,9 +1188,6 @@ fn split(settings: &Settings) -> UResult<()> {
|
||||||
let chunk_number = chunk_number - 1;
|
let chunk_number = chunk_number - 1;
|
||||||
kth_chunk_by_line(settings, &mut reader, chunk_number, num_chunks)
|
kth_chunk_by_line(settings, &mut reader, chunk_number, num_chunks)
|
||||||
}
|
}
|
||||||
Strategy::Number(NumberType::RoundRobin(num_chunks)) => {
|
|
||||||
split_into_n_chunks_by_line_round_robin(settings, &mut reader, num_chunks)
|
|
||||||
}
|
|
||||||
Strategy::Number(_) => Err(USimpleError::new(1, "-n mode not yet fully implemented")),
|
Strategy::Number(_) => Err(USimpleError::new(1, "-n mode not yet fully implemented")),
|
||||||
Strategy::Lines(chunk_size) => {
|
Strategy::Lines(chunk_size) => {
|
||||||
let mut writer = LineChunkWriter::new(chunk_size, settings)
|
let mut writer = LineChunkWriter::new(chunk_size, settings)
|
||||||
|
|
|
@ -6,11 +6,39 @@
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (vars) NANOS numstr
|
// spell-checker:ignore (vars) NANOS numstr
|
||||||
|
//! Parsing a duration from a string.
|
||||||
|
//!
|
||||||
|
//! Use the [`from_str`] function to parse a [`Duration`] from a string.
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::display::Quotable;
|
use crate::display::Quotable;
|
||||||
|
|
||||||
|
/// Parse a duration from a string.
|
||||||
|
///
|
||||||
|
/// The string may contain only a number, like "123" or "4.5", or it
|
||||||
|
/// may contain a number with a unit specifier, like "123s" meaning
|
||||||
|
/// one hundred twenty three seconds or "4.5d" meaning four and a half
|
||||||
|
/// days. If no unit is specified, the unit is assumed to be seconds.
|
||||||
|
///
|
||||||
|
/// This function uses [`Duration::saturating_mul`] to compute the
|
||||||
|
/// number of seconds, so it does not overflow. If overflow would have
|
||||||
|
/// occurred, [`Duration::MAX`] is returned instead.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// This function returns an error if the input string is empty, the
|
||||||
|
/// input is not a valid number, or the unit specifier is invalid or
|
||||||
|
/// unknown.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// use uucore::parse_time::from_str;
|
||||||
|
/// assert_eq!(from_str("123"), Ok(Duration::from_secs(123)));
|
||||||
|
/// assert_eq!(from_str("2d"), Ok(Duration::from_secs(60 * 60 * 24 * 2)));
|
||||||
|
/// ```
|
||||||
pub fn from_str(string: &str) -> Result<Duration, String> {
|
pub fn from_str(string: &str) -> Result<Duration, String> {
|
||||||
let len = string.len();
|
let len = string.len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
|
@ -39,5 +67,42 @@ pub fn from_str(string: &str) -> Result<Duration, String> {
|
||||||
let whole_secs = num.trunc();
|
let whole_secs = num.trunc();
|
||||||
let nanos = (num.fract() * (NANOS_PER_SEC as f64)).trunc();
|
let nanos = (num.fract() * (NANOS_PER_SEC as f64)).trunc();
|
||||||
let duration = Duration::new(whole_secs as u64, nanos as u32);
|
let duration = Duration::new(whole_secs as u64, nanos as u32);
|
||||||
Ok(duration * times)
|
Ok(duration.saturating_mul(times))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use crate::parse_time::from_str;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_no_units() {
|
||||||
|
assert_eq!(from_str("123"), Ok(Duration::from_secs(123)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_units() {
|
||||||
|
assert_eq!(from_str("2d"), Ok(Duration::from_secs(60 * 60 * 24 * 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_saturating_mul() {
|
||||||
|
assert_eq!(from_str("9223372036854775808d"), Ok(Duration::MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_empty() {
|
||||||
|
assert!(from_str("").is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_invalid_unit() {
|
||||||
|
assert!(from_str("123X").is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_invalid_magnitude() {
|
||||||
|
assert!(from_str("12abc3s").is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// spell-checker:ignore dont
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
@ -115,3 +116,28 @@ fn test_sleep_sum_duration_many() {
|
||||||
fn test_sleep_wrong_time() {
|
fn test_sleep_wrong_time() {
|
||||||
new_ucmd!().args(&["0.1s", "abc"]).fails();
|
new_ucmd!().args(&["0.1s", "abc"]).fails();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO These tests would obviously block for a very long time. We
|
||||||
|
// only want to verify that there is no error here, so we could just
|
||||||
|
// figure out a way to terminate the child process after a short
|
||||||
|
// period of time.
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn test_dont_overflow() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("9223372036854775808d")
|
||||||
|
.succeeds()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn test_sum_overflow() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["100000000000000d", "100000000000000d", "100000000000000d"])
|
||||||
|
.succeeds()
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout();
|
||||||
|
}
|
||||||
|
|
|
@ -605,19 +605,3 @@ fn test_line_bytes() {
|
||||||
assert_eq!(at.read("xac"), "cccc\ndd\n");
|
assert_eq!(at.read("xac"), "cccc\ndd\n");
|
||||||
assert_eq!(at.read("xad"), "ee\n");
|
assert_eq!(at.read("xad"), "ee\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_round_robin() {
|
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
|
||||||
|
|
||||||
let file_read = |f| {
|
|
||||||
let mut s = String::new();
|
|
||||||
at.open(f).read_to_string(&mut s).unwrap();
|
|
||||||
s
|
|
||||||
};
|
|
||||||
|
|
||||||
ucmd.args(&["-n", "r/2", "fivelines.txt"]).succeeds();
|
|
||||||
|
|
||||||
assert_eq!(file_read("xaa"), "1\n3\n5\n");
|
|
||||||
assert_eq!(file_read("xab"), "2\n4\n");
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// spell-checker:ignore dont
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
// FIXME: this depends on the system having true and false in PATH
|
// FIXME: this depends on the system having true and false in PATH
|
||||||
|
@ -64,3 +65,19 @@ fn test_preserve_status() {
|
||||||
.no_stderr()
|
.no_stderr()
|
||||||
.no_stdout();
|
.no_stdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dont_overflow() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["9223372036854775808d", "sleep", "0"])
|
||||||
|
.succeeds()
|
||||||
|
.code_is(0)
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout();
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-k", "9223372036854775808d", "10", "sleep", "0"])
|
||||||
|
.succeeds()
|
||||||
|
.code_is(0)
|
||||||
|
.no_stderr()
|
||||||
|
.no_stdout();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue