|
| 1 | +--- |
| 2 | +title: "Testing Processor" |
| 3 | +--- |
| 4 | + |
| 5 | +# Processor Test Runbook |
| 6 | + |
| 7 | +### What Are We Testing With This? |
| 8 | + |
| 9 | +- **Transaction correctness**: Ensure that each transaction is processed and stored accurately. |
| 10 | +- **Schema consistency**: Verify that the database schema is correctly set up and maintained throughout the tests. |
| 11 | + |
| 12 | +### General Flow |
| 13 | + |
| 14 | +1. Prepare testing transactions (refer to prior documentation). |
| 15 | +2. Update dependencies as needed. |
| 16 | +3. Import new transactions. |
| 17 | +4. Write test cases. |
| 18 | +5. Generate expected database output and validate. |
| 19 | +6. Merge. |
| 20 | + |
| 21 | +Ensure tests pass whenever there are updates in the processor code. |
| 22 | + |
| 23 | + |
| 24 | +## Prerequisites |
| 25 | + |
| 26 | +1. Ensure Docker is running for PostgreSQL container support. |
| 27 | +2. Identify the transactions to test. |
| 28 | +3. Import necessary modules, see example: |
| 29 | + ```rust |
| 30 | + use aptos_indexer_testing_framework::{ |
| 31 | + database::{PostgresTestDatabase, TestDatabase}, |
| 32 | + sdk_test_context::SdkTestContext, |
| 33 | + }; |
| 34 | + ``` |
| 35 | + |
| 36 | +> 💡 **Key Considerations**: |
| 37 | +> |
| 38 | +> - Each test runs in an isolated environment using a PostgreSQL container to prevent interference. |
| 39 | +> - Proper handling of versions ensures transactions are processed and validated in the correct order. |
| 40 | +> - Validation logic must detect changes or issues by comparing processor output with the expected baseline. |
| 41 | +
|
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | + |
| 46 | +## Steps to Write a Test |
| 47 | + |
| 48 | +### 1. Set Up the Test Environment |
| 49 | + |
| 50 | +```rust |
| 51 | +let (diff_flag, custom_output_path) = get_test_config(); |
| 52 | +let output_path = custom_output_path.unwrap_or_else(|| format!("{}/imported_mainnet_txns", DEFAULT_OUTPUT_FOLDER)); |
| 53 | + |
| 54 | +// Replace with your test transaction |
| 55 | +let (db, mut test_context) = setup_test_environment(&[IMPORTED_MAINNET_TXNS_438536688_ANS_CURRENT_ANS_LOOKUP_V2]).await; |
| 56 | +``` |
| 57 | + |
| 58 | +### 2. Configure the Processor |
| 59 | + |
| 60 | +```rust |
| 61 | +let db_url = db.get_db_url(); |
| 62 | +let (indexer_processor_config, processor_name) = |
| 63 | + setup_ans_processor_config(&test_context, &db_url); |
| 64 | +``` |
| 65 | + |
| 66 | +### 3. Create the Processor |
| 67 | + |
| 68 | +```rust |
| 69 | +let processor = DefaultProcessor::new(indexer_processor_config) |
| 70 | + .await |
| 71 | + .expect("Failed to create processor"); |
| 72 | +``` |
| 73 | + |
| 74 | +### 4. Query the Databasefaw |
| 75 | + |
| 76 | +Set up a query to load data from the local database and compare it with expected results. |
| 77 | + |
| 78 | +### 5. Run the Processor Test |
| 79 | + |
| 80 | +```rust |
| 81 | +#[derive(Debug, Clone)] |
| 82 | +pub struct TestArgs { |
| 83 | + pub generate_output: bool, |
| 84 | + pub output_path: Option<String>, |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +Run the processor and verify the outputs using `SdkTestContext.run`. |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +## Tips |
| 93 | +1. **Isolate Tests**: Use Docker containers for database isolation. |
| 94 | +2. **Handle Non-Deterministic Fields**: Use helpers like `remove_inserted_at` to clean up timestamps before validation. |
| 95 | +3. **Enable Debugging**: Use `eprintln!` for detailed error logging. |
| 96 | + |
| 97 | + |
| 98 | +## FAQ |
| 99 | + |
| 100 | +### What Types of Tests Does It Support? |
| 101 | + |
| 102 | +- Database (PostgreSQL) schema output diff. |
| 103 | + |
| 104 | +### How Does It Work? |
| 105 | + |
| 106 | +#### Step-by-Step Flow: |
| 107 | + |
| 108 | +1. Setup Test Configuration: Define the parameters in the CLI command. |
| 109 | +2. Specify Transactions to Import: List the transactions to test. |
| 110 | +3. Initialize the Test Environment: Set up the test database and context. |
| 111 | +4. Optional - Deserialize Transactions: Convert transactions into `Transaction` structs for processing. |
| 112 | +5. Configure the Processor: Define the database URL and processor settings. |
| 113 | +6. Run the Processor Test: Execute the processor and validate correctness. |
| 114 | + |
| 115 | +### What Is `TestContext`? |
| 116 | + |
| 117 | +`TestContext` is a struct that manages: |
| 118 | + |
| 119 | +- `transaction_batches`: A collection of transaction batches. |
| 120 | +- `postgres_container`: A PostgreSQL container for test isolation. |
| 121 | + |
| 122 | +It initializes and manages the database and transaction context for tests. |
| 123 | + |
| 124 | +#### What Does `TestContext.run` Do? |
| 125 | + |
| 126 | +This function executes the processor, applies validation logic, and optionally generates output files. |
| 127 | + |
| 128 | +#### Key Features: |
| 129 | + |
| 130 | +- Flexible Validation: Accepts a user-provided verification function. |
| 131 | +- Multi-Table Support: Handles data across multiple tables. |
| 132 | +- Retries: Uses exponential backoff and timeout for retries. |
| 133 | +- Optional File Generation: Controlled by a flag. |
| 134 | + |
| 135 | +#### Example Usage: |
| 136 | + |
| 137 | +```rust |
| 138 | +pub async fn run<F>( |
| 139 | + &mut self, |
| 140 | + processor: &impl ProcessorTrait, |
| 141 | + txn_version: u64, |
| 142 | + generate_files: bool, // Flag to control file generation |
| 143 | + output_path: String, // Output path |
| 144 | + custom_file_name: Option<String>, // Custom file name |
| 145 | + verification_f: F, // Verification function |
| 146 | +) -> anyhow::Result<HashMap<String, Value>> |
| 147 | +where |
| 148 | +``` |
| 149 | + |
| 150 | +### How to Generate Expected DB Output? |
| 151 | + |
| 152 | +Run the following command: |
| 153 | + |
| 154 | +```bash |
| 155 | +cargo test sdk_tests -- --nocapture generate-output |
| 156 | +``` |
| 157 | + |
| 158 | +Supported Test Args: |
| 159 | + |
| 160 | +1. `generate-output` |
| 161 | +2. `output_path` |
| 162 | + |
| 163 | +--- |
| 164 | + |
| 165 | +## Additional Notes |
| 166 | + |
| 167 | +- **Adapting to Other Databases**: |
| 168 | + - Replace PostgreSQL-specific code with relevant database APIs (e.g., MySQL). |
| 169 | + - Update schema initialization and query methods. |
| 170 | +- **Docker Installation**: Follow the [Docker setup guide](https://docs.docker.com/get-docker/). |
| 171 | +- **Referencing Existing Tests**: |
| 172 | + - Example: [Event Processor Tests](https://github.com/aptos-labs/aptos-indexer-processors/blob/main/rust/integration-tests/src/sdk_tests/events_processor_tests.rs#L139). |
0 commit comments