mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 07:04:29 +00:00
Add an FFI test facility
This allow testing Rust functions (from fish_tests.cpp) which need to cross the FFI. See the example in smoke.rs.
This commit is contained in:
parent
096b254c4a
commit
681a165721
8 changed files with 114 additions and 0 deletions
|
@ -17,6 +17,7 @@ set(fish_autocxx_gen_dir "${CMAKE_BINARY_DIR}/fish-autocxx-gen/")
|
|||
|
||||
corrosion_import_crate(
|
||||
MANIFEST_PATH "${CMAKE_SOURCE_DIR}/fish-rust/Cargo.toml"
|
||||
FEATURES "fish-ffi-tests"
|
||||
)
|
||||
|
||||
# We need the build dir because cxx puts our headers in there.
|
||||
|
|
32
fish-rust/Cargo.lock
generated
32
fish-rust/Cargo.lock
generated
|
@ -232,6 +232,16 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.81"
|
||||
|
@ -343,6 +353,7 @@ dependencies = [
|
|||
"cxx-build",
|
||||
"cxx-gen",
|
||||
"errno",
|
||||
"inventory",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"miette",
|
||||
|
@ -364,6 +375,17 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghost"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41973d4c45f7a35af8753ba3457cc99d406d863941fd7f52663cff54a5ab99b3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.27.0"
|
||||
|
@ -432,6 +454,16 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inventory"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16fe3b35d64bd1f72917f06425e7573a2f63f74f42c8f56e53ea6826dde3a2b5"
|
||||
dependencies = [
|
||||
"ctor",
|
||||
"ghost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
version = "1.1.1"
|
||||
|
|
|
@ -10,6 +10,7 @@ widestring-suffix = { path = "./widestring-suffix/" }
|
|||
autocxx = "0.23.1"
|
||||
cxx = "1.0"
|
||||
errno = "0.2.8"
|
||||
inventory = { version = "0.3.3", optional = true}
|
||||
lazy_static = "1.4.0"
|
||||
libc = "0.2.137"
|
||||
nix = "0.25.0"
|
||||
|
@ -26,6 +27,12 @@ miette = { version = "5", features = ["fancy"] }
|
|||
[lib]
|
||||
crate-type=["staticlib"]
|
||||
|
||||
[features]
|
||||
# The fish-ffi-tests feature causes tests to be built which need to use the FFI.
|
||||
# These tests are run by fish_tests().
|
||||
default = ["fish-ffi-tests"]
|
||||
fish-ffi-tests = ["inventory"]
|
||||
|
||||
[patch.crates-io]
|
||||
cxx = { git = "https://github.com/ridiculousfish/cxx", branch = "fish" }
|
||||
cxx-gen = { git = "https://github.com/ridiculousfish/cxx", branch = "fish" }
|
||||
|
|
|
@ -21,6 +21,7 @@ fn main() -> miette::Result<()> {
|
|||
let source_files = vec![
|
||||
"src/fd_readable_set.rs",
|
||||
"src/ffi_init.rs",
|
||||
"src/ffi_tests.rs",
|
||||
"src/smoke.rs",
|
||||
"src/topic_monitor.rs",
|
||||
];
|
||||
|
|
63
fish-rust/src/ffi_tests.rs
Normal file
63
fish-rust/src/ffi_tests.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
/// Support for tests which need to cross the FFI.
|
||||
/// Because the C++ is not compiled by `cargo test` and there is no natural way to
|
||||
/// do it, use the following facilities for tests which need to use C++ types.
|
||||
/// This uses the inventory crate to build a custom-test harness
|
||||
/// as described at https://www.infinyon.com/blog/2021/04/rust-custom-test-harness/
|
||||
/// See smoke.rs add_test for an example of how to use this.
|
||||
|
||||
#[cfg(all(feature = "fish-ffi-tests", not(test)))]
|
||||
mod ffi_tests_impl {
|
||||
use inventory;
|
||||
|
||||
/// A test which needs to cross the FFI.
|
||||
#[derive(Debug)]
|
||||
pub struct FFITest {
|
||||
pub name: &'static str,
|
||||
pub func: fn(),
|
||||
}
|
||||
|
||||
/// Add a new test.
|
||||
/// Example usage:
|
||||
/// ```
|
||||
/// add_test!("test_name", || {
|
||||
/// assert!(1 + 2 == 3);
|
||||
/// });
|
||||
/// ```
|
||||
macro_rules! add_test {
|
||||
($name:literal, $func:expr) => {
|
||||
inventory::submit!(crate::ffi_tests::FFITest {
|
||||
name: $name,
|
||||
func: $func,
|
||||
});
|
||||
};
|
||||
}
|
||||
pub(crate) use add_test;
|
||||
|
||||
inventory::collect!(crate::ffi_tests::FFITest);
|
||||
|
||||
/// Runs all ffi tests.
|
||||
pub fn run_ffi_tests() {
|
||||
for test in inventory::iter::<crate::ffi_tests::FFITest> {
|
||||
println!("Running ffi test {}", test.name);
|
||||
(test.func)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(feature = "fish-ffi-tests", not(test))))]
|
||||
mod ffi_tests_impl {
|
||||
macro_rules! add_test {
|
||||
($name:literal, $func:expr) => {};
|
||||
}
|
||||
pub(crate) use add_test;
|
||||
pub fn run_ffi_tests() {}
|
||||
}
|
||||
|
||||
pub(crate) use ffi_tests_impl::*;
|
||||
|
||||
#[cxx::bridge(namespace = rust)]
|
||||
mod ffi_tests {
|
||||
extern "Rust" {
|
||||
fn run_ffi_tests();
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ mod fd_readable_set;
|
|||
mod fds;
|
||||
mod ffi;
|
||||
mod ffi_init;
|
||||
mod ffi_tests;
|
||||
mod flog;
|
||||
mod signal;
|
||||
mod smoke;
|
||||
|
|
|
@ -19,3 +19,8 @@ mod tests {
|
|||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
|
||||
use crate::ffi_tests::add_test;
|
||||
add_test!("test_add", || {
|
||||
assert_eq!(add(2, 3), 5);
|
||||
});
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "fd_readable_set.rs.h"
|
||||
#include "fds.h"
|
||||
#include "ffi_init.rs.h"
|
||||
#include "ffi_tests.rs.h"
|
||||
#include "function.h"
|
||||
#include "future_feature_flags.h"
|
||||
#include "global_safety.h"
|
||||
|
@ -7148,6 +7149,8 @@ void test_rust_smoke() {
|
|||
do_test(x == 42);
|
||||
}
|
||||
|
||||
void test_rust_ffi() { rust::run_ffi_tests(); }
|
||||
|
||||
// typedef void (test_entry_point_t)();
|
||||
using test_entry_point_t = void (*)();
|
||||
struct test_t {
|
||||
|
@ -7269,6 +7272,7 @@ static const test_t s_tests[]{
|
|||
{TEST_GROUP("re"), test_re_substitute},
|
||||
{TEST_GROUP("wgetopt"), test_wgetopt},
|
||||
{TEST_GROUP("rust_smoke"), test_rust_smoke},
|
||||
{TEST_GROUP("rust_ffi"), test_rust_ffi},
|
||||
};
|
||||
|
||||
void list_tests() {
|
||||
|
|
Loading…
Reference in a new issue