Skip to content

Commit 53e2a8f

Browse files
create-env
1 parent 57b1cd3 commit 53e2a8f

File tree

2 files changed

+183
-1
lines changed

2 files changed

+183
-1
lines changed

commands.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ $ solana-test-suite [OPTIONS] COMMAND [ARGS]...
1616

1717
**Commands**:
1818

19+
* `create-env`: Set up environment for debugging a...
1920
* `create-fixtures`: Create test fixtures from a directory of...
2021
* `debug-mismatches`: Run tests on a set of targets with a list...
2122
* `decode-protobufs`: Convert Context and/or Fixture messages to...
@@ -27,6 +28,33 @@ $ solana-test-suite [OPTIONS] COMMAND [ARGS]...
2728
* `regenerate-fixtures`: Regenerate Fixture messages by checking...
2829
* `run-tests`: Run tests on a set of targets with a...
2930

31+
## `solana-test-suite create-env`
32+
33+
Set up environment for debugging a mismatch from FuzzCorp
34+
35+
**Usage**:
36+
37+
```console
38+
$ solana-test-suite create-env [OPTIONS]
39+
```
40+
41+
**Options**:
42+
43+
* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: impl/lib/libsolfuzz_agave_v2.0.so]
44+
* `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness]
45+
* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: impl/lib/libsolfuzz_firedancer.so]
46+
* `-o, --output-dir PATH`: Output directory for messages [default: debug_mismatch]
47+
* `-u, --repro-urls TEXT`: Comma-delimited list of FuzzCorp mismatch links
48+
* `-n, --section-names TEXT`: Comma-delimited list of FuzzCorp section names
49+
* `-f, --fuzzcorp-url TEXT`: Comma-delimited list of FuzzCorp section names [default: https://api.dev.fuzzcorp.asymmetric.re/uglyweb/firedancer-io/solfuzz/bugs/]
50+
* `-l, --log-level INTEGER`: FD logging level [default: 5]
51+
* `-r, --randomize-output-buffer`: Randomizes bytes in output buffer before shared library execution
52+
* `-p, --num-processes INTEGER`: Number of processes to use [default: 4]
53+
* `-l, --section-limit INTEGER`: Limit number of fixture per section [default: 0]
54+
* `-fd, --firedancer-repo PATH`: Path to firedancer repository
55+
* `-tv, --test-vectors-repo PATH`: Path to test-vectors repository
56+
* `--help`: Show this message and exit.
57+
3058
## `solana-test-suite create-fixtures`
3159

3260
Create test fixtures from a directory of Context and/or Fixture messages.

src/test_suite/test_suite.py

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,8 @@ def run_tests(
483483
):
484484
print(f"Diff between {name1} and {name2}: vimdiff {file1} {file2}")
485485

486+
return (failed == 0) and (skipped == 0) and (passed > 0)
487+
486488

487489
@app.command(help=f"Convert Context and/or Fixture messages to human-readable format.")
488490
def decode_protobufs(
@@ -711,7 +713,7 @@ def debug_mismatches(
711713
):
712714
os.remove(files[j])
713715

714-
run_tests(
716+
return run_tests(
715717
input=globals.inputs_dir,
716718
reference_shared_library=reference_shared_library,
717719
default_harness_ctx=default_harness_ctx,
@@ -1033,5 +1035,157 @@ def exec_fixtures(
10331035
print(f"Skipped tests: {skipped_tests}")
10341036

10351037

1038+
@app.command(
1039+
help=f"""
1040+
Set up environment for debugging a mismatch from FuzzCorp
1041+
"""
1042+
)
1043+
def create_env(
1044+
reference_shared_library: Path = typer.Option(
1045+
Path(os.getenv("SOLFUZZ_TARGET", "impl/lib/libsolfuzz_agave_v2.0.so")),
1046+
"--solana-target",
1047+
"-s",
1048+
help="Solana (or ground truth) shared object (.so) target file path",
1049+
),
1050+
default_harness_ctx: str = typer.Option(
1051+
"InstrHarness",
1052+
"--default-harness-type",
1053+
"-h",
1054+
help=f"Harness type to use for Context protobufs",
1055+
),
1056+
shared_libraries: List[Path] = typer.Option(
1057+
[Path(os.getenv("FIREDANCER_TARGET", "impl/lib/libsolfuzz_firedancer.so"))],
1058+
"--target",
1059+
"-t",
1060+
help="Shared object (.so) target file paths (pairs with --keep-passing)."
1061+
f" Targets must have required function entrypoints defined",
1062+
),
1063+
output_dir: Path = typer.Option(
1064+
Path("debug_mismatch"),
1065+
"--output-dir",
1066+
"-o",
1067+
help=f"Output directory for messages",
1068+
),
1069+
repro_urls: str = typer.Option(
1070+
"", "--repro-urls", "-u", help="Comma-delimited list of FuzzCorp mismatch links"
1071+
),
1072+
section_names: str = typer.Option(
1073+
"",
1074+
"--section-names",
1075+
"-n",
1076+
help="Comma-delimited list of FuzzCorp section names",
1077+
),
1078+
fuzzcorp_url: str = typer.Option(
1079+
os.getenv(
1080+
"FUZZCORP_URL",
1081+
"https://api.dev.fuzzcorp.asymmetric.re/uglyweb/firedancer-io/solfuzz/bugs/",
1082+
),
1083+
"--fuzzcorp-url",
1084+
"-f",
1085+
help="Comma-delimited list of FuzzCorp section names",
1086+
),
1087+
log_level: int = typer.Option(
1088+
5,
1089+
"--log-level",
1090+
"-l",
1091+
help="FD logging level",
1092+
),
1093+
randomize_output_buffer: bool = typer.Option(
1094+
False,
1095+
"--randomize-output-buffer",
1096+
"-r",
1097+
help="Randomizes bytes in output buffer before shared library execution",
1098+
),
1099+
num_processes: int = typer.Option(
1100+
4, "--num-processes", "-p", help="Number of processes to use"
1101+
),
1102+
section_limit: int = typer.Option(
1103+
0, "--section-limit", "-l", help="Limit number of fixture per section"
1104+
),
1105+
firedancer_repo_path: Path = typer.Option(
1106+
os.getenv("FIREDANCER_DIR"),
1107+
"--firedancer-repo",
1108+
"-fd",
1109+
help="Path to firedancer repository",
1110+
),
1111+
test_vectors_repos_path: Path = typer.Option(
1112+
os.getenv("TEST_VECTORS_DIR"),
1113+
"--test-vectors-repo",
1114+
"-tv",
1115+
help="Path to test-vectors repository",
1116+
),
1117+
):
1118+
lists = [
1119+
f"{file.parent.name}/{file.name}"
1120+
for file in firedancer_repo_path.glob(
1121+
"contrib/test/test-vectors-fixtures/*fixtures*/*list"
1122+
)
1123+
]
1124+
1125+
max_width = max(len(option) for option in lists) + 2
1126+
1127+
print("Select correct list for mismatch:")
1128+
for i, option in enumerate(lists, start=1):
1129+
print(f"{i}. {option}".ljust(max_width), end="\t")
1130+
if i % 4 == 0:
1131+
print()
1132+
1133+
if len(lists) % 4 != 0:
1134+
print()
1135+
1136+
while True:
1137+
try:
1138+
choice = int(input("Enter the list of your choice: "))
1139+
if 1 <= choice <= len(lists):
1140+
selected_option = lists[choice - 1]
1141+
break
1142+
else:
1143+
print(f"Please enter a number between 1 and {len(lists)}.")
1144+
except ValueError:
1145+
print("Invalid input. Please enter a number.")
1146+
1147+
print(f"Adding fixture to: {selected_option}")
1148+
list_path = glob(
1149+
str(firedancer_repo_path)
1150+
+ f"/contrib/test/test-vectors-fixtures/{selected_option}"
1151+
)[0]
1152+
1153+
passed = debug_mismatches(
1154+
reference_shared_library=reference_shared_library,
1155+
default_harness_ctx=default_harness_ctx,
1156+
shared_libraries=shared_libraries,
1157+
output_dir=output_dir,
1158+
repro_urls=repro_urls,
1159+
section_names=section_names,
1160+
fuzzcorp_url=fuzzcorp_url,
1161+
log_level=log_level,
1162+
randomize_output_buffer=randomize_output_buffer,
1163+
num_processes=num_processes,
1164+
section_limit=section_limit,
1165+
)
1166+
1167+
if passed:
1168+
print("All fixtures already pass")
1169+
typer.Exit(code=1)
1170+
1171+
failures = glob(str(output_dir) + "/test_results/failed_protobufs/*")
1172+
1173+
for failure in failures:
1174+
with open(list_path, "r") as file:
1175+
lines = file.readlines()
1176+
1177+
last_line = lines[-1].strip()
1178+
1179+
failure_path = os.path.dirname(last_line) + "/" + os.path.basename(failure)
1180+
with open(list_path, "a") as file:
1181+
file.write(failure_path + "\n")
1182+
print(f"\nAdded {os.path.basename(failure)} to {list_path}")
1183+
1184+
failure_test_vector_path = failure_path.replace(
1185+
"dump/test-vectors", str(test_vectors_repos_path)
1186+
)
1187+
shutil.copy2(failure, os.path.dirname(failure_test_vector_path))
1188+
1189+
10361190
if __name__ == "__main__":
10371191
app()

0 commit comments

Comments
 (0)