Relocate program tests (#7259)

This commit is contained in:
Jack May 2019-12-04 12:41:54 -08:00 committed by GitHub
parent 1a135fa30e
commit 703a5348e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 194 additions and 186 deletions

16
Cargo.lock generated
View File

@ -3279,21 +3279,6 @@ dependencies = [
"solana-sdk 0.22.0",
]
[[package]]
name = "solana-config-tests"
version = "0.22.0"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-config-program 0.22.0",
"solana-logger 0.22.0",
"solana-runtime 0.22.0",
"solana-sdk 0.22.0",
]
[[package]]
name = "solana-core"
version = "0.22.0"
@ -3948,6 +3933,7 @@ dependencies = [
name = "solana-storage-program"
version = "0.22.0"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -29,7 +29,6 @@ members = [
"programs/btc_spv",
"programs/btc_spv_bin",
"programs/config",
"programs/config_tests",
"programs/exchange",
"programs/failure",
"programs/noop",

View File

@ -19,6 +19,9 @@ serde_derive = "1.0.103"
solana-logger = { path = "../../logger", version = "0.22.0" }
solana-sdk = { path = "../../sdk", version = "0.22.0" }
[dev-dependencies]
assert_matches = "1.3.0"
[lib]
crate-type = ["lib", "cdylib"]
name = "solana_storage_program"

View File

@ -94,3 +94,192 @@ pub fn process_instruction(
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
id,
storage_contract::STORAGE_ACCOUNT_SPACE,
storage_instruction::{self, StorageAccountType},
};
use log::*;
use assert_matches::assert_matches;
use solana_sdk::{
account::{create_keyed_accounts, Account, KeyedAccount},
clock::DEFAULT_SLOTS_PER_SEGMENT,
hash::Hash,
instruction::{Instruction, InstructionError},
signature::Signature,
sysvar::{
clock::{self, Clock},
Sysvar,
},
};
fn test_instruction(
ix: &Instruction,
program_accounts: &mut [Account],
) -> Result<(), InstructionError> {
let mut keyed_accounts: Vec<_> = ix
.accounts
.iter()
.zip(program_accounts.iter_mut())
.map(|(account_meta, account)| {
KeyedAccount::new(&account_meta.pubkey, account_meta.is_signer, account)
})
.collect();
let ret = process_instruction(&id(), &mut keyed_accounts, &ix.data);
info!("ret: {:?}", ret);
ret
}
#[test]
fn test_proof_bounds() {
let account_owner = Pubkey::new_rand();
let pubkey = Pubkey::new_rand();
let mut account = Account {
data: vec![0; STORAGE_ACCOUNT_SPACE as usize],
..Account::default()
};
{
let mut storage_account = StorageAccount::new(pubkey, &mut account);
storage_account
.initialize_storage(account_owner, StorageAccountType::Archiver)
.unwrap();
}
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// the proof is for segment 0, need to move the slot into segment 2
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT * 2,
segment: 2,
..Clock::default()
},
&mut clock_account,
);
assert_eq!(test_instruction(&ix, &mut [account, clock_account]), Ok(()));
}
#[test]
fn test_storage_tx() {
let pubkey = Pubkey::new_rand();
let mut accounts = [(pubkey, Account::default())];
let mut keyed_accounts = create_keyed_accounts(&mut accounts);
assert!(process_instruction(&id(), &mut keyed_accounts, &[]).is_err());
}
#[test]
fn test_serialize_overflow() {
let pubkey = Pubkey::new_rand();
let clock_id = clock::id();
let mut keyed_accounts = Vec::new();
let mut user_account = Account::default();
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account));
keyed_accounts.push(KeyedAccount::new(&clock_id, false, &mut clock_account));
let ix = storage_instruction::advertise_recent_blockhash(&pubkey, Hash::default(), 1);
assert_eq!(
process_instruction(&id(), &mut keyed_accounts, &ix.data),
Err(InstructionError::InvalidAccountData)
);
}
#[test]
fn test_invalid_accounts_len() {
let pubkey = Pubkey::new_rand();
let mut accounts = [Account::default()];
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// move tick height into segment 1
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: 16,
segment: 1,
..Clock::default()
},
&mut clock_account,
);
assert!(test_instruction(&ix, &mut accounts).is_err());
let mut accounts = [Account::default(), clock_account, Account::default()];
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
fn test_submit_mining_invalid_slot() {
solana_logger::setup();
let pubkey = Pubkey::new_rand();
let mut accounts = [Account::default(), Account::default()];
accounts[0].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
accounts[1].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// submitting a proof for a slot in the past, so this should fail
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
fn test_submit_mining_ok() {
solana_logger::setup();
let account_owner = Pubkey::new_rand();
let pubkey = Pubkey::new_rand();
let mut account = Account::default();
account.data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
{
let mut storage_account = StorageAccount::new(pubkey, &mut account);
storage_account
.initialize_storage(account_owner, StorageAccountType::Archiver)
.unwrap();
}
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// move slot into segment 1
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT,
segment: 1,
..Clock::default()
},
&mut clock_account,
);
assert_matches!(test_instruction(&ix, &mut [account, clock_account]), Ok(_));
}
}

