البدء
let mut svm = LiteSVM::new();
يقوم هذا بإنشاء نسخة اختبار litesvm الأساسية، والتي تتضمن جميع ميزات وقت التشغيل المُفعَّلة، والمتغيرات النظامية الافتراضية، والتجميعات المسبقة، وبرامج spl، والتحقق من التوقيعات، وجميع البرامج المدمجة مثل 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
الطريقة الثانية: النشر من ملف (.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
عندما تحتاج إلى برنامج لا تملك كوده المصدري، استخدم واجهة سطر أوامر سولانا لاستخراج البرامج من الشبكات الحية واستخدامها في الاختبارات:
# 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 البرنامج
عند بناء برنامج سولانا:
- ينشئ Anchor
target/deploy/program-keypair.json - تنشئ عمليات بناء Native ملف keypair إلى جانب ملف
.so - عنوان البرنامج على السلسلة هو المفتاح العام لهذا keypair، والمعروف أيضاً بمعرّف البرنامج.
- بالنسبة لـ PDAs، يتطلب
find_program_address()معرّف البرنامج كـ seed - بالنسبة لـ CPIs، يُستخدم معرّف البرنامج لاستدعاء البرامج الأخرى
المشكلات الشائعة وحلولها
إخفاقات النشر الصامتة
المشكلة: يبدو أن البرنامج يتم نشره، لكن المعاملات تفشل بـ "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();
انشر مع المعرّف المطابق
svm.add_program(program_id, &program_bytes).unwrap();
تحقق من النشر
assert!(svm.get_account(&program_id).unwrap().executable);
انشر أي برامج يستدعيها برنامجك عبر CPI إلى نموذج اختبار litesvm
الخطوات التالية
في القسم التالي، سنتعلم كيفية تنفيذ تعليمات البرنامج والتعامل مع أنماط المعاملات المعقدة.
Is this page helpful?