Skip to content

Commit 59403ab

Browse files
committed
add core bpf mode with new diff fn
1 parent 302059e commit 59403ab

File tree

4 files changed

+70
-7
lines changed

4 files changed

+70
-7
lines changed

commands.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ $ solana-test-suite run-tests [OPTIONS]
231231
* `-c, --chunk-size INTEGER`: Number of test results per file [default: 10000]
232232
* `-v, --verbose`: Verbose output: log failed test cases
233233
* `-c, --consensus-mode`: Only fail on consensus failures. One such effect is to normalize error codes when comparing results
234+
* `-cb, --core-bpf-mode`: Deliberately skip known mismatches between BPF programs and builtins, only failing on genuine mimatches. For example, builtin programs may throw errors on readonly account state violations sooner than BPF programs, compute unit usage will be different, etc. This feature is primarily used to test a BPF program against a builtin.
234235
* `-f, --failures-only`: Only log failed test cases
235236
* `-sf, --save-failures`: Saves failed test cases to results directory
236237
* `-ss, --save-successes`: Saves successful test cases to results directory

src/test_suite/instr/diff_utils.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
1+
from enum import Enum
12
import test_suite.invoke_pb2 as invoke_pb
23

34

5+
class DiffMode(Enum):
6+
STANDARD = 0
7+
CONSENSUS = 1
8+
CORE_BPF = 2
9+
10+
def apply_diff(self, a: invoke_pb.InstrEffects, b: invoke_pb.InstrEffects):
11+
"""Applies the specified diff effects.
12+
- STANDARD: No diff effects.
13+
- CONSENSUS: Consensus-only diff effects.
14+
- CORE_BPF: Core BPF diff effects for testing a BPF program against a builtin.
15+
"""
16+
if self == DiffMode.CONSENSUS:
17+
return consensus_instr_diff_effects(a, b)
18+
if self == DiffMode.CORE_BPF:
19+
return core_bpf_instr_diff_effects(a, b)
20+
21+
422
def consensus_instr_diff_effects(a: invoke_pb.InstrEffects, b: invoke_pb.InstrEffects):
523
a_san = invoke_pb.InstrEffects()
624
a_san.CopyFrom(a)
@@ -17,3 +35,29 @@ def consensus_instr_diff_effects(a: invoke_pb.InstrEffects, b: invoke_pb.InstrEf
1735
b_san.cu_avail = 0
1836

1937
return a_san == b_san
38+
39+
40+
def core_bpf_instr_diff_effects(a: invoke_pb.InstrEffects, b: invoke_pb.InstrEffects):
41+
a_san = invoke_pb.InstrEffects()
42+
a_san.CopyFrom(a)
43+
b_san = invoke_pb.InstrEffects()
44+
b_san.CopyFrom(b)
45+
46+
# If the result is an error (not 0), don't return modified accounts.
47+
if a_san.result != 0:
48+
while len(a_san.modified_accounts) > 0:
49+
a_san.modified_accounts.pop()
50+
if b_san.result != 0:
51+
while len(b_san.modified_accounts) > 0:
52+
b_san.modified_accounts.pop()
53+
54+
# Normalize error codes and cus
55+
a_san.result = 0
56+
a_san.custom_err = 0
57+
a_san.cu_avail = 0
58+
59+
b_san.result = 0
60+
b_san.custom_err = 0
61+
b_san.cu_avail = 0
62+
63+
return a_san == b_san

src/test_suite/multiprocessing_utils.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,8 @@ def build_test_results(
314314
effects = harness_ctx.effects_type()
315315
effects.ParseFromString(result)
316316

317-
if globals.consensus_mode:
318-
harness_ctx.diff_effect_fn = harness_ctx.consensus_diff_effect_fn
319-
320-
# Note: diff_effect_fn may modify effects in-place
321-
all_passed &= harness_ctx.diff_effect_fn(ref_effects, effects)
317+
# Note: apply_diff may modify effects in-place
318+
all_passed &= globals.diff_mode.apply_diff(ref_effects, effects)
322319

323320
harness_ctx.effects_human_encode_fn(effects)
324321
outputs[target] = text_format.MessageToString(effects)

src/test_suite/test_suite.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
extract_context_from_fixture,
1818
write_fixture_to_disk,
1919
)
20+
from test_suite.instr.diff_utils import DiffMode
2021
from test_suite.log_utils import log_results
2122
from test_suite.multiprocessing_utils import (
2223
decode_single_test_case,
@@ -355,6 +356,14 @@ def run_tests(
355356
"-c",
356357
help="Only fail on consensus failures. One such effect is to normalize error codes when comparing results",
357358
),
359+
core_bpf_mode: bool = typer.Option(
360+
False,
361+
"--core-bpf-mode",
362+
"-cb",
363+
help="Deliberately skip known mismatches between BPF programs and builtins, only failing on genuine mimatches. \
364+
For example, builtin programs may throw errors on readonly account state violations sooner than BPF programs, \
365+
compute unit usage will be different, etc. This feature is primarily used to test a BPF program against a builtin.",
366+
),
358367
failures_only: bool = typer.Option(
359368
False,
360369
"--failures-only",
@@ -388,8 +397,19 @@ def run_tests(
388397
globals.reference_shared_library = reference_shared_library
389398
globals.default_harness_ctx = HARNESS_MAP[default_harness_ctx]
390399

391-
# Set diff mode to consensus if specified
392-
globals.consensus_mode = consensus_mode
400+
# Set diff mode if specified
401+
if consensus_mode and core_bpf_mode:
402+
typer.echo(
403+
"Error: --consensus-mode and --core-bpf-mode cannot be used together.",
404+
err=True,
405+
)
406+
raise typer.Exit(code=1)
407+
if consensus_mode:
408+
globals.diff_mode = DiffMode.CONSENSUS
409+
elif core_bpf_mode:
410+
globals.diff_mode = DiffMode.CORE_BPF
411+
else:
412+
globals.diff_mode = DIffMode.STANDARD
393413

394414
# Create the output directory, if necessary
395415
if globals.output_dir.exists():
@@ -703,6 +723,7 @@ def debug_mismatches(
703723
log_chunk_size=10000,
704724
verbose=True,
705725
consensus_mode=False,
726+
core_bpf_mode=False,
706727
failures_only=False,
707728
save_failures=True,
708729
save_successes=True,

0 commit comments

Comments
 (0)