time_test.c 2.0 KB

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