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

chore: Add tests #80

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
424 changes: 377 additions & 47 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ clap = { version = "4.5" }
dirs-next = "2.0.0"
futures = "0.3"
indicatif = "0.17"
litesvm = "0.2"
litesvm-token = "0.2"
log = "0.4"
nom = "~7"
proc-macro2 = "1.0"
Expand Down
9 changes: 9 additions & 0 deletions programs/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ anchor-lang.workspace = true
anchor-spl = { features = ["mint", "token"], workspace = true }
sablier-utils.workspace = true
bytemuck = { workspace = true, features = ["derive", "min_const_generics"] }

[dev-dependencies]
litesvm.workspace = true
litesvm-token.workspace = true
solana-sdk.workspace = true
spl-token = { workspace = true, features = ["no-entrypoint"] }
spl-associated-token-account = { workspace = true, features = [
"no-entrypoint",
] }
35 changes: 35 additions & 0 deletions programs/network/tests/integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use litesvm::LiteSVM;
use litesvm_token::CreateMint;
use solana_sdk::{native_token::LAMPORTS_PER_SOL, signature::Keypair, signer::Signer};

mod test_instructions;
mod utils;

fn setup() -> (LiteSVM, Keypair) {
let mut svm = LiteSVM::new();

let path = format!(
"{}/../deploy/sablier_network_program.so",
env!("CARGO_TARGET_TMPDIR")
);
svm.add_program_from_file(sablier_network_program::ID, path)
.unwrap();

let admin_kp = Keypair::new();

svm.airdrop(&admin_kp.pubkey(), 10 * LAMPORTS_PER_SOL)
.unwrap();

(svm, admin_kp)
}

#[test]
pub fn integration_test() {
let (mut svm, admin_kp) = setup();

let mint = CreateMint::new(&mut svm, &admin_kp).send().unwrap();

test_instructions::initialize(&mut svm, &admin_kp, &mint).unwrap();
test_instructions::pool_create(&mut svm, &admin_kp).unwrap();
test_instructions::worker_create(&mut svm, &admin_kp, &mint).unwrap();
}
60 changes: 60 additions & 0 deletions programs/network/tests/test_instructions/initialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use litesvm::{types::FailedTransactionMetadata, LiteSVM};
use sablier_network_program::{
constants::SEED_REGISTRY,
state::{Config, Registry, Snapshot},
};
use solana_sdk::{
pubkey::Pubkey, signature::Keypair, signer::Signer, system_program, transaction::Transaction,
};

use crate::utils::{build_ix, get_anchor_account};

pub fn initialize(
svm: &mut LiteSVM,
admin_kp: &Keypair,
mint: &Pubkey,
) -> Result<(), FailedTransactionMetadata> {
let admin = admin_kp.pubkey();

let (registry, registry_bump) =
Pubkey::find_program_address(&[SEED_REGISTRY], &sablier_network_program::ID);
let ix = build_ix(
sablier_network_program::accounts::Initialize {
admin,
config: Config::pubkey(),
mint: *mint,
registry,
snapshot: Snapshot::pubkey(0),
system_program: system_program::ID,
},
sablier_network_program::instruction::Initialize {},
);

let blockhash = svm.latest_blockhash();
let tx = Transaction::new_signed_with_payer(&[ix], Some(&admin), &[&admin_kp], blockhash);
svm.send_transaction(tx)?;

// CHECKS

let config: Config = get_anchor_account(svm, &Config::pubkey());
assert_eq!(config.admin, admin);
assert_eq!(config.mint, *mint);
assert_eq!(config.hasher_thread, Pubkey::default());
assert_eq!(config.hasher_thread, Pubkey::default());

let registry: Registry = get_anchor_account(svm, &Registry::pubkey());
assert_eq!(registry.current_epoch, 0);
assert_eq!(registry.locked, false);
assert_eq!(registry.nonce, 0);
assert_eq!(registry.total_pools, 0);
assert_eq!(registry.total_unstakes, 0);
assert_eq!(registry.total_workers, 0);
assert_eq!(registry.bump, registry_bump);

let snapshot: Snapshot = get_anchor_account(svm, &Snapshot::pubkey(0));
assert_eq!(snapshot.id, 0);
assert_eq!(snapshot.total_frames, 0);
assert_eq!(snapshot.total_stake, 0);

Ok(())
}
7 changes: 7 additions & 0 deletions programs/network/tests/test_instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod initialize;
mod pool_create;
mod worker_create;

pub use initialize::*;
pub use pool_create::*;
pub use worker_create::*;
45 changes: 45 additions & 0 deletions programs/network/tests/test_instructions/pool_create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::collections::VecDeque;

use anchor_lang::system_program;
use litesvm::{types::FailedTransactionMetadata, LiteSVM};
use sablier_network_program::state::{Config, Pool, Registry};
use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction};

use crate::utils::{build_ix, get_anchor_account};

