Skip to content

Commit df4d483

Browse files
committed
Add test to validate deduplication of 'tm.tm_zone' string.
Signed-off-by: shamb0 <r.raajey@gmail.com>
1 parent 6666c44 commit df4d483

File tree

1 file changed

+100
-1
lines changed

1 file changed

+100
-1
lines changed

tests/pass-dep/libc/libc-time.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ fn main() {
88
test_localtime_r_gmt();
99
test_localtime_r_pst();
1010
test_localtime_r_epoch();
11+
test_localtime_r_verify_string_deduplication();
12+
test_localtime_r_multiple_calls_deduplication()
1113
// Architecture-specific tests.
1214
#[cfg(target_pointer_width = "32")]
1315
test_localtime_r_future_32b();
@@ -125,7 +127,7 @@ fn test_localtime_r_gmt() {
125127
fn test_localtime_r_pst() {
126128
let key = "TZ";
127129
env::set_var(key, "PST8PDT");
128-
const TIME_SINCE_EPOCH: libc::time_t = 1712475836;// 2024-04-07 07:43:56 GMT
130+
const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT
129131
let custom_time_ptr = &TIME_SINCE_EPOCH;
130132
let mut tm = create_empty_tm();
131133

@@ -276,3 +278,100 @@ fn test_localtime_r_future_32b() {
276278
assert!(ptr::eq(res, &mut tm));
277279
env::remove_var(key);
278280
}
281+
282+
fn test_localtime_r_verify_string_deduplication() {
283+
let key = "TZ";
284+
env::set_var(key, "PST8PDT");
285+
286+
// Two timestamps that are in the same timezone (PST/PDT).
287+
const TIME_SINCE_EPOCH_TZ_CONST1: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT
288+
const TIME_SINCE_EPOCH_TZ_CONST2: libc::time_t = 1712575836; // 2024-04-08 11:23:56 GMT
289+
const TIME_SINCE_EPOCH_TZ_CONST3: libc::time_t = 1712675836; // 2024-04-09 11:23:56 GMT
290+
291+
let mut tm1 = create_empty_tm();
292+
let mut tm2 = create_empty_tm();
293+
let mut tm3 = create_empty_tm();
294+
295+
unsafe {
296+
let res1 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST1, &mut tm1);
297+
let res2 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST2, &mut tm2);
298+
let res3 = libc::localtime_r(&TIME_SINCE_EPOCH_TZ_CONST3, &mut tm3);
299+
300+
assert!(res1.is_null() == false, "localtime_r failed for first timestamp");
301+
assert!(res2.is_null() == false, "localtime_r failed for second timestamp");
302+
assert!(res3.is_null() == false, "localtime_r failed for third timestamp");
303+
304+
#[cfg(any(
305+
target_os = "linux",
306+
target_os = "macos",
307+
target_os = "freebsd",
308+
target_os = "android"
309+
))]
310+
{
311+
let tm_zone1 = std::ffi::CStr::from_ptr(tm1.tm_zone);
312+
let tm_zone2 = std::ffi::CStr::from_ptr(tm2.tm_zone);
313+
314+
println!("tz res1 :: {:#?}", tm1.tm_zone);
315+
println!("tz res2 :: {:#?}", tm2.tm_zone);
316+
println!("tz res3 :: {:#?}", tm3.tm_zone);
317+
318+
assert_eq!(
319+
tm_zone1, tm_zone2,
320+
"tm_zone strings are not equal, indicating different values."
321+
);
322+
323+
assert_eq!(
324+
tm1.tm_zone, tm2.tm_zone,
325+
"tm_zone pointers are not equal, string deduplication is not happening."
326+
);
327+
}
328+
}
329+
}
330+
331+
fn test_localtime_r_multiple_calls_deduplication() {
332+
let key = "TZ";
333+
env::set_var(key, "PST8PDT");
334+
335+
const TIME_SINCE_EPOCH_BASE: libc::time_t = 1712475836; // Base timestamp: 2024-04-07 07:43:56 GMT
336+
const NUM_CALLS: usize = 50;
337+
338+
let mut tm_array: Vec<libc::tm> = vec![create_empty_tm(); NUM_CALLS];
339+
let mut unique_pointers = std::collections::HashSet::new();
340+
341+
unsafe {
342+
for i in 0..NUM_CALLS {
343+
let timestamp = TIME_SINCE_EPOCH_BASE + (i as libc::time_t * 3600); // Increment by 1 hour for each call
344+
let tm_ptr = libc::localtime_r(&timestamp, &mut tm_array[i]);
345+
346+
assert!(!tm_ptr.is_null(), "localtime_r failed for timestamp {timestamp}");
347+
348+
#[cfg(any(
349+
target_os = "linux",
350+
target_os = "macos",
351+
target_os = "freebsd",
352+
target_os = "android"
353+
))]
354+
{
355+
let tm_zone_ptr = tm_array[i].tm_zone;
356+
unique_pointers.insert(tm_zone_ptr);
357+
}
358+
}
359+
360+
#[cfg(any(
361+
target_os = "linux",
362+
target_os = "macos",
363+
target_os = "freebsd",
364+
target_os = "android"
365+
))]
366+
{
367+
let unique_count = unique_pointers.len();
368+
println!("Number of unique tm_zone pointers: {}", unique_count);
369+
370+
assert!(
371+
unique_count >= 2 && unique_count <= (NUM_CALLS - 1),
372+
"Unexpected number of unique tm_zone pointers: {} (expected between 2 and {})",
373+
unique_count, NUM_CALLS - 1
374+
);
375+
}
376+
}
377+
}

0 commit comments

Comments
 (0)