From bcbf2cbb98232cf2e80924b6beb28d9a7801cd6a Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Tue, 4 Mar 2025 15:39:10 +0100 Subject: [PATCH] Test main for failure seen in #7378 for Y2038 bug It's unclear to me how the failure seen in #7378 is related to the change in the PR, it just happen that the test need to try touching in 2068. The 2^32 error in the test makes me strongly think of the year 2038 bug, so I added a test for that. --- tests/by-util/test_touch.rs | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 91298ff9e7..cb7771e178 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -5,6 +5,7 @@ // spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime use crate::common::util::{AtPath, TestScenario}; +use chrono::NaiveDate; #[cfg(not(target_os = "freebsd"))] use filetime::set_symlink_file_times; use filetime::FileTime; @@ -118,6 +119,47 @@ fn test_touch_set_mdhms_time() { assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45296); } +#[test] +fn test_y2038_touch() { + // Jan 19 2038, 03:14:07 UTC is the moment of the Y2038 bug + // test 1 second before, at, and 1 second after + let year = 2038; + let month = 1; + let day = 19; + let hours = 3; + let minutes = 14; + let seconds = 7; + for deltas in [-1i32, 0, 1] { + let (at, mut ucmd) = at_and_ucmd!(); + + let date = NaiveDate::from_ymd_opt(year, month, day).unwrap(); + let datetime = date + .and_hms_opt(hours, minutes, (seconds + deltas).try_into().unwrap()) + .unwrap(); + let timestamp = datetime.and_utc().timestamp(); + + let date = format!( + "{}{:02}{:02}{:02}{:02}.{:02}", + year, + month, + day, + hours, + minutes, + seconds + deltas + ); + let file = format!("Y2038_{}_{}", date, deltas); + ucmd.args(&["-t", &date, &file]).succeeds().no_output(); + + assert!(at.file_exists(&file)); + + let expected = FileTime::from_unix_time(timestamp, 0); + let (atime, mtime) = get_file_times(&at, &file); + assert_eq!(atime, mtime); + assert_eq!(atime, expected); + assert_eq!(mtime, expected); + } +} + #[test] fn test_touch_set_ymdhm_time() { let (at, mut ucmd) = at_and_ucmd!();