test-time-util: suppress timestamp conversion failures for Africa/Khartoum timezone
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 26 Nov 2023 19:58:43 +0000 (20:58 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 27 Nov 2023 16:22:09 +0000 (16:22 +0000)
Our timestamp conversion roundtrip test was failing. But I think that this
is not our bug:

$ TZ='Africa/Khartoum' date --date='@1509482094'
Tue Oct 31 23:34:54 EAT 2017
$ TZ='Africa/Khartoum' date --date='Tue Oct 31 23:34:54 EAT 2017' +%s
1509485694
$ TZ='Africa/Khartoum' date --date='@1509485694'
Tue Oct 31 23:34:54 CAT 2017
$ echo $[1509485694 - 1509482094]
3600

This is essentially the same as what happens in our test. After a round-trip, we
end up one hour ahead.

> For 1509482094632752, from the change log of tzdata:
>
> Release 2017c - 2017-10-20 14:49:34 -0700
>
>  Changes to future timestamps
>    Sudan will switch from +03 to +02 on 2017-11-01.

Fixes https://github.com/systemd/systemd/issues/28472.

src/test/test-time-util.c

index e7b1a55..76931ce 100644 (file)
@@ -391,7 +391,7 @@ TEST(format_timestamp) {
 }
 
 static void test_format_timestamp_impl(usec_t x) {
-        bool success;
+        bool success, override;
         const char *xx, *yy;
         usec_t y;
 
@@ -402,9 +402,19 @@ static void test_format_timestamp_impl(usec_t x) {
         assert_se(yy);
 
         success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
-        log_full(success ? LOG_DEBUG : LOG_ERR, "@" USEC_FMT " → %s → @" USEC_FMT " → %s", x, xx, y, yy);
-        assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
-        assert_se(streq(xx, yy));
+        /* Workaround for https://github.com/systemd/systemd/issues/28472 */
+        override = !success &&
+                   (STRPTR_IN_SET(tzname[0], "CAT", "EAT") ||
+                    STRPTR_IN_SET(tzname[1], "CAT", "EAT")) &&
+                   DIV_ROUND_UP(y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
+        log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
+                 "@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
+                 x, xx, y, yy,
+                 override ? ", ignoring." : "");
+        if (!override) {
+                assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
+                assert_se(streq(xx, yy));
+        }
 }
 
 static void test_format_timestamp_loop(void) {
@@ -414,6 +424,10 @@ static void test_format_timestamp_loop(void) {
         test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX-1);
         test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX);
 
+        /* Two cases which trigger https://github.com/systemd/systemd/issues/28472 */
+        test_format_timestamp_impl(1504938962980066);
+        test_format_timestamp_impl(1509482094632752);
+
         for (unsigned i = 0; i < TRIAL; i++) {
                 usec_t x;