use super::debug_contracts::LoggingSchemaDebugReport;
use super::debug_report_output_entry_stage_input_assembly::build_debug_report_output_entry_stage_input_assembly;
use super::debug_report_output_entry_stage_input_contracts::LoggingSchemaDebugReportOutputEntryStageInput;
use super::debug_report_output_entry_stage_output_assembly::build_debug_report_output_entry_stage_output_assembly;
use super::debug_report_output_evaluation_sort_stage::build_debug_report_output_sorted_evaluation;
use super::debug_report_output_from_entry_stage_output_assembly::build_logging_schema_debug_report_output_from_entry_stage_output_assembly;
use super::debug_report_output_input_contracts::LoggingSchemaDebugReportOutputInput;
pub(super) fn build_logging_schema_debug_report_output_from_input(
input: LoggingSchemaDebugReportOutputInput,
) -> LoggingSchemaDebugReport {
let LoggingSchemaDebugReportOutputInput {
logging_client,
summary,
evaluation,
still_needed,
observed_map,
} = input;
let evaluation = build_debug_report_output_sorted_evaluation(evaluation);
let stage_input: LoggingSchemaDebugReportOutputEntryStageInput =
build_debug_report_output_entry_stage_input_assembly(
logging_client,
summary,
evaluation,
still_needed,
observed_map,
);
let stage = build_debug_report_output_entry_stage_output_assembly(stage_input);
build_logging_schema_debug_report_output_from_entry_stage_output_assembly(stage)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::api::schema::debug_contracts::LoggingSchemaDebugSummary;
use crate::api::schema::debug_evaluation::{
ExpectedTablesEvaluation, LoggingSchemaExpectedTableStatus,
};
use crate::api::schema::debug_observed_tables::{
LoggingSchemaObservedTable, ObservedTablesMap,
};
use crate::api::schema::debug_still_needed::LoggingSchemaDebugStillNeeded;
fn expected_table_status(schema: &str, table: &str) -> LoggingSchemaExpectedTableStatus {
LoggingSchemaExpectedTableStatus {
table_schema: schema.to_string(),
table_name: table.to_string(),
expected_relation_type: "BASE TABLE".to_string(),
required: true,
purpose: "test".to_string(),
expected_columns: vec!["id".to_string()],
found: true,
found_relation_type: Some("BASE TABLE".to_string()),
relation_type_matches: true,
found_columns: vec!["id".to_string()],
missing_columns: Vec::new(),
unexpected_columns: Vec::new(),
}
}
#[test]
fn report_output_sorts_expected_tables_by_relation_key() {
let mut evaluation = ExpectedTablesEvaluation::default();
evaluation.expected_tables = vec![
expected_table_status("public", "zeta"),
expected_table_status("analytics", "alpha"),
];
let observed_map: ObservedTablesMap = [
(
"public.zeta".to_string(),
LoggingSchemaObservedTable {
table_schema: "public".to_string(),
table_name: "zeta".to_string(),
relation_type: "BASE TABLE".to_string(),
columns: vec!["id".to_string()],
},
),
(
"analytics.alpha".to_string(),
LoggingSchemaObservedTable {
table_schema: "analytics".to_string(),
table_name: "alpha".to_string(),
relation_type: "BASE TABLE".to_string(),
columns: vec!["id".to_string()],
},
),
]
.into_iter()
.collect();
let summary = LoggingSchemaDebugSummary {
health: "healthy".to_string(),
health_reasons: vec![],
expected_table_count: 2,
found_table_count: 2,
required_missing_table_count: 0,
optional_missing_table_count: 0,
required_missing_column_count: 0,
optional_missing_column_count: 0,
relation_type_mismatch_count: 0,
};
let report = build_logging_schema_debug_report_output_from_input(
LoggingSchemaDebugReportOutputInput {
logging_client: "athena_logging".to_string(),
summary,
evaluation,
still_needed: LoggingSchemaDebugStillNeeded {
required_missing_tables: Vec::new(),
optional_missing_tables: Vec::new(),
required_missing_columns: Vec::new(),
optional_missing_columns: Vec::new(),
relation_type_mismatches: Vec::new(),
},
observed_map,
},
);
assert_eq!(
report
.expected_tables
.iter()
.map(|row| format!("{}.{}", row.table_schema, row.table_name))
.collect::<Vec<String>>(),
vec!["analytics.alpha".to_string(), "public.zeta".to_string()]
);
assert!(report.still_needed.required_missing_tables.is_empty());
assert!(report.still_needed.optional_missing_tables.is_empty());
assert!(report.still_needed.required_missing_columns.is_empty());
assert!(report.still_needed.optional_missing_columns.is_empty());
assert!(report.still_needed.relation_type_mismatches.is_empty());
assert_eq!(
report
.observed_tables
.iter()
.map(|row| format!("{}.{}", row.table_schema, row.table_name))
.collect::<Vec<String>>(),
vec!["analytics.alpha".to_string(), "public.zeta".to_string()]
);
assert_eq!(
report.missing_required_tables,
report.still_needed.required_missing_tables
);
assert_eq!(
report.missing_optional_tables,
report.still_needed.optional_missing_tables
);
}
}