Skip to content
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

Register External Contract for Unit Testing #518

Closed
mootz12 opened this issue Aug 29, 2022 · 7 comments
Closed

Register External Contract for Unit Testing #518

mootz12 opened this issue Aug 29, 2022 · 7 comments
Labels
bug Something isn't working

Comments

@mootz12
Copy link
Contributor

mootz12 commented Aug 29, 2022

What version are you using?

Commit b4cc8fc

What did you do?

Import an external contract and register it using the following function:

soroban_sdk::env::Env
pub fn register_contract<T>(&self, contract_id: &BytesN<32>, contract: T)

in an "integration" test format (within the tests folder). The function will not compile with the following error:

the trait `ContractFunctionSet` is not implemented for `ExampleContract`

The test works as expected in the "unit" test format.

Minimum example repository here: https://github.com/mootz12/soroban-external-contract-test

What did you expect to see?

Imported external contracts can be registered against the env without having to rely on test structs (as seen with consumption of the token contract https://github.com/stellar/soroban-token-contract/blob/main/src/testutils.rs)

What did you see instead?

Testing can still be completed using the "unit" test approach or with a test struct.

@mootz12 mootz12 added the bug Something isn't working label Aug 29, 2022
@leighmcculloch
Copy link
Member

This is because the test utilities are only compiled in for test builds where the test cfg is enabled, or when testutils feature is enabled. Unit tests are built with the test cfg enabled. Integration tests in Rust do not. Integration tests build the crate without the test cfg.

I would recommend building integration tests that use the test utilities with a #![cfg(feature = "testutils")] at the top of the integration test and then enabling the testutils feature when running tests.

@jonjove
Copy link
Contributor

jonjove commented Aug 30, 2022

@leighmcculloch when I was trying to reproduce the issue reported by @mootz12 I did exactly what you suggested, and I started getting some other errors about missing conversions (coming from contractimpl)

error[E0277]: the trait bound `ScVec: TryFrom<(&soroban_sdk::BytesN<32_usize>, &str, &u64)>` is not satisfied
  --> src/lib.rs:15:1
   |
15 | #[contractimpl]
   | ^^^^^^^^^^^^^^^ the trait `TryFrom<(&soroban_sdk::BytesN<32_usize>, &str, &u64)>` is not implemented for `ScVec`
   |
   = help: the following other types implement trait `TryFrom<T>`:
             <ScVec as TryFrom<&std::vec::Vec<ScVal>>>
             <ScVec as TryFrom<(T0, T1)>>
             <ScVec as TryFrom<(T0, T1, T2)>>
             <ScVec as TryFrom<(T0, T1, T2, T3)>>
             <ScVec as TryFrom<(T0, T1, T2, T3, T4)>>
             <ScVec as TryFrom<(T0, T1, T2, T3, T4, T5)>>
             <ScVec as TryFrom<(T0, T1, T2, T3, T4, T5, T6)>>
             <ScVec as TryFrom<(T0, T1, T2, T3, T4, T5, T6, T7)>>
           and 6 others
   = note: required because of the requirements on the impl of `TryInto<ScVec>` for `(&soroban_sdk::BytesN<32_usize>, &str, &u64)`
   = note: this error originates in the attribute macro `contractimpl` (in Nightly builds, run with -Z macro-backtrace for more info)

That error is originating from derive_client and derive_fn. This error doesn't occur when setting up the code in "unit test" style, so there is probably some other feature issue going on.

@mootz12
Copy link
Contributor Author

mootz12 commented Aug 30, 2022

@jonjove I also have the same issue, although my note claims it originates in the macro ::soroban_sdk::contractclient

Did a bit more poking around, and noticed that the example contract listed does not build with cargo build --features testutils (due to the error Jon documented). It appears to be caused by having a function argument of u64, since I can resolve the error with the following code update:

    // update trait and tests to match...

    fn do_thing(x: u32) -> u64 {
        u64::from(x + 1)
    }

At this point, unit testing and integration testing both work. (although, testing in Integration mode might warrant some additional documentation around the use of testutils features)

@jonjove
Copy link
Contributor

jonjove commented Aug 30, 2022

@mootz12 that was exactly the piece of information I needed to find what conversion was missing, thank you! See stellar/rs-stellar-xdr#149. Can you try picking that change up and see if it fixes your issue?

@mootz12
Copy link
Contributor Author

mootz12 commented Aug 30, 2022

Yup, confirmed that both of these work as expected after getting your change:

cargo test --features testutils

and

cargo build --features testutils

@jonjove
Copy link
Contributor

jonjove commented Aug 30, 2022

I merged stellar/rs-stellar-xdr#149 and opened stellar-deprecated/soroban-docs#86 to track the documentation improvement. I'm going to close this issue now since I think those cover everything actionable here, but if there are any other aspects of this that I missed then we can reopen.

@jonjove jonjove closed this as completed Aug 30, 2022
@leighmcculloch
Copy link
Member

I added docs about integration tests on two pages in stellar-deprecated/soroban-docs#88 and stellar-deprecated/soroban-docs#91. See those issues for screenshots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants