Devuan fork of gpsd
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

262 lines
10 KiB

  1. /*
  2. * tests for mktime(), mkgmtime(), timespec_to_iso8601() and
  3. * iso8601_to_timespec().
  4. * mktime() is a libc function, why test it?
  5. *
  6. * This file is Copyright (c) 2010-2019 by the GPSD project
  7. * SPDX-License-Identifier: BSD-2-clause
  8. */
  9. #include <limits.h>
  10. #include <math.h> /* for fabs() */
  11. #include <stdbool.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <time.h>
  16. #include "../gps.h"
  17. #include "../compiler.h"
  18. #include "../timespec.h"
  19. static struct
  20. {
  21. struct tm t;
  22. time_t result;
  23. } tests[] = {
  24. /* *INDENT-OFF* */
  25. /* sec, min, h, md, mon, year, wd, yd, isdst, gmtoff, zone,
  26. * time_t what */
  27. /* lower limit */
  28. {{ 0, 0, 0, 1, 0, 70, 0, 0, 0, 0, 0}, 0},
  29. /* upper limit */
  30. {{ 7, 14, 3, 19, 0, 138, 0, 0, 0, 0, 0}, 0x7fffffff},
  31. /* leap year */
  32. {{ 0, 0, 12, 1, 0, 99, 0, 0, 0, 0, 0}, 915192000},
  33. /* leap year */
  34. {{ 0, 0, 12, 1, 1, 99, 0, 0, 0, 0, 0}, 917870400},
  35. /* leap year */
  36. {{ 0, 0, 12, 1, 2, 99, 0, 0, 0, 0, 0}, 920289600},
  37. /* leap year */
  38. {{ 0, 0, 12, 1, 8, 99, 0, 0, 0, 0, 0}, 936187200},
  39. /* leap year */
  40. {{ 0, 0, 12, 1, 0, 100, 0, 0, 0, 0, 0}, 946728000},
  41. /* leap year */
  42. {{ 0, 0, 12, 1, 1, 100, 0, 0, 0, 0, 0}, 949406400},
  43. /* leap year */
  44. {{ 0, 0, 12, 1, 2, 100, 0, 0, 0, 0, 0}, 951912000},
  45. /* leap year */
  46. {{ 0, 0, 12, 1, 8, 100, 0, 0, 0, 0, 0}, 967809600},
  47. /* leap year */
  48. {{ 0, 0, 12, 1, 0, 101, 0, 0, 0, 0, 0}, 978350400},
  49. /* leap year */
  50. {{ 0, 0, 12, 1, 1, 101, 0, 0, 0, 0, 0}, 981028800},
  51. /* leap year */
  52. {{ 0, 0, 12, 1, 2, 101, 0, 0, 0, 0, 0}, 983448000},
  53. /* leap year */
  54. {{ 0, 0, 12, 1, 8, 101, 0, 0, 0, 0, 0}, 999345600},
  55. /* leap year */
  56. {{ 0, 0, 12, 1, 0, 102, 0, 0, 0, 0, 0}, 1009886400},
  57. /* leap year */
  58. {{ 0, 0, 12, 1, 1, 102, 0, 0, 0, 0, 0}, 1012564800},
  59. /* leap year */
  60. {{ 0, 0, 12, 1, 2, 102, 0, 0, 0, 0, 0}, 1014984000},
  61. /* leap year */
  62. {{ 0, 0, 12, 1, 8, 102, 0, 0, 0, 0, 0}, 1030881600},
  63. /* leap year */
  64. {{ 0, 0, 12, 1, 0, 103, 0, 0, 0, 0, 0}, 1041422400},
  65. /* leap year */
  66. {{ 0, 0, 12, 1, 1, 103, 0, 0, 0, 0, 0}, 1044100800},
  67. /* leap year */
  68. {{ 0, 0, 12, 1, 2, 103, 0, 0, 0, 0, 0}, 1046520000},
  69. /* leap year */
  70. {{ 0, 0, 12, 1, 8, 103, 0, 0, 0, 0, 0}, 1062417600},
  71. /* leap year */
  72. {{ 0, 0, 12, 1, 0, 104, 0, 0, 0, 0, 0}, 1072958400},
  73. /* leap year */
  74. {{ 0, 0, 12, 1, 1, 104, 0, 0, 0, 0, 0}, 1075636800},
  75. /* leap year */
  76. {{ 0, 0, 12, 1, 2, 104, 0, 0, 0, 0, 0}, 1078142400},
  77. {{ 0, 0, 12, 1, 2, 104, 0, 0, 0, 0, 0}, 1078142400},
  78. /* leap year */
  79. {{ 0, 0, 12, 1, 8, 104, 0, 0, 0, 0, 0}, 1094040000},
  80. /* leap year */
  81. {{ 0, 0, 12, 1, 0, 108, 0, 0, 0, 0, 0}, 1199188800},
  82. /* leap year */
  83. {{ 0, 0, 12, 1, 1, 108, 0, 0, 0, 0, 0}, 1201867200},
  84. /* leap year */
  85. {{ 0, 0, 12, 1, 2, 108, 0, 0, 0, 0, 0}, 1204372800},
  86. /* leap year */
  87. {{ 0, 0, 12, 1, 8, 108, 0, 0, 0, 0, 0}, 1220270400},
  88. /* year wrap */
  89. {{ 59, 59, 23, 31, 12, 110, 0, 0, 0, 0, 0}, 1296518399},
  90. /* year wrap */
  91. {{ 0, 0, 0, 1, 0, 111, 0, 0, 0, 0, 0}, 1293840000},
  92. /* year wrap */
  93. {{ 59, 59, 23, 31, 12, 111, 0, 0, 0, 0, 0}, 1328054399},
  94. /* year wrap */
  95. {{ 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0}, 1325376000},
  96. /* year wrap */
  97. {{ 59, 59, 23, 31, 12, 112, 0, 0, 0, 0, 0}, 1359676799},
  98. /* year wrap */
  99. {{ 0, 0, 0, 1, 0, 113, 0, 0, 0, 0, 0}, 1356998400},
  100. /* month wrap */
  101. {{ 59, 59, 23, 31, 0, 115, 0, 0, 0, 0, 0}, 1422748799},
  102. /* month wrap */
  103. {{ 0, 0, 0, 1, 1, 115, 0, 0, 0, 0, 0}, 1422748800},
  104. /* month wrap */
  105. {{ 59, 59, 23, 28, 1, 115, 0, 0, 0, 0, 0}, 1425167999},
  106. /* month wrap */
  107. {{ 0, 0, 0, 1, 2, 115, 0, 0, 0, 0, 0}, 1425168000},
  108. /* month wrap */
  109. {{ 59, 59, 23, 31, 2, 115, 0, 0, 0, 0, 0}, 1427846399},
  110. /* month wrap */
  111. {{ 0, 0, 0, 1, 3, 115, 0, 0, 0, 0, 0}, 1427846400},
  112. /* month wrap */
  113. {{ 59, 59, 23, 30, 3, 115, 0, 0, 0, 0, 0}, 1430438399},
  114. /* month wrap */
  115. {{ 0, 0, 0, 1, 4, 115, 0, 0, 0, 0, 0}, 1430438400},
  116. /* month wrap */
  117. {{ 59, 59, 23, 31, 4, 115, 0, 0, 0, 0, 0}, 1433116799},
  118. /* month wrap */
  119. {{ 0, 0, 0, 1, 5, 115, 0, 0, 0, 0, 0}, 1433116800},
  120. /* month wrap */
  121. {{ 59, 59, 23, 30, 5, 115, 0, 0, 0, 0, 0}, 1435708799},
  122. /* month wrap */
  123. {{ 0, 0, 0, 1, 6, 115, 0, 0, 0, 0, 0}, 1435708800},
  124. /* month wrap */
  125. {{ 59, 59, 23, 31, 6, 115, 0, 0, 0, 0, 0}, 1438387199},
  126. /* month wrap */
  127. {{ 0, 0, 0, 1, 7, 115, 0, 0, 0, 0, 0}, 1438387200},
  128. /* month wrap */
  129. {{ 59, 59, 23, 31, 7, 115, 0, 0, 0, 0, 0}, 1441065599},
  130. /* month wrap */
  131. {{ 0, 0, 0, 1, 8, 115, 0, 0, 0, 0, 0}, 1441065600},
  132. /* month wrap */
  133. {{ 59, 59, 23, 30, 8, 115, 0, 0, 0, 0, 0}, 1443657599},
  134. /* month wrap */
  135. {{ 0, 0, 0, 1, 9, 115, 0, 0, 0, 0, 0}, 1443657600},
  136. /* month wrap */
  137. {{ 59, 59, 23, 31, 9, 115, 0, 0, 0, 0, 0}, 1446335999},
  138. /* month wrap */
  139. {{ 0, 0, 0, 1, 10, 115, 0, 0, 0, 0, 0}, 1446336000},
  140. /* month wrap */
  141. {{ 59, 59, 23, 30, 10, 115, 0, 0, 0, 0, 0}, 1448927999},
  142. /* month wrap */
  143. {{ 0, 0, 0, 1, 11, 115, 0, 0, 0, 0, 0}, 1448928000},
  144. /* month wrap */
  145. {{ 59, 59, 23, 31, 11, 115, 0, 0, 0, 0, 0}, 1451606399},
  146. /* month wrap */
  147. {{ 0, 0, 0, 1, 0, 116, 0, 0, 0, 0, 0}, 1451606400},
  148. /* *INDENT-ON* */
  149. };
  150. /* tests for timespec_to_iso8601() */
  151. static struct
  152. {
  153. timespec_t ts_time;
  154. char *iso8601; /* iso8601 result */
  155. } tests1[] = {
  156. /* time zero */
  157. {{0, 0}, "1970-01-01T00:00:00.000Z"},
  158. /* before/after leap second end of 2008, notice no :60! */
  159. {{1230767999L, 1000000L}, "2008-12-31T23:59:59.001Z"},
  160. {{1230767999L, 10000000L}, "2008-12-31T23:59:59.010Z"},
  161. {{1230767999L, 100000000L}, "2008-12-31T23:59:59.100Z"},
  162. {{1230768000L, 20000000L}, "2009-01-01T00:00:00.020Z"},
  163. /* test for rounding at %.3f */
  164. {{1541766896L, 999412000L}, "2018-11-09T12:34:56.999Z"},
  165. {{1541766896L, 999499000L}, "2018-11-09T12:34:56.999Z"},
  166. {{1541766896L, 999500000L}, "2018-11-09T12:34:57.000Z"},
  167. {{1541766896L, 999501000L}, "2018-11-09T12:34:57.000Z"},
  168. /* the end of time: 2038 */
  169. {{2147483647L, 123456000L}, "2038-01-19T03:14:07.123Z"},
  170. #if 4 < SIZEOF_TIME_T
  171. /* this next line generates compiler warning if 4 < sizeof(time_t)
  172. * if so, the test will fail, and your system will break in 2038 */
  173. {{2147483648L, 123456000L}, "2038-01-19T03:14:08.123Z"},
  174. #endif
  175. };
  176. int main(int argc UNUSED, char *argv[] UNUSED)
  177. {
  178. int i;
  179. char tbuf[128];
  180. bool failed = false;
  181. timespec_t ts_time;
  182. char ts_buf[TIMESPEC_LEN];
  183. (void)setenv("TZ", "GMT", 1);
  184. /* test mktime() */
  185. for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
  186. time_t ts = mktime(&tests[i].t);
  187. if (ts != tests[i].result) {
  188. failed = true;
  189. (void)strftime(tbuf, sizeof(tbuf), "%F %T", &tests[i].t);
  190. (void)printf("test_mktime: mktime() test %2d failed.\n"
  191. " Time returned from: %s should be %lu "
  192. " (but was: %lu)\n",
  193. i, tbuf, (unsigned long)tests[i].result,
  194. (unsigned long)ts);
  195. }
  196. }
  197. /* test mkgmtime() */
  198. for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
  199. time_t ts = mkgmtime(&tests[i].t);
  200. if (ts != tests[i].result) {
  201. failed = true;
  202. (void)strftime(tbuf, sizeof(tbuf), "%F %T", &tests[i].t);
  203. (void)printf("test_mktime: mkgmtime() test %2d failed.\n"
  204. " Time returned from: %s should be %lu "
  205. " (but was: %lu)\n",
  206. i, tbuf, (unsigned long)tests[i].result,
  207. (unsigned long)ts);
  208. }
  209. }
  210. /* test timespec_to_iso8601() */
  211. if ( 4 >= sizeof(time_t)) {
  212. (void)printf("WARNING: time_t too small. This gpsd binary "
  213. "will fail at the 2038 roll over\n");
  214. }
  215. for (i = 0; i < (int)(sizeof(tests1) / sizeof(tests1[0])); i++) {
  216. timespec_to_iso8601(tests1[i].ts_time, tbuf, sizeof(tbuf));
  217. if (0 != strcmp(tests1[i].iso8601, tbuf)) {
  218. failed = true;
  219. (void)printf("test_mktime: timespec_to_iso8601() test %s failed.\n"
  220. " Got %s, s/b %s\n",
  221. timespec_str(&tests1[i].ts_time, ts_buf,
  222. sizeof(ts_buf)),
  223. tbuf, tests1[i].iso8601);
  224. }
  225. }
  226. /* test iso8601_to_timespec() */
  227. for (i = 0; i < (int)(sizeof(tests1) / sizeof(tests1[0])); i++) {
  228. timespec_t ts_tmp;
  229. ts_time = iso8601_to_timespec(tests1[i].iso8601);
  230. TS_SUB(&ts_tmp, &ts_time, &tests1[i].ts_time);
  231. if (0.001 <= fabs(TSTONS(&ts_tmp))) {
  232. failed = true;
  233. (void)printf("test_mktime: iso8601_to_timespec() test %s failed.\n"
  234. " Got %.3f, s/b %.3f\n",
  235. tests1[i].iso8601, TSTONS(&ts_time),
  236. TSTONS(&tests1[i].ts_time));
  237. }
  238. }
  239. return (int)failed;
  240. }
  241. /* end */