chore: replace jest with mocha

This commit is contained in:
Justin Starry
2021-02-06 10:59:00 +08:00
committed by Justin Starry
parent 612958ece0
commit c675c67c26
41 changed files with 4635 additions and 6665 deletions

View File

@@ -1,6 +1,8 @@
// @flow
import fs from 'mz/fs';
import {expect, use} from 'chai';
import chaiAsPromised from 'chai-as-promised';
import {
Connection,
@@ -9,263 +11,278 @@ import {
sendAndConfirmTransaction,
Account,
} from '../src';
import {mockRpcEnabled} from './__mocks__/node-fetch';
import {url} from './url';
import {newAccountWithLamports} from './new-account-with-lamports';
import {BPF_LOADER_PROGRAM_ID} from '../src/bpf-loader';
import {helpers} from './mocks/rpc-http';
if (!mockRpcEnabled) {
// The default of 5 seconds is too slow for live testing sometimes
jest.setTimeout(240000);
}
use(chaiAsPromised);
test('load BPF C program', async () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
return;
}
if (process.env.TEST_LIVE) {
describe('BPF Loader', () => {
it('load BPF C program', async () => {
const data = await fs.readFile('test/fixtures/noop-c/noop.so');
const data = await fs.readFile('test/fixtures/noop-c/noop.so');
const connection = new Connection(url, 'singleGossip');
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
BpfLoader.getMinNumSignatures(data.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(
0,
);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
data.length,
);
const connection = new Connection(url, 'singleGossip');
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
BpfLoader.getMinNumSignatures(data.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
data.length,
);
const from = await newAccountWithLamports(
connection,
payerBalance + fees + executableBalance,
);
const from = new Account();
await helpers.airdrop({
connection,
address: from.publicKey,
amount: payerBalance + fees + executableBalance,
});
const program = new Account();
await BpfLoader.load(connection, from, program, data, BPF_LOADER_PROGRAM_ID);
// Check that program loading costed exactly `fees + executableBalance`
const fromBalance = await connection.getBalance(from.publicKey);
expect(fromBalance).toEqual(payerBalance);
const transaction = new Transaction().add({
keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}],
programId: program.publicKey,
});
await sendAndConfirmTransaction(connection, transaction, [from], {
commitment: 'singleGossip',
preflightCommitment: 'singleGossip',
});
});
describe('load BPF Rust program', () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
return;
}
const connection = new Connection(url, 'singleGossip');
let program: Account;
let payerAccount: Account;
let programData: Buffer;
beforeAll(async () => {
programData = await fs.readFile(
'test/fixtures/noop-rust/solana_bpf_rust_noop.so',
);
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
BpfLoader.getMinNumSignatures(programData.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(0);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
programData.length,
);
payerAccount = await newAccountWithLamports(
connection,
payerBalance + fees + executableBalance,
);
// Create program account with low balance
program = await newAccountWithLamports(connection, executableBalance - 1);
// First load will fail part way due to lack of funds
const insufficientPayerAccount = await newAccountWithLamports(
connection,
2 * feeCalculator.lamportsPerSignature * 8,
);
const failedLoad = BpfLoader.load(
connection,
insufficientPayerAccount,
program,
programData,
BPF_LOADER_PROGRAM_ID,
);
await expect(failedLoad).rejects.toThrow();
// Second load will succeed
await BpfLoader.load(
connection,
payerAccount,
program,
programData,
BPF_LOADER_PROGRAM_ID,
);
});
test('get confirmed transaction', async () => {
const transaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const signature = await sendAndConfirmTransaction(
connection,
transaction,
[payerAccount],
{
commitment: 'max', // `getParsedConfirmedTransaction` requires max commitment
preflightCommitment: connection.commitment || 'max',
},
);
const parsedTx = await connection.getParsedConfirmedTransaction(signature);
if (parsedTx === null) {
expect(parsedTx).not.toBeNull();
return;
}
const {signatures, message} = parsedTx.transaction;
expect(signatures[0]).toEqual(signature);
const ix = message.instructions[0];
if (ix.parsed) {
expect('parsed' in ix).toBe(false);
} else {
expect(ix.programId.equals(program.publicKey)).toBe(true);
expect(ix.data).toEqual('');
}
});
test('simulate transaction', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction, [payerAccount])
).value;
expect(err).toBeNull();
if (logs === null) {
expect(logs).not.toBeNull();
return;
}
expect(logs.length).toBeGreaterThanOrEqual(2);
expect(logs[0]).toEqual(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).toEqual(
`Program ${program.publicKey.toBase58()} success`,
);
});
test('deprecated - simulate transaction without signature verification', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
simulatedTransaction.setSigners(payerAccount.publicKey);
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).toBeNull();
if (logs === null) {
expect(logs).not.toBeNull();
return;
}
expect(logs.length).toBeGreaterThanOrEqual(2);
expect(logs[0]).toEqual(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).toEqual(
`Program ${program.publicKey.toBase58()} success`,
);
});
test('simulate transaction without signature verification', async () => {
const simulatedTransaction = new Transaction({
feePayer: payerAccount.publicKey,
}).add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).toBeNull();
if (logs === null) {
expect(logs).not.toBeNull();
return;
}
expect(logs.length).toBeGreaterThanOrEqual(2);
expect(logs[0]).toEqual(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).toEqual(
`Program ${program.publicKey.toBase58()} success`,
);
});
test('simulate transaction with bad programId', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: new Account().publicKey,
});
simulatedTransaction.setSigners(payerAccount.publicKey);
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).toEqual('ProgramAccountNotFound');
if (logs === null) {
expect(logs).not.toBeNull();
return;
}
expect(logs.length).toEqual(0);
});
test('reload program', async () => {
expect(
const program = new Account();
await BpfLoader.load(
connection,
payerAccount,
from,
program,
programData,
data,
BPF_LOADER_PROGRAM_ID,
),
).toBe(false);
);
// Check that program loading costed exactly `fees + executableBalance`
const fromBalance = await connection.getBalance(from.publicKey);
expect(fromBalance).to.eq(payerBalance);
const transaction = new Transaction().add({
keys: [{pubkey: from.publicKey, isSigner: true, isWritable: true}],
programId: program.publicKey,
});
await sendAndConfirmTransaction(connection, transaction, [from], {
commitment: 'singleGossip',
preflightCommitment: 'singleGossip',
});
}).timeout(5000);
describe('load BPF Rust program', () => {
const connection = new Connection(url, 'singleGossip');
let program = new Account();
let payerAccount = new Account();
let programData: Buffer;
before(async function () {
this.timeout(60_000);
programData = await fs.readFile(
'test/fixtures/noop-rust/solana_bpf_rust_noop.so',
);
const {feeCalculator} = await connection.getRecentBlockhash();
const fees =
feeCalculator.lamportsPerSignature *
BpfLoader.getMinNumSignatures(programData.length);
const payerBalance = await connection.getMinimumBalanceForRentExemption(
0,
);
const executableBalance = await connection.getMinimumBalanceForRentExemption(
programData.length,
);
await helpers.airdrop({
connection,
address: payerAccount.publicKey,
amount: payerBalance + fees + executableBalance,
});
// Create program account with low balance
await helpers.airdrop({
connection,
address: program.publicKey,
amount: executableBalance - 1,
});
// First load will fail part way due to lack of funds
const insufficientPayerAccount = new Account();
await helpers.airdrop({
connection,
address: insufficientPayerAccount.publicKey,
amount: 2 * feeCalculator.lamportsPerSignature * 8,
});
const failedLoad = BpfLoader.load(
connection,
insufficientPayerAccount,
program,
programData,
BPF_LOADER_PROGRAM_ID,
);
await expect(failedLoad).to.be.rejected;
// Second load will succeed
await BpfLoader.load(
connection,
payerAccount,
program,
programData,
BPF_LOADER_PROGRAM_ID,
);
});
it('get confirmed transaction', async () => {
const transaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const signature = await sendAndConfirmTransaction(
connection,
transaction,
[payerAccount],
{
commitment: 'max', // `getParsedConfirmedTransaction` requires max commitment
preflightCommitment: connection.commitment || 'max',
},
);
const parsedTx = await connection.getParsedConfirmedTransaction(
signature,
);
if (parsedTx === null) {
expect(parsedTx).not.to.be.null;
return;
}
const {signatures, message} = parsedTx.transaction;
expect(signatures[0]).to.eq(signature);
const ix = message.instructions[0];
if (ix.parsed) {
expect('parsed' in ix).to.eq(false);
} else {
expect(ix.programId).to.eql(program.publicKey);
expect(ix.data).to.eq('');
}
}).timeout(30000);
it('simulate transaction', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction, [
payerAccount,
])
).value;
expect(err).to.be.null;
if (logs === null) {
expect(logs).not.to.be.null;
return;
}
expect(logs.length).to.be.at.least(2);
expect(logs[0]).to.eq(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).to.eq(
`Program ${program.publicKey.toBase58()} success`,
);
});
it('deprecated - simulate transaction without signature verification', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
simulatedTransaction.setSigners(payerAccount.publicKey);
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).to.be.null;
if (logs === null) {
expect(logs).not.to.be.null;
return;
}
expect(logs.length).to.be.at.least(2);
expect(logs[0]).to.eq(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).to.eq(
`Program ${program.publicKey.toBase58()} success`,
);
});
it('simulate transaction without signature verification', async () => {
const simulatedTransaction = new Transaction({
feePayer: payerAccount.publicKey,
}).add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).to.be.null;
if (logs === null) {
expect(logs).not.to.be.null;
return;
}
expect(logs.length).to.be.at.least(2);
expect(logs[0]).to.eq(
`Program ${program.publicKey.toBase58()} invoke [1]`,
);
expect(logs[logs.length - 1]).to.eq(
`Program ${program.publicKey.toBase58()} success`,
);
});
it('simulate transaction with bad programId', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: new Account().publicKey,
});
simulatedTransaction.setSigners(payerAccount.publicKey);
const {err, logs} = (
await connection.simulateTransaction(simulatedTransaction)
).value;
expect(err).to.eq('ProgramAccountNotFound');
if (logs === null) {
expect(logs).not.to.be.null;
return;
}
expect(logs).to.have.length(0);
});
it('reload program', async () => {
expect(
await BpfLoader.load(
connection,
payerAccount,
program,
programData,
BPF_LOADER_PROGRAM_ID,
),
).to.eq(false);
});
});
});
});
}