Початок роботи
let mut svm = LiteSVM::new();
Це створює базовий тестовий екземпляр litesvm, який включає всі увімкнені функції середовища виконання, стандартні sysvar, прекомпіляції, програми spl, sigverify та всі вбудовані програми, як-от System Program.
Щоб взаємодіяти з будь-якою іншою програмою у своїх тестах, необхідно розгорнути цю програму у тестовому середовищі.
-
Зберіть і розгорніть програму, яку хочете протестувати
-
Знайдіть усі програми, до яких наведена вище програма здійснює CPI-виклики, і розгорніть їх
Приклад: Якщо ваша програма використовує дані про ціни від Pyth, вам потрібно розгорнути програму Pyth у своєму тестовому екземплярі.
Базове розгортання програм
Метод 1: Розгортання з байтів
Розгортайте програми безпосередньо з байтових масивів для найшвидшого виконання тестів:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read the program's keypair to get correct IDlet program_keypair = read_keypair_file("target/deploy/my_program-keypair.json").expect("Program keypair file not found");let program_id = program_keypair.pubkey();// Include bytes at compile timelet program_bytes = include_bytes!("../target/deploy/my_program.so");// Deploy from bytessvm.add_program(program_id, program_bytes).expect("Failed to deploy program");// Verify deploymentassert!(svm.get_account(&program_id).is_some(), "Program account not created");assert!(svm.get_account(&program_id).unwrap().executable, "Program not executable");
include_bytes! вбудовує двійковий файл безпосередньо у виконуваний файл тесту
під час компіляції, що усуває операції введення/виведення під час виконання
тестів.
✓ Переваги
- •Швидше під час виконання (без зчитування з диска)
- •Самодостатній виконуваний файл тесту
- •Працює навіть якщо файл .so видалено після компіляції
✗ Недоліки
- •Більший розмір виконуваного файлу тесту
- •Необхідно перекомпілювати тести при зміні файлу .so
Метод 2: Розгортання з файлу (.so)
Завантажуйте програми з файлової системи, коли вони часто змінюються:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read keypair for correct program IDlet program_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = program_keypair.pubkey();// Deploy from filesvm.add_program_from_file(program_id, "target/deploy/program.so").expect("Failed to deploy program from file");// Always verifyassert!(svm.get_account(&program_id).unwrap().executable);
✓ Переваги
- •Менший тестовий бінарний файл
- •Можна підхоплювати зміни .so без перекомпіляції тестів
- •Більша гнучкість для CI/CD-конвеєрів
✗ Недоліки
- •Повільніше (дисковий ввід/вивід під час виконання)
- •Файл .so має існувати на момент виконання тесту
- •Шлях до файлу має бути правильним відносно каталогу виконання тестів
Завантаження програм із Mainnet/Devnet
Якщо вам потрібна програма, вихідного коду якої у вас немає, скористайтесь Solana CLI, щоб вивантажити програми з живих кластерів і використовувати їх у тестах:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Потім завантажте її у своїх тестах:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Найкращі практики
1. Виберіть правильний метод розгортання
-
Використовуйте
add_program(), якщо:- Програми вбудовані у ваш тестовий бінарний файл під час компіляції
- Вам потрібне швидше виконання тестів (без ввід/виводу під час виконання)
- Тести є самодостатніми
-
Використовуйте
add_program_from_file(), коли:- Програми зібрані окремо (тобто завантажуються з devnet)
- Програми часто змінюються під час розробки (можна повторно запускати тести без перекомпіляції)
- У вас є середовища CI/CD, де файли .so є артефактами
Розуміння keypair програми
Коли ви збираєте програму Solana:
- Anchor створює
target/deploy/program-keypair.json - Native збірки створюють файл keypair поруч із файлом
.so - Адреса програми в мережі — це pubkey цього keypair, яка також відома як ідентифікатор програми.
- Для PDA
find_program_address()потребує ідентифікатор програми як seed - Для CPI ідентифікатор програми використовується для виклику інших програм
Поширені проблеми та рішення
Приховані збої розгортання
Проблема: Програма, здається, розгорнута, але транзакції завершуються помилкою "InvalidProgramForExecution".
Причина: Ідентифікатор програми не відповідає keypair.
Рішення:
// Always use the keypair-derived IDlet keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();svm.add_program(program_id, &program_bytes).unwrap();// Verify with detailed checkslet account = svm.get_account(&program_id).expect("Program account doesn't exist");assert!(account.executable, "Program not executable");assert_eq!(account.owner, solana_sdk::bpf_loader::id(), "Wrong owner");assert!(!account.data.is_empty(), "Program data is empty");println!("✅ Program verified at {}", program_id);
Помилка «Програму не знайдено»
Помилка: TransactionError::InvalidProgramForExecution
Поширені причини:
- Програму не розгорнуто
- У інструкції використовується неправильний ідентифікатор програми
- Невідповідність ідентифікатора програми з keypair
Кроки для налагодження:
// Step 1: Check if program existsif let Some(account) = svm.get_account(&program_id) {println!("Program exists");println!(" Executable: {}", account.executable);println!(" Owner: {}", account.owner);println!(" Data length: {}", account.data.len());} else {println!("Program does not exist at {}", program_id);}// Step 2: Verify the ID matches keypairlet expected_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let expected_id = expected_keypair.pubkey();if program_id != expected_id {println!(" ID mismatch!");println!(" Used: {}", program_id);println!(" Expected: {}", expected_id);}// Step 3: Check instruction program IDprintln!("Instruction program_id: {}", instruction.program_id);assert_eq!(instruction.program_id, program_id, "Instruction uses wrong program ID");
CPI до нерозгорнутих програм
Проблема: Ваша програма здійснює виклик CPI до програми, яка не розгорнута.
Рішення: Розгорніть усі залежні програми:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Якщо вам потрібно завантажити програму з кластера, перегляньте цей розділ.
Недостатньо lamport для розгортання
Примітка: LiteSVM автоматично обробляє баланс, звільнений від орендної плати, для програм.
// No need to manually fund - LiteSVM handles thissvm.add_program(program_id, &program_bytes).unwrap();// But you can check the rent if neededlet program_len = program_bytes.len();let required_lamports = svm.minimum_balance_for_rent_exemption(program_len);println!("Program requires {} lamports for rent exemption", required_lamports);
Контрольний список перевірки розгортання
Зчитайте keypair програми
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Розгорніть з відповідним ID
svm.add_program(program_id, &program_bytes).unwrap();
Перевірте розгортання
assert!(svm.get_account(&program_id).unwrap().executable);
Розгорніть усі програми, які ваша програма викликає через CPI, до тестового екземпляра litesvm
Наступні кроки
У наступному розділі ми дізнаємося, як виконувати інструкції програми та обробляти складні патерни транзакцій.
Is this page helpful?