Processor Test Runbook
What Are We Testing With This?
- Transaction correctness: Ensure that each transaction is processed and stored accurately.
- Schema consistency: Verify that the database schema is correctly set up and maintained throughout the tests.
General Flow
- Prepare testing transactions (refer to prior documentation).
- Update dependencies as needed.
- Import new transactions.
- Write test cases.
- Generate expected database output and validate.
- Merge.
Ensure tests pass whenever there are updates in the processor code.
Prerequisites
- Ensure Docker is running for PostgreSQL container support.
- Identify the transactions to test.
- Import necessary modules, see example:
use aptos_indexer_testing_framework::{ database::{PostgresTestDatabase, TestDatabase}, sdk_test_context::SdkTestContext, };
💡 Key Considerations:
- Each test runs in an isolated environment using a PostgreSQL container to prevent interference.
- Proper handling of versions ensures transactions are processed and validated in the correct order.
- Validation logic must detect changes or issues by comparing processor output with the expected baseline.
Steps to Write a Test
1. Set Up the Test Environment
let (diff_flag, custom_output_path) = get_test_config();
let output_path = custom_output_path.unwrap_or_else(|| format!("{}/imported_mainnet_txns", DEFAULT_OUTPUT_FOLDER));
// Replace with your test transaction
let (db, mut test_context) = setup_test_environment(&[IMPORTED_MAINNET_TXNS_438536688_ANS_CURRENT_ANS_LOOKUP_V2]).await;
2. Configure the Processor
let db_url = db.get_db_url();
let (indexer_processor_config, processor_name) =
setup_ans_processor_config(&test_context, &db_url);
3. Create the Processor
let processor = DefaultProcessor::new(indexer_processor_config)
.await
.expect("Failed to create processor");
4. Query the Databasefaw
Set up a query to load data from the local database and compare it with expected results.
5. Run the Processor Test
#[derive(Debug, Clone)]
pub struct TestArgs {
pub generate_output: bool,
pub output_path: Option<String>,
}
Run the processor and verify the outputs using SdkTestContext.run
.
Tips
- Isolate Tests: Use Docker containers for database isolation.
- Handle Non-Deterministic Fields: Use helpers like
remove_inserted_at
to clean up timestamps before validation. - Enable Debugging: Use
eprintln!
for detailed error logging.
FAQ
What Types of Tests Does It Support?
- Database (PostgreSQL) schema output diff.
How Does It Work?
Step-by-Step Flow:
- Setup Test Configuration: Define the parameters in the CLI command.
- Specify Transactions to Import: List the transactions to test.
- Initialize the Test Environment: Set up the test database and context.
- Optional - Deserialize Transactions: Convert transactions into
Transaction
structs for processing. - Configure the Processor: Define the database URL and processor settings.
- Run the Processor Test: Execute the processor and validate correctness.
What Is TestContext
?
TestContext
is a struct that manages:
transaction_batches
: A collection of transaction batches.postgres_container
: A PostgreSQL container for test isolation.
It initializes and manages the database and transaction context for tests.
What Does TestContext.run
Do?
This function executes the processor, applies validation logic, and optionally generates output files.
Key Features:
- Flexible Validation: Accepts a user-provided verification function.
- Multi-Table Support: Handles data across multiple tables.
- Retries: Uses exponential backoff and timeout for retries.
- Optional File Generation: Controlled by a flag.
Example Usage:
pub async fn run<F>(
&mut self,
processor: &impl ProcessorTrait,
txn_version: u64,
generate_files: bool, // Flag to control file generation
output_path: String, // Output path
custom_file_name: Option<String>, // Custom file name
verification_f: F, // Verification function
) -> anyhow::Result<HashMap<String, Value>>
where
How to Generate Expected DB Output?
Run the following command:
cargo test sdk_tests -- --nocapture generate-output
Supported Test Args:
generate-output
output_path
Additional Notes
- Adapting to Other Databases:
- Replace PostgreSQL-specific code with relevant database APIs (e.g., MySQL).
- Update schema initialization and query methods.
- Docker Installation: Follow the Docker setup guide.
- Referencing Existing Tests:
- Example: Event Processor Tests.