mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +00:00
Merge pull request #1583 from rivy/fix.test-utils
Fix sub-crate/utility testing
This commit is contained in:
commit
e7a1d13380
19 changed files with 306 additions and 173 deletions
96
.github/workflows/CICD.yml
vendored
96
.github/workflows/CICD.yml
vendored
|
@ -1,30 +1,30 @@
|
|||
name: CICD
|
||||
|
||||
# spell-checker:ignore (acronyms) CICD MSVC musl
|
||||
# spell-checker:ignore (env/flags) Ccodegen Coverflow RUSTFLAGS
|
||||
# spell-checker:ignore (env/flags) Ccodegen Coverflow Cpanic RUSTDOCFLAGS RUSTFLAGS Zpanic
|
||||
# spell-checker:ignore (jargon) SHAs deps softprops toolchain
|
||||
# spell-checker:ignore (names) CodeCOV MacOS MinGW Peltoche rivy
|
||||
# spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot gmake grcov halium lcov libssl mkdir popd printf pushd rustc rustfmt rustup shopt xargs
|
||||
# spell-checker:ignore (misc) aarch alnum armhf coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend uutils
|
||||
# spell-checker:ignore (misc) aarch alnum armhf coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend tempfile uutils
|
||||
|
||||
env:
|
||||
PROJECT_NAME: coreutils
|
||||
PROJECT_DESC: "Core universal (cross-platform) utilities"
|
||||
PROJECT_AUTH: "uutils"
|
||||
RUST_MIN_SRV: "1.32.0" ## v1.32.0 - minimum version for half, tempfile, etc
|
||||
RUST_COV_SRV: "2020-04-29" ## (~v1.45.0) supported rust version for code coverage; (date required/used by 'coverage') ## !maint: refactor when code coverage support is included in the stable channel
|
||||
RUST_COV_SRV: "2020-08-01" ## (~v1.47.0) supported rust version for code coverage; (date required/used by 'coverage') ## !maint: refactor when code coverage support is included in the stable channel
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
style:
|
||||
name: Style
|
||||
code_format:
|
||||
name: Style/format
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: unix }
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Initialize workflow variables
|
||||
|
@ -58,16 +58,16 @@ jobs:
|
|||
# * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message>
|
||||
S=$(find tests -name "*.rs" -print0 | xargs -0 cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" | sed -E -n "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::warning file=\1,line=\2::WARNING: \`cargo fmt\`: style violation/p" ; }
|
||||
|
||||
clippy:
|
||||
name: Clippy
|
||||
code_warnings:
|
||||
name: Style/warnings
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: unix }
|
||||
- { os: macos-latest , features: macos }
|
||||
- { os: windows-latest , features: windows }
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Initialize workflow variables
|
||||
|
@ -309,6 +309,16 @@ jobs:
|
|||
target: ${{ matrix.job.target }}
|
||||
default: true
|
||||
profile: minimal # minimal component installation (ie, no documentation)
|
||||
- name: Initialize toolchain-dependent workflow variables
|
||||
id: dep_vars
|
||||
shell: bash
|
||||
run: |
|
||||
## Dependent VARs setup
|
||||
# * determine sub-crate utility list
|
||||
UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})"
|
||||
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)"
|
||||
echo set-output name=UTILITY_LIST::${UTILITY_LIST}
|
||||
echo ::set-output name=CARGO_UTILITY_LIST_OPTIONS::${CARGO_UTILITY_LIST_OPTIONS}
|
||||
- name: Install `cargo-tree` # for dependency information
|
||||
uses: actions-rs/install@v0.1
|
||||
with:
|
||||
|
@ -352,6 +362,12 @@ jobs:
|
|||
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
|
||||
command: test
|
||||
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||
- name: Test individual utilities
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
|
||||
command: test
|
||||
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||
- name: Archive executable artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
@ -454,6 +470,16 @@ jobs:
|
|||
toolchain: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
default: true
|
||||
profile: minimal # minimal component installation (ie, no documentation)
|
||||
- name: Initialize toolchain-dependent workflow variables
|
||||
id: dep_vars
|
||||
shell: bash
|
||||
run: |
|
||||
## Dependent VARs setup
|
||||
# * determine sub-crate utility list
|
||||
UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})"
|
||||
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)"
|
||||
echo set-output name=UTILITY_LIST::${UTILITY_LIST}
|
||||
echo ::set-output name=CARGO_UTILITY_LIST_OPTIONS::${CARGO_UTILITY_LIST_OPTIONS}
|
||||
- name: Test
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
|
@ -462,7 +488,19 @@ jobs:
|
|||
env:
|
||||
CARGO_INCREMENTAL: '0'
|
||||
RUSTC_WRAPPER: ''
|
||||
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads'
|
||||
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort'
|
||||
RUSTDOCFLAGS: '-Cpanic=abort'
|
||||
# RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- name: Test individual utilities
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||
env:
|
||||
CARGO_INCREMENTAL: '0'
|
||||
RUSTC_WRAPPER: ''
|
||||
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort'
|
||||
RUSTDOCFLAGS: '-Cpanic=abort'
|
||||
# RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- name: "`grcov` ~ install"
|
||||
uses: actions-rs/install@v0.1
|
||||
|
@ -470,33 +508,6 @@ jobs:
|
|||
crate: grcov
|
||||
version: latest
|
||||
use-tool-cache: true
|
||||
- name: "`grcov` ~ display coverage files" ## (for debugging)
|
||||
shell: bash
|
||||
run: |
|
||||
# display coverage files (per `grcov`)
|
||||
grcov . --output-type files | sort --unique
|
||||
- name: "`grcov` ~ configure + fixups" ## note: fixups, when needed, must be done *after* testing so that coverage files exist for renaming
|
||||
shell: bash
|
||||
run: |
|
||||
# create `grcov` configuration file
|
||||
GRCOV_CONFIG_DIR="${GITHUB_WORKSPACE}/.github/actions-rs"
|
||||
mkdir -p "${GRCOV_CONFIG_DIR}"
|
||||
GRCOV_CONFIG_FILE="${GRCOV_CONFIG_DIR}/grcov.yml"
|
||||
echo "branch: true" >> "${GRCOV_CONFIG_FILE}"
|
||||
echo "ignore:" >> "${GRCOV_CONFIG_FILE}"
|
||||
echo "- \"build.rs\"" >> "${GRCOV_CONFIG_FILE}"
|
||||
echo "- \"/*\"" >> "${GRCOV_CONFIG_FILE}"
|
||||
echo "- \"[a-zA-Z]:/*\"" >> "${GRCOV_CONFIG_FILE}"
|
||||
cat "${GRCOV_CONFIG_FILE}"
|
||||
# ## 'actions-rs/grcov@v0.1' expects coverage files (*.gc*) to be prefixed with the crate name (using '_' in place of '-')
|
||||
# ## * uutils workspace packages
|
||||
# prefix="uu_"
|
||||
# for f in "target/debug/deps/uu_"*-*.gc* ; do to="${f/uu_/${PROJECT_NAME}-uu_}" ; mv "$f" "$to" ; echo "mv $f $to" ; done
|
||||
# ## * tests
|
||||
# for f in "target/debug/deps/tests"-*.gc* ; do to="${f/tests/${PROJECT_NAME}-tests}" ; mv "$f" "$to" ; echo "mv $f $to" ; done
|
||||
# - name: Generate coverage data (via `grcov`)
|
||||
# id: coverage
|
||||
# uses: actions-rs/grcov@v0.1
|
||||
- name: Generate coverage data (via `grcov`)
|
||||
id: coverage
|
||||
shell: bash
|
||||
|
@ -504,8 +515,13 @@ jobs:
|
|||
# generate coverage data
|
||||
COVERAGE_REPORT_DIR="target/debug"
|
||||
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
|
||||
# GRCOV_IGNORE_OPTION='--ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*"' ## `grcov` ignores these params when passed as an environment variable (why?)
|
||||
# GRCOV_EXCLUDE_OPTION='--excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"' ## `grcov` ignores these params when passed as an environment variable (why?)
|
||||
mkdir -p "${COVERAGE_REPORT_DIR}"
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch ${GRCOV_IGNORE_OPTION} --ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*"
|
||||
# display coverage files
|
||||
grcov . --output-type files --ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique
|
||||
# generate coverage report
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"
|
||||
echo ::set-output name=report::${COVERAGE_REPORT_FILE}
|
||||
- name: Upload coverage results (to Codecov.io)
|
||||
uses: codecov/codecov-action@v1
|
||||
|
|
|
@ -208,6 +208,34 @@ dependencies = [
|
|||
"core::post-test",
|
||||
]
|
||||
|
||||
[tasks.test-util]
|
||||
description = "## Test (individual) utilities; usage: `cargo make (test-util | test-uutil) [UTIL_NAME...]`"
|
||||
category = "[project]"
|
||||
dependencies = [
|
||||
"action-test-utils",
|
||||
]
|
||||
|
||||
[tasks.test-utils]
|
||||
description = "hidden plural-form alias for 'test-util'"
|
||||
category = "[project]"
|
||||
dependencies = [
|
||||
"test-util",
|
||||
]
|
||||
|
||||
[tasks.test-uutil]
|
||||
description = "hidden alias for 'test-util'"
|
||||
category = "[project]"
|
||||
dependencies = [
|
||||
"test-util",
|
||||
]
|
||||
|
||||
[tasks.test-uutils]
|
||||
description = "hidden alias for 'test-util'"
|
||||
category = "[project]"
|
||||
dependencies = [
|
||||
"test-util",
|
||||
]
|
||||
|
||||
[tasks.uninstall]
|
||||
description = "## Remove project binary (from $HOME/.cargo/bin)"
|
||||
category = "[project]"
|
||||
|
@ -232,7 +260,11 @@ dependencies = [
|
|||
]
|
||||
|
||||
[tasks.uutil]
|
||||
alias = "utils"
|
||||
description = "hidden alias for 'util'"
|
||||
category = "[project]"
|
||||
dependencies = [
|
||||
"util",
|
||||
]
|
||||
|
||||
[tasks.uutils]
|
||||
description = "hidden plural-form alias for 'util'"
|
||||
|
@ -351,6 +383,15 @@ description = "`codespell` spellcheck repository"
|
|||
command = "codespell" # (from `pip install codespell`)
|
||||
args = [".", "--skip=*/.git,./target,./tests/fixtures", "--ignore-words-list=mut,od"]
|
||||
|
||||
[tasks.action-test-utils]
|
||||
description = "Build individual utilities"
|
||||
dependencies = [
|
||||
"action-determine-utils",
|
||||
]
|
||||
command = "cargo"
|
||||
# args = ["build", "@@remove-empty(CARGO_MAKE_TASK_BUILD_UTILS_ARGS)" ]
|
||||
args = ["test", "@@split(CARGO_MAKE_TASK_BUILD_UTILS_ARGS, )" ]
|
||||
|
||||
[tasks.action-test_quiet]
|
||||
description = "Test (in `--quiet` mode)"
|
||||
command = "cargo"
|
||||
|
|
|
@ -464,7 +464,7 @@ fn write_nonprint_to_end<W: Write>(in_buf: &[u8], writer: &mut W, tab: &[u8]) ->
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::io::{stdout, BufWriter};
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ mod tests {
|
|||
fn divisor(a: u64, b: u64) -> bool {
|
||||
// Test that gcd(a, b) divides a and b
|
||||
let g = gcd(a, b);
|
||||
if g == 0 { return a == 0 && b == 0; }
|
||||
a % g == 0 && b % g == 0
|
||||
}
|
||||
|
||||
|
|
|
@ -20,18 +20,40 @@ pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbolic_modes() {
|
||||
assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(parse_mode(Some("+x".to_owned())).unwrap(), 0o777);
|
||||
assert_eq!(parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
|
||||
assert_eq!(parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
/// Test if the program is running under WSL
|
||||
// ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
|
||||
// ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy
|
||||
pub fn is_wsl() -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
|
||||
if let Ok(s) = std::str::from_utf8(&b) {
|
||||
let a = s.to_ascii_lowercase();
|
||||
return a.contains("microsoft") || a.contains("wsl");
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numeric_modes() {
|
||||
assert_eq!(parse_mode(Some("644".to_owned())).unwrap(), 0o644);
|
||||
assert_eq!(parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
|
||||
assert_eq!(parse_mode(None).unwrap(), 0o666);
|
||||
#[test]
|
||||
fn symbolic_modes() {
|
||||
assert_eq!(super::parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(
|
||||
super::parse_mode(Some("+x".to_owned())).unwrap(),
|
||||
if !is_wsl() { 0o777 } else { 0o776 }
|
||||
);
|
||||
assert_eq!(super::parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
|
||||
assert_eq!(super::parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn numeric_modes() {
|
||||
assert_eq!(super::parse_mode(Some("644".to_owned())).unwrap(), 0o644);
|
||||
assert_eq!(super::parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
|
||||
assert_eq!(super::parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
|
||||
assert_eq!(super::parse_mode(None).unwrap(), 0o666);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,8 +159,8 @@ impl<'a> MemoryDecoder<'a> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use byteorder_io::ByteOrder;
|
||||
use peekreader::PeekReader;
|
||||
use crate::byteorder_io::ByteOrder;
|
||||
use crate::peekreader::PeekReader;
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// https://github.com/lazy-bitfield/rust-mockstream/pull/2
|
||||
|
||||
use std::error::Error as errorError;
|
||||
use std::io::{Cursor, Error, ErrorKind, Read, Result};
|
||||
|
||||
/// `FailingMockStream` mocks a stream which will fail upon read or write
|
||||
|
@ -87,7 +86,7 @@ fn test_failing_mock_stream_read() {
|
|||
let mut v = [0; 4];
|
||||
let error = s.read(v.as_mut()).unwrap_err();
|
||||
assert_eq!(error.kind(), ErrorKind::BrokenPipe);
|
||||
assert_eq!(error.description(), "The dog ate the ethernet cable");
|
||||
assert_eq!(error.to_string(), "The dog ate the ethernet cable");
|
||||
// after a single error, it will return Ok(0)
|
||||
assert_eq!(s.read(v.as_mut()).unwrap(), 0);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ impl<'b> HasError for MultifileReader<'b> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use mockstream::*;
|
||||
use crate::mockstream::*;
|
||||
use std::io::{Cursor, ErrorKind, Read};
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -99,7 +99,7 @@ impl OutputInfo {
|
|||
///
|
||||
/// Multiple representations of the same data, will be right-aligned for easy reading.
|
||||
/// For example a 64 bit octal and a 32-bit decimal with a 16-bit hexadecimal looks like this:
|
||||
/// ```
|
||||
/// ```ignore
|
||||
/// 1777777777777777777777 1777777777777777777777
|
||||
/// 4294967295 4294967295 4294967295 4294967295
|
||||
/// ffff ffff ffff ffff ffff ffff ffff ffff
|
||||
|
@ -131,7 +131,7 @@ impl OutputInfo {
|
|||
///
|
||||
/// Here is another example showing the alignment of 64-bit unsigned decimal numbers,
|
||||
/// 32-bit hexadecimal number, 16-bit octal numbers and 8-bit hexadecimal numbers:
|
||||
/// ```
|
||||
/// ```ignore
|
||||
/// 18446744073709551615 18446744073709551615
|
||||
/// ffffffff ffffffff ffffffff ffffffff
|
||||
/// 177777 177777 177777 177777 177777 177777 177777 177777
|
||||
|
|
|
@ -337,7 +337,7 @@ fn parse_type_string(params: &str) -> Result<Vec<ParsedFormatterItemInfo>, Strin
|
|||
pub fn parse_format_flags_str(
|
||||
args_str: &Vec<&'static str>,
|
||||
) -> Result<Vec<FormatterItemInfo>, String> {
|
||||
let args = args_str.iter().map(|s| s.to_string()).collect();
|
||||
let args: Vec<String> = args_str.iter().map(|s| s.to_string()).collect();
|
||||
match parse_format_flags(&args) {
|
||||
Err(e) => Err(e),
|
||||
Ok(v) => {
|
||||
|
|
|
@ -76,8 +76,7 @@ impl<R: HasError> HasError for PartialReader<R> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use mockstream::*;
|
||||
use std::error::Error;
|
||||
use crate::mockstream::*;
|
||||
use std::io::{Cursor, ErrorKind, Read};
|
||||
|
||||
#[test]
|
||||
|
@ -97,7 +96,7 @@ mod tests {
|
|||
|
||||
let error = sut.read(v.as_mut()).unwrap_err();
|
||||
assert_eq!(error.kind(), ErrorKind::PermissionDenied);
|
||||
assert_eq!(error.description(), "No access");
|
||||
assert_eq!(error.to_string(), "No access");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -126,7 +125,7 @@ mod tests {
|
|||
|
||||
let error = sut.read(v.as_mut()).unwrap_err();
|
||||
assert_eq!(error.kind(), ErrorKind::PermissionDenied);
|
||||
assert_eq!(error.description(), "No access");
|
||||
assert_eq!(error.to_string(), "No access");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -173,7 +172,7 @@ mod tests {
|
|||
|
||||
let error = sut.read(v.as_mut()).unwrap_err();
|
||||
assert_eq!(error.kind(), ErrorKind::PermissionDenied);
|
||||
assert_eq!(error.description(), "No access");
|
||||
assert_eq!(error.to_string(), "No access");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -197,8 +197,6 @@ fn test_format_flo64() {
|
|||
|
||||
#[test]
|
||||
fn test_format_flo16() {
|
||||
use half::consts::*;
|
||||
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8400u16)), "-6.104e-5");
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8401u16)), "-6.109e-5");
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8402u16)), "-6.115e-5");
|
||||
|
@ -213,11 +211,11 @@ fn test_format_flo16() {
|
|||
assert_eq!(format_flo16(f16::from_f32(-0.2)), " -0.2000");
|
||||
assert_eq!(format_flo16(f16::from_f32(-0.02)), "-2.000e-2");
|
||||
|
||||
assert_eq!(format_flo16(MIN_POSITIVE_SUBNORMAL), " 5.966e-8");
|
||||
assert_eq!(format_flo16(MIN), " -6.550e4");
|
||||
assert_eq!(format_flo16(NAN), " NaN");
|
||||
assert_eq!(format_flo16(INFINITY), " inf");
|
||||
assert_eq!(format_flo16(NEG_INFINITY), " -inf");
|
||||
assert_eq!(format_flo16(NEG_ZERO), " -0");
|
||||
assert_eq!(format_flo16(ZERO), " 0");
|
||||
assert_eq!(format_flo16(f16::MIN_POSITIVE_SUBNORMAL), " 5.960e-8");
|
||||
assert_eq!(format_flo16(f16::MIN), " -6.550e4");
|
||||
assert_eq!(format_flo16(f16::NAN), " NaN");
|
||||
assert_eq!(format_flo16(f16::INFINITY), " inf");
|
||||
assert_eq!(format_flo16(f16::NEG_INFINITY), " -inf");
|
||||
assert_eq!(format_flo16(f16::NEG_ZERO), " -0");
|
||||
assert_eq!(format_flo16(f16::ZERO), " 0");
|
||||
}
|
||||
|
|
|
@ -4,9 +4,6 @@ use self::tail::parse_size;
|
|||
use crate::common::util::*;
|
||||
use std::char::from_digit;
|
||||
use std::io::Write;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
static FOOBAR_TXT: &'static str = "foobar.txt";
|
||||
static FOOBAR_2_TXT: &'static str = "foobar2.txt";
|
||||
|
@ -98,8 +95,14 @@ fn test_follow_stdin() {
|
|||
.stdout_is_fixture("follow_stdin.expected");
|
||||
}
|
||||
|
||||
// FixME: test PASSES for usual windows builds, but fails for coverage testing builds (likely related to the specific RUSTFLAGS '-Zpanic_abort_tests -Cpanic=abort')
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn test_follow_with_pid() {
|
||||
use std::process::{Command, Stdio};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
#[cfg(unix)]
|
||||
|
|
59
util/build-code_coverage.BAT
Normal file
59
util/build-code_coverage.BAT
Normal file
|
@ -0,0 +1,59 @@
|
|||
@setLocal
|
||||
@echo off
|
||||
set "ERRORLEVEL="
|
||||
|
||||
@rem ::# spell-checker:ignore (abbrevs/acronyms) gcno
|
||||
@rem ::# spell-checker:ignore (CMD) COMSPEC ERRORLEVEL
|
||||
@rem ::# spell-checker:ignore (jargon) toolchain
|
||||
@rem ::# spell-checker:ignore (rust) Ccodegen Cinline Coverflow Cpanic RUSTC RUSTDOCFLAGS RUSTFLAGS RUSTUP Zpanic
|
||||
@rem ::# spell-checker:ignore (utils) genhtml grcov lcov sccache uutils
|
||||
|
||||
@rem ::# ref: https://github.com/uutils/coreutils/pull/1476
|
||||
|
||||
set "FEATURES_OPTION=--features feat_os_windows"
|
||||
|
||||
cd "%~dp0.."
|
||||
call echo [ "%CD%" ]
|
||||
|
||||
for /f "tokens=*" %%G in ('%~dp0\show-utils.BAT %FEATURES_OPTION%') do set UTIL_LIST=%%G
|
||||
REM echo UTIL_LIST=%UTIL_LIST%
|
||||
set "CARGO_INDIVIDUAL_PACKAGE_OPTIONS="
|
||||
for %%H in (%UTIL_LIST%) do (
|
||||
if DEFINED CARGO_INDIVIDUAL_PACKAGE_OPTIONS call set "CARGO_INDIVIDUAL_PACKAGE_OPTIONS=%%CARGO_INDIVIDUAL_PACKAGE_OPTIONS%% "
|
||||
call set "CARGO_INDIVIDUAL_PACKAGE_OPTIONS=%%CARGO_INDIVIDUAL_PACKAGE_OPTIONS%%-puu_%%H"
|
||||
)
|
||||
REM echo CARGO_INDIVIDUAL_PACKAGE_OPTIONS=%CARGO_INDIVIDUAL_PACKAGE_OPTIONS%
|
||||
|
||||
REM call cargo clean
|
||||
|
||||
set "CARGO_INCREMENTAL=0"
|
||||
set "RUSTC_WRAPPER=" &@REM ## NOTE: RUSTC_WRAPPER=='sccache' breaks code coverage calculations (uu_*.gcno files are not created during build)
|
||||
@REM set "RUSTFLAGS=-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
|
||||
set "RUSTFLAGS=-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
set "RUSTDOCFLAGS=-Cpanic=abort"
|
||||
set "RUSTUP_TOOLCHAIN=nightly-gnu"
|
||||
call cargo build %FEATURES_OPTION%
|
||||
call cargo test --no-run %FEATURES_OPTION%
|
||||
call cargo test --quiet %FEATURES_OPTION%
|
||||
call cargo test --quiet %FEATURES_OPTION% %CARGO_INDIVIDUAL_PACKAGE_OPTIONS%
|
||||
|
||||
if NOT DEFINED COVERAGE_REPORT_DIR set COVERAGE_REPORT_DIR=target\debug\coverage-win
|
||||
call rm -r "%COVERAGE_REPORT_DIR%" 2>NUL
|
||||
|
||||
set GRCOV_IGNORE_OPTION=--ignore build.rs --ignore "/*" --ignore "[A-Za-z]:/*" --ignore "C:/Users/*"
|
||||
set GRCOV_EXCLUDE_OPTION=--excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"
|
||||
@rem ::# * build LCOV coverage file
|
||||
REM echo call grcov . --output-type lcov --output-path "%COVERAGE_REPORT_DIR%/../lcov.info" --branch %GRCOV_IGNORE_OPTION% %GRCOV_EXCLUDE_OPTION%
|
||||
call grcov . --output-type lcov --output-path "%COVERAGE_REPORT_DIR%/../lcov.info" --branch %GRCOV_IGNORE_OPTION% %GRCOV_EXCLUDE_OPTION%
|
||||
@rem ::# * build HTML
|
||||
@rem ::# -- use `genhtml` if available for display of additional branch coverage information
|
||||
set "ERRORLEVEL="
|
||||
call genhtml --version 2>NUL 1>&2
|
||||
if NOT ERRORLEVEL 1 (
|
||||
echo call genhtml target/debug/lcov.info --prefix "%CD%" --output-directory "%COVERAGE_REPORT_DIR%" --branch-coverage --function-coverage ^| grep ": [0-9]"
|
||||
call genhtml target/debug/lcov.info --prefix "%CD%" --output-directory "%COVERAGE_REPORT_DIR%" --branch-coverage --function-coverage | grep ": [0-9]"
|
||||
) else (
|
||||
echo call grcov . --output-type html --output-path "%COVERAGE_REPORT_DIR%" --branch %GRCOV_IGNORE_OPTION%
|
||||
call grcov . --output-type html --output-path "%COVERAGE_REPORT_DIR%" --branch %GRCOV_IGNORE_OPTION%
|
||||
)
|
||||
if ERRORLEVEL 1 goto _undefined_ 2>NUL || @for %%G in ("%COMSPEC%") do @title %%nG & @"%COMSPEC%" /d/c exit %ERRORLEVEL%
|
56
util/build-code_coverage.sh
Normal file
56
util/build-code_coverage.sh
Normal file
|
@ -0,0 +1,56 @@
|
|||
#!/bin/sh
|
||||
|
||||
# spell-checker:ignore (abbrevs/acronyms) HTML gcno llvm
|
||||
# spell-checker:ignore (jargon) toolchain
|
||||
# spell-checker:ignore (rust) Ccodegen Cinline Coverflow Cpanic RUSTC RUSTDOCFLAGS RUSTFLAGS RUSTUP Zpanic
|
||||
# spell-checker:ignore (shell) OSID esac
|
||||
# spell-checker:ignore (utils) genhtml grcov lcov readlink sccache uutils
|
||||
|
||||
FEATURES_OPTION="--features feat_os_unix"
|
||||
|
||||
ME_dir="$(dirname -- $(readlink -fm -- "$0"))"
|
||||
REPO_main_dir="$(dirname -- "${ME_dir}")"
|
||||
|
||||
cd "${REPO_main_dir}"
|
||||
echo "[ \"$PWD\" ]"
|
||||
|
||||
UTIL_LIST=$("${ME_dir}"/show-utils.sh ${FEATURES_OPTION})
|
||||
CARGO_INDIVIDUAL_PACKAGE_OPTIONS=""
|
||||
for UTIL in ${UTIL_LIST}; do
|
||||
if [ -n "${CARGO_INDIVIDUAL_PACKAGE_OPTIONS}" ]; then CARGO_INDIVIDUAL_PACKAGE_OPTIONS="${CARGO_INDIVIDUAL_PACKAGE_OPTIONS} "; fi
|
||||
CARGO_INDIVIDUAL_PACKAGE_OPTIONS="${CARGO_INDIVIDUAL_PACKAGE_OPTIONS}-puu_${UTIL}"
|
||||
done
|
||||
# echo "CARGO_INDIVIDUAL_PACKAGE_OPTIONS=${CARGO_INDIVIDUAL_PACKAGE_OPTIONS}"
|
||||
|
||||
# cargo clean
|
||||
|
||||
export CARGO_INCREMENTAL=0
|
||||
export RUSTC_WRAPPER="" ## NOTE: RUSTC_WRAPPER=='sccache' breaks code coverage calculations (uu_*.gcno files are not created during build)
|
||||
# export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
|
||||
export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
export RUSTDOCFLAGS="-Cpanic=abort"
|
||||
export RUSTUP_TOOLCHAIN="nightly-gnu"
|
||||
cargo build ${FEATURES_OPTION}
|
||||
cargo test --no-run ${FEATURES_OPTION}
|
||||
cargo test --quiet ${FEATURES_OPTION}
|
||||
cargo test --quiet ${FEATURES_OPTION} ${CARGO_INDIVIDUAL_PACKAGE_OPTIONS}
|
||||
|
||||
export COVERAGE_REPORT_DIR
|
||||
if [ -z "${COVERAGE_REPORT_DIR}" ]; then COVERAGE_REPORT_DIR="${REPO_main_dir}/target/debug/coverage-nix"; fi
|
||||
rm -r "${COVERAGE_REPORT_DIR}" 2>/dev/null
|
||||
mkdir -p "${COVERAGE_REPORT_DIR}"
|
||||
|
||||
## NOTE: `grcov` is not accepting environment variable contents as options for `--ignore` or `--excl_br_line`
|
||||
# export GRCOV_IGNORE_OPTION="--ignore build.rs --ignore '/*' --ignore '[A-Za-z]:/*' --ignore 'C:/Users/*'"
|
||||
# export GRCOV_EXCLUDE_OPTION="--excl-br-line '^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()'"
|
||||
# * build LCOV coverage file
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_DIR}/../lcov.info" --branch --ignore build.rs --ignore '/*' --ignore '[A-Za-z]:/*' --ignore 'C:/Users/*' --excl-br-line '^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()'
|
||||
# * build HTML
|
||||
# -- use `genhtml` if available for display of additional branch coverage information
|
||||
genhtml --version 2>/dev/null 1>&2
|
||||
if [ $? -eq 0 ]; then
|
||||
genhtml "${COVERAGE_REPORT_DIR}/../lcov.info" --output-directory "${COVERAGE_REPORT_DIR}" --branch-coverage --function-coverage | grep ": [0-9]"
|
||||
else
|
||||
grcov . --output-type html --output-path "${COVERAGE_REPORT_DIR}" --branch --ignore build.rs --ignore '/*' --ignore '[A-Za-z]:/*' --ignore 'C:/Users/*' --excl-br-line '^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()'
|
||||
fi
|
||||
if [ $? -ne 0 ]; then exit 1 ; fi
|
16
util/show-code_coverage.BAT
Normal file
16
util/show-code_coverage.BAT
Normal file
|
@ -0,0 +1,16 @@
|
|||
@setLocal
|
||||
@echo off
|
||||
|
||||
@rem:: # spell-checker:ignore (shell/CMD) COMSPEC ERRORLEVEL
|
||||
|
||||
set "ME_dir=%~dp0."
|
||||
set "REPO_main_dir=%ME_dir%\.."
|
||||
|
||||
set "ERRORLEVEL="
|
||||
set "COVERAGE_REPORT_DIR=%REPO_main_dir%\target\debug\coverage-win"
|
||||
|
||||
call "%ME_dir%\build-code_coverage.BAT"
|
||||
if ERRORLEVEL 1 goto _undefined_ 2>NUL || @for %%G in ("%COMSPEC%") do @title %%nG & @"%COMSPEC%" /d/c exit %ERRORLEVEL%
|
||||
|
||||
call start "" "%COVERAGE_REPORT_DIR%"\index.html
|
||||
if ERRORLEVEL 1 goto _undefined_ 2>NUL || @for %%G in ("%COMSPEC%") do @title %%nG & @"%COMSPEC%" /d/c exit %ERRORLEVEL%
|
16
util/show-code_coverage.sh
Normal file
16
util/show-code_coverage.sh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
# spell-checker:ignore (vars) OSID
|
||||
|
||||
ME_dir="$(dirname -- $(readlink -fm -- "$0"))"
|
||||
REPO_main_dir="$(dirname -- "${ME_dir}")"
|
||||
|
||||
export COVERAGE_REPORT_DIR="${REPO_main_dir}/target/debug/coverage-nix"
|
||||
|
||||
"${ME_dir}/build-code_coverage.sh"
|
||||
if [ $? -ne 0 ]; then exit 1 ; fi
|
||||
|
||||
case ";$OSID_tags;" in
|
||||
*";wsl;"* ) powershell.exe -c $(wslpath -w "${COVERAGE_REPORT_DIR}"/index.html) ;;
|
||||
* ) xdg-open --version >/dev/null 2>&1 && xdg-open "${COVERAGE_REPORT_DIR}"/index.html || echo "report available at '\"${COVERAGE_REPORT_DIR}\"/index.html'" ;;
|
||||
esac ;
|
|
@ -1,43 +0,0 @@
|
|||
@setLocal
|
||||
@echo off
|
||||
|
||||
@rem ::# spell-checker:ignore (abbrevs/acronyms) gcno
|
||||
@rem ::# spell-checker:ignore (CMD) COMSPEC ERRORLEVEL
|
||||
@rem ::# spell-checker:ignore (jargon) toolchain
|
||||
@rem ::# spell-checker:ignore (rust) Ccodegen Cinline Coverflow RUSTC RUSTFLAGS RUSTUP
|
||||
@rem ::# spell-checker:ignore (utils) genhtml grcov lcov sccache uutils
|
||||
|
||||
set BIN=uutils
|
||||
|
||||
set "FEATURES_OPTION=--features windows"
|
||||
|
||||
cd "%~dp0.."
|
||||
call echo [ "%CD%" ]
|
||||
|
||||
call cargo clean
|
||||
|
||||
set CARGO_INCREMENTAL=0
|
||||
set "RUSTC_WRAPPER=" &@REM ## NOTE: RUSTC_WRAPPER=='sccache' breaks code coverage calculations (uu_*.gcno files are not created during build)
|
||||
set "RUSTFLAGS=-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
|
||||
set RUSTUP_TOOLCHAIN=nightly-x86_64-pc-windows-gnu
|
||||
call cargo build %FEATURES_OPTION%
|
||||
call cargo test --no-run %FEATURES_OPTION%
|
||||
call cargo test --quiet %FEATURES_OPTION%
|
||||
|
||||
set COVERAGE_REPORT_DIR=target\debug\coverage-win
|
||||
call rm -r "%COVERAGE_REPORT_DIR%" 2>NUL
|
||||
|
||||
set GRCOV_IGNORE_OPTION=--ignore build.rs --ignore "/*" --ignore "[A-Za-z]:/*"
|
||||
@rem ::# * build LCOV coverage file
|
||||
call grcov . --output-type lcov --output-path "%COVERAGE_REPORT_DIR%/../lcov.info" --branch %GRCOV_IGNORE_OPTION%
|
||||
@rem ::# * build HTML
|
||||
@rem ::# -- use `genhtml` if available for display of additional branch coverage information
|
||||
call genhtml --version 2>NUL 1>&2
|
||||
if NOT ERRORLEVEL 1 (
|
||||
call genhtml target/debug/lcov.info --output-directory "%COVERAGE_REPORT_DIR%" --branch-coverage --function-coverage
|
||||
) else (
|
||||
call grcov . --output-type html --output-path "%COVERAGE_REPORT_DIR%" --branch %GRCOV_IGNORE_OPTION%
|
||||
)
|
||||
if ERRORLEVEL 1 goto _undefined_ 2>NUL || @for %%G in ("%COMSPEC%") do @title %%nG & @"%COMSPEC%" /d/c exit %ERRORLEVEL%
|
||||
|
||||
call start "" "%COVERAGE_REPORT_DIR%"\index.html
|
|
@ -1,50 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# spell-checker:ignore (abbrevs/acronyms) HTML gcno llvm
|
||||
# spell-checker:ignore (jargon) toolchain
|
||||
# spell-checker:ignore (rust) Ccodegen Cinline Coverflow RUSTC RUSTFLAGS RUSTUP
|
||||
# spell-checker:ignore (shell) OSID esac
|
||||
# spell-checker:ignore (utils) genhtml grcov lcov readlink sccache uutils
|
||||
|
||||
BIN=uutils
|
||||
|
||||
FEATURES_OPTION="--features unix"
|
||||
|
||||
cd "$(dirname -- $(readlink -fm -- "$0"/..))"
|
||||
echo "[ \"$PWD\" ]"
|
||||
|
||||
cargo clean
|
||||
|
||||
export CARGO_INCREMENTAL=0
|
||||
export RUSTC_WRAPPER="" ## NOTE: RUSTC_WRAPPER=='sccache' breaks code coverage calculations (uu_*.gcno files are not created during build)
|
||||
export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads"
|
||||
export RUSTUP_TOOLCHAIN=nightly
|
||||
cargo build ${FEATURES_OPTION}
|
||||
cargo test --no-run ${FEATURES_OPTION}
|
||||
cargo test --quiet ${FEATURES_OPTION}
|
||||
|
||||
export COVERAGE_REPORT_DIR="target/debug/coverage-nix"
|
||||
rm -r "${COVERAGE_REPORT_DIR}" 2>/dev/null
|
||||
mkdir -p "${COVERAGE_REPORT_DIR}"
|
||||
|
||||
# GRCOV_IGNORE_OPTION="--ignore build.rs --ignore \"/cargo/*\" --ignore \"/rustc/*\" --ignore \"${HOME}/.cargo/*\" --ignore \"${PWD}/rustc/*\""
|
||||
export GRCOV_IGNORE_OPTION="--ignore build.rs --ignore \"/*\" --ignore \"[A-Za-z]:/*\""
|
||||
## FixME: `grcov . ... ${GRCOV_IGNORE_OPTION}` fails, completely ignoring the contents of ${GRCOV_IGNORE_OPTION}
|
||||
# * build LCOV coverage file
|
||||
## FixME: grcov . --output-type lcov --output-path "${COVERAGE_REPORT_DIR}/../lcov.info" --branch ${GRCOV_IGNORE_OPTION}
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_DIR}/../lcov.info" --branch --ignore build.rs --ignore '/*' --ignore '[A-Za-z]:/*'
|
||||
# * build HTML
|
||||
# -- use `genhtml` if available for display of additional branch coverage information
|
||||
genhtml --version 2>/dev/null 1>&2
|
||||
if [ $? -eq 0 ]; then
|
||||
genhtml "${COVERAGE_REPORT_DIR}/../lcov.info" --output-directory "${COVERAGE_REPORT_DIR}" --branch-coverage --function-coverage
|
||||
else
|
||||
## FixME: grcov . --output-type html --output-path "${COVERAGE_REPORT_DIR}" --branch ${GRCOV_IGNORE_OPTION}
|
||||
grcov . --output-type html --output-path "${COVERAGE_REPORT_DIR}" --branch --ignore build.rs --ignore '/*' --ignore '[A-Za-z]:/*'
|
||||
fi
|
||||
if [ $? -ne 0 ]; then exit 1 ; fi
|
||||
|
||||
case ";$OSID_tags;" in
|
||||
*";wsl;"* ) powershell.exe -c "${COVERAGE_REPORT_DIR}"/index.html ;;
|
||||
* ) xdg-open --version >/dev/null 2>&1 && xdg-open "${COVERAGE_REPORT_DIR}"/index.html || echo "report available at '\"${COVERAGE_REPORT_DIR}\"/index.html'" ;;
|
||||
esac ;
|
Loading…
Add table
Add a link
Reference in a new issue