| #![cfg_attr(f16_enabled, feature(f16))] |
| #![cfg_attr(f128_enabled, feature(f128))] |
| #![allow(clippy::unusual_byte_groupings)] // sometimes we group by sign_exp_sig |
| |
| pub mod domain; |
| mod f8_impl; |
| pub mod generate; |
| #[cfg(feature = "build-mpfr")] |
| pub mod mpfloat; |
| mod num; |
| pub mod op; |
| mod precision; |
| mod run_cfg; |
| mod test_traits; |
| |
| use std::env; |
| use std::fs::File; |
| use std::io::Write; |
| use std::path::PathBuf; |
| use std::sync::LazyLock; |
| use std::time::SystemTime; |
| |
| pub use f8_impl::{f8, hf8}; |
| pub use libm::support::{Float, Int, IntTy, MinInt}; |
| pub use num::{FloatExt, linear_ints, logspace}; |
| pub use op::{ |
| BaseName, FloatTy, Identifier, MathOp, OpCFn, OpCRet, OpFTy, OpRustArgs, OpRustFn, OpRustRet, |
| Ty, |
| }; |
| pub use precision::{MaybeOverride, SpecialCase, default_ulp}; |
| use run_cfg::extensive_max_iterations; |
| pub use run_cfg::{ |
| CheckBasis, CheckCtx, EXTENSIVE_ENV, GeneratorKind, bigint_fuzz_iteration_count, |
| skip_extensive_test, |
| }; |
| pub use test_traits::{CheckOutput, Hex, TupleCall}; |
| |
| /// Result type for tests is usually from `anyhow`. Most times there is no success value to |
| /// propagate. |
| pub type TestResult<T = (), E = anyhow::Error> = Result<T, E>; |
| |
| /// True if `EMULATED` is set and nonempty. Used to determine how many iterations to run. |
| pub const fn emulated() -> bool { |
| match option_env!("EMULATED") { |
| Some(s) if s.is_empty() => false, |
| None => false, |
| Some(_) => true, |
| } |
| } |
| |
| /// True if `CI` is set and nonempty. |
| pub const fn ci() -> bool { |
| match option_env!("CI") { |
| Some(s) if s.is_empty() => false, |
| None => false, |
| Some(_) => true, |
| } |
| } |
| |
| /// Print to stderr and additionally log it to `target/test-log.txt`. This is useful for saving |
| /// output that would otherwise be consumed by the test harness. |
| pub fn test_log(s: &str) { |
| // Handle to a file opened in append mode, unless a suitable path can't be determined. |
| static OUTFILE: LazyLock<Option<File>> = LazyLock::new(|| { |
| // If the target directory is overridden, use that environment variable. Otherwise, save |
| // at the default path `{workspace_root}/target`. |
| let target_dir = match env::var("CARGO_TARGET_DIR") { |
| Ok(s) => PathBuf::from(s), |
| Err(_) => { |
| let Ok(x) = env::var("CARGO_MANIFEST_DIR") else { |
| return None; |
| }; |
| |
| PathBuf::from(x).join("../target") |
| } |
| }; |
| let outfile = target_dir.join("test-log.txt"); |
| |
| let mut f = File::options() |
| .create(true) |
| .append(true) |
| .open(outfile) |
| .expect("failed to open logfile"); |
| let now = SystemTime::now() |
| .duration_since(SystemTime::UNIX_EPOCH) |
| .unwrap(); |
| |
| writeln!(f, "\n\nTest run at {}", now.as_secs()).unwrap(); |
| writeln!(f, "arch: {}", env::consts::ARCH).unwrap(); |
| writeln!(f, "os: {}", env::consts::OS).unwrap(); |
| writeln!(f, "bits: {}", usize::BITS).unwrap(); |
| writeln!(f, "emulated: {}", emulated()).unwrap(); |
| writeln!(f, "ci: {}", ci()).unwrap(); |
| writeln!(f, "cargo features: {}", env!("CFG_CARGO_FEATURES")).unwrap(); |
| writeln!(f, "opt level: {}", env!("CFG_OPT_LEVEL")).unwrap(); |
| writeln!(f, "target features: {}", env!("CFG_TARGET_FEATURES")).unwrap(); |
| writeln!(f, "extensive iterations {}", extensive_max_iterations()).unwrap(); |
| |
| Some(f) |
| }); |
| |
| eprintln!("{s}"); |
| |
| if let Some(mut f) = OUTFILE.as_ref() { |
| writeln!(f, "{s}").unwrap(); |
| } |
| } |