From 2e11eb25e2729cf7b4725a5083910db3e17a336b Mon Sep 17 00:00:00 2001 From: Kunal Bhargava Date: Tue, 22 Oct 2024 18:21:02 +0000 Subject: [PATCH] changes --- .gitignore | 2 +- commands.md | 79 ++++++------- src/test_suite/debugger.py | 79 ------------- src/test_suite/multiprocessing_utils.py | 41 ++++--- src/test_suite/test_suite.py | 141 ++++++++++-------------- 5 files changed, 116 insertions(+), 226 deletions(-) delete mode 100644 src/test_suite/debugger.py diff --git a/.gitignore b/.gitignore index f2e35a2..80f06e3 100644 --- a/.gitignore +++ b/.gitignore @@ -167,4 +167,4 @@ cython_debug/ scratch/ # protosol -protosol/ \ No newline at end of file +protosol/ diff --git a/commands.md b/commands.md index bcd5c89..66ecf3a 100644 --- a/commands.md +++ b/commands.md @@ -17,20 +17,19 @@ $ solana-test-suite [OPTIONS] COMMAND [ARGS]... **Commands**: * `create-fixtures`: Create test fixtures from a directory of... -* `debug-instr` * `debug-mismatches`: Run tests on a set of targets with a list... * `debug-non-repros`: Run tests on a set of targets with a list... -* `decode-protobuf`: Convert messages to human-readable format. -* `exec-instr`: Execute message(s) and print the effects. -* `instr-from-fixtures`: Extract messages from fixtures. +* `decode-protobufs`: Convert Context and/or Fixture messages to... +* `execute`: Execute Context or Fixture message(s) and... +* `fix-to-ctx`: Extract Context messages from Fixtures. * `list-harness-types`: List harness types available for use. * `regenerate-all-fixtures`: Regenerate all fixtures in provided... -* `regenerate-fixtures`: Regenerate messages by checking FeatureSet... +* `regenerate-fixtures`: Regenerate Fixture messages by checking... * `run-tests`: Run tests on a set of targets with a... ## `solana-test-suite create-fixtures` -Create test fixtures from a directory of messages. +Create test fixtures from a directory of Context and/or Fixture messages. Effects are generated by the target passed in with --solana-target or -s. You can also pass in additional targets with --target or -t and use --keep-passing or -k to only generate effects for test cases that match. @@ -43,10 +42,10 @@ $ solana-test-suite create-fixtures [OPTIONS] **Options**: -* `-i, --input-dir PATH`: Either a file or directory containing messages [default: corpus8] -* `-h, --default-harness-type TEXT`: Harness type to use for context protobufs [default: InstrHarness] +* `-i, --input PATH`: Input protobuf file or directory of protobuf files [default: corpus8] +* `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] * `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] -* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have defined +* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined * `-o, --output-dir PATH`: Output directory for fixtures [default: test_fixtures] * `-p, --num-processes INTEGER`: Number of processes to use [default: 4] * `-r, --readable`: Output fixtures in human-readable format @@ -54,22 +53,6 @@ $ solana-test-suite create-fixtures [OPTIONS] * `-g, --group-by-program`: Group fixture output by program type * `--help`: Show this message and exit. -## `solana-test-suite debug-instr` - -**Usage**: - -```console -$ solana-test-suite debug-instr [OPTIONS] -``` - -**Options**: - -* `-i, --input PATH`: Input file -* `-t, --target PATH`: Shared object (.so) target file path to debug [default: impl/lib/libsolfuzz_firedancer.so] -* `-d, --debugger TEXT`: Debugger to use (gdb, rust-gdb) [default: gdb] -* `-h, --default-harness-type TEXT`: Harness type to use for context protobufs [default: InstrHarness] -* `--help`: Show this message and exit. - ## `solana-test-suite debug-mismatches` Run tests on a set of targets with a list of FuzzCorp mismatch links. @@ -85,7 +68,7 @@ $ solana-test-suite debug-mismatches [OPTIONS] **Options**: * `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] -* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have defined [default: /home/kbhargava/repos/firedancer/build/native/gcc/lib/libfd_exec_sol_compat.so] +* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: /home/kbhargava/repos/firedancer/build/native/gcc/lib/libfd_exec_sol_compat.so] * `-o, --output-dir PATH`: Output directory for messages [default: debug_mismatch] * `-u, --repro-urls TEXT`: Comma-delimited list of FuzzCorp mismatch links * `-s, --section-names TEXT`: Comma-delimited list of FuzzCorp section names @@ -107,61 +90,62 @@ $ solana-test-suite debug-non-repros [OPTIONS] **Options**: * `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] -* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have defined [default: /home/kbhargava/repos/firedancer/build/native/gcc/lib/libfd_exec_sol_compat.so] +* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: /home/kbhargava/repos/firedancer/build/native/gcc/lib/libfd_exec_sol_compat.so] * `-o, --output-dir PATH`: Output directory for messages [default: debug_mismatch] * `-u, --repro-urls TEXT`: Comma-delimited list of FuzzCorp mismatch links * `-s, --section-names TEXT`: Comma-delimited list of FuzzCorp section names * `-f, --fuzzcorp-url TEXT`: Comma-delimited list of FuzzCorp section names [default: https://api.dev.fuzzcorp.asymmetric.re/uglyweb/firedancer-io/solfuzz/bugs/] * `--help`: Show this message and exit. -## `solana-test-suite decode-protobuf` +## `solana-test-suite decode-protobufs` -Convert messages to human-readable format. +Convert Context and/or Fixture messages to human-readable format. **Usage**: ```console -$ solana-test-suite decode-protobuf [OPTIONS] +$ solana-test-suite decode-protobufs [OPTIONS] ``` **Options**: -* `-i, --input PATH`: Either a message or directory of messages [default: raw_context] -* `-o, --output-dir PATH`: Output directory for base58-encoded, human-readable messages [default: readable_context] +* `-i, --input PATH`: Input protobuf file or directory of protobuf files [default: raw_context] +* `-o, --output-dir PATH`: Output directory for base58-encoded, Context and/or Fixture human-readable messages [default: readable_context] * `-p, --num-processes INTEGER`: Number of processes to use [default: 4] -* `-h, --default-harness-type TEXT`: Harness type to use for context protobufs [default: InstrHarness] +* `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] * `--help`: Show this message and exit. -## `solana-test-suite exec-instr` +## `solana-test-suite execute` -Execute message(s) and print the effects. +Execute Context or Fixture message(s) and print the Effects. **Usage**: ```console -$ solana-test-suite exec-instr [OPTIONS] +$ solana-test-suite execute [OPTIONS] ``` **Options**: -* `-i, --input PATH`: Input file or directory of files +* `-i, --input PATH`: Input protobuf file or directory of protobuf files +* `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] * `-t, --target PATH`: Shared object (.so) target file path to execute [default: impl/firedancer/build/native/clang/lib/libfd_exec_sol_compat.so] * `-r, --randomize-output-buffer`: Randomizes bytes in output buffer before shared library execution * `--help`: Show this message and exit. -## `solana-test-suite instr-from-fixtures` +## `solana-test-suite fix-to-ctx` -Extract messages from fixtures. +Extract Context messages from Fixtures. **Usage**: ```console -$ solana-test-suite instr-from-fixtures [OPTIONS] +$ solana-test-suite fix-to-ctx [OPTIONS] ``` **Options**: -* `-i, --input-dir PATH`: Input directory containing messages [default: fixtures] +* `-i, --input PATH`: Input Fixture file or directory of Fixture files [default: fixtures] * `-o, --output-dir PATH`: Output directory for messages [default: instr] * `-p, --num-processes INTEGER`: Number of processes to use [default: 4] * `--help`: Show this message and exit. @@ -192,7 +176,7 @@ $ solana-test-suite regenerate-all-fixtures [OPTIONS] **Options**: -* `-i, --input-dir PATH`: Input test-vectors directory [default: corpus8] +* `-i, --input PATH`: Input test-vectors directory [default: corpus8] * `-o, --output-dir PATH`: Output directory for regenerated fixtures [default: /tmp/regenerated_fixtures] * `-t, --target PATH`: Shared object (.so) target file path to execute [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] * `-s, --stubbed-target PATH`: Stubbed shared object (.so) target file path to execute [default: /home/kbhargava/repos/solfuzz-agave/target/x86_64-unknown-linux-gnu/release/libsolfuzz_agave_stubbed.so] @@ -200,8 +184,7 @@ $ solana-test-suite regenerate-all-fixtures [OPTIONS] ## `solana-test-suite regenerate-fixtures` -Regenerate messages by -checking FeatureSet compatibility with the target shared library. +Regenerate Fixture messages by checking FeatureSet compatibility with the target shared library. **Usage**: @@ -211,7 +194,7 @@ $ solana-test-suite regenerate-fixtures [OPTIONS] **Options**: -* `-i, --input-dir PATH`: Either a file or directory containing messages [default: corpus8] +* `-i, --input PATH`: Either a file or directory containing messages [default: corpus8] * `-t, --target PATH`: Shared object (.so) target file path to execute [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] * `-o, --output-dir PATH`: Output directory for regenerated fixtures [default: regenerated_fixtures] * `-d, --dry-run`: Only print the fixtures that would be regenerated @@ -220,8 +203,7 @@ $ solana-test-suite regenerate-fixtures [OPTIONS] ## `solana-test-suite run-tests` -Run tests on a set of targets with a directory of -or messages. +Run tests on a set of targets with a directory of Context and/or Fixture messages. Note: each `.so` target filename must be unique. @@ -233,7 +215,8 @@ $ solana-test-suite run-tests [OPTIONS] **Options**: -* `-i, --input PATH`: Single input file or input directory containing or messages [default: corpus8] +* `-i, --input PATH`: Input protobuf file or directory of protobuf files [default: corpus8] +* `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] * `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /home/kbhargava/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] * `-t, --target PATH`: Shared object (.so) target file paths [default: /home/kbhargava/repos/firedancer/build/native/gcc/lib/libfd_exec_sol_compat.so] * `-o, --output-dir PATH`: Output directory for test results [default: test_results] diff --git a/src/test_suite/debugger.py b/src/test_suite/debugger.py deleted file mode 100644 index b7abaa8..0000000 --- a/src/test_suite/debugger.py +++ /dev/null @@ -1,79 +0,0 @@ -import ctypes -import multiprocessing -from multiprocessing import Pipe -import signal -import subprocess -import os -from test_suite.multiprocessing_utils import ( - initialize_process_output_buffers, - process_target, -) -import test_suite.globals as globals - - -def debug_target(shared_library, test_input, pipe): - initialize_process_output_buffers() - - # Signal to parent that we are ready for the debugger - pipe.send("started") - - # Suspend self so the debugger has time to attach - os.kill(os.getpid(), signal.SIGSTOP) - # ... at this point, the debugger has sent us a SIGCONT signal, - # is watching any dlopen() call and has set breakpoints - - lib = ctypes.CDLL(shared_library) - lib.sol_compat_init() - process_target(lib, test_input) - lib.sol_compat_fini() - - -def debug_host(harness_ctx, shared_library, instruction_context, gdb): - # Sets up the following debug environment: - # - # +-------------------------------+ - # | Main Python Process | - # | (this function) | - # | | - # | +-----------------------+ | - # | | Child Python Process | | - # | | (With sol_compat lib) | | - # | +-----------------------+ | - # | /\ Attached to | - # | +-----------------------+ | - # | | Debugger Process | | - # | +-----------------------+ | - # | | - # +-------------------------------+ - - # Spawn the Python interpreter - pipe, child_pipe = Pipe() - target = multiprocessing.Process( - target=debug_target, args=(shared_library, instruction_context, child_pipe) - ) - target.start() - # Wait for a signal that the child process is ready - assert pipe.recv() == "started" - - commands = [ - # Skip loading Python interpreter libraries, as those are not interesting - "set auto-solib-add off", - # Attach to the debug target Python process - f"attach {target.pid}", - # As soon as the target library gets loaded, set a breakpoint - # for the newly appeared executor function - "set breakpoint pending on", - f"break {harness_ctx.fuzz_fn_name}", - # GDB stops the process when attaching, let it continue - "continue", - # ... At this point, the child process has SIGSTOP'ed itself - "set auto-solib-add on", - # Continue it - "signal SIGCONT", - # ... At this point, the child process has dlopen()ed the - # target library and the breakpoint was hit - "layout src", - ] - invoke = [gdb, "-q"] + ["--eval-command=" + cmd for cmd in commands] - print(f"Running {' '.join(invoke)}") - subprocess.run(invoke) diff --git a/src/test_suite/multiprocessing_utils.py b/src/test_suite/multiprocessing_utils.py index ca71b3f..0a7a21f 100644 --- a/src/test_suite/multiprocessing_utils.py +++ b/src/test_suite/multiprocessing_utils.py @@ -61,7 +61,7 @@ def process_target( def read_context_serialized(harness_ctx: HarnessCtx, test_file: Path) -> str | None: """ - Reads in test files and generates an InstrContext Protobuf object for a test case. + Reads in test files and generates an Context Protobuf object for a test case. Args: - test_file (Path): Path to the instruction context message. @@ -197,7 +197,7 @@ def read_fixture(fixture_file: Path) -> message.Message | None: return fixture -def decode_single_test_case(harness_ctx: HarnessCtx, test_file: Path) -> int: +def decode_single_test_case(test_file: Path) -> int: """ Decode a single test case into a human-readable message @@ -207,21 +207,34 @@ def decode_single_test_case(harness_ctx: HarnessCtx, test_file: Path) -> int: Returns: - int: 1 if successfully decoded and written, 0 if skipped. """ - serialized_instruction_context = read_context_serialized(harness_ctx, test_file) + if test_file.suffix == ".fix": + fn_entrypoint = extract_metadata(test_file).fn_entrypoint + harness_ctx = HARNESS_ENTRYPOINT_MAP[fn_entrypoint] + serialized_protobuf = read_fixture_serialized(test_file) + else: + harness_ctx = globals.default_harness_ctx + serialized_protobuf = read_context_serialized(harness_ctx, test_file) # Skip if input is invalid - if serialized_instruction_context is None: + if serialized_protobuf is None: return 0 # Encode the input fields to be human readable - instruction_context = harness_ctx.context_type() - instruction_context.ParseFromString(serialized_instruction_context) - harness_ctx.context_human_encode_fn(instruction_context) + if test_file.suffix == ".fix": + output = harness_ctx.fixture_type() + else: + output = harness_ctx.context_type() + + output.ParseFromString(serialized_protobuf) + + if test_file.suffix == ".fix": + harness_ctx.context_human_encode_fn(output.input) + harness_ctx.effects_human_encode_fn(output.output) + else: + harness_ctx.context_human_encode_fn(output) with open(globals.output_dir / (test_file.stem + ".txt"), "w") as f: - f.write( - text_format.MessageToString(instruction_context, print_unknown_fields=False) - ) + f.write(text_format.MessageToString(output, print_unknown_fields=False)) return 1 @@ -246,7 +259,6 @@ def process_single_test_case( # Execute test case on each target library results = {} for target in globals.target_libraries: - print(f"Processing {target}...") instruction_effects = process_target( harness_ctx, globals.target_libraries[target], @@ -392,8 +404,11 @@ def run_test(test_file: Path) -> tuple[str, int, dict | None]: - Dictionary of target library names and file-dumpable serialized instruction effects """ # Process fixtures through this entrypoint as well - fn_entrypoint = extract_metadata(test_file).fn_entrypoint - harness_ctx = HARNESS_ENTRYPOINT_MAP[fn_entrypoint] + if test_file.suffix == ".fix": + fn_entrypoint = extract_metadata(test_file).fn_entrypoint + harness_ctx = HARNESS_ENTRYPOINT_MAP[fn_entrypoint] + else: + harness_ctx = globals.default_harness_ctx context = serialize_context(harness_ctx, test_file) results = process_single_test_case(harness_ctx, context) pruned_results = harness_ctx.prune_effects_fn(harness_ctx, context, results) diff --git a/src/test_suite/test_suite.py b/src/test_suite/test_suite.py index 5a0cce3..c1e3381 100644 --- a/src/test_suite/test_suite.py +++ b/src/test_suite/test_suite.py @@ -19,15 +19,12 @@ decode_single_test_case, extract_metadata, read_fixture, - read_context_serialized, initialize_process_output_buffers, - process_single_test_case, process_target, run_test, serialize_context, ) import test_suite.globals as globals -from test_suite.debugger import debug_host from test_suite.util import set_ld_preload_asan import resource import tqdm @@ -52,13 +49,19 @@ app = typer.Typer(help=f"Validate effects from clients using Protobuf messages.") -@app.command(help=f"Execute message(s) and print the effects.") -def exec_instr( - file_or_dir: Path = typer.Option( +@app.command(help=f"Execute Context or Fixture message(s) and print the Effects.") +def execute( + input: Path = typer.Option( None, "--input", "-i", - help=f"Input file or directory of files", + help=f"Input protobuf file or directory of protobuf files", + ), + default_harness_ctx: str = typer.Option( + "InstrHarness", + "--default-harness-type", + "-h", + help=f"Harness type to use for Context protobufs", ), shared_library: Path = typer.Option( Path("impl/firedancer/build/native/clang/lib/libfd_exec_sol_compat.so"), @@ -83,12 +86,14 @@ def exec_instr( except: set_ld_preload_asan() - files_to_exec = file_or_dir.iterdir() if file_or_dir.is_dir() else [file_or_dir] + files_to_exec = input.iterdir() if input.is_dir() else [input] for file in files_to_exec: print(f"Handling {file}...") - - fn_entrypoint = extract_metadata(file).fn_entrypoint - harness_ctx = HARNESS_ENTRYPOINT_MAP[fn_entrypoint] + if file.suffix == ".fix": + fn_entrypoint = extract_metadata(file).fn_entrypoint + harness_ctx = HARNESS_ENTRYPOINT_MAP[fn_entrypoint] + else: + harness_ctx = eval(default_harness_ctx) # Execute and cleanup context = serialize_context(harness_ctx, file) @@ -123,44 +128,13 @@ def exec_instr( lib.sol_compat_fini() -@app.command() -def debug_instr( - file: Path = typer.Option(None, "--input", "-i", help="Input file"), - shared_library: Path = typer.Option( - Path("impl/lib/libsolfuzz_firedancer.so"), - "--target", - "-t", - help="Shared object (.so) target file path to debug", - ), - debugger: str = typer.Option( - "gdb", "--debugger", "-d", help="Debugger to use (gdb, rust-gdb)" - ), - default_harness_ctx: str = typer.Option( - "InstrHarness", - "--default-harness-type", - "-h", - help=f"Harness type to use for context protobufs", - ), -): - print("-" * LOG_FILE_SEPARATOR_LENGTH) - print(f"Processing {file.name}...") - - # Decode the file and pass it into GDB - harness_ctx = eval( - default_harness_ctx - ) # TODO have this programmatically determined - instruction_context = read_context_serialized(harness_ctx, file) - assert instruction_context is not None, f"Unable to read {file.name}" - debug_host(harness_ctx, shared_library, instruction_context, gdb=debugger) - - -@app.command(help=f"Extract messages from fixtures.") -def instr_from_fixtures( - input_dir: Path = typer.Option( +@app.command(help=f"Extract Context messages from Fixtures.") +def fix_to_ctx( + input: Path = typer.Option( Path("fixtures"), - "--input-dir", + "--input", "-i", - help=f"Input directory containing messages", + help=f"Input Fixture file or directory of Fixture files", ), output_dir: Path = typer.Option( Path("instr"), @@ -180,10 +154,10 @@ def instr_from_fixtures( shutil.rmtree(globals.output_dir) globals.output_dir.mkdir(parents=True, exist_ok=True) - test_cases = list(input_dir.iterdir()) + test_cases = input.iterdir() if input.is_dir() else [input] num_test_cases = len(test_cases) - print(f"Converting to...") + print(f"Converting to Fixture messages...") results = [] with Pool(processes=num_processes) as pool: for result in tqdm.tqdm( @@ -199,24 +173,24 @@ def instr_from_fixtures( @app.command( help=f""" - Create test fixtures from a directory of messages. + Create test fixtures from a directory of Context and/or Fixture messages. Effects are generated by the target passed in with --solana-target or -s. You can also pass in additional targets with --target or -t and use --keep-passing or -k to only generate effects for test cases that match. """ ) def create_fixtures( - input_path: Path = typer.Option( + input: Path = typer.Option( Path("corpus8"), - "--input-dir", + "--input", "-i", - help=f"Either a file or directory containing messages", + help=f"Input protobuf file or directory of protobuf files", ), default_harness_ctx: str = typer.Option( "InstrHarness", "--default-harness-type", "-h", - help=f"Harness type to use for context protobufs", + help=f"Harness type to use for Context protobufs", ), reference_shared_library: Path = typer.Option( Path(os.getenv("SOLFUZZ_TARGET", "impl/lib/libsolfuzz_agave_v2.0.so")), @@ -229,7 +203,7 @@ def create_fixtures( "--target", "-t", help="Shared object (.so) target file paths (pairs with --keep-passing)." - f" Targets must have defined", + f" Targets must have required function entrypoints defined", ), output_dir: Path = typer.Option( Path("test_fixtures"), @@ -272,7 +246,7 @@ def create_fixtures( lib.sol_compat_init() globals.target_libraries[target] = lib - test_cases = [input_path] if input_path.is_file() else list(input_path.iterdir()) + test_cases = [input] if input.is_file() else list(input.iterdir()) num_test_cases = len(test_cases) globals.default_harness_ctx = eval(default_harness_ctx) @@ -303,18 +277,23 @@ def create_fixtures( @app.command( help=f""" - Run tests on a set of targets with a directory of - or messages. + Run tests on a set of targets with a directory of Context and/or Fixture messages. Note: each `.so` target filename must be unique. """ ) def run_tests( - file_or_dir: Path = typer.Option( + input: Path = typer.Option( Path("corpus8"), "--input", "-i", - help=f"Single input file or input directory containing" f" or messages", + help=f"Input protobuf file or directory of protobuf files", + ), + default_harness_ctx: str = typer.Option( + "InstrHarness", + "--default-harness-type", + "-h", + help=f"Harness type to use for Context protobufs", ), reference_shared_library: Path = typer.Option( Path(os.getenv("SOLFUZZ_TARGET", "impl/lib/libsolfuzz_agave_v2.0.so")), @@ -377,6 +356,7 @@ def run_tests( # Specify globals globals.output_dir = output_dir globals.reference_shared_library = reference_shared_library + globals.default_harness_ctx = eval(default_harness_ctx) # Set diff mode to consensus if specified globals.consensus_mode = consensus_mode @@ -402,7 +382,7 @@ def run_tests( failed_protobufs_dir = globals.output_dir / "failed_protobufs" failed_protobufs_dir.mkdir(parents=True, exist_ok=True) - test_cases = list(file_or_dir.iterdir()) if file_or_dir.is_dir() else [file_or_dir] + test_cases = list(input.iterdir()) if input.is_dir() else [input] num_test_cases = len(test_cases) # Process the test results in parallel @@ -478,19 +458,19 @@ def run_tests( print("Failures tests are in: ", globals.output_dir / "failed_protobufs") -@app.command(help=f"Convert messages to human-readable format.") -def decode_protobuf( - input_path: Path = typer.Option( +@app.command(help=f"Convert Context and/or Fixture messages to human-readable format.") +def decode_protobufs( + input: Path = typer.Option( Path("raw_context"), "--input", "-i", - help=f"Either a message or directory of messages", + help=f"Input protobuf file or directory of protobuf files", ), output_dir: Path = typer.Option( Path("readable_context"), "--output-dir", "-o", - help=f"Output directory for base58-encoded, human-readable messages", + help=f"Output directory for base58-encoded, Context and/or Fixture human-readable messages", ), num_processes: int = typer.Option( 4, "--num-processes", "-p", help="Number of processes to use" @@ -499,7 +479,7 @@ def decode_protobuf( "InstrHarness", "--default-harness-type", "-h", - help=f"Harness type to use for context protobufs", + help=f"Harness type to use for Context protobufs", ), ): globals.output_dir = output_dir @@ -508,23 +488,15 @@ def decode_protobuf( if globals.output_dir.exists(): shutil.rmtree(globals.output_dir) globals.output_dir.mkdir(parents=True, exist_ok=True) + globals.default_harness_ctx = eval(default_harness_ctx) - harness_type = eval(default_harness_ctx) - - if not input_path.is_dir(): - ok = decode_single_test_case( - harness_type, input_path - ) # TODO: check if we really need harness_type in decode_single_test_case - if not ok: - print(f"Error decoding {input_path}") - return - - num_test_cases = len(list(input_path.iterdir())) + test_cases = list(input.iterdir()) if input.is_dir() else [input] + num_test_cases = len(test_cases) write_results = [] with Pool(processes=num_processes) as pool: for result in tqdm.tqdm( - pool.imap(decode_single_test_case, harness_type, input_path.iterdir()), + pool.imap(decode_single_test_case, test_cases), total=num_test_cases, ): write_results.append(result) @@ -561,7 +533,7 @@ def debug_mismatches( "--target", "-t", help="Shared object (.so) target file paths (pairs with --keep-passing)." - f" Targets must have defined", + f" Targets must have required function entrypoints defined", ), output_dir: Path = typer.Option( Path("debug_mismatch"), @@ -699,7 +671,7 @@ def debug_non_repros( "--target", "-t", help="Shared object (.so) target file paths (pairs with --keep-passing)." - f" Targets must have defined", + f" Targets must have required function entrypoints defined", ), output_dir: Path = typer.Option( Path("debug_mismatch"), @@ -802,14 +774,13 @@ def debug_non_repros( @app.command( help=f""" - Regenerate messages by - checking FeatureSet compatibility with the target shared library. + Regenerate Fixture messages by checking FeatureSet compatibility with the target shared library. """ ) def regenerate_fixtures( input_path: Path = typer.Option( Path("corpus8"), - "--input-dir", + "--input", "-i", help=f"Either a file or directory containing messages", ), @@ -907,7 +878,7 @@ def regenerate_fixtures( def regenerate_all_fixtures( test_vectors: Path = typer.Option( Path("corpus8"), - "--input-dir", + "--input", "-i", help=f"Input test-vectors directory", ),