Skip to main content

odra_test_env_wrapper/
lib.rs

1use std::cell::RefCell;
2
3use dlopen::wrapper::{Container, WrapperApi};
4use dlopen_derive::WrapperApi;
5use odra_types::{bytesrepr::Bytes, event::EventError, Address, EventData, OdraError, RuntimeArgs};
6
7thread_local! {
8    static TEST_ENV: RefCell<Container<TestBackend>> = RefCell::new(unsafe {
9        let filename = format!(
10            r"{}odra_test_env.{}",
11            dlopen::utils::PLATFORM_FILE_PREFIX,
12            dlopen::utils::PLATFORM_FILE_EXTENSION
13        );
14        Container::load(filename).expect("Could not open library or load symbols")
15    });
16}
17
18/// Wrapped Test Env API.
19#[derive(WrapperApi)]
20pub struct TestBackend {
21    /// Returns the backend name.
22    backend_name: fn() -> String,
23    /// Registers the contract in Test Env.
24    register_contract: fn(name: &str, args: &RuntimeArgs) -> Address,
25    /// Calls contract at `address` invoking the `entrypoint` with `args`.
26    call_contract:
27        fn(addr: &Address, entrypoint: &str, args: &RuntimeArgs, has_return: bool) -> Bytes,
28    /// Returns nth user account.
29    get_account: fn(n: usize) -> Address,
30    /// Replaces the current caller.
31    set_caller: fn(address: &Address),
32    /// Gets the current error.
33    get_error: fn() -> Option<OdraError>,
34    /// Gets nth event emitted by contract at `address`.
35    get_event: fn(address: &Address, index: i32) -> Result<EventData, EventError>,
36}
37
38/// An entry point for communication with dynamically loaded Test Env.
39pub fn on_backend<F, R>(f: F) -> R
40where
41    F: FnOnce(&Container<TestBackend>) -> R,
42{
43    TEST_ENV.with(|env| {
44        let backend = &*env.borrow();
45        f(backend)
46    })
47}