-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
16bc66d
commit a1945f1
Showing
3 changed files
with
280 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,234 @@ | ||
use { | ||
mollusk::{result::Check, Mollusk}, | ||
solana_sdk::{instruction::Instruction, program_error::ProgramError, pubkey::Pubkey}, | ||
mollusk::{program::system_program_account, result::Check, Mollusk}, | ||
solana_sdk::{ | ||
account::AccountSharedData, | ||
incinerator, | ||
instruction::{AccountMeta, Instruction}, | ||
program_error::ProgramError, | ||
pubkey::Pubkey, | ||
system_instruction::SystemError, | ||
system_program, | ||
}, | ||
}; | ||
|
||
#[test] | ||
fn test_set_return_data() { | ||
fn test_write_data() { | ||
std::env::set_var("SBF_OUT_DIR", "../target/deploy"); | ||
|
||
let program_id = Pubkey::new_unique(); | ||
|
||
let instruction = Instruction::new_with_bytes(program_id, &[1], vec![]); | ||
let checks = vec![Check::success(), Check::compute_units(143)]; | ||
|
||
let mollusk = Mollusk::new(&program_id, "test_program"); | ||
|
||
mollusk.process_and_validate_instruction(&instruction, vec![], &checks); | ||
let data = &[1, 2, 3, 4, 5]; | ||
let space = data.len(); | ||
let lamports = mollusk.get_rent().minimum_balance(space); | ||
|
||
let key = Pubkey::new_unique(); | ||
let account = AccountSharedData::new(lamports, space, &program_id); | ||
|
||
let instruction = { | ||
let mut instruction_data = vec![1]; | ||
instruction_data.extend_from_slice(data); | ||
Instruction::new_with_bytes( | ||
program_id, | ||
&instruction_data, | ||
vec![AccountMeta::new(key, true)], | ||
) | ||
}; | ||
|
||
// Fail account not signer. | ||
{ | ||
let mut account_not_signer_ix = instruction.clone(); | ||
account_not_signer_ix.accounts[0].is_signer = false; | ||
|
||
mollusk.process_and_validate_instruction( | ||
&account_not_signer_ix, | ||
vec![(key, account.clone())], | ||
&[ | ||
Check::err(ProgramError::MissingRequiredSignature), | ||
Check::compute_units(272), | ||
], | ||
); | ||
} | ||
|
||
// Fail data too large. | ||
{ | ||
let mut data_too_large_ix = instruction.clone(); | ||
data_too_large_ix.data = vec![1; space + 2]; | ||
|
||
mollusk.process_and_validate_instruction( | ||
&data_too_large_ix, | ||
vec![(key, account.clone())], | ||
&[ | ||
Check::err(ProgramError::AccountDataTooSmall), | ||
Check::compute_units(281), | ||
], | ||
); | ||
} | ||
|
||
// Success. | ||
mollusk.process_and_validate_instruction( | ||
&instruction, | ||
vec![(key, account.clone())], | ||
&[ | ||
Check::success(), | ||
Check::compute_units(350), | ||
Check::account(&key) | ||
.data(data) | ||
.lamports(lamports) | ||
.owner(program_id) | ||
.build(), | ||
], | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_fail_empty_input() { | ||
fn test_transfer() { | ||
std::env::set_var("SBF_OUT_DIR", "../target/deploy"); | ||
|
||
let program_id = Pubkey::new_unique(); | ||
|
||
let instruction = Instruction::new_with_bytes(program_id, &[], vec![]); | ||
let checks = vec![ | ||
Check::err(ProgramError::InvalidInstructionData), | ||
Check::compute_units(55), | ||
]; | ||
let mollusk = Mollusk::new(&program_id, "test_program"); | ||
|
||
let payer = Pubkey::new_unique(); | ||
let payer_lamports = 100_000_000; | ||
let payer_account = AccountSharedData::new(payer_lamports, 0, &system_program::id()); | ||
|
||
let recipient = Pubkey::new_unique(); | ||
let recipient_lamports = 0; | ||
let recipient_account = AccountSharedData::new(recipient_lamports, 0, &system_program::id()); | ||
|
||
let transfer_amount = 2_000_000_u64; | ||
|
||
let instruction = { | ||
let mut instruction_data = vec![2]; | ||
instruction_data.extend_from_slice(&transfer_amount.to_le_bytes()); | ||
Instruction::new_with_bytes( | ||
program_id, | ||
&instruction_data, | ||
vec![ | ||
AccountMeta::new(payer, true), | ||
AccountMeta::new(recipient, false), | ||
AccountMeta::new_readonly(system_program::id(), false), | ||
], | ||
) | ||
}; | ||
|
||
// Fail payer not signer. | ||
{ | ||
let mut payer_not_signer_ix = instruction.clone(); | ||
payer_not_signer_ix.accounts[0].is_signer = false; | ||
|
||
mollusk.process_and_validate_instruction( | ||
&payer_not_signer_ix, | ||
vec![ | ||
(payer, payer_account.clone()), | ||
(recipient, recipient_account.clone()), | ||
(system_program::id(), system_program_account()), | ||
], | ||
&[ | ||
Check::err(ProgramError::MissingRequiredSignature), | ||
Check::compute_units(598), | ||
], | ||
); | ||
} | ||
|
||
// Fail insufficient lamports. | ||
{ | ||
mollusk.process_and_validate_instruction( | ||
&instruction, | ||
vec![ | ||
(payer, AccountSharedData::default()), | ||
(recipient, recipient_account.clone()), | ||
(system_program::id(), system_program_account()), | ||
], | ||
&[ | ||
Check::err(ProgramError::Custom( | ||
SystemError::ResultWithNegativeLamports as u32, | ||
)), | ||
Check::compute_units(2256), | ||
], | ||
); | ||
} | ||
|
||
// Success. | ||
mollusk.process_and_validate_instruction( | ||
&instruction, | ||
vec![ | ||
(payer, payer_account.clone()), | ||
(recipient, recipient_account.clone()), | ||
(system_program::id(), system_program_account()), | ||
], | ||
&[ | ||
Check::success(), | ||
Check::compute_units(2366), | ||
Check::account(&payer) | ||
.lamports(payer_lamports - transfer_amount) | ||
.build(), | ||
Check::account(&recipient) | ||
.lamports(recipient_lamports + transfer_amount) | ||
.build(), | ||
], | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_close_account() { | ||
std::env::set_var("SBF_OUT_DIR", "../target/deploy"); | ||
|
||
let program_id = Pubkey::new_unique(); | ||
|
||
let mollusk = Mollusk::new(&program_id, "test_program"); | ||
|
||
mollusk.process_and_validate_instruction(&instruction, vec![], &checks); | ||
let key = Pubkey::new_unique(); | ||
let account = AccountSharedData::new(50_000_000, 50, &program_id); | ||
|
||
let instruction = Instruction::new_with_bytes( | ||
program_id, | ||
&[3], | ||
vec![ | ||
AccountMeta::new(key, true), | ||
AccountMeta::new(incinerator::id(), false), | ||
AccountMeta::new_readonly(system_program::id(), false), | ||
], | ||
); | ||
|
||
// Fail account not signer. | ||
{ | ||
let mut account_not_signer_ix = instruction.clone(); | ||
account_not_signer_ix.accounts[0].is_signer = false; | ||
|
||
mollusk.process_and_validate_instruction( | ||
&account_not_signer_ix, | ||
vec![ | ||
(key, account.clone()), | ||
(incinerator::id(), AccountSharedData::default()), | ||
(system_program::id(), system_program_account()), | ||
], | ||
&[ | ||
Check::err(ProgramError::MissingRequiredSignature), | ||
Check::compute_units(597), | ||
], | ||
); | ||
} | ||
|
||
// Success. | ||
mollusk.process_and_validate_instruction( | ||
&instruction, | ||
vec![ | ||
(key, account.clone()), | ||
(incinerator::id(), AccountSharedData::default()), | ||
(system_program::id(), system_program_account()), | ||
], | ||
&[ | ||
Check::success(), | ||
Check::compute_units(2557), | ||
Check::account(&key) | ||
.data(&[]) | ||
.lamports(0) | ||
.owner(system_program::id()) | ||
.closed() | ||
.build(), | ||
], | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters