From 9d8906da30af984bd5fbaf9c06e315c047e8f65e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bennet=20Ble=C3=9Fmann?= Date: Mon, 20 Jan 2025 23:00:03 +0100 Subject: [PATCH] add ffi tests using f64 --- tests-pl/ffi_f64_minus_zero.pl | 16 ++++++ tests-pl/ffi_f64_nan.pl | 10 ++++ tests/scryer/ffi.rs | 101 +++++++++++++++++++++++++++++++++ tests/scryer/main.rs | 2 + 4 files changed, 129 insertions(+) create mode 100644 tests-pl/ffi_f64_minus_zero.pl create mode 100644 tests-pl/ffi_f64_nan.pl create mode 100644 tests/scryer/ffi.rs diff --git a/tests-pl/ffi_f64_minus_zero.pl b/tests-pl/ffi_f64_minus_zero.pl new file mode 100644 index 00000000..974b6e92 --- /dev/null +++ b/tests-pl/ffi_f64_minus_zero.pl @@ -0,0 +1,16 @@ +:- use_module(library(os)). +:- use_module(library(ffi)). + +test :- + getenv("ffi_f64_minus_zero_LIB", LIB), + use_foreign_module(LIB, ['ffi_f64_minus_zero'([], f64), 'signum'([f64], f64)]), + ffi:'ffi_f64_minus_zero'(N), + A is max(0.0, N), + B is max(N, 0.0), + ffi:'signum'(A, SA), + ffi:'signum'(B, SB), + write((SA, SB)), + -1.0 is SA, % incorrect, based on https://www.swi-prolog.org/pldoc/man?function=max/2 -0.0 is less than 0.0 so A and B should be 0.0 for which signum should be 1 + 1.0 is SB. + +:- initialization(test). diff --git a/tests-pl/ffi_f64_nan.pl b/tests-pl/ffi_f64_nan.pl new file mode 100644 index 00000000..a80dbd90 --- /dev/null +++ b/tests-pl/ffi_f64_nan.pl @@ -0,0 +1,10 @@ +:- use_module(library(os)). +:- use_module(library(ffi)). + +test :- + getenv("ffi_f64_nan_LIB", LIB), + use_foreign_module(LIB, ['ffi_f64_nan'([], f64)]), + ffi:'ffi_f64_nan'(N), + _ is round(N). + +:- initialization(test). diff --git a/tests/scryer/ffi.rs b/tests/scryer/ffi.rs new file mode 100644 index 00000000..33beec1f --- /dev/null +++ b/tests/scryer/ffi.rs @@ -0,0 +1,101 @@ +use std::{ + env::consts::{DLL_PREFIX, DLL_SUFFIX}, + io::Write, + path::Path, + process::Stdio, +}; + +use crate::helper::load_module_test; + +#[test] +fn ffi_f64_nan() { + let tmp_dir: &Path = env!("CARGO_TARGET_TMPDIR").as_ref(); + println!("CARGO_TARGET_TMPDIR: {tmp_dir:?}"); + + // technically UB as tests are by default multi-threaded, + // but there is currently no other easy way to get the dynamic library file path as an input into a load_module_test test + std::env::set_var( + "ffi_f64_nan_LIB", + tmp_dir.join(format!("{DLL_PREFIX}ffi_f64_nan{DLL_SUFFIX}")), + ); + + let mut child = std::process::Command::new("rustc") + .stdin(Stdio::piped()) + .arg("--crate-type=dylib") + .arg("--crate-name=ffi_f64_nan") + .arg("--out-dir") + .arg(tmp_dir) + .arg("-") + .spawn() + .unwrap(); + + child + .stdin + .take() + .unwrap() + .write_all( + r##" + #[no_mangle] + extern "C" fn ffi_f64_nan() -> f64 { + f64::NAN + } + "## + .as_bytes(), + ) + .unwrap(); + + assert!(child.wait().unwrap().success()); + + load_module_test( + "tests-pl/ffi_f64_nan.pl", + " error(evaluation_error(undefined),round/1).\n", + ); +} + +#[test] +fn ffi_f64_minus_zero() { + let tmp_dir: &Path = env!("CARGO_TARGET_TMPDIR").as_ref(); + println!("CARGO_TARGET_TMPDIR: {tmp_dir:?}"); + + // technically UB as tests are by default multi-threaded, + // but there is currently no other easy way to get the dynamic library file path as an input into a load_module_test test + std::env::set_var( + "ffi_f64_minus_zero_LIB", + tmp_dir.join(format!("{DLL_PREFIX}ffi_f64_minus_zero{DLL_SUFFIX}")), + ); + + let mut child = std::process::Command::new("rustc") + .stdin(Stdio::piped()) + .arg("--crate-type=dylib") + .arg("--crate-name=ffi_f64_minus_zero") + .arg("--out-dir") + .arg(tmp_dir) + .arg("-") + .spawn() + .unwrap(); + + child + .stdin + .take() + .unwrap() + .write_all( + r##" + #[no_mangle] + extern "C" fn ffi_f64_minus_zero() -> f64 { + -0.0 + } + + #[no_mangle] + extern "C" fn signum(f: f64) -> f64 { + f.signum() + } + "## + .as_bytes(), + ) + .unwrap(); + + assert!(child.wait().unwrap().success()); + + // note: ouput is currently wrong correct would be 1.0,1.0 + load_module_test("tests-pl/ffi_f64_minus_zero.pl", "-1.0,1.0"); +} diff --git a/tests/scryer/main.rs b/tests/scryer/main.rs index a501bd42..c9274166 100644 --- a/tests/scryer/main.rs +++ b/tests/scryer/main.rs @@ -2,6 +2,8 @@ mod helper; mod issues; mod src_tests; +mod ffi; + /// To add new cli test copy an existing .toml file in `tests/scryer/cli/issues/` or `tests/scryer/cli/issues/src_tests/`, /// adjust as necessary the `-f` and `--no-add-history` args should be kept but additional args may be added. /// For input on stdin add a .stdin file with the same filename. -- 2.54.0