Skip to main content

wp_solana_test_core/
accounts.rs

1//! Account loading and manipulation helpers for [`TestContext`].
2//!
3//! All functions take the SVM `std::sync::Mutex` synchronously via `lock()`.
4//! Critical sections here never span an `.await` point, so async callers
5//! can use these helpers freely.
6
7use anyhow::Result;
8use solana_sdk::{account::Account, pubkey::Pubkey};
9
10use crate::{context::TestContext, fixture_loader};
11
12/// Load a BPF program into the SVM at `program_id`.
13pub fn load_program(ctx: &TestContext, program_id: Pubkey, bytes: &[u8]) -> Result<()> {
14    let mut svm = ctx.lock_svm();
15    svm.add_program(program_id, bytes)?;
16    Ok(())
17}
18
19/// Load multiple accounts from a JSON fixture array into the SVM.
20///
21/// The JSON format matches [`fixture_loader::load_account_fixtures`].
22pub fn load_accounts_json(ctx: &TestContext, json: &[u8]) -> Result<()> {
23    let accounts = fixture_loader::load_account_fixtures(json)?;
24    let mut svm = ctx.lock_svm();
25    for (addr, account) in accounts {
26        svm.set_account(addr, account)?;
27    }
28    Ok(())
29}
30
31/// Set a single account in the SVM at `addr`.
32pub fn set_account(ctx: &TestContext, addr: Pubkey, account: Account) -> Result<()> {
33    let mut svm = ctx.lock_svm();
34    svm.set_account(addr, account)?;
35    Ok(())
36}
37
38#[cfg(test)]
39mod tests {
40    use base64::Engine;
41    use solana_sdk::pubkey::Pubkey;
42
43    use super::*;
44    use crate::context::new_test_context;
45
46    /// System program ID used only in tests.
47    const SYSTEM_PROGRAM: Pubkey = solana_sdk::pubkey!("11111111111111111111111111111111");
48
49    #[test]
50    fn test_set_and_get_account() {
51        let ctx = new_test_context().unwrap();
52        let addr = Pubkey::new_unique();
53        let account = Account {
54            lamports: 42_000,
55            data: vec![1, 2, 3],
56            owner: SYSTEM_PROGRAM,
57            executable: false,
58            rent_epoch: 0,
59        };
60
61        set_account(&ctx, addr, account.clone()).unwrap();
62
63        let svm = ctx.lock_svm();
64        let stored = svm.get_account(&addr).expect("account should exist");
65        assert_eq!(stored.lamports, 42_000);
66        assert_eq!(stored.data, vec![1, 2, 3]);
67        assert_eq!(stored.owner, SYSTEM_PROGRAM);
68    }
69
70    #[test]
71    fn test_load_accounts_json() {
72        let ctx = new_test_context().unwrap();
73
74        let json = serde_json::json!([
75          {
76            "address": "11111111111111111111111111111111",
77            "data": base64::engine::general_purpose::STANDARD.encode([10, 20]),
78            "encoding": "base64",
79            "lamports": 500,
80            "owner": "11111111111111111111111111111111",
81            "executable": false,
82            "rent_epoch": 0
83          }
84        ]);
85        let bytes = serde_json::to_vec(&json).unwrap();
86
87        load_accounts_json(&ctx, &bytes).unwrap();
88
89        let svm = ctx.lock_svm();
90        let addr: Pubkey = "11111111111111111111111111111111".parse().unwrap();
91        let stored = svm.get_account(&addr).expect("account should exist");
92        assert_eq!(stored.lamports, 500);
93        assert_eq!(stored.data, vec![10, 20]);
94    }
95}