Skip to content

Commit 7d08d04

Browse files
committed
Update based on comments from @Copilot
1 parent 28d7e9e commit 7d08d04

3 files changed

Lines changed: 134 additions & 41 deletions

File tree

crates/modelardb_macros/src/lib.rs

Lines changed: 127 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,29 @@ impl Display for ParameterType {
4747
}
4848
}
4949

50+
/// An function that will create an argument to be passed to a function as a borrow.
51+
struct BorrowedArgument {
52+
/// Name of the function.
53+
name: String,
54+
/// Module containing the function.
55+
module: String,
56+
/// Specify if the function must be called with a path.
57+
need_path: bool,
58+
/// Specify if the function must be called with .await.
59+
need_await: bool,
60+
}
61+
62+
impl BorrowedArgument {
63+
fn new(name: &str, module: &str, need_path: bool, need_await: bool) -> Self {
64+
BorrowedArgument {
65+
name: name.to_owned(),
66+
module: module.to_owned(),
67+
need_path,
68+
need_await,
69+
}
70+
}
71+
}
72+
5073
/// Macro for generating test functions that use all permutations with replacements of `DataFolder`
5174
/// The macro must be placed on an `async` function without `#[test]` or `#[tokio::test]` that only
5275
/// has `&DataFolder` parameters. It will generate one `#[tokio::test]` function for each
@@ -61,7 +84,7 @@ pub fn data_folder_test(
6184
let (function_name, data_folder_parameter_count) =
6285
function_name_and_checked_parameter_count(input.clone(), ParameterType::DataFolder);
6386

64-
// Build the async tokio::test functions that will call the annotated function using all
87+
// Generate the async tokio::test functions that will call the annotated function using all
6588
// combinations of data folder configurations. A separate function is created for each
6689
// permutation of data folder configurations instead of a single function with nested loops to
6790
// make it simpler to see which combination of data folder configurations fail a test. The name
@@ -73,10 +96,30 @@ pub fn data_folder_test(
7396
// fail. Finally, each part of the name is separated by two underscores to make it more readable
7497
// and to avoid conflicts with user code as function names should not use two underscores.
7598
let data_folders = &[
76-
"in_memory_data_folder",
77-
"local_file_system_data_folder",
78-
"aws3_data_folder",
79-
"azure_data_folder",
99+
BorrowedArgument::new(
100+
"in_memory_data_folder",
101+
"modelardb_test::data_folder",
102+
false,
103+
true,
104+
),
105+
BorrowedArgument::new(
106+
"local_file_system_data_folder",
107+
"modelardb_test::data_folder",
108+
true,
109+
true,
110+
),
111+
BorrowedArgument::new(
112+
"aws3_data_folder",
113+
"modelardb_test::data_folder",
114+
false,
115+
true,
116+
),
117+
BorrowedArgument::new(
118+
"azure_data_folder",
119+
"modelardb_test::data_folder",
120+
false,
121+
true,
122+
),
80123
];
81124

82125
let data_folder_permutations_with_replacements =
@@ -85,19 +128,9 @@ pub fn data_folder_test(
85128

86129
let mut code = String::new();
87130
for data_folder_permutation in data_folder_permutations_with_replacements {
88-
let name = data_folder_permutation.clone().iter().join("__");
89-
let arguments = data_folder_permutation
90-
.iter()
91-
.map(|osn| format!("&modelardb_test::data_folder::{}().await", osn))
92-
.join(", ");
93-
94-
code.push_str(&format!(
95-
"
96-
#[tokio::test]
97-
async fn {function_name}__{name}() {{
98-
{function_name}({arguments}).await
99-
}}
100-
"
131+
code.push_str(&generate_test_function(
132+
&function_name,
133+
&data_folder_permutation,
101134
));
102135
}
103136

@@ -119,10 +152,30 @@ pub fn object_store_test(
119152
function_name_and_checked_parameter_count(input.clone(), ParameterType::ObjectStore);
120153

121154
let object_stores = &[
122-
"in_memory_object_store",
123-
"local_file_system_object_store",
124-
"aws3_object_store",
125-
"azure_object_store",
155+
BorrowedArgument::new(
156+
"in_memory_object_store",
157+
"modelardb_test::object_store",
158+
false,
159+
false,
160+
),
161+
BorrowedArgument::new(
162+
"local_file_system_object_store",
163+
"modelardb_test::object_store",
164+
true,
165+
false,
166+
),
167+
BorrowedArgument::new(
168+
"aws3_object_store",
169+
"modelardb_test::object_store",
170+
false,
171+
false,
172+
),
173+
BorrowedArgument::new(
174+
"azure_object_store",
175+
"modelardb_test::object_store",
176+
false,
177+
false,
178+
),
126179
];
127180

128181
let object_store_permutations_with_replacements =
@@ -131,19 +184,9 @@ pub fn object_store_test(
131184

132185
let mut code = String::new();
133186
for object_store_permutation in object_store_permutations_with_replacements {
134-
let name = object_store_permutation.iter().join("__");
135-
let arguments = object_store_permutation
136-
.iter()
137-
.map(|osn| format!("&modelardb_test::object_store::{}()", osn))
138-
.join(", ");
139-
140-
code.push_str(&format!(
141-
"
142-
#[tokio::test]
143-
async fn {function_name}__{name}() {{
144-
{function_name}({arguments}).await
145-
}}
146-
"
187+
code.push_str(&generate_test_function(
188+
&function_name,
189+
&object_store_permutation,
147190
));
148191
}
149192

@@ -285,3 +328,52 @@ fn append_code_to_token_stream(mut input: TokenStream, code: String) -> TokenStr
285328
input.extend(implementation_tokens);
286329
input
287330
}
331+
332+
/// Generate a call to `function_name` and pass it the `permutation` with replacements of arguments.
333+
fn generate_test_function(function_name: &str, permutation: &[&BorrowedArgument]) -> String {
334+
let permutation_name = permutation.iter().map(|ba| &ba.name).join("__");
335+
336+
let mut temp_dir_name_counter = 0;
337+
let temp_dirs = permutation
338+
.iter()
339+
.filter_map(|ba| {
340+
if ba.need_path {
341+
temp_dir_name_counter += 1;
342+
Some(format!(
343+
"let temp_dir{temp_dir_name_counter} = tempfile::tempdir().unwrap();"
344+
))
345+
} else {
346+
None
347+
}
348+
})
349+
.join(" ");
350+
351+
temp_dir_name_counter = 0;
352+
let arguments = permutation
353+
.iter()
354+
.map(|ba| {
355+
let mut argument = String::new();
356+
argument.push_str(&format!("&{}::{}", ba.module, ba.name));
357+
if ba.need_path {
358+
temp_dir_name_counter += 1;
359+
argument.push_str(&format!("(temp_dir{temp_dir_name_counter}.path())"));
360+
} else {
361+
argument.push_str("()");
362+
}
363+
if ba.need_await {
364+
argument.push_str(".await")
365+
}
366+
argument
367+
})
368+
.join(", ");
369+
370+
format!(
371+
"
372+
#[tokio::test]
373+
async fn {function_name}__{permutation_name}() {{
374+
{temp_dirs}
375+
{function_name}({arguments}).await
376+
}}
377+
"
378+
)
379+
}

crates/modelardb_test/src/data_folder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
//! Functions for creating data folders used throughout ModelarDB for testing purposes.
1717
18+
use std::path::Path as StdPath;
19+
1820
use modelardb_storage::data_folder::DataFolder;
1921

2022
use crate::BUCKET_AND_CONTAINER_NAME;
@@ -25,9 +27,8 @@ pub async fn in_memory_data_folder() -> DataFolder {
2527
}
2628

2729
/// Return a [`DataFolder`] storing data on local disk for testing.
28-
pub async fn local_file_system_data_folder() -> DataFolder {
29-
let temp_dir = tempfile::tempdir().unwrap();
30-
DataFolder::open_local(temp_dir.path()).await.unwrap()
30+
pub async fn local_file_system_data_folder(data_folder_path: &StdPath) -> DataFolder {
31+
DataFolder::open_local(data_folder_path).await.unwrap()
3132
}
3233

3334
/// Return a [`DataFolder`] storing data in an AWS3 compatible object store for testing using Minio.

crates/modelardb_test/src/object_store.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
//! `Box<dyn ObjectStore>` to match the output of [`object_store::parse_url_opts()`].
1818
1919
use std::collections::HashMap;
20+
use std::path::Path as StdPath;
2021

2122
use object_store::{ObjectStore, aws::AmazonS3Builder, local::LocalFileSystem, memory::InMemory};
2223
use url::Url;
@@ -29,9 +30,8 @@ pub fn in_memory_object_store() -> Box<dyn ObjectStore> {
2930
}
3031

3132
/// Return a [`LocalFileSystem`] [`ObjectStore`] for testing.
32-
pub fn local_file_system_object_store() -> Box<dyn ObjectStore> {
33-
let temp_dir = tempfile::tempdir().unwrap();
34-
let local_file_system = LocalFileSystem::new_with_prefix(temp_dir.path()).unwrap();
33+
pub fn local_file_system_object_store(object_store_path: &StdPath) -> Box<dyn ObjectStore> {
34+
let local_file_system = LocalFileSystem::new_with_prefix(object_store_path).unwrap();
3535
Box::new(local_file_system)
3636
}
3737

0 commit comments

Comments
 (0)