Go'dan özel bir Solana programını test etmek, derlenmiş .so dosyasını
SVM'ye yüklemek, programın beklediği hesapları ayarlamak ve programa karşı
talimatlar göndermek anlamına gelir. litesvm-go tüm bunları işlem içinde
gerçekleştirir - validator gerekmez.
Program Yükleme
package mytestimport ("os""testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go")func TestLoadProgram(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Configure for program testing. Setters are infallible in practice;// discarding the return keeps the example readable._ = svm.SetSigverify(false)_ = svm.SetBlockhashCheck(false)_ = svm.SetSysvars()_ = svm.SetBuiltins()// Load program from .so file.programID := solana.NewWallet().PublicKey()soPath := "./target/deploy/my_program.so"if _, err := os.Stat(soPath); err != nil {t.Skipf("program file not found: %s (build with: cargo build-sbf)", soPath)}if err := svm.AddProgramFromFile(programID, soPath); err != nil {t.Fatal(err)}t.Logf("program loaded: %s", programID)// Verify the program account.acct := svm.GetAccount(programID)if acct == nil {t.Fatal("program account missing after load")}defer acct.Close()t.Logf(" executable: %v", acct.Executable())t.Logf(" data size: %d bytes", len(acct.Data()))}
Eksiksiz Program Test Kurulumu
package mytestimport ("os""testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go")func TestProgramEndToEnd(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Wide-open config: faster tests, less plumbing. Setters are infallible// in practice; discarding the return keeps the example readable._ = svm.SetSigverify(false)_ = svm.SetBlockhashCheck(false)_ = svm.SetSysvars()_ = svm.SetBuiltins()_ = svm.SetPrecompiles()_ = svm.SetTransactionHistory(100)// Load the program.programID := solana.NewWallet().PublicKey()soPath := "./target/deploy/my_program.so"if _, err := os.Stat(soPath); err != nil {t.Skipf("missing %s", soPath)}if err := svm.AddProgramFromFile(programID, soPath); err != nil {t.Fatal(err)}// Seed any data accounts the program expects.dataAddr := solana.NewWallet().PublicKey()dataPayload := make([]byte, 100)rent, err := svm.MinimumBalanceForRentExemption(len(dataPayload))if err != nil {t.Fatal(err)}acct, err := litesvm.NewAccount(rent, dataPayload, programID, false, 0)if err != nil {t.Fatal(err)}defer acct.Close()if err := svm.SetAccount(dataAddr, acct); err != nil {t.Fatal(err)}// Fund a payer that will sign the test instruction.priv, err := solana.NewRandomPrivateKey()if err != nil {t.Fatal(err)}payer := priv.PublicKey()if err := svm.Airdrop(payer, 1_000_000_000); err != nil {t.Fatal(err)}// Build an instruction against the program.bh, err := svm.LatestBlockhash()if err != nil {t.Fatal(err)}ix := &solana.GenericInstruction{ProgID: programID,AccountValues: solana.AccountMetaSlice{{PublicKey: dataAddr, IsWritable: true, IsSigner: false},{PublicKey: payer, IsWritable: true, IsSigner: true},},DataBytes: []byte{0x01 /* discriminator + args */},}tx, err := solana.NewTransaction([]solana.Instruction{ix},bh,solana.TransactionPayer(payer),)if err != nil {t.Fatal(err)}if _, err := tx.Sign(func(k solana.PublicKey) *solana.PrivateKey {if k.Equals(payer) {return &priv}return nil}); err != nil {t.Fatal(err)}txBytes, err := tx.MarshalBinary()if err != nil {t.Fatal(err)}// Execute and inspect.out, err := svm.SendLegacyTransaction(txBytes)if err != nil {t.Fatal(err)}defer out.Close()if !out.IsOk() {t.Fatalf("program failed: %s\nlogs: %v", out.Error(), out.Logs())}t.Logf("logs: %v", out.Logs())t.Logf("compute: %d CU", out.ComputeUnits())// Verify state changes by reading the data account back.updated := svm.GetAccount(dataAddr)if updated == nil {t.Fatal("data account missing after execution")}defer updated.Close()// Decode `updated.Data()` and assert as needed.}
Varsayılan Programları Kullanma
Standart programlara (SPL Token, Memo, ...) ihtiyaç duyan testler için:
svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()if err := svm.SetDefaultPrograms(); err != nil { // SPL Token, Memo, etc.t.Fatal(err)}if err := svm.WithNativeMints(); err != nil { // wrapped-SOL mintt.Fatal(err)}
.so dosyasını oluşturmak için Solana programınızı cargo build-sbf ile derleyin.
Kalıp her zaman aynıdır:
- Yapılandırma - gerektiğinde sysvar'ları, yerleşikleri ve ön derleme bileşenlerini etkinleştirin.
- Program yükleme -
AddProgramFromFile(veya bellek içi baytlar içinAddProgram). - Hesap kurulumu - veri hesaplarını
SetAccountile önceden doldurun. - Gönderme -
solana-goile talimatı oluşturun, serileştirin veSendLegacyTransactionaracılığıyla gönderin. - Doğrulama - hesapları
GetAccountile geri okuyun ve günlükler, hesaplama birimleri ve son durum üzerinde doğrulama yapın.
Bu iskelet çalışır hale geldiğinde, daha fazla talimat, daha fazla hesap ve standart kod için bir yardımcı ekleyerek ölçeği büyütün.
Is this page helpful?