Skip to content

Commit

Permalink
expose generate file function (#72)
Browse files Browse the repository at this point in the history
* expose generate file function

* move cli parser to sdk and expose it

* lint

* wrap around tests mod

* move functions
  • Loading branch information
yuunlimm authored Oct 16, 2024
1 parent 366b93b commit c3be0b5
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 54 deletions.
1 change: 1 addition & 0 deletions aptos-indexer-processors-sdk/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aptos-indexer-processors-sdk/testing-framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ futures-util = { workspace = true }

# Postgres SSL support
native-tls = { workspace = true }
once_cell = { workspace = true }
postgres-native-tls = { workspace = true }

serde_json = { workspace = true }
Expand Down
53 changes: 53 additions & 0 deletions aptos-indexer-processors-sdk/testing-framework/src/cli_parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#[cfg(test)]
pub mod tests {
use once_cell::sync::Lazy;
use std::sync::Mutex;

#[derive(Debug, Clone)]
pub struct TestArgs {
pub generate_output: bool,
pub output_path: Option<String>,
}

// Define a global static to store the parsed arguments
static TEST_CONFIG: Lazy<Mutex<TestArgs>> = Lazy::new(|| {
let args = parse_test_args();
Mutex::new(args)
});

// Function to fetch global test args
pub fn get_test_config() -> (bool, Option<String>) {
let test_args = TEST_CONFIG.lock().unwrap().clone();
(test_args.generate_output, test_args.output_path)
}

pub fn parse_test_args() -> TestArgs {
let raw_args: Vec<String> = std::env::args().collect();

// Find the "--" separator (if it exists)
let clap_args_position = raw_args.iter().position(|arg| arg == "--");

// Only pass the arguments that come after "--", if it exists
let custom_args: Vec<String> = match clap_args_position {
Some(position) => raw_args[position + 1..].to_vec(), // Slice after `--`
None => Vec::new(), // If no `--` is found, treat as no custom args
};

// Manually parse the "--generate-output" flag
let generate_output_flag = custom_args.contains(&"--generate-output".to_string());

// Manually parse the "--output-path" flag and get its associated value
let output_path = custom_args
.windows(2)
.find(|args| args[0] == "--output-path")
.map(|args| args[1].clone());

println!("Parsed generate_output_flag: {}", generate_output_flag);
println!("Parsed output_path: {:?}", output_path);

TestArgs {
generate_output: generate_output_flag,
output_path,
}
}
}
3 changes: 2 additions & 1 deletion aptos-indexer-processors-sdk/testing-framework/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod cli_parser;
pub mod database;
mod mock_grpc;
pub mod new_test_context;
pub mod sdk_test_context;
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl SdkTestContext {
anyhow::anyhow!(
"Failed to parse transaction at index {}: {}",
idx,
format_serde_error(err)
Self::format_serde_error(err)
)
})
})
Expand Down Expand Up @@ -115,9 +115,9 @@ impl SdkTestContext {

// Iterate over each table's data in the HashMap and generate an output file
for (table_name, table_data) in db_values.iter_mut() {
remove_inserted_at(table_data);
Self::remove_inserted_at(table_data);

generate_output_file(
self.generate_output_file(
processor.name(),
table_name,
&format!("{}", txn_version),
Expand Down Expand Up @@ -174,63 +174,65 @@ impl SdkTestContext {
indexer_grpc_response_item_timeout_secs: 60,
}
}
}

/// Helper function to format serde_json errors for better readability.
fn format_serde_error(err: SerdeError) -> String {
match err.classify() {
serde_json::error::Category::Io => format!("I/O error: {}", err),
serde_json::error::Category::Syntax => format!("Syntax error: {}", err),
serde_json::error::Category::Data => format!("Data error: {}", err),
serde_json::error::Category::Eof => format!("Unexpected end of input: {}", err),
/// Helper function to format serde_json errors for better readability.
fn format_serde_error(err: SerdeError) -> String {
match err.classify() {
serde_json::error::Category::Io => format!("I/O error: {}", err),
serde_json::error::Category::Syntax => format!("Syntax error: {}", err),
serde_json::error::Category::Data => format!("Data error: {}", err),
serde_json::error::Category::Eof => format!("Unexpected end of input: {}", err),
}
}
}

// Helper function to construct the output file path with the table name
fn construct_file_path(
output_dir: &str,
processor_name: &str,
table_name: &str,
txn_version: &str,
) -> PathBuf {
Path::new(output_dir)
.join(processor_name)
.join(txn_version)
.join(format!("{}.json", table_name)) // Including table_name in the format
}
// Helper function to construct the output file path with the table name
fn construct_file_path(
output_dir: &str,
processor_name: &str,
table_name: &str,
txn_version: &str,
) -> PathBuf {
Path::new(output_dir)
.join(processor_name)
.join(txn_version)
.join(format!("{}.json", table_name)) // Including table_name in the format
}

// Helper function to ensure the directory exists
fn ensure_directory_exists(path: &Path) -> anyhow::Result<()> {
if let Some(parent_dir) = path.parent() {
fs::create_dir_all(parent_dir).context("Failed to create directory")?;
// Helper function to ensure the directory exists
fn ensure_directory_exists(path: &Path) -> anyhow::Result<()> {
if let Some(parent_dir) = path.parent() {
fs::create_dir_all(parent_dir).context("Failed to create directory")?;
}
Ok(())
}
Ok(())
}

// Helper function to generate output files for each table
fn generate_output_file(
processor_name: &str,
table_name: &str,
txn_version: &str,
db_values: &serde_json::Value,
output_dir: String,
) -> anyhow::Result<()> {
let file_path = construct_file_path(&output_dir, processor_name, table_name, txn_version); // Pass table_name here

ensure_directory_exists(&file_path)?;

fs::write(&file_path, to_string_pretty(db_values)?)
.context(format!("Failed to write file to {:?}", file_path))?;
println!("[TEST] Generated output file at: {}", file_path.display());
Ok(())
}
// Helper function to generate output files for each table
pub fn generate_output_file(
&self,
processor_name: &str,
table_name: &str,
txn_version: &str,
db_values: &serde_json::Value,
output_dir: String,
) -> anyhow::Result<()> {
let file_path =
Self::construct_file_path(&output_dir, processor_name, table_name, txn_version); // Pass table_name here

Self::ensure_directory_exists(&file_path)?;

fs::write(&file_path, to_string_pretty(db_values)?)
.context(format!("Failed to write file to {:?}", file_path))?;
println!("[TEST] Generated output file at: {}", file_path.display());
Ok(())
}

#[allow(dead_code)]
pub fn remove_inserted_at(value: &mut Value) {
if let Some(array) = value.as_array_mut() {
for item in array.iter_mut() {
if let Some(obj) = item.as_object_mut() {
obj.remove("inserted_at");
#[allow(dead_code)]
pub fn remove_inserted_at(value: &mut Value) {
if let Some(array) = value.as_array_mut() {
for item in array.iter_mut() {
if let Some(obj) = item.as_object_mut() {
obj.remove("inserted_at");
}
}
}
}
Expand Down

0 comments on commit c3be0b5

Please sign in to comment.