wp-solana-test-core 0.1.1

Protocol-agnostic Solana test infrastructure built on LiteSVM
Documentation
//! Account loading and manipulation helpers for [`TestContext`].
//!
//! All functions take the SVM `std::sync::Mutex` synchronously via `lock()`.
//! Critical sections here never span an `.await` point, so async callers
//! can use these helpers freely.

use anyhow::Result;
use solana_sdk::{account::Account, pubkey::Pubkey};

use crate::{context::TestContext, fixture_loader};

/// Load a BPF program into the SVM at `program_id`.
pub fn load_program(ctx: &TestContext, program_id: Pubkey, bytes: &[u8]) -> Result<()> {
    let mut svm = ctx.lock_svm();
    svm.add_program(program_id, bytes)?;
    Ok(())
}

/// Load multiple accounts from a JSON fixture array into the SVM.
///
/// The JSON format matches [`fixture_loader::load_account_fixtures`].
pub fn load_accounts_json(ctx: &TestContext, json: &[u8]) -> Result<()> {
    let accounts = fixture_loader::load_account_fixtures(json)?;
    let mut svm = ctx.lock_svm();
    for (addr, account) in accounts {
        svm.set_account(addr, account)?;
    }
    Ok(())
}

/// Set a single account in the SVM at `addr`.
pub fn set_account(ctx: &TestContext, addr: Pubkey, account: Account) -> Result<()> {
    let mut svm = ctx.lock_svm();
    svm.set_account(addr, account)?;
    Ok(())
}

#[cfg(test)]
mod tests {
    use base64::Engine;
    use solana_sdk::pubkey::Pubkey;

    use super::*;
    use crate::context::new_test_context;

    /// System program ID used only in tests.
    const SYSTEM_PROGRAM: Pubkey = solana_sdk::pubkey!("11111111111111111111111111111111");

    #[test]
    fn test_set_and_get_account() {
        let ctx = new_test_context().unwrap();
        let addr = Pubkey::new_unique();
        let account = Account {
            lamports: 42_000,
            data: vec![1, 2, 3],
            owner: SYSTEM_PROGRAM,
            executable: false,
            rent_epoch: 0,
        };

        set_account(&ctx, addr, account.clone()).unwrap();

        let svm = ctx.lock_svm();
        let stored = svm.get_account(&addr).expect("account should exist");
        assert_eq!(stored.lamports, 42_000);
        assert_eq!(stored.data, vec![1, 2, 3]);
        assert_eq!(stored.owner, SYSTEM_PROGRAM);
    }

    #[test]
    fn test_load_accounts_json() {
        let ctx = new_test_context().unwrap();

        let json = serde_json::json!([
          {
            "address": "11111111111111111111111111111111",
            "data": base64::engine::general_purpose::STANDARD.encode([10, 20]),
            "encoding": "base64",
            "lamports": 500,
            "owner": "11111111111111111111111111111111",
            "executable": false,
            "rent_epoch": 0
          }
        ]);
        let bytes = serde_json::to_vec(&json).unwrap();

        load_accounts_json(&ctx, &bytes).unwrap();

        let svm = ctx.lock_svm();
        let addr: Pubkey = "11111111111111111111111111111111".parse().unwrap();
        let stored = svm.get_account(&addr).expect("account should exist");
        assert_eq!(stored.lamports, 500);
        assert_eq!(stored.data, vec![10, 20]);
    }
}