Erste Schritte
let mut svm = LiteSVM::new();
Dies erstellt die grundlegende LiteSVM-Testinstanz, die alle aktivierten Laufzeitfunktionen, Standard-Sysvars, Precompiles, SPL-Programme, Sigverify und alle integrierten Programme wie das System Program umfasst.
Um in Ihren Tests mit einem anderen Programm zu interagieren, müssen Sie dieses Programm in Ihrer Testumgebung deployen.
-
Erstellen und deployen Sie das Programm, das Sie testen möchten
-
Ermitteln Sie alle Programme, an die das obige Programm CPI-Aufrufe sendet, und deployen Sie diese Programme
Beispiel: Wenn Ihr Programm Daten-Feeds von Pyth verwendet, müssen Sie das Pyth-Programm in Ihrer Testinstanz deployen.
Grundlegendes Programm-Deployment
Methode 1: Deployment aus Bytes
Deployen Sie Programme direkt aus Byte-Arrays für eine schnellstmögliche Testausführung:
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! bettet die Binärdatei zur Kompilierzeit direkt in die
ausführbare Testdatei ein und eliminiert so E/A-Operationen während der
Testausführung.
✓ Vorteile
- •Schneller zur Laufzeit (keine Festplattenzugriffe)
- •In sich geschlossene Test-Binärdatei
- •Funktioniert auch, wenn die .so-Datei nach der Kompilierung gelöscht wird
✗ Nachteile
- •Größere Test-Binärdatei
- •Tests müssen neu kompiliert werden, wenn sich die .so-Datei ändert
Methode 2: Deployment aus Datei (.so)
Programme aus dem Dateisystem laden, wenn sie sich häufig ändern:
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);
✓ Vorteile
- •Kleinere Test-Binärdatei
- •Kann .so-Änderungen übernehmen, ohne Tests neu zu kompilieren
- •Flexibler für CI/CD-Pipelines
✗ Nachteile
- •Langsamer (Datenträger-E/A zur Laufzeit)
- •Erfordert, dass die .so-Datei zum Zeitpunkt der Testausführung vorhanden ist
- •Dateipfad muss relativ zum Testausführungsverzeichnis korrekt sein
Programme von Mainnet/Devnet abrufen
Wenn Sie ein Programm benötigen, für das Sie keinen Quellcode haben, verwenden Sie die Solana CLI, um Programme aus Live-Clustern zu exportieren und in Tests zu verwenden:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Dann laden Sie es in Ihren Tests:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Best Practices
1. Die richtige Deployment-Methode wählen
-
Use
add_program()wenn:- Programme zum Zeitpunkt der Kompilierung in Ihre Test-Binärdatei eingebettet sind
- Sie eine schnellere Testausführung wünschen (kein Laufzeit-E/A)
- In sich geschlossene Tests
-
Verwende
add_program_from_file()wenn:- Programme separat gebaut werden (d.h. von devnet bezogen werden)
- Programme sich während der Entwicklung häufig ändern (Tests können ohne Neukompilierung erneut ausgeführt werden)
- Du CI/CD-Umgebungen hast, in denen .so-Dateien Artefakte sind
Das program keypair verstehen
Wenn du ein Solana-Programm baust:
- Anchor erstellt
target/deploy/program-keypair.json - Native Builds erstellen eine keypair-Datei zusammen mit der
.so-Datei - Die On-Chain-Adresse des Programms ist der öffentliche Schlüssel dieses keypair, der auch als Programm-ID bekannt ist.
- Bei PDAs erfordert
find_program_address()die Programm-ID als seed - Bei CPIs wird die Programm-ID verwendet, um andere Programme aufzurufen
Häufige Probleme und Lösungen
Stille Deployment-Fehler
Problem: Das Programm scheint erfolgreich deployed zu sein, aber Transaktionen schlagen mit "InvalidProgramForExecution" fehl.
Ursache: Die Programm-ID stimmt nicht mit dem keypair überein.
Lösung:
// 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);
Fehler: Programm nicht gefunden
Fehler: TransactionError::InvalidProgramForExecution
Häufige Ursachen:
- Programm nicht deployed
- Falsche Programm-ID in der Anweisung verwendet
- Programm-ID stimmt nicht mit dem keypair überein
Debugging-Schritte:
// 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 zu nicht deployten Programmen
Problem: Dein Programm führt einen CPI-Aufruf an ein Programm durch, das nicht deployed ist.
Lösung: Alle Abhängigkeitsprogramme deployen:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Wenn du das Programm aus einem Cluster beziehen musst, lies diesen Abschnitt.
Unzureichende lamports für das Deployment
Hinweis: LiteSVM verwaltet automatisch den rent-exempt-Saldo für Programme.
// 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);
Deployment Verifikations-Checkliste
Programm-keypair lesen
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Mit passender ID deployen
svm.add_program(program_id, &program_bytes).unwrap();
Deployment überprüfen
assert!(svm.get_account(&program_id).unwrap().executable);
Deployen Sie alle Programme, die Ihr Programm per CPI aufruft, in die litesvm-Testinstanz
Nächste Schritte
Im nächsten Abschnitt lernen wir, wie man Programm Anweisungen ausführt und komplexe Transaktionsmuster verarbeitet.
Is this page helpful?