Skip to content
Snippets Groups Projects
Commit 9de037e5 authored by Georgy Moshkin's avatar Georgy Moshkin :speech_balloon: Committed by Yaroslav Dynnikov
Browse files

refactor(test): extract src/test.rs module

parent 3f5ff337
No related branches found
No related tags found
1 merge request!464Feat/tarantool test
......@@ -7,19 +7,21 @@ use picodata::args;
use picodata::ipc;
use picodata::tlog;
use picodata::Entrypoint;
use picodata::InnerTest;
use picodata::IpcMessage;
use tarantool::fiber;
mod test;
fn main() -> ! {
match args::Picodata::parse() {
args::Picodata::Run(args) => main_run(args),
args::Picodata::Test(args) => main_test(args),
args::Picodata::Test(args) => test::main_test(args),
args::Picodata::Tarantool(args) => main_tarantool(args),
args::Picodata::Expel(args) => main_expel(args),
}
}
#[macro_export]
macro_rules! tarantool_main {
(
$tt_args:expr,
......@@ -231,147 +233,3 @@ fn main_expel(args: args::Expel) -> ! {
);
std::process::exit(rc);
}
macro_rules! color {
(@priv red) => { "\x1b[0;31m" };
(@priv green) => { "\x1b[0;32m" };
(@priv clear) => { "\x1b[0m" };
(@priv $s:literal) => { $s };
($($s:tt)*) => {
::std::concat![ $( color!(@priv $s) ),* ]
}
}
pub fn main_test(args: args::Test) -> ! {
// Tarantool implicitly parses some environment variables.
// We don't want them to affect the behavior and thus filter them out.
for (k, _) in std::env::vars() {
if k.starts_with("TT_") || k.starts_with("TARANTOOL_") {
std::env::remove_var(k)
}
}
const PASSED: &str = color![green "ok" clear];
const FAILED: &str = color![red "FAILED" clear];
let mut cnt_passed = 0u32;
let mut cnt_failed = 0u32;
let mut cnt_skipped = 0u32;
let now = std::time::Instant::now();
println!();
println!(
"total {} tests",
inventory::iter::<InnerTest>.into_iter().count()
);
for t in inventory::iter::<InnerTest> {
if let Some(filter) = args.filter.as_ref() {
if !t.name.contains(filter) {
cnt_skipped += 1;
continue;
}
}
print!("test {} ... ", t.name);
let (mut rx, tx) = ipc::pipe().expect("pipe creation failed");
let pid = unsafe { fork() };
match pid.expect("fork failed") {
ForkResult::Child => {
drop(rx);
unistd::close(0).ok(); // stdin
if !args.nocapture {
unistd::dup2(*tx, 1).ok(); // stdout
unistd::dup2(*tx, 2).ok(); // stderr
}
drop(tx);
let rc = tarantool_main!(
args.tt_args().unwrap(),
callback_data: t,
callback_data_type: &InnerTest,
callback_body: test_one(t)
);
std::process::exit(rc);
}
ForkResult::Parent { child } => {
drop(tx);
let log = {
let mut buf = Vec::new();
use std::io::Read;
if !args.nocapture {
rx.read_to_end(&mut buf)
.map_err(|e| println!("error reading ipc pipe: {e}"))
.ok();
}
buf
};
let mut rc: i32 = 0;
unsafe {
libc::waitpid(
child.into(), // pid_t
&mut rc as *mut libc::c_int, // int*
0, // int options
)
};
if rc == 0 {
println!("{PASSED}");
cnt_passed += 1;
} else {
println!("{FAILED}");
cnt_failed += 1;
if args.nocapture {
continue;
}
use std::io::Write;
println!();
std::io::stderr()
.write_all(&log)
.map_err(|e| println!("error writing stderr: {e}"))
.ok();
println!();
}
}
};
}
let ok = cnt_failed == 0;
println!();
print!("test result: {}.", if ok { PASSED } else { FAILED });
print!(" {cnt_passed} passed;");
print!(" {cnt_failed} failed;");
print!(" {cnt_skipped} skipped;");
println!(" finished in {:.2}s", now.elapsed().as_secs_f32());
println!();
std::process::exit(!ok as _);
}
fn test_one(t: &InnerTest) {
use picodata::tarantool;
let temp = tempfile::tempdir().expect("Failed creating a temp directory");
std::env::set_current_dir(temp.path()).expect("Failed chainging current directory");
let cfg = tarantool::Cfg {
listen: Some("127.0.0.1:0".into()),
read_only: false,
log_level: ::tarantool::log::SayLevel::Verbose as u8,
..Default::default()
};
tarantool::set_cfg(&cfg);
tarantool::exec(
r#"
box.schema.user.grant('guest', 'super', nil, nil, {if_not_exists = true})
"#,
)
.unwrap();
(t.body)();
std::process::exit(0i32);
}
use crate::tarantool_main;
use nix::unistd::{self, fork, ForkResult};
use picodata::args;
use picodata::ipc;
use picodata::InnerTest;
macro_rules! color {
(@priv red) => { "\x1b[0;31m" };
(@priv green) => { "\x1b[0;32m" };
(@priv clear) => { "\x1b[0m" };
(@priv $s:literal) => { $s };
($($s:tt)*) => {
::std::concat![ $( color!(@priv $s) ),* ]
}
}
pub fn main_test(args: args::Test) -> ! {
// Tarantool implicitly parses some environment variables.
// We don't want them to affect the behavior and thus filter them out.
for (k, _) in std::env::vars() {
if k.starts_with("TT_") || k.starts_with("TARANTOOL_") {
std::env::remove_var(k)
}
}
const PASSED: &str = color![green "ok" clear];
const FAILED: &str = color![red "FAILED" clear];
let mut cnt_passed = 0u32;
let mut cnt_failed = 0u32;
let mut cnt_skipped = 0u32;
let now = std::time::Instant::now();
println!();
println!(
"total {} tests",
inventory::iter::<InnerTest>.into_iter().count()
);
for t in inventory::iter::<InnerTest> {
if let Some(filter) = args.filter.as_ref() {
if !t.name.contains(filter) {
cnt_skipped += 1;
continue;
}
}
print!("test {} ... ", t.name);
let (mut rx, tx) = ipc::pipe().expect("pipe creation failed");
let pid = unsafe { fork() };
match pid.expect("fork failed") {
ForkResult::Child => {
drop(rx);
unistd::close(0).ok(); // stdin
if !args.nocapture {
unistd::dup2(*tx, 1).ok(); // stdout
unistd::dup2(*tx, 2).ok(); // stderr
}
drop(tx);
let rc = tarantool_main!(
args.tt_args().unwrap(),
callback_data: t,
callback_data_type: &InnerTest,
callback_body: test_one(t)
);
std::process::exit(rc);
}
ForkResult::Parent { child } => {
drop(tx);
let log = {
let mut buf = Vec::new();
use std::io::Read;
if !args.nocapture {
rx.read_to_end(&mut buf)
.map_err(|e| println!("error reading ipc pipe: {e}"))
.ok();
}
buf
};
let mut rc: i32 = 0;
unsafe {
libc::waitpid(
child.into(), // pid_t
&mut rc as *mut libc::c_int, // int*
0, // int options
)
};
if rc == 0 {
println!("{PASSED}");
cnt_passed += 1;
} else {
println!("{FAILED}");
cnt_failed += 1;
if args.nocapture {
continue;
}
use std::io::Write;
println!();
std::io::stderr()
.write_all(&log)
.map_err(|e| println!("error writing stderr: {e}"))
.ok();
println!();
}
}
};
}
let ok = cnt_failed == 0;
println!();
print!("test result: {}.", if ok { PASSED } else { FAILED });
print!(" {cnt_passed} passed;");
print!(" {cnt_failed} failed;");
print!(" {cnt_skipped} skipped;");
println!(" finished in {:.2}s", now.elapsed().as_secs_f32());
println!();
std::process::exit(!ok as _);
}
fn test_one(t: &InnerTest) {
use picodata::tarantool;
let temp = tempfile::tempdir().expect("Failed creating a temp directory");
std::env::set_current_dir(temp.path()).expect("Failed chainging current directory");
let cfg = tarantool::Cfg {
listen: Some("127.0.0.1:0".into()),
read_only: false,
log_level: ::tarantool::log::SayLevel::Verbose as u8,
..Default::default()
};
tarantool::set_cfg(&cfg);
tarantool::exec(
r#"
box.schema.user.grant('guest', 'super', nil, nil, {if_not_exists = true})
"#,
)
.unwrap();
(t.body)();
std::process::exit(0i32);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment