From df4d4836751cb058afc85eeaae97bcb852a78f7e Mon Sep 17 00:00:00 2001 From: shamb0 Date: Wed, 11 Dec 2024 19:11:07 +0530 Subject: [PATCH] Add test to validate deduplication of 'tm.tm_zone' string. Signed-off-by: shamb0 --- tests/pass-dep/libc/libc-time.rs | 101 ++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/tests/pass-dep/libc/libc-time.rs b/tests/pass-dep/libc/libc-time.rs index 06af1e8c85..7f64f52219 100644 --- a/tests/pass-dep/libc/libc-time.rs +++ b/tests/pass-dep/libc/libc-time.rs @@ -8,6 +8,8 @@ fn main() { test_localtime_r_gmt(); test_localtime_r_pst(); test_localtime_r_epoch(); + test_localtime_r_verify_string_deduplication(); + test_localtime_r_multiple_calls_deduplication() // Architecture-specific tests. #[cfg(target_pointer_width = "32")] test_localtime_r_future_32b(); @@ -125,7 +127,7 @@ fn test_localtime_r_gmt() { fn test_localtime_r_pst() { let key = "TZ"; env::set_var(key, "PST8PDT"); - const TIME_SINCE_EPOCH: libc::time_t = 1712475836;// 2024-04-07 07:43:56 GMT + const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT let custom_time_ptr = &TIME_SINCE_EPOCH; let mut tm = create_empty_tm(); @@ -276,3 +278,100 @@ fn test_localtime_r_future_32b() { assert!(ptr::eq(res, &mut tm)); env::remove_var(key); } + +fn test_localtime_r_verify_string_deduplication() { + let key = "TZ"; + env::set_var(key, "PST8PDT"); + + // Two timestamps that are in the same timezone (PST/PDT). + const TIME_SINCE_EPOCH_TZ_CONST1: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT + const TIME_SINCE_EPOCH_TZ_CONST2: libc::time_t = 1712575836; // 2024-04-08 11:23:56 GMT + const TIME_SINCE_EPOCH_TZ_CONST3: libc::time_t = 1712675836; // 2024-04-09 11:23:56 GMT + + let mut tm1 = create_empty_tm(); + let mut tm2 = create_empty_tm(); + let mut tm3 = create_empty_tm(); + + unsafe { + let res1 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST1, &mut tm1); + let res2 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST2, &mut tm2); + let res3 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST3, &mut tm3); + + assert!(res1.is_null() == false, "localtime_r failed for first timestamp"); + assert!(res2.is_null() == false, "localtime_r failed for second timestamp"); + assert!(res3.is_null() == false, "localtime_r failed for third timestamp"); + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + let tm_zone1 = std::ffi::CStr::from_ptr(tm1.tm_zone); + let tm_zone2 = std::ffi::CStr::from_ptr(tm2.tm_zone); + + println!("tz res1 :: {:#?}", tm1.tm_zone); + println!("tz res2 :: {:#?}", tm2.tm_zone); + println!("tz res3 :: {:#?}", tm3.tm_zone); + + assert_eq!( + tm_zone1, tm_zone2, + "tm_zone strings are not equal, indicating different values." + ); + + assert_eq!( + tm1.tm_zone, tm2.tm_zone, + "tm_zone pointers are not equal, string deduplication is not happening." + ); + } + } +} + +fn test_localtime_r_multiple_calls_deduplication() { + let key = "TZ"; + env::set_var(key, "PST8PDT"); + + const TIME_SINCE_EPOCH_BASE: libc::time_t = 1712475836; // Base timestamp: 2024-04-07 07:43:56 GMT + const NUM_CALLS: usize = 50; + + let mut tm_array: Vec = vec![create_empty_tm(); NUM_CALLS]; + let mut unique_pointers = std::collections::HashSet::new(); + + unsafe { + for i in 0..NUM_CALLS { + let timestamp = TIME_SINCE_EPOCH_BASE + (i as libc::time_t * 3600); // Increment by 1 hour for each call + let tm_ptr = libc::localtime_r(×tamp, &mut tm_array[i]); + + assert!(!tm_ptr.is_null(), "localtime_r failed for timestamp {timestamp}"); + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + let tm_zone_ptr = tm_array[i].tm_zone; + unique_pointers.insert(tm_zone_ptr); + } + } + + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "android" + ))] + { + let unique_count = unique_pointers.len(); + println!("Number of unique tm_zone pointers: {}", unique_count); + + assert!( + unique_count >= 2 && unique_count <= (NUM_CALLS - 1), + "Unexpected number of unique tm_zone pointers: {} (expected between 2 and {})", + unique_count, NUM_CALLS - 1 + ); + } + } +}