microsoft / microsoft/injectorppforrust

Ability to capture different input paramters per function

Open
#108 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Rust
Stars
404
Forks
19
Avg merge
23h 57m
Merged PRs (30d)
1

Description

Hi,

I'm trying to write the unit test below by using injectorpp:

#[test]
    fn mount_happy() {
        const ROOTFS_PATH_STR: &str = "/tmp/mock-root-fs";

        let rootfs_path = Path::new(ROOTFS_PATH_STR);
        // let mount_list = oci_spec::runtime::get_default_mounts();
  
    let mut m_proc = Mount::default();
    m_proc.set_destination(PathBuf::from("/proc"));
    m_proc.set_typ(Some("proc".to_string()));
    m_proc.set_source(Some(PathBuf::from("proc")));
    m_proc.set_options(None);

    let mut m_dev = Mount::default();
    m_dev.set_destination(PathBuf::from("/dev"));
    m_dev.set_typ(Some("tmpfs".to_string()));
    m_dev.set_source(Some(PathBuf::from("tmpfs")));
    m_dev.set_options(Some(vec![
        "nosuid".into(),
        "strictatime".into(),
        "mode=755".into(),
        "size=65536k".into(),
    ]));

    let mount_list = vec![
        m_proc
    ];
        let mut injector = InjectorPP::new();

        injector
            .when_called(injectorpp::func!(
                nix::mount::mount,
                fn(
                    Option<&std::ffi::OsStr>,
                    &std::ffi::OsStr,
                    Option<&str>,
                    MsFlags,
                    Option<&str>,
                ) -> nix::Result<()>
            ))
            .will_execute(injectorpp::fake!(
                func_type: fn(source: Option<&std::ffi::OsStr>, target: &std::ffi::OsStr, fstype: Option<&str>, flags: MsFlags, data: Option<&str>) -> nix::Result<()>,
                when: source.unwrap().to_str().unwrap() == "proc" && 
                    target.to_str() == PathBuf::new().join(ROOTFS_PATH_STR).join("proc").to_str() && 
                    fstype.unwrap() == "proc" && 
                    flags == MsFlags::MS_NOEXEC | MsFlags::MS_NOSUID | MsFlags::MS_NODEV && 
                    data.is_none(),
                returns: Ok(()),
                times: 1
            ));

            injector
            .when_called(injectorpp::func!(
                nix::mount::mount,
                fn(
                    Option<&std::ffi::OsStr>,
                    &std::ffi::OsStr,
                    Option<&str>,
                    MsFlags,
                    Option<&str>,
                ) -> nix::Result<()>
            ))
            .will_execute(injectorpp::fake!(
                func_type: fn(source: Option<&std::ffi::OsStr>, target: &std::ffi::OsStr, fstype: Option<&str>, flags: MsFlags, data: Option<&str>) -> nix::Result<()>,
                when: source.unwrap().to_str().unwrap() == "tmpfs" && 
                    target.to_str() == PathBuf::new().join(ROOTFS_PATH_STR).join("dev").to_str() && 
                    fstype.unwrap() == "tmpfs" && 
                    flags == MsFlags::MS_NOSUID | MsFlags::MS_STRICTATIME && 
                    data.unwrap().contains("mode=755") && data.unwrap().contains("size=65536k"),
                returns: Ok(())
            ));

        let result = mount(rootfs_path, &mount_list);
        assert!(result.is_ok(), "mount() must succeed!, err: {:?}", result);
    }

See that I'm trying to capture whether the function nix::mount::mount is called with different input parameters or not.

The stack trace I'm getting is below:

thread 'linux_util::namespace::mount::tests::mount_happy' panicked at src/linux_util/namespace/mount.rs:228:27:
Fake function called with unexpected arguments
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panicking.rs:697:5
   1: core::panicking::panic_fmt
             at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/core/src/panicking.rs:75:14
   2: nucleus::linux_util::namespace::mount::tests::mount_happy::fake
             at /home/fatih/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/injectorpp-0.4.0/src/interface/macros.rs:326:18
   3: nucleus::linux_util::namespace::mount::mount
             at ./src/linux_util/namespace/mount.rs:76:9
   4: nucleus::linux_util::namespace::mount::tests::mount_happy
             at ./src/linux_util/namespace/mount.rs:238:22
   5: nucleus::linux_util::namespace::mount::tests::mount_happy::{{closure}}
             at ./src/linux_util/namespace/mount.rs:167:21
   6: core::ops::function::FnOnce::call_once
             at /home/fatih/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:253:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/core/src/ops/function.rs:253:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test linux_util::namespace::mount::tests::mount_happy ... FAILED

See that Fake function called with unexpected arguments.

It's all ok when I comment out the will_execute call for the same function but to match different parameters within the when clause.

I was checking the will_execute unit tests you have as well, but I didn't see that you try to capture the function calls for the same signature but with different parameters.

Wondering if I'm missing something or such a feature is not supported by the library?

Thanks a lot for the package! It's super dope!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing injectorpp's will_execute and fake behavior, especially the will_execute unit tests and the matching logic behind the unexpected-arguments panic. Reproduce the mount example with multiple handlers for the same nix::mount::mount signature. Done means argument-specific calls are either dispatched reliably to distinct handlers or the supported behavior and limitation are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
testing-qa, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.