pub fn pool_create(svm: &mut LiteSVM, admin_kp: &Keypair) -> Result<(), FailedTransactionMetadata> {
let admin = admin_kp.pubkey();

let ix = build_ix(
sablier_network_program::accounts::PoolCreate {
config: Config::pubkey(),
system_program: system_program::ID,
payer: admin,
pool: Pool::pubkey(0),
admin,
registry: Registry::pubkey(),
},
sablier_network_program::instruction::PoolCreate {},
);

let blockhash = svm.latest_blockhash();
let tx = Transaction::new_signed_with_payer(&[ix], Some(&admin), &[&admin_kp], blockhash);
svm.send_transaction(tx)?;

// CHECKS

let registry: Registry = get_anchor_account(svm, &Registry::pubkey());
assert_eq!(registry.current_epoch, 0);
assert_eq!(registry.locked, false);
assert_eq!(registry.nonce, 0);
assert_eq!(registry.total_pools, 1);
assert_eq!(registry.total_unstakes, 0);
assert_eq!(registry.total_workers, 0);

let pool: Pool = get_anchor_account(svm, &Pool::pubkey(0));
assert_eq!(pool.id, 0);
assert_eq!(pool.size, 1);
assert_eq!(pool.workers, VecDeque::new());

Ok(())
}
66 changes: 66 additions & 0 deletions programs/network/tests/test_instructions/worker_create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use litesvm::{types::FailedTransactionMetadata, LiteSVM};
use sablier_network_program::state::{Config, Registry, Worker};
use solana_sdk::{
native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, signature::Keypair, signer::Signer,
system_program, transaction::Transaction,
};
use spl_associated_token_account::get_associated_token_address;

use crate::utils::{build_ix, get_anchor_account};

pub fn worker_create(
svm: &mut LiteSVM,
admin_kp: &Keypair,
mint: &Pubkey,
) -> Result<(), FailedTransactionMetadata> {
let admin = admin_kp.pubkey();
let worker_authority = Keypair::new();

svm.airdrop(&worker_authority.pubkey(), 2 * LAMPORTS_PER_SOL)?;

let worker = Worker::pubkey(0);
let worker_tokens = get_associated_token_address(&worker, mint);

let ix = build_ix(
sablier_network_program::accounts::WorkerCreate {
authority: admin,
config: Config::pubkey(),
mint: *mint,
registry: Registry::pubkey(),
signatory: worker_authority.pubkey(),
worker,
worker_tokens,
system_program: system_program::ID,
associated_token_program: spl_associated_token_account::ID,
token_program: spl_token::ID,
},
sablier_network_program::instruction::WorkerCreate {},
);

let blockhash = svm.latest_blockhash();
let tx = Transaction::new_signed_with_payer(
&[ix],
Some(&admin),
&[&admin_kp, &worker_authority],
blockhash,
);
svm.send_transaction(tx)?;

let worker: Worker = get_anchor_account(svm, &Worker::pubkey(0));
assert_eq!(worker.id, 0);
assert_eq!(worker.total_delegations, 0);
assert_eq!(worker.authority, admin);
assert_eq!(worker.commission_balance, 0);
assert_eq!(worker.commission_rate, 0);
assert_eq!(worker.signatory, worker_authority.pubkey());

let registry: Registry = get_anchor_account(svm, &Registry::pubkey());
assert_eq!(registry.current_epoch, 0);
assert_eq!(registry.locked, false);
assert_eq!(registry.nonce, 0);
assert_eq!(registry.total_pools, 1);
assert_eq!(registry.total_unstakes, 0);
assert_eq!(registry.total_workers, 1);

Ok(())
}
16 changes: 16 additions & 0 deletions programs/network/tests/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use anchor_lang::{AccountDeserialize, InstructionData, ToAccountMetas};
use litesvm::LiteSVM;
use solana_sdk::{instruction::Instruction, pubkey::Pubkey};

pub fn build_ix(accounts: impl ToAccountMetas, data: impl InstructionData) -> Instruction {
Instruction {
program_id: sablier_network_program::ID,
accounts: accounts.to_account_metas(None),
data: data.data(),
}
}

pub fn get_anchor_account<T: AccountDeserialize>(svm: &mut LiteSVM, key: &Pubkey) -> T {
let account = svm.get_account(key).unwrap();
T::try_deserialize(&mut &account.data[..]).unwrap()
}
6 changes: 6 additions & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ name = "sablier_sdk"
anchor-lang.workspace = true
sablier-thread-program = { workspace = true, features = ["cpi"] }

[dev-dependencies]
sablier-network-program = { workspace = true, features = ["cpi"] }
litesvm.workspace = true
litesvm-token.workspace = true
solana-sdk.workspace = true

[features]
default = []
3 changes: 3 additions & 0 deletions sdk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[cfg(test)]
mod litesvm;

pub use sablier_thread_program::errors;
pub use sablier_thread_program::program::ThreadProgram;
pub use sablier_thread_program::ID;
Expand Down
43 changes: 43 additions & 0 deletions sdk/src/litesvm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::path::Path;

use litesvm::{
types::{FailedTransactionMetadata, TransactionResult},
LiteSVM,
};
use litesvm_token::{CreateAssociatedTokenAccount, CreateMint, MintTo};
use solana_sdk::{
native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, signature::Keypair, signer::Signer,
};

fn setup_test_environment(
network_program_path: impl AsRef<Path>,
thread_program_path: impl AsRef<Path>,
) -> Result<(), FailedTransactionMetadata> {
let mut svm = LiteSVM::new();

let sablier_admin_kp = Keypair::new();
let sablier_admin_pk = sablier_admin_kp.pubkey();

svm.airdrop(&sablier_admin_pk, 10 * LAMPORTS_PER_SOL)?;

svm.add_program_from_file(sablier_network_program::id(), network_program_path.as_ref())
.unwrap();
svm.add_program_from_file(sablier_thread_program::id(), thread_program_path.as_ref())
.unwrap();

let mint = setup_sablier_token(&mut svm, &sablier_admin_kp)?;

Ok(())
}

fn setup_sablier_token(
svm: &mut LiteSVM,
sablier_admin_kp: &Keypair,
) -> Result<Pubkey, FailedTransactionMetadata> {
let mint = CreateMint::new(svm, sablier_admin_kp).send()?;

let ata = CreateAssociatedTokenAccount::new(svm, sablier_admin_kp, &mint).send()?;
MintTo::new(svm, sablier_admin_kp, &mint, &ata, 10).send()?;

Ok(mint)
}
Loading