-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL-2288: Create mongosqltranslate integration tests #251
base: on-prem-eap
Are you sure you want to change the base?
Changes from all commits
91e709e
f9039e0
2997ffd
71e5ec3
6519307
914ca8f
59a37de
74b8d02
e7ce323
401713b
65ff048
5bc7a32
f5541e3
9125f5c
8050d4f
4e45044
52be409
558358d
e7e8234
ac45b5d
2ca83d0
d3645cf
2f9c330
faba35f
b17ce9e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,17 @@ | ||
use crate::{ | ||
cluster_type::MongoClusterType, | ||
col_metadata::{MongoColMetadata, ResultSetSchema, SqlGetSchemaResponse}, | ||
collections::MongoODBCCollectionSpecification, | ||
conn::MongoConnection, | ||
err::{Error, Result}, | ||
stmt::MongoStatement, | ||
util::to_name_regex, | ||
util::{databases_filter, to_name_regex}, | ||
BsonTypeInfo, TypeMode, | ||
}; | ||
use constants::SQL_SCHEMAS_COLLECTION; | ||
use definitions::{Nullability, SqlDataType}; | ||
use mongodb::{ | ||
bson::{doc, Bson}, | ||
bson::{doc, Bson, Document}, | ||
results::CollectionType, | ||
}; | ||
use once_cell::sync::OnceCell; | ||
|
@@ -484,7 +486,7 @@ impl MongoFields { | |
.unwrap() | ||
// MHOUSE-7119 - admin database and empty strings are showing in list_database_names | ||
.iter() | ||
.filter(|&db_name| !db_name.is_empty() && !db_name.eq("admin")) | ||
.filter(|&db_name| databases_filter(db_name)) | ||
.map(|s| s.to_string()) | ||
.collect() | ||
}, | ||
|
@@ -542,23 +544,71 @@ impl MongoFields { | |
// The collection does not match the filter, moving to the next one | ||
continue; | ||
} | ||
let get_schema_cmd = doc! {"sqlGetSchema": collection_name.clone()}; | ||
|
||
let db = mongo_connection.client.database(&self.current_db_name); | ||
let current_col_metadata_response: Result<SqlGetSchemaResponse> = | ||
mongodb::bson::from_document( | ||
db.run_command(get_schema_cmd).await.unwrap(), | ||
) | ||
.map_err(|e| { | ||
Error::CollectionDeserialization(collection_name.clone(), e) | ||
}); | ||
if let Err(error) = current_col_metadata_response { | ||
// If there is an Error while deserializing the schema, we won't show any columns for it | ||
warnings.push(error); | ||
continue; | ||
} | ||
let current_col_metadata_response: ResultSetSchema = | ||
current_col_metadata_response.unwrap().into(); | ||
|
||
let current_col_metadata_response: ResultSetSchema = if mongo_connection | ||
Comment on lines
+549
to
+550
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code was merged into master with SQL-2374 |
||
.cluster_type | ||
== MongoClusterType::AtlasDataFederation | ||
{ | ||
let get_schema_cmd = doc! {"sqlGetSchema": &collection_name}; | ||
|
||
let sql_get_schema_response: Result<SqlGetSchemaResponse> = | ||
mongodb::bson::from_document( | ||
db.run_command(get_schema_cmd).await.unwrap(), | ||
) | ||
.map_err(|e| { | ||
Error::CollectionDeserialization(collection_name.clone(), e) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about an integration test that confirms we get this on a deserialization error? |
||
}); | ||
|
||
let error_checked_sql_get_schema_response = | ||
match sql_get_schema_response { | ||
Ok(sql_get_schema_response) => sql_get_schema_response, | ||
Err(error) => { | ||
// If there is an Error while deserializing the schema, we won't show any columns for it | ||
warnings.push(error); | ||
continue; | ||
} | ||
}; | ||
|
||
error_checked_sql_get_schema_response.into() | ||
} else if mongo_connection.cluster_type == MongoClusterType::Enterprise { | ||
let schema_collection = | ||
db.collection::<Document>(SQL_SCHEMAS_COLLECTION); | ||
|
||
let schema_doc: Document = mongo_connection | ||
.runtime | ||
.block_on(async { | ||
schema_collection | ||
.find_one(doc! { | ||
"_id": &collection_name | ||
}) | ||
.await | ||
.map_err(Error::QueryExecutionFailed) | ||
})? | ||
.ok_or(Error::SchemaDocumentNotFoundInSchemaCollection(vec![ | ||
collection_name.clone(), | ||
]))?; | ||
|
||
let result_set_schema: Result<ResultSetSchema> = | ||
ResultSetSchema::from_sql_schemas_document(&schema_doc).map_err( | ||
|e| { | ||
Error::CollectionDeserialization(collection_name.clone(), e) | ||
}, | ||
); | ||
|
||
match result_set_schema { | ||
Ok(result_set_schema) => result_set_schema, | ||
Err(error) => { | ||
// If there is an Error while deserializing the schema, we won't show any columns for it | ||
warnings.push(error); | ||
continue; | ||
} | ||
} | ||
} else { | ||
unreachable!() | ||
}; | ||
|
||
match current_col_metadata_response.process_collection_metadata( | ||
&self.current_db_name, | ||
collection_name.as_str(), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,8 +42,8 @@ fn get_library_name(library_type: &str) -> String { | |
} | ||
} | ||
|
||
fn get_library_path(library_type: &str) -> PathBuf { | ||
let lib_name = get_library_name(library_type); | ||
fn get_library_path() -> PathBuf { | ||
let lib_name = get_library_name(LIBRARY_NAME); | ||
let mut path = PathBuf::from(LIBRARY_INSTALL_PATH); | ||
path.push(lib_name); | ||
path | ||
|
@@ -63,12 +63,12 @@ fn get_mock_library_path() -> PathBuf { | |
// and is responsible for determining the library name and path. | ||
// The library name and path are determined based on the operating system and architecture. | ||
// It is stored in a static variable to ensure that it is only loaded once. | ||
pub fn load_mongosqltranslate_library() { | ||
pub fn load_mongosqltranslate_library(mock_library: bool) { | ||
INIT.call_once(|| { | ||
let library_path = if cfg!(test) { | ||
let library_path = if mock_library { | ||
get_mock_library_path() | ||
} else { | ||
get_library_path(LIBRARY_NAME) | ||
get_library_path() | ||
Comment on lines
+66
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
}; | ||
|
||
match unsafe { Library::new(library_path.clone()) } { | ||
|
@@ -221,6 +221,7 @@ impl CheckDriverVersion { | |
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(tag = "command_type")] | ||
pub enum CommandResponse { | ||
Comment on lines
+224
to
225
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The deserialization wasn't working without this. |
||
Translate(TranslateCommandResponse), | ||
GetNamespaces(GetNamespacesCommandResponse), | ||
|
@@ -306,9 +307,14 @@ pub(crate) fn libmongosqltranslate_run_command<T: CommandName + Serialize>( | |
capacity: command_bytes_capacity, | ||
}; | ||
|
||
log::info!( | ||
"Calling `{}` libmongosqltranslate runCommand.", | ||
T::command_name() | ||
); | ||
|
||
let decomposed_returned_doc = unsafe { run_command_function(libmongosqltranslate_command) }; | ||
|
||
let command_response_doc: Document = unsafe { | ||
let mut command_response_doc: Document = unsafe { | ||
bson::from_slice( | ||
Vec::from_raw_parts( | ||
decomposed_returned_doc.data.cast_mut(), | ||
|
@@ -320,6 +326,20 @@ pub(crate) fn libmongosqltranslate_run_command<T: CommandName + Serialize>( | |
.map_err(Error::LibmongosqltranslateDeserialization)? | ||
}; | ||
|
||
let command_type = if command_response_doc.get_str("error").is_ok() { | ||
"Error" | ||
} else { | ||
match T::command_name() { | ||
"getNamespaces" => "GetNamespaces", | ||
"translate" => "Translate", | ||
"getMongosqlTranslateVersion" => "GetMongosqlTranslateVersion", | ||
"checkDriverVersion" => "CheckDriverVersion", | ||
_ => unreachable!(), | ||
} | ||
}; | ||
|
||
command_response_doc.insert("command_type", command_type); | ||
|
||
let command_response = CommandResponse::from_document(&command_response_doc)?; | ||
|
||
if let CommandResponse::Error(error_response) = command_response { | ||
|
@@ -340,7 +360,7 @@ mod unit { | |
|
||
#[test] | ||
fn library_load_and_run_command_test() { | ||
load_mongosqltranslate_library(); | ||
load_mongosqltranslate_library(true); | ||
assert!(get_mongosqltranslate_library().is_some()); | ||
|
||
let run_command = get_run_command_fn_ptr().expect("Failed to load runCommand symbol"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
DRIVER_ODBC_VERSION
wasn't a valid semver version, so I switched to theDRIVER_METRICS_VERSION
.