#[cfg(feature = "time_profiling")]
use std::env;
#[cfg(feature = "time_profiling")]
use thag_profiler::{
ProfileConfiguration, ProfileType, end, profile,
profiling::{
disable_profiling, is_profiling_enabled, is_profiling_state_enabled, set_profile_config,
},
};
#[cfg(feature = "time_profiling")]
#[thag_profiler::enable_profiling]
fn default_enabled_function() {
assert!(is_profiling_enabled(), "Profiling should be enabled");
#[cfg(feature = "full_profiling")]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Both,
"Default global profile type should be Both with full_profiling feature"
);
#[cfg(all(feature = "time_profiling", not(feature = "full_profiling")))]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Time,
"Default global profile type should be Time with time_profiling feature"
);
profile!(default_section, time);
let _ = (0..100).sum::<i32>(); end!(default_section);
}
#[cfg(feature = "time_profiling")]
#[thag_profiler::enable_profiling(yes)]
fn yes_enabled_function() {
assert!(
is_profiling_enabled(),
"Profiling should be enabled with 'yes' option"
);
profile!(yes_section, time);
let _ = (0..100).sum::<i32>(); end!(yes_section);
}
#[cfg(feature = "time_profiling")]
#[thag_profiler::enable_profiling(no)]
fn no_disabled_function() {
assert!(
!is_profiling_enabled(),
"Profiling should be disabled with 'no' option"
);
profile!(no_section, time);
let _ = (0..100).sum::<i32>(); end!(no_section);
}
#[cfg(feature = "time_profiling")]
#[thag_profiler::enable_profiling(time)]
fn time_enabled_function() {
assert!(
is_profiling_enabled(),
"Profiling should be enabled with 'time' option"
);
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Time,
"Global profile type should be Time"
);
profile!(time_section, time);
let _ = (0..100).sum::<i32>(); end!(time_section);
}
#[cfg(feature = "full_profiling")]
#[thag_profiler::enable_profiling(memory)]
fn memory_enabled_function() {
assert!(
is_profiling_enabled(),
"Profiling should be enabled with 'memory' option"
);
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Memory,
"Global profile type should be Memory"
);
profile!(memory_section, mem_summary);
let data = vec![0u8; 1024]; let _ = data.len(); end!(memory_section);
}
#[cfg(feature = "full_profiling")]
#[thag_profiler::enable_profiling(both)]
fn both_enabled_function() {
assert!(
is_profiling_enabled(),
"Profiling should be enabled with 'both' option"
);
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Both,
"Global profile type should be Both"
);
profile!(both_section, both);
let data = vec![0u8; 1024]; let result = (0..100).sum::<usize>(); let _ = data.len() + result; end!(both_section);
}
#[cfg(feature = "time_profiling")]
#[thag_profiler::enable_profiling(runtime)]
fn runtime_controlled_function() {
let env_var_exists = env::var("THAG_PROFILER").is_ok();
assert_eq!(
is_profiling_enabled(),
env_var_exists,
"Profiling enabled state should match THAG_PROFILER environment variable presence"
);
if env_var_exists {
let env_value = env::var("THAG_PROFILER").unwrap();
let parts: Vec<&str> = env_value.split(',').collect();
if !parts.is_empty() {
let profile_type = parts[0].trim();
match profile_type {
"time" => assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Time,
"Global profile type should be Time from env var"
),
"memory" => {
#[cfg(feature = "full_profiling")]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Memory,
"Global profile type should be Memory from env var"
);
#[cfg(not(feature = "full_profiling"))]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Time,
"Global profile type should fall back to Time when Memory requested but full_profiling not enabled"
);
}
"both" => {
#[cfg(feature = "full_profiling")]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Both,
"Global profile type should be Both from env var"
);
#[cfg(not(feature = "full_profiling"))]
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Time,
"Global profile type should fall back to Time when Both requested but full_profiling not enabled"
);
}
_ => {}
}
if parts.len() >= 4 && !parts[3].trim().is_empty() {
let detailed_memory = parts[3].trim().parse::<bool>().unwrap_or(false);
assert_eq!(
thag_profiler::is_detailed_memory(),
detailed_memory
&& (profile_type == "memory" || profile_type == "both")
&& cfg!(feature = "full_profiling"),
"Detailed memory setting should match env var"
);
}
}
}
if is_profiling_enabled() {
profile!(runtime_section, time);
let _ = (0..100).sum::<i32>(); end!(runtime_section);
}
}
#[test]
#[cfg(feature = "time_profiling")]
#[allow(clippy::too_many_lines)]
fn test_enable_profiling_full_sequence() {
use thag_profiler::profiling::{clear_profile_config_cache, set_global_profile_type};
let max_profile_type = if cfg!(feature = "full_profiling") {
ProfileType::Both
} else {
ProfileType::Time
};
unsafe { env::remove_var("THAG_PROFILER") };
disable_profiling();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled at test start"
);
eprintln!("Testing default enabled function...");
default_enabled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
assert_eq!(thag_profiler::get_global_profile_type(), max_profile_type);
eprintln!("Testing yes enabled function...");
disable_profiling(); yes_enabled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
eprintln!("Testing no disabled function...");
enable_time_profiling_for_test();
no_disabled_function();
#[thag_profiler::enable_profiling(time)]
fn enable_time_profiling_for_test() {}
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
eprintln!("Testing time enabled function...");
disable_profiling();
set_global_profile_type(ProfileType::None);
time_enabled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
#[cfg(feature = "full_profiling")]
{
eprintln!("Testing memory enabled function...");
disable_profiling();
memory_enabled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
}
#[cfg(feature = "full_profiling")]
{
eprintln!("Testing both enabled function...");
disable_profiling();
both_enabled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
}
eprintln!("Testing runtime with no env var...");
unsafe { env::remove_var("THAG_PROFILER") };
disable_profiling();
clear_profile_config_cache();
runtime_controlled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
eprintln!("Testing runtime with time profile...");
unsafe { env::set_var("THAG_PROFILER", "time,.,none,false") };
disable_profiling();
clear_profile_config_cache();
runtime_controlled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
eprintln!("Testing runtime with invalid profile...");
unsafe { env::set_var("THAG_PROFILER", "invalid,.,none,false") };
disable_profiling();
clear_profile_config_cache();
let _result = std::panic::catch_unwind(|| {
runtime_controlled_function();
});
set_profile_config(
ProfileConfiguration::try_from(vec!["time", "", "announce"].as_slice()).unwrap(),
);
disable_profiling();
assert!(
!is_profiling_state_enabled(),
"Profiling should be disabled after function"
);
#[cfg(feature = "full_profiling")]
{
unsafe { env::set_var("THAG_PROFILER", "both,.,none,true") };
clear_profile_config_cache();
runtime_controlled_function();
assert!(!is_profiling_state_enabled());
assert_eq!(thag_profiler::get_global_profile_type(), max_profile_type);
assert!(thag_profiler::is_detailed_memory());
}
#[cfg(feature = "full_profiling")]
{
unsafe { env::set_var("THAG_PROFILER", "memory,.,quiet,false") };
clear_profile_config_cache();
runtime_controlled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should remain disabled when THAG_PROFILER is not set"
);
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Memory,
"Global profile type should be Memory when set in environment variable"
);
assert!(
!thag_profiler::is_detailed_memory(),
"Detailed memory should be disabled"
);
}
#[cfg(feature = "full_profiling")]
{
unsafe { env::set_var("THAG_PROFILER", "memory,.,announce,true") };
clear_profile_config_cache();
runtime_controlled_function();
assert!(
!is_profiling_state_enabled(),
"Profiling should remain disabled when THAG_PROFILER is not set"
);
assert_eq!(
thag_profiler::get_global_profile_type(),
ProfileType::Memory,
"Global profile type should be Memory when set in environment variable"
);
assert!(
thag_profiler::is_detailed_memory(),
"Detailed memory should be enabled"
);
}
unsafe { env::remove_var("THAG_PROFILER") };
disable_profiling();
println!("All enable_profiling tests completed successfully!");
}