View File

@ -7,26 +7,22 @@ use solana_runtime::{
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use solana_sdk::{
account::{create_keyed_accounts, Account, KeyedAccount},
account_utils::State,
client::SyncClient,
clock::{get_segment_from_slot, DEFAULT_SLOTS_PER_SEGMENT, DEFAULT_TICKS_PER_SLOT},
hash::{hash, Hash},
instruction::{Instruction, InstructionError},
message::Message,
pubkey::Pubkey,
signature::{Keypair, KeypairUtil, Signature},
system_instruction,
sysvar::{
clock::{self, Clock},
rewards::{self, Rewards},
Sysvar,
},
};
use solana_storage_program::{
id,
storage_contract::StorageAccount,
storage_contract::{ProofStatus, StorageContract, STORAGE_ACCOUNT_SPACE},
storage_contract::{ProofStatus, StorageContract},
storage_instruction::{self, StorageAccountType},
storage_processor::process_instruction,
};
@ -35,24 +31,6 @@ use std::sync::Arc;
const TICKS_IN_SEGMENT: u64 = DEFAULT_SLOTS_PER_SEGMENT * DEFAULT_TICKS_PER_SLOT;
fn test_instruction(
ix: &Instruction,
program_accounts: &mut [Account],
) -> Result<(), InstructionError> {
let mut keyed_accounts: Vec<_> = ix
.accounts
.iter()
.zip(program_accounts.iter_mut())
.map(|(account_meta, account)| {
KeyedAccount::new(&account_meta.pubkey, account_meta.is_signer, account)
})
.collect();
let ret = process_instruction(&id(), &mut keyed_accounts, &ix.data);
info!("ret: {:?}", ret);
ret
}
#[test]
fn test_account_owner() {
let account_owner = Pubkey::new_rand();
@ -113,153 +91,6 @@ fn test_account_owner() {
}
}
#[test]
fn test_proof_bounds() {
let account_owner = Pubkey::new_rand();
let pubkey = Pubkey::new_rand();
let mut account = Account {
data: vec![0; STORAGE_ACCOUNT_SPACE as usize],
..Account::default()
};
{
let mut storage_account = StorageAccount::new(pubkey, &mut account);
storage_account
.initialize_storage(account_owner, StorageAccountType::Archiver)
.unwrap();
}
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// the proof is for segment 0, need to move the slot into segment 2
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT * 2,
segment: 2,
..Clock::default()
},
&mut clock_account,
);
assert_eq!(test_instruction(&ix, &mut [account, clock_account]), Ok(()));
}
#[test]
fn test_storage_tx() {
let pubkey = Pubkey::new_rand();
let mut accounts = [(pubkey, Account::default())];
let mut keyed_accounts = create_keyed_accounts(&mut accounts);
assert!(process_instruction(&id(), &mut keyed_accounts, &[]).is_err());
}
#[test]
fn test_serialize_overflow() {
let pubkey = Pubkey::new_rand();
let clock_id = clock::id();
let mut keyed_accounts = Vec::new();
let mut user_account = Account::default();
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account));
keyed_accounts.push(KeyedAccount::new(&clock_id, false, &mut clock_account));
let ix = storage_instruction::advertise_recent_blockhash(&pubkey, Hash::default(), 1);
assert_eq!(
process_instruction(&id(), &mut keyed_accounts, &ix.data),
Err(InstructionError::InvalidAccountData)
);
}
#[test]
fn test_invalid_accounts_len() {
let pubkey = Pubkey::new_rand();
let mut accounts = [Account::default()];
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// move tick height into segment 1
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: 16,
segment: 1,
..Clock::default()
},
&mut clock_account,
);
assert!(test_instruction(&ix, &mut accounts).is_err());
let mut accounts = [Account::default(), clock_account, Account::default()];
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
fn test_submit_mining_invalid_slot() {
solana_logger::setup();
let pubkey = Pubkey::new_rand();
let mut accounts = [Account::default(), Account::default()];
accounts[0].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
accounts[1].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// submitting a proof for a slot in the past, so this should fail
assert!(test_instruction(&ix, &mut accounts).is_err());
}
#[test]
fn test_submit_mining_ok() {
solana_logger::setup();
let account_owner = Pubkey::new_rand();
let pubkey = Pubkey::new_rand();
let mut account = Account::default();
account.data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
{
let mut storage_account = StorageAccount::new(pubkey, &mut account);
storage_account
.initialize_storage(account_owner, StorageAccountType::Archiver)
.unwrap();
}
let ix = storage_instruction::mining_proof(
&pubkey,
Hash::default(),
0,
Signature::default(),
Hash::default(),
);
// move slot into segment 1
let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account(
&Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT,
segment: 1,
..Clock::default()
},
&mut clock_account,
);
assert_matches!(test_instruction(&ix, &mut [account, clock_account]), Ok(_));
}
#[test]
fn test_validate_mining() {
solana_logger::setup();