linux/kernel/time/time_test.c
<<
>>
Prefs
   1// SPDX-License-Identifier: LGPL-2.1+
   2
   3#include <kunit/test.h>
   4#include <linux/time.h>
   5
   6/*
   7 * Traditional implementation of leap year evaluation.
   8 */
   9static bool is_leap(long year)
  10{
  11        return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
  12}
  13
  14/*
  15 * Gets the last day of a month.
  16 */
  17static int last_day_of_month(long year, int month)
  18{
  19        if (month == 2)
  20                return 28 + is_leap(year);
  21        if (month == 4 || month == 6 || month == 9 || month == 11)
  22                return 30;
  23        return 31;
  24}
  25
  26/*
  27 * Advances a date by one day.
  28 */
  29static void advance_date(long *year, int *month, int *mday, int *yday)
  30{
  31        if (*mday != last_day_of_month(*year, *month)) {
  32                ++*mday;
  33                ++*yday;
  34                return;
  35        }
  36
  37        *mday = 1;
  38        if (*month != 12) {
  39                ++*month;
  40                ++*yday;
  41                return;
  42        }
  43
  44        *month = 1;
  45        *yday  = 0;
  46        ++*year;
  47}
  48
  49/*
  50 * Checks every day in a 160000 years interval centered at 1970-01-01
  51 * against the expected result.
  52 */
  53static void time64_to_tm_test_date_range(struct kunit *test)
  54{
  55        /*
  56         * 80000 years  = (80000 / 400) * 400 years
  57         *              = (80000 / 400) * 146097 days
  58         *              = (80000 / 400) * 146097 * 86400 seconds
  59         */
  60        time64_t total_secs = ((time64_t) 80000) / 400 * 146097 * 86400;
  61        long year = 1970 - 80000;
  62        int month = 1;
  63        int mdday = 1;
  64        int yday = 0;
  65
  66        struct tm result;
  67        time64_t secs;
  68        s64 days;
  69
  70        for (secs = -total_secs; secs <= total_secs; secs += 86400) {
  71
  72                time64_to_tm(secs, 0, &result);
  73
  74                days = div_s64(secs, 86400);
  75
  76                #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %ld", \
  77                        year, month, mdday, yday, days
  78
  79                KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
  80                KUNIT_ASSERT_EQ_MSG(test, month - 1, result.tm_mon, FAIL_MSG);
  81                KUNIT_ASSERT_EQ_MSG(test, mdday, result.tm_mday, FAIL_MSG);
  82                KUNIT_ASSERT_EQ_MSG(test, yday, result.tm_yday, FAIL_MSG);
  83
  84                advance_date(&year, &month, &mdday, &yday);
  85        }
  86}
  87
  88static struct kunit_case time_test_cases[] = {
  89        KUNIT_CASE(time64_to_tm_test_date_range),
  90        {}
  91};
  92
  93static struct kunit_suite time_test_suite = {
  94        .name = "time_test_cases",
  95        .test_cases = time_test_cases,
  96};
  97
  98kunit_test_suite(time_test_suite);
  99MODULE_LICENSE("GPL");
 100