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