Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1+
0002 
0003 #include <kunit/test.h>
0004 #include <linux/time.h>
0005 
0006 /*
0007  * Traditional implementation of leap year evaluation.
0008  */
0009 static bool is_leap(long year)
0010 {
0011     return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
0012 }
0013 
0014 /*
0015  * Gets the last day of a month.
0016  */
0017 static int last_day_of_month(long year, int month)
0018 {
0019     if (month == 2)
0020         return 28 + is_leap(year);
0021     if (month == 4 || month == 6 || month == 9 || month == 11)
0022         return 30;
0023     return 31;
0024 }
0025 
0026 /*
0027  * Advances a date by one day.
0028  */
0029 static void advance_date(long *year, int *month, int *mday, int *yday)
0030 {
0031     if (*mday != last_day_of_month(*year, *month)) {
0032         ++*mday;
0033         ++*yday;
0034         return;
0035     }
0036 
0037     *mday = 1;
0038     if (*month != 12) {
0039         ++*month;
0040         ++*yday;
0041         return;
0042     }
0043 
0044     *month = 1;
0045     *yday  = 0;
0046     ++*year;
0047 }
0048 
0049 /*
0050  * Checks every day in a 160000 years interval centered at 1970-01-01
0051  * against the expected result.
0052  */
0053 static void time64_to_tm_test_date_range(struct kunit *test)
0054 {
0055     /*
0056      * 80000 years  = (80000 / 400) * 400 years
0057      *      = (80000 / 400) * 146097 days
0058      *      = (80000 / 400) * 146097 * 86400 seconds
0059      */
0060     time64_t total_secs = ((time64_t) 80000) / 400 * 146097 * 86400;
0061     long year = 1970 - 80000;
0062     int month = 1;
0063     int mdday = 1;
0064     int yday = 0;
0065 
0066     struct tm result;
0067     time64_t secs;
0068     s64 days;
0069 
0070     for (secs = -total_secs; secs <= total_secs; secs += 86400) {
0071 
0072         time64_to_tm(secs, 0, &result);
0073 
0074         days = div_s64(secs, 86400);
0075 
0076         #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %ld", \
0077             year, month, mdday, yday, days
0078 
0079         KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
0080         KUNIT_ASSERT_EQ_MSG(test, month - 1, result.tm_mon, FAIL_MSG);
0081         KUNIT_ASSERT_EQ_MSG(test, mdday, result.tm_mday, FAIL_MSG);
0082         KUNIT_ASSERT_EQ_MSG(test, yday, result.tm_yday, FAIL_MSG);
0083 
0084         advance_date(&year, &month, &mdday, &yday);
0085     }
0086 }
0087 
0088 static struct kunit_case time_test_cases[] = {
0089     KUNIT_CASE(time64_to_tm_test_date_range),
0090     {}
0091 };
0092 
0093 static struct kunit_suite time_test_suite = {
0094     .name = "time_test_cases",
0095     .test_cases = time_test_cases,
0096 };
0097 
0098 kunit_test_suite(time_test_suite);
0099 MODULE_LICENSE("GPL");