use crate::test_optimization::lib::*;
use crate::test_optimization::utils::*;
use crate::test_optimization::*;
use std::alloc::{alloc, dealloc, Layout};
use std::collections::HashMap;
use std::ffi::{c_char, CString};
use std::ptr::null_mut;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum TestStatus {
Pass = 0,
Fail = 1,
Skip = 2,
}
#[derive(Debug, Clone)]
pub struct Test {
pub(in crate::test_optimization) session_id: u64,
pub(in crate::test_optimization) module_id: u64,
pub(in crate::test_optimization) suite_id: u64,
pub test_id: u64,
}
impl Test {
#[allow(dead_code)]
pub fn get_suite(&self) -> TestSuite {
TestSuite { suite_id: self.suite_id, module_id: self.module_id, session_id: self.session_id }
}
#[allow(dead_code)]
pub fn set_string_tag(&self, key: impl AsRef<str>, value: impl AsRef<str>) -> bool {
let key_cstring = CString::new(key.as_ref()).unwrap();
let value_cstring = CString::new(value.as_ref()).unwrap();
unsafe {
Bool_to_bool(topt_test_set_string_tag(
self.test_id,
key_cstring.as_ptr() as *mut c_char,
value_cstring.as_ptr() as *mut c_char,
))
}
}
#[allow(dead_code)]
pub fn set_number_tag(&self, key: impl AsRef<str>, value: f64) -> bool {
let key_cstring = CString::new(key.as_ref()).unwrap();
unsafe {
Bool_to_bool(topt_test_set_number_tag(
self.test_id,
key_cstring.as_ptr() as *mut c_char,
value,
))
}
}
#[allow(dead_code)]
pub fn set_error_info(
&self,
error_type: impl AsRef<str>,
error_message: impl AsRef<str>,
error_stacktrace: impl AsRef<str>,
) -> bool {
let error_type_cstring = CString::new(error_type.as_ref()).unwrap();
let error_message_cstring = CString::new(error_message.as_ref()).unwrap();
let error_stacktrace_cstring = CString::new(error_stacktrace.as_ref()).unwrap();
unsafe {
Bool_to_bool(topt_test_set_error(
self.test_id,
error_type_cstring.as_ptr() as *mut c_char,
error_message_cstring.as_ptr() as *mut c_char,
error_stacktrace_cstring.as_ptr() as *mut c_char,
))
}
}
#[allow(dead_code)]
pub fn set_test_source(
&self,
file: impl AsRef<str>,
start_line: *const i32,
end_line: *const i32,
) -> bool {
let file_cstring = CString::new(file.as_ref()).unwrap();
unsafe {
Bool_to_bool(topt_test_set_source(
self.test_id,
file_cstring.as_ptr() as *mut c_char,
start_line as *mut i32,
end_line as *mut i32,
))
}
}
#[allow(dead_code)]
pub fn close(&self, status: TestStatus) -> bool {
let mut now = get_now();
let close_options = topt_TestCloseOptions {
status: status as u8,
finish_time: &mut now,
skip_reason: null_mut(),
unused01: null_mut(),
unused02: null_mut(),
unused03: null_mut(),
unused04: null_mut(),
unused05: null_mut(),
};
unsafe {
Bool_to_bool(topt_test_close(self.test_id, close_options))
}
}
#[allow(dead_code)]
pub fn close_with_skip_reason(&self, skip_reason: impl AsRef<str>) -> bool {
let skip_reason_ref = skip_reason.as_ref();
if !skip_reason_ref.is_empty() {
let skip_reason_cstring = CString::new(skip_reason_ref).unwrap();
let mut now = get_now();
let close_options = topt_TestCloseOptions {
status: TestStatus::Skip as u8,
finish_time: &mut now,
skip_reason: skip_reason_cstring.as_ptr() as *mut c_char,
unused01: null_mut(),
unused02: null_mut(),
unused03: null_mut(),
unused04: null_mut(),
unused05: null_mut(),
};
unsafe { Bool_to_bool(topt_test_close(self.test_id, close_options)) }
} else {
self.close(TestStatus::Skip)
}
}
#[allow(dead_code)]
pub fn set_coverage_data(&self, files: &[impl AsRef<str>]) {
unsafe {
let layout = Layout::array::<topt_TestCoverageFile>(files.len()).unwrap();
let coverage_file_ptr = alloc(layout) as *mut topt_TestCoverageFile;
let mut cstrings = Vec::with_capacity(files.len());
for (idx, file) in files.iter().enumerate() {
let cstr = CString::new(file.as_ref()).unwrap();
cstrings.push(cstr);
let filename_ptr = cstrings.last().unwrap().as_ptr() as *mut c_char;
*coverage_file_ptr.add(idx) = topt_TestCoverageFile {
filename: filename_ptr,
bitmap: null_mut(),
bitmap_len: 0,
};
}
let mut coverage_data = topt_TestCoverage {
session_id: self.session_id,
suite_id: self.suite_id,
test_id: self.test_id,
files: coverage_file_ptr,
files_len: files.len(),
};
topt_send_code_coverage_payload(&mut coverage_data, 1);
dealloc(coverage_file_ptr as *mut u8, layout);
}
}
#[allow(dead_code)]
pub fn set_benchmark_string_data<K: AsRef<str>, V: AsRef<str>>(
&self,
measure_type: impl AsRef<str>,
data: &HashMap<K, V>,
) -> bool {
let num_pairs = data.len();
if num_pairs == 0 {
return true;
}
let layout = Layout::array::<topt_KeyValuePair>(num_pairs).unwrap();
let kv_array_ptr = unsafe { alloc(layout) as *mut topt_KeyValuePair };
let mut cstrings: Vec<CString> = Vec::with_capacity(num_pairs * 2);
for (i, (key, value)) in data.iter().enumerate() {
let key_c = CString::new(key.as_ref()).unwrap();
let value_c = CString::new(value.as_ref()).unwrap();
let kv = topt_KeyValuePair {
key: key_c.as_ptr() as *mut c_char,
value: value_c.as_ptr() as *mut c_char,
};
unsafe {
*kv_array_ptr.add(i) = kv;
}
cstrings.push(key_c);
cstrings.push(value_c);
}
let kv_array = topt_KeyValueArray {
data: kv_array_ptr,
len: num_pairs,
};
let measure_type_c = CString::new(measure_type.as_ref()).unwrap();
let result = unsafe {
Bool_to_bool(topt_test_set_benchmark_string_data(
self.test_id,
measure_type_c.as_ptr() as *mut c_char,
kv_array,
))
};
unsafe { dealloc(kv_array_ptr as *mut u8, layout); }
result
}
#[allow(dead_code)]
pub fn set_benchmark_number_data<K: AsRef<str>>(
&self,
measure_type: impl AsRef<str>,
data: &HashMap<K, f64>,
) -> bool {
let num_pairs = data.len();
if num_pairs == 0 {
return true;
}
let layout = Layout::array::<topt_KeyNumberPair>(num_pairs).unwrap();
let kn_array_ptr = unsafe { alloc(layout) as *mut topt_KeyNumberPair };
let mut cstrings: Vec<CString> = Vec::with_capacity(num_pairs);
let mut i = 0;
for (key, &value) in data.iter() {
let key_c = CString::new(key.as_ref()).unwrap();
let kn = topt_KeyNumberPair {
key: key_c.as_ptr() as *mut c_char,
value,
};
unsafe {
*kn_array_ptr.add(i) = kn;
}
cstrings.push(key_c);
i += 1;
}
let kn_array = topt_KeyNumberArray {
data: kn_array_ptr,
len: num_pairs,
};
let measure_type_c = CString::new(measure_type.as_ref()).unwrap();
let result = unsafe {
Bool_to_bool(topt_test_set_benchmark_number_data(
self.test_id,
measure_type_c.as_ptr() as *mut c_char,
kn_array,
))
};
unsafe { dealloc(kn_array_ptr as *mut u8, layout); }
result
}
#[allow(dead_code)]
pub fn log(&self, message: impl AsRef<str>, tags: Option<impl AsRef<str>>) -> bool {
let message_cstring = CString::new(message.as_ref()).unwrap();
let tags_cstring = tags.map(|wd| CString::new(wd.as_ref()).unwrap());
unsafe {
Bool_to_bool(topt_test_log(
self.test_id,
message_cstring.as_ptr() as *mut c_char,
tags_cstring
.as_ref()
.map_or(null_mut(), |s| s.as_ptr() as *mut c_char),
))
}
}
}