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

Off-Chain Test (endowment) Does Not Work #1117

Open
sulnong opened this issue Jan 27, 2022 · 5 comments
Open

Off-Chain Test (endowment) Does Not Work #1117

sulnong opened this issue Jan 27, 2022 · 5 comments
Labels
C-question Further information is requested

Comments

@sulnong
Copy link

sulnong commented Jan 27, 2022

Environment:
cargo-contract : 0.17.0-unknown-x86_64-macos
ink version: 3.0.0-rc8

Describe the bug
Following is my contract code:

/// Deposit
#[ink(message, payable)]
pub fn deposit(&mut self) {
    let caller = self.env().caller();
    let deposited = self.env().transferred_value();
    let mut balance = self.balance_of(&caller);
    balance += deposited;
    self.balances.insert(caller, balance);
}

In off-chain test (run with command cargo +nightly test), i got self.env().transferred_value() correctly, but account (who call this execution) balance have no change.
That makes test failed.

Following is test code:

#[ink::test]
fn deposit_works() {
    // Use Alice as contract owner
    let accounts = default_accounts();
    let alice = accounts.alice;
    let bob = accounts.bob;
    let eve = accounts.eve;
    set_sender(alice, None);
    let mut contract = Bytepay::new();

    // Bob Deposit
    set_balance(bob, 200);
    set_sender(bob, Some(100));
    contract.deposit();
    assert_eq!(contract.get(), 100);

    // Eve havn't deposit
    set_balance(eve, 200);
    set_sender(eve, None);
    assert_eq!(contract.get(), 0);
    assert_eq!(get_balance(eve), 200);
}

fn set_sender(sender: AccountId, endowment: Option<Balance>) {
    let callee = ink_env::account_id::<ink_env::DefaultEnvironment>();
    test::push_execution_context::<Environment>(
        sender,
        callee,
        1000000,
        endowment.unwrap_or(0),
        test::CallData::new(call::Selector::new([0x00; 4])), // dummy
    );
}

fn default_accounts() -> ink_env::test::DefaultAccounts<ink_env::DefaultEnvironment> {
    ink_env::test::default_accounts::<ink_env::DefaultEnvironment>()
        .expect("Off-chain environment should have been initialized already")
}

fn set_balance(account_id: AccountId, balance: Balance) {
    ink_env::test::set_account_balance::<ink_env::DefaultEnvironment>(account_id, balance)
        .expect("Cannot set account balance");
}

fn get_balance(account_id: AccountId) -> Balance {
    ink_env::test::get_account_balance::<ink_env::DefaultEnvironment>(account_id)
        .expect("Cannot set account balance")
}
}

I wander if i coding incorrect or this is off-chain test problem.

@HCastano
Copy link
Contributor

@sulnong can you post the full error that you're getting?

@HCastano HCastano added the C-question Further information is requested label Jan 28, 2022
@sulnong
Copy link
Author

sulnong commented Jan 28, 2022

/// Deposit
#[ink(message, payable)]
pub fn deposit(&mut self) {
    let caller = self.env().caller();
    let deposited = self.env().transferred_value();
    println!("deposited: {}", deposited);
    let mut balance = self.balance_of(&caller);
    balance += deposited;
    self.balances.insert(caller, balance);
}

#[ink::test]
fn deposit_works() {
    // Use Alice as contract owner
    let accounts = default_accounts();
    let alice = accounts.alice;
    let bob = accounts.bob;
    let eve = accounts.eve;
    set_sender(alice, None);
    let mut contract = Bytepay::new();

    // Bob Deposit
    set_balance(bob, 200);
    set_sender(bob, Some(100));
    contract.deposit();
    assert_eq!(contract.get(), 100);
    assert_eq!(get_balance(bob), 100);

    // Eve havn't deposit
    set_balance(eve, 200);
    set_sender(eve, None);
    assert_eq!(contract.get(), 0);
    assert_eq!(get_balance(eve), 200);
}
running 5 tests
test bytepay::tests::set_whitelist_works ... ok
test bytepay::tests::contract_init_works ... ok
test bytepay::tests::transfer_works ... ok
test bytepay::tests::withdraw_works ... FAILED
test bytepay::tests::deposit_works ... FAILED

failures:

---- bytepay::tests::withdraw_works stdout ----
deposited: 100
thread 'bytepay::tests::withdraw_works' panicked at 'assertion failed: self.env().transfer(caller, amount).is_ok()', lib.rs:70:13

---- bytepay::tests::deposit_works stdout ----
deposited: 100
thread 'bytepay::tests::deposit_works' panicked at 'assertion failed: `(left == right)`
  left: `200`,
 right: `100`', lib.rs:162:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    bytepay::tests::deposit_works
    bytepay::tests::withdraw_works

test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

After call contract.deposit(), bob'account balance shoule be 100, we can see in the console deposited: 100
But assert_eq!(get_balance(bob), 100) failed.

@HCastano
Copy link
Contributor

HCastano commented Feb 1, 2022

Tbh this looks fine to me. Even looking at the contract-transfer example it doesn't seem like the contract_id and eve's balances get updated correctly, so maybe there are some quirks around transfers in the test environment.

@cmichi can you take a look since you know about this better than me?

@Levike34
Copy link

Levike34 commented Apr 6, 2022

Further to this, testing does not seem to work at all using ink_env::test module. I followed these steps to run tests related with balances and set_caller:

add ink-experimental-engine = ["ink_env/ink-experimental-engine"] to Cargo.toml

add #[cfg(feature = "ink-experimental-engine")] above mod tests {}

despite this, ink_env::tests::default_accounts() is not found, nor is ink_env::tests::set_caller() working. It is only possible to test pure rust parts of the smart contracts that don't involve transfers or various accounts other than the constructor caller.

@Levike34
Copy link

Levike34 commented Apr 6, 2022

error[E0425]: cannot find function set_caller in module ink_env::test
--> pixelland_map/lib.rs:194:28
|
194 | ink_env::test::set_caller::<ink_env::DefaultEnvironment>(accounts.bob);
| ^^^^^^^^^^ not found in ink_env::test

error[E0609]: no field bob on type std::result::Result<DefaultAccounts<DefaultEnvironment>, ink_env::Error>
--> pixelland_map/lib.rs:194:79
|
194 | ink_env::test::set_caller::<ink_env::DefaultEnvironment>(accounts.bob);
| ^^^

error[E0609]: no field bob on type std::result::Result<DefaultAccounts<DefaultEnvironment>, ink_env::Error>
--> pixelland_map/lib.rs:202:42
|
202 | assert_eq!(result3, accounts.bob);
| ^^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants