Skip to content

Commit ac4e91c

Browse files
authored
implement mollusk conformance testing (#26)
1 parent 7c6eb49 commit ac4e91c

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

.github/workflows/main.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,37 @@ jobs:
140140
echo "CU usage has changed. Please run `cargo bench` and commit the new results.";
141141
exit 1;
142142
fi
143+
144+
conformance:
145+
name: Conformance Test
146+
runs-on: ubuntu-latest
147+
needs: build_programs
148+
steps:
149+
- name: Git Checkout
150+
uses: actions/checkout@v4
151+
152+
- name: Setup Environment
153+
uses: ./.github/actions/setup
154+
with:
155+
cargo-cache-key: cargo-program-conformance
156+
cargo-cache-fallback-key: cargo-programs
157+
solana: true
158+
159+
- name: Install System Dependencies
160+
run: |
161+
sudo apt-get update
162+
sudo apt-get install -y libudev-dev pkg-config
163+
command -v mollusk >/dev/null 2>&1 || cargo install mollusk-svm-cli
164+
165+
- name: Restore Program Builds
166+
uses: actions/cache/restore@v4
167+
with:
168+
path: ./**/*.so
169+
key: ${{ runner.os }}-builds-${{ github.sha }}
170+
171+
- name: Conformance Test
172+
shell: bash
173+
run: pnpm zx ./scripts/ci/conformance.mjs
143174

144175
generate_idls:
145176
name: Check IDL Generation

scripts/ci/conformance.mjs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env zx
2+
3+
// Mollusk conformance testing of this Core BPF Feature Gate program against
4+
// the version running on mainnet-beta.
5+
6+
import 'zx/globals';
7+
import { getProgramId, getProgramSharedObjectPath, workingDirectory } from '../utils.mjs';
8+
9+
const programId = getProgramId('program');
10+
const programBinaryPath = getProgramSharedObjectPath('program');
11+
const baseBinaryDirPath = path.join(workingDirectory, 'target', 'dump-solana');
12+
const baseBinaryPath = path.join(baseBinaryDirPath, 'base.so');
13+
const molluskFixturesPath = path.join(workingDirectory, 'program', 'fuzz', 'blob');
14+
15+
// Clone the program from mainnet-beta.
16+
await $`mkdir -p ${baseBinaryDirPath}`;
17+
await $`solana program dump -um ${programId} ${baseBinaryPath}`;
18+
19+
// Test this program against the cloned program for conformance with Mollusk.
20+
let output = await $`mollusk run-test \
21+
--proto firedancer --ignore-compute-units \
22+
${baseBinaryPath} ${programBinaryPath} \
23+
${molluskFixturesPath} ${programId}`;
24+
25+
// The last line of output should exactly match the following:
26+
// [DONE][TEST RESULT]: 0 failures
27+
if (!output.stdout.includes("[DONE][TEST RESULT]: 0 failures")) {
28+
throw new Error(`Error: mismatches detected.`);
29+
}

scripts/utils.mjs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,27 @@ export function getAllProgramFolders() {
7070
);
7171
}
7272

73+
export function getProgramId(folder) {
74+
return getCargoMetadata(folder)?.solana?.['program-id'];
75+
}
76+
77+
export function getProgramName(folder) {
78+
return getCargo(folder).package?.name;
79+
}
80+
81+
export function getProgramSharedObjectName(folder) {
82+
return `${getProgramName(folder).replace(/-/g, '_')}.so`;
83+
}
84+
85+
export function getProgramSharedObjectPath(folder) {
86+
return path.join(
87+
workingDirectory,
88+
'target',
89+
'deploy',
90+
getProgramSharedObjectName(folder),
91+
);
92+
}
93+
7394
export function getCargo(folder) {
7495
return parseToml(
7596
fs.readFileSync(

0 commit comments

Comments
 (0)