test_mainloop.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* Copyright (c) 2018, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file test_mainloop.c
  5. * \brief Tests for functions closely related to the Tor main loop
  6. */
  7. #include "test/test.h"
  8. #include "test/log_test_helpers.h"
  9. #include "core/or/or.h"
  10. #include "core/mainloop/main.h"
  11. static const uint64_t BILLION = 1000000000;
  12. static void
  13. test_mainloop_update_time_normal(void *arg)
  14. {
  15. (void)arg;
  16. monotime_enable_test_mocking();
  17. /* This is arbitrary */
  18. uint64_t mt_now = UINT64_C(7493289274986);
  19. /* This time is in the past as of when this test was written. */
  20. time_t now = 1525272090;
  21. monotime_coarse_set_mock_time_nsec(mt_now);
  22. reset_uptime();
  23. update_current_time(now);
  24. tt_int_op(approx_time(), OP_EQ, now);
  25. tt_int_op(get_uptime(), OP_EQ, 0);
  26. update_current_time(now); // Same time as before is a no-op.
  27. tt_int_op(get_uptime(), OP_EQ, 0);
  28. now += 1;
  29. mt_now += BILLION;
  30. monotime_coarse_set_mock_time_nsec(mt_now);
  31. update_current_time(now);
  32. tt_int_op(approx_time(), OP_EQ, now);
  33. tt_int_op(get_uptime(), OP_EQ, 1);
  34. now += 2; // two-second jump is unremarkable.
  35. mt_now += 2*BILLION;
  36. update_current_time(now);
  37. monotime_coarse_set_mock_time_nsec(mt_now);
  38. tt_int_op(approx_time(), OP_EQ, now);
  39. tt_int_op(get_uptime(), OP_EQ, 3);
  40. now -= 1; // a one-second hop backwards is also unremarkable.
  41. update_current_time(now);
  42. tt_int_op(approx_time(), OP_EQ, now); // it changes the approx time...
  43. tt_int_op(get_uptime(), OP_EQ, 3); // but it doesn't roll back our uptime
  44. done:
  45. monotime_disable_test_mocking();
  46. }
  47. static void
  48. test_mainloop_update_time_jumps(void *arg)
  49. {
  50. (void)arg;
  51. monotime_enable_test_mocking();
  52. /* This is arbitrary */
  53. uint64_t mt_now = UINT64_C(7493289274986);
  54. /* This time is in the past as of when this test was written. */
  55. time_t now = 220897152;
  56. monotime_coarse_set_mock_time_nsec(mt_now);
  57. reset_uptime();
  58. update_current_time(now);
  59. tt_int_op(approx_time(), OP_EQ, now);
  60. tt_int_op(get_uptime(), OP_EQ, 0);
  61. /* Put some uptime on the clock.. */
  62. now += 3;
  63. mt_now += 3*BILLION;
  64. monotime_coarse_set_mock_time_nsec(mt_now);
  65. update_current_time(now);
  66. tt_int_op(approx_time(), OP_EQ, now);
  67. tt_int_op(get_uptime(), OP_EQ, 3);
  68. /* Now try jumping forward and backward, without updating the monotonic
  69. * clock. */
  70. setup_capture_of_logs(LOG_NOTICE);
  71. now += 1800;
  72. update_current_time(now);
  73. expect_single_log_msg_containing(
  74. "Your system clock just jumped 1800 seconds forward");
  75. tt_int_op(approx_time(), OP_EQ, now);
  76. tt_int_op(get_uptime(), OP_EQ, 3); // no uptime change.
  77. mock_clean_saved_logs();
  78. now -= 600;
  79. update_current_time(now);
  80. expect_single_log_msg_containing(
  81. "Your system clock just jumped 600 seconds backward");
  82. tt_int_op(approx_time(), OP_EQ, now);
  83. tt_int_op(get_uptime(), OP_EQ, 3); // no uptime change.
  84. mock_clean_saved_logs();
  85. /* uptime tracking should go normally now if the clock moves sensibly. */
  86. now += 2;
  87. mt_now += 2*BILLION;
  88. update_current_time(now);
  89. tt_int_op(approx_time(), OP_EQ, now);
  90. tt_int_op(get_uptime(), OP_EQ, 5);
  91. /* If we skip forward by a few minutes but the monotonic clock agrees,
  92. * we've just been idle: that counts as not worth warning about. */
  93. now += 1800;
  94. mt_now += 1800*BILLION;
  95. monotime_coarse_set_mock_time_nsec(mt_now);
  96. update_current_time(now);
  97. expect_no_log_entry();
  98. tt_int_op(approx_time(), OP_EQ, now);
  99. tt_int_op(get_uptime(), OP_EQ, 5); // this doesn't count to uptime, though.
  100. /* If we skip forward by a long time, even if the clock agrees, it's
  101. * idnless that counts. */
  102. now += 4000;
  103. mt_now += 4000*BILLION;
  104. monotime_coarse_set_mock_time_nsec(mt_now);
  105. update_current_time(now);
  106. expect_single_log_msg_containing("Tor has been idle for 4000 seconds");
  107. tt_int_op(approx_time(), OP_EQ, now);
  108. tt_int_op(get_uptime(), OP_EQ, 5);
  109. done:
  110. teardown_capture_of_logs();
  111. monotime_disable_test_mocking();
  112. }
  113. #define MAINLOOP_TEST(name) \
  114. { #name, test_mainloop_## name , TT_FORK, NULL, NULL }
  115. struct testcase_t mainloop_tests[] = {
  116. MAINLOOP_TEST(update_time_normal),
  117. MAINLOOP_TEST(update_time_jumps),
  118. END_OF_TESTCASES
  119. };