-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
External functions seem to be "overwritten" by mocks when exported #602
Comments
Can you reproduce the problem with a single crate, or are 2 crates always required? A linker issue would be very "interesting"... |
Woops, good catch. It turns out that multiple crates are not required. This snippet exhibits the same behavior: pub mod outer {
#[mockall::automock]
pub mod inner {
extern "C" {
pub fn foo(val: i32) -> i32;
}
}
}
#[test]
fn test() {
unsafe {
outer::inner::foo(5i32);
}
} |
Improve it to ensure that the original, non-mock function can still be called even when the mock version is present in the build. Issue #602
I've improved the regression test for this feature, and it fails in the way that you describe. Could you please show me the error that your CI linker shows you? And what linker is it? |
The linker in our CI is
So it appears it's the symbol of the original C function that's clashing with the symbol of the mocked function (presumably because its symbol isn't being mangled?) Edit: |
The bug was introduced by #504 . Fixing it without breaking the intention of that PR will be tricky. There are 3 distinct use cases that we need to satisfy:
One solution would be to remove the |
I'm still new to Rust. That's why I can't add comments. I will follow changes. |
@Enes1313 could you please provide some more information about how your project is structured? Do you build a cdylib crate containing the mock function, and call that from a C program? If so, then how do you set the expectations? Or do you build a Rust program that links to a C library, and you pass the mock function to the C library as a function pointer? |
My main goal is a system to prepare unit and integration tests in Rust language for C projects. For example: There are a.h, a.c ("a" module), b.h, b.c ("b" module) files. a.c . The a.c file uses b.h.. I haven't looked at what I'm talking about for a long time. I may be remembering incorrectly, but I think it was like I said. I was planning to develop a tool that would make this work easier. Maybe I don't have to write a tool. It could be a document. |
@Enes1313 could you please share an example of the command that you use to link the C objects and Rust objects together? |
It will take some time because my files are elsewhere. I will share a repo with you soon. @asomers |
Hi again, I created two repos about my project. The project is at the very beginning. test-with-rust: https://github.com/Enes1313/test-with-rust 1- Place the two projects under one directory. (If you don't want this, change "project_path" in Cargo.toml) |
I am working on a project with multiple packages, where one package exposes a module containing an
extern "C"
block with a number of foreign functions. And it seems that once I put an#[mockall::automock]
attribute on this module, I can no longer access the original function.To illustrate the problem, imagine a project with 2 crates:
test
andtest_sys
. The latter exposes a single foreign function, andtest
imports that (mocked) module and tries to call the foreign function.test_sys/src/lib.rs
:test/src/lib.rs
Now when I run that test, I get the following error message:
Suggesting that we called the mocked function rather than the original, which is not what we intended to do!
Looking at the macro expanded source of
test_sys
, it does seem like automock created a newmock_inner
module and left the originalinner
module in place. So I'm not sure why we end up calling the mocked variant when we're not using#[double]
or anything. The only thing I can think of is that maybe the use of#[no_mangle]
on the definition of the mock function is throwing the linker for a loop or something?Or maybe it's something else entirely, of course. In any case, I'd be very grateful for your guidance!
Edit: it indeed appears to be a linker issue. On our CI, which uses a different linker, this is now throwing multiple symbol definition errors for these external functions.
The text was updated successfully, but these errors were encountered: