Run tests parallelly in the `testsuite` keyspace

This saves us time and simplifies things. A lot.
next
Sayan Nandan 3 years ago
parent 728c71f84f
commit 1025933cfb

1
Cargo.lock generated

@ -948,6 +948,7 @@ version = "0.6.3"
dependencies = [
"proc-macro2",
"quote",
"rand",
"syn",
]

@ -54,7 +54,7 @@ RELEASE_SERVER_COMMAND += $(BUILD_SERVER_COMMAND)
RELEASE_SERVER_COMMAND += --release
RELEASE_COMMAND += cargo build --release $(TARGET_ARG)
BUILD_COMMAND += $(BUILD_VERBOSE)
TEST_COMMAND += cargo test $(TARGET_ARG) -- --test-threads=1
TEST_COMMAND += cargo test $(TARGET_ARG)
START_COMMAND += cargo run $(TARGET_ARG) -p skyd
START_COMMAND_RELEASE =
START_COMMAND_RELEASE += ${START_COMMAND}
@ -132,7 +132,7 @@ test: .build-server
@echo "===================================================================="
@echo "Running all tests"
@echo "===================================================================="
cargo test $(TARGET_ARG) -- --test-threads=1
cargo test $(TARGET_ARG)
@$(STOP_SERVER)
@sleep 2
@rm -f .sky_pid cert.pem key.pem

@ -129,7 +129,7 @@ fn test_runtime_panic_32bit_or_lower() {
}
mod interface_tests {
use super::interface::{create_tree, DIR_KSROOT, DIR_ROOT, DIR_SNAPROOT};
use super::interface::{create_tree, DIR_KSROOT, DIR_SNAPROOT};
use crate::corestore::memstore::Memstore;
use std::fs;
use std::path::PathBuf;
@ -143,7 +143,8 @@ mod interface_tests {
v.to_string_lossy().to_string()
})
.collect();
assert_veceq!(read_ks, vec!["default".to_owned(), "system".to_owned()]);
assert!(read_ks.contains(&"system".to_owned()));
assert!(read_ks.contains(&"default".to_owned()));
// just read one level of the snaps dir
let read_snaps: Vec<String> = fs::read_dir(DIR_SNAPROOT)
.unwrap()
@ -154,8 +155,6 @@ mod interface_tests {
.collect();
assert_eq!(read_snaps, Vec::<String>::new());
assert!(PathBuf::from("data/backups").is_dir());
// clean up
fs::remove_dir_all(DIR_ROOT).unwrap();
}
}
@ -267,7 +266,6 @@ mod flush_routines {
.clone(),
Data::from("world")
);
fs::remove_dir_all("data/ks/myks1").unwrap()
}
#[test]
fn test_flush_unflush_keyspace() {
@ -302,6 +300,5 @@ mod flush_routines {
Data::from("world")
);
assert!(tbl2_ret.get_kvstore().unwrap().len() == 0);
fs::remove_dir_all("data/ks/myks_1").unwrap()
}
}

@ -14,3 +14,4 @@ proc-macro = true
syn = {version = "1.0.73", features = ["full"]}
quote = "1.0.9"
proc-macro2 = "1.0.27"
rand = "0.8.4"

@ -47,11 +47,16 @@ use proc_macro2::Span;
use quote::quote;
use syn::{self};
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/// This parses a function within a `dbtest` module
///
/// This accepts an `async` function and returns a non-`async` version of it - by
/// making the body of the function use the `tokio` runtime
fn parse_dbtest(mut input: syn::ItemFn) -> Result<TokenStream, syn::Error> {
fn parse_dbtest(
mut input: syn::ItemFn,
rng: &mut impl rand::Rng,
) -> Result<TokenStream, syn::Error> {
let sig = &mut input.sig;
let fname = sig.ident.to_string();
let body = &input.block;
@ -65,8 +70,33 @@ fn parse_dbtest(mut input: syn::ItemFn) -> Result<TokenStream, syn::Error> {
return Err(syn::Error::new_spanned(sig.fn_token, msg));
}
sig.asyncness = None;
let rand_string: String = (0..30)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect();
let body = quote! {
let mut con = skytable::AsyncConnection::new("127.0.0.1", 2003).await.unwrap();
let __create_ks =
con.run_simple_query(
&skytable::query!("create", "keyspace", "testsuite")
).await.unwrap();
let __switch_ks =
con.run_simple_query(
&skytable::query!("use", "testsuite")
).await.unwrap();
let __create_tbl =
con.run_simple_query(
&skytable::query!("create", "table", #rand_string, "keymap(binstr,binstr)")
).await.unwrap();
let mut __concat_entity = std::string::String::new();
__concat_entity.push_str("testsuite:");
__concat_entity.push_str(&#rand_string);
let __switch_entity =
con.run_simple_query(
&skytable::query!("use", __concat_entity)
).await.unwrap();
let mut query = skytable::Query::new();
#body
{
@ -95,7 +125,7 @@ fn parse_dbtest(mut input: syn::ItemFn) -> Result<TokenStream, syn::Error> {
}
/// This function checks if the current function is eligible to be a test
fn parse_test_sig(input: syn::ItemFn) -> TokenStream {
fn parse_test_sig(input: syn::ItemFn, rng: &mut impl rand::Rng) -> TokenStream {
for attr in &input.attrs {
if attr.path.is_ident("test") {
let msg = "second test attribute is supplied";
@ -111,7 +141,7 @@ fn parse_test_sig(input: syn::ItemFn) -> TokenStream {
.to_compile_error()
.into();
}
parse_dbtest(input).unwrap_or_else(|e| e.to_compile_error().into())
parse_dbtest(input, rng).unwrap_or_else(|e| e.to_compile_error().into())
}
/// This function accepts an entire module which comprises of `dbtest` functions.
@ -175,6 +205,7 @@ fn parse_test_module(args: TokenStream, item: TokenStream) -> TokenStream {
.into();
}
let mut result = quote! {};
let mut rng = rand::thread_rng();
for item in content {
match item {
// We just care about functions, so parse functions and ignore everything
@ -187,7 +218,7 @@ fn parse_test_module(args: TokenStream, item: TokenStream) -> TokenStream {
};
continue;
}
let inp = parse_test_sig(function);
let inp = parse_test_sig(function, &mut rng);
let __tok: syn::ItemFn = syn::parse_macro_input!(inp as syn::ItemFn);
let tok = quote! {
#__tok

Loading…
Cancel
Save