1 /* Copyright (c) 2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
5 * \file test_mainloop.c
6 * \brief Tests for functions closely related to the Tor main loop
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;
18 test_mainloop_update_time_normal(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
);
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);
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.
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
56 monotime_disable_test_mocking();
60 test_mainloop_update_time_jumps(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
);
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.. */
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
85 setup_capture_of_logs(LOG_NOTICE
);
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();
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. */
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. */
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. */
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);
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
),