gnd(test): Add mock-based subgraph test runner#6361
Draft
dimitrovmaksim wants to merge 29 commits intographprotocol:masterfrom
Draft
gnd(test): Add mock-based subgraph test runner#6361dimitrovmaksim wants to merge 29 commits intographprotocol:masterfrom
dimitrovmaksim wants to merge 29 commits intographprotocol:masterfrom
Conversation
3ae7b01 to
1a978ee
Compare
Replaces monolithic gnd/src/commands/test.rs with organized test/ directory containing: - mod.rs: Main entry point and test orchestration - runner.rs: Test execution and infrastructure setup - assertion.rs: GraphQL assertion logic - block_stream.rs: Mock block stream implementation - noop.rs: Stub trait implementations - schema.rs: JSON schema and test types - trigger.rs: ABI encoding for test triggers - output.rs: Test result formatting - mock_chain.rs: Block pointer helpers Updates main.rs to make Test command async (.await). Adds dependencies for test runner (graph-chain-ethereum, graph-graphql, graph-store-postgres).
Adds supporting modules for test infrastructure: - mock_chain: Helpers for block pointer construction - schema: JSON schema types and parsing - output: Console output formatting - trigger: ABI encoding of test triggers
Adds module declarations for refactored components: - mod assertion - mod block_stream - mod noop Updates module documentation to reflect the new structure and improved separation of concerns.
Removes ~500 lines from runner.rs by delegating to new focused modules: - block_stream: Mock block delivery infrastructure - noop: Stub trait implementations - assertion: GraphQL assertion logic runner.rs now focuses exclusively on test orchestration: - setup_stores: Initialize PostgreSQL and chain store - setup_chain: Construct mock Ethereum chain - setup_context: Wire up graph-node components - wait_for_sync: Poll store until indexing completes Reduced from 1198 to 729 lines (39% reduction). Improves readability by separating concerns.
Moves assertion execution to gnd/src/commands/test/assertion.rs: - run_assertions: Execute all test assertions - run_single_assertion: Execute and compare a single query - r_value_to_json: Convert graph-node's r::Value to serde_json - json_equal: Compare JSON with string-vs-number coercion Makes TestContext fields pub(super) to allow assertion module access.
Moves unused adapter stubs to gnd/src/commands/test/noop.rs: - StaticBlockRefetcher - NoopRuntimeAdapter / NoopRuntimeAdapterBuilder - NoopAdapterSelector - NoopTriggersAdapter These satisfy Chain constructor trait bounds but are never called during normal test execution since triggers are pre-built and host functions are not available in mocks.
- Add baseFeePerGas field to TestBlock schema - Parse and apply base fee when creating test blocks - Replace graph-node helper functions with direct alloy types - Extract dummy_transaction creation into dedicated function - Use alloy Block::empty() constructor for cleaner block creation
- Rename 'triggers' field to 'events' in TestBlock - Remove TestTrigger enum and BlockTrigger type - Keep LogEvent as the only event type users specify - Auto-inject Start and End block triggers for every block - This ensures block handlers fire correctly without explicit config - Update docs to reflect that block triggers are automatic
- Extract min startBlock from manifest in extract_start_block_from_manifest() - Use startBlock as default test block numbering base - Create start_block_override to bypass on-chain validation - Pass override through setup_context() to SubgraphRegistrar - This allows testing subgraphs that specify startBlock without needing a real chain
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
- Replace positional `manifest` arg with `--manifest` / `-m` flag (default: subgraph.yaml) - Add positional `tests` args accepting file or directory - When no args given, default to scanning `tests/` - Bare filenames resolve to `tests/<filename>` for convenience (e.g., `gnd test foo.json` → `tests/foo.json`) - Remove `--test-dir` flag (replaced by positional args) - Update README with new usage examples Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
…ersion
- Add Array, FixedArray, Tuple branches to json_to_sol_value
- Fix strip_prefix("0x") usage (trim_start_matches incorrectly strips repeated 0s)
- Fix i64::MIN two's complement handling via I256::into_raw()
- Add block number overflow check against i32::MAX
- discover_test_files now walks subdirectories recursively - Skip entries starting with non-alphanumeric chars (.hidden, _fixture)
Add upfront arity checks in encode_function_call and encode_return_value so mismatches produce clear errors instead of silently truncating. Also simplify redundant .with_context() wrappers in populate_single_call.
- Remove FilterStoreEventEndedDrain log filter and unused logger field - Always call stop_subgraph after test, even on error - Warn when a test has blocks but no assertions - Add block number overflow check against i32::MAX
…ker mode Add alphanumeric/hyphen/underscore validation before interpolating the datasource name into Docker's sh -c command. Also simplify redundant .with_context() wrappers.
- block_stream: .unwrap() -> .expect() on mutex lock - noop: unimplemented!() -> Err(anyhow!(...)) - mod: Fail early with bail! on missing test file
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
1a978ee to
68169a2
Compare
Add `-v` / `--verbose` flag with count semantics for controlling graph-node log verbosity during tests (-v=info, -vv=debug, -vvv=trace). GRAPH_LOG env var always takes precedence when set. Extract manifest loading into `ManifestInfo` struct loaded once per run, avoiding redundant parsing across tests. Thread a single logger through setup_stores/setup_chain instead of creating ad-hoc loggers.
Add gnd_test integration test suite with fixture subgraph and test
cases for blocks, transfers, templates, and expected failures. Fix
pgtemp Unix socket path overflow on macOS by overriding
unix_socket_directories to /tmp. Reduce default pool_size to 2.
5669e90 to
739a649
Compare
2013849 to
4e1111b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements a native test runner for
gnd testthat executes JSON-defined tests through real graph-node infrastructure (store, WASM runtime, trigger processing) with only the blockchain layer mocked. Provides a faster, integrated alternative to Matchstick while maintaining backward compatibility.Key Features
once,polling, no filter)--matchstickflag preserves legacy behaviorArchitecture
Design decisions:
StaticStreamBuilder)Usage
Test Format Example
{ "name": "Transfer creates entity", "blocks": [ { "number": 1, "events": [ { "address": "0x1234...", "event": "Transfer(address indexed from, address indexed to, uint256 value)", "params": {"from": "0xaaaa...", "to": "0xbbbb...", "value": "1000"} } ], "ethCalls": [ { "address": "0x1234...", "function": "balanceOf(address)(uint256)", "params": ["0xaaaa..."], "returns": ["1000000000000000000"] } ] } ], "assertions": [ { "query": "{ transfer(id: \"1\") { from to value } }", "expected": {"transfer": {"from": "0xaaaa...", "to": "0xbbbb...", "value": "1000"}} } ] }Implementation
Modified Graph-Node Files
graph/src/data_source/subgraph.rs- Minor exports for startBlock supportSupported Features
once,polling, no filter)call)Breaking Changes
None. Adds native testing while preserving
--matchstickfor backward compatibility.Code Attribution
Human contributions: Initial requirements, code review, validation, and bug fixes.
Future Work
--jsonCI output format--filter)Checklist
--matchstickcall)