mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 02:13:38 +08: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
|
@ -17,6 +17,7 @@ set(fish_autocxx_gen_dir "${CMAKE_BINARY_DIR}/fish-autocxx-gen/")
|
||||||
|
|
||||||
corrosion_import_crate(
|
corrosion_import_crate(
|
||||||
MANIFEST_PATH "${CMAKE_SOURCE_DIR}/fish-rust/Cargo.toml"
|
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.
|
# 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",
|
"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]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.81"
|
version = "1.0.81"
|
||||||
|
@ -343,6 +353,7 @@ dependencies = [
|
||||||
"cxx-build",
|
"cxx-build",
|
||||||
"cxx-gen",
|
"cxx-gen",
|
||||||
"errno",
|
"errno",
|
||||||
|
"inventory",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"miette",
|
"miette",
|
||||||
|
@ -364,6 +375,17 @@ dependencies = [
|
||||||
"wasi",
|
"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]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.27.0"
|
version = "0.27.0"
|
||||||
|
@ -432,6 +454,16 @@ dependencies = [
|
||||||
"cfg-if",
|
"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]]
|
[[package]]
|
||||||
name = "is_ci"
|
name = "is_ci"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
|
|
@ -10,6 +10,7 @@ widestring-suffix = { path = "./widestring-suffix/" }
|
||||||
autocxx = "0.23.1"
|
autocxx = "0.23.1"
|
||||||
cxx = "1.0"
|
cxx = "1.0"
|
||||||
errno = "0.2.8"
|
errno = "0.2.8"
|
||||||
|
inventory = { version = "0.3.3", optional = true}
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libc = "0.2.137"
|
libc = "0.2.137"
|
||||||
nix = "0.25.0"
|
nix = "0.25.0"
|
||||||
|
@ -26,6 +27,12 @@ miette = { version = "5", features = ["fancy"] }
|
||||||
[lib]
|
[lib]
|
||||||
crate-type=["staticlib"]
|
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]
|
[patch.crates-io]
|
||||||
cxx = { git = "https://github.com/ridiculousfish/cxx", branch = "fish" }
|
cxx = { git = "https://github.com/ridiculousfish/cxx", branch = "fish" }
|
||||||
cxx-gen = { 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![
|
let source_files = vec![
|
||||||
"src/fd_readable_set.rs",
|
"src/fd_readable_set.rs",
|
||||||
"src/ffi_init.rs",
|
"src/ffi_init.rs",
|
||||||
|
"src/ffi_tests.rs",
|
||||||
"src/smoke.rs",
|
"src/smoke.rs",
|
||||||
"src/topic_monitor.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 fds;
|
||||||
mod ffi;
|
mod ffi;
|
||||||
mod ffi_init;
|
mod ffi_init;
|
||||||
|
mod ffi_tests;
|
||||||
mod flog;
|
mod flog;
|
||||||
mod signal;
|
mod signal;
|
||||||
mod smoke;
|
mod smoke;
|
||||||
|
|
|
@ -19,3 +19,8 @@ mod tests {
|
||||||
assert_eq!(result, 4);
|
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 "fd_readable_set.rs.h"
|
||||||
#include "fds.h"
|
#include "fds.h"
|
||||||
#include "ffi_init.rs.h"
|
#include "ffi_init.rs.h"
|
||||||
|
#include "ffi_tests.rs.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "future_feature_flags.h"
|
#include "future_feature_flags.h"
|
||||||
#include "global_safety.h"
|
#include "global_safety.h"
|
||||||
|
@ -7148,6 +7149,8 @@ void test_rust_smoke() {
|
||||||
do_test(x == 42);
|
do_test(x == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_rust_ffi() { rust::run_ffi_tests(); }
|
||||||
|
|
||||||
// typedef void (test_entry_point_t)();
|
// typedef void (test_entry_point_t)();
|
||||||
using test_entry_point_t = void (*)();
|
using test_entry_point_t = void (*)();
|
||||||
struct test_t {
|
struct test_t {
|
||||||
|
@ -7269,6 +7272,7 @@ static const test_t s_tests[]{
|
||||||
{TEST_GROUP("re"), test_re_substitute},
|
{TEST_GROUP("re"), test_re_substitute},
|
||||||
{TEST_GROUP("wgetopt"), test_wgetopt},
|
{TEST_GROUP("wgetopt"), test_wgetopt},
|
||||||
{TEST_GROUP("rust_smoke"), test_rust_smoke},
|
{TEST_GROUP("rust_smoke"), test_rust_smoke},
|
||||||
|
{TEST_GROUP("rust_ffi"), test_rust_ffi},
|
||||||
};
|
};
|
||||||
|
|
||||||
void list_tests() {
|
void list_tests() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user