1 /* Copyright (c) 2013-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
7 #include "core/or/or.h"
8 #include "app/config/config.h"
9 #include "lib/err/torerr.h"
10 #include "lib/log/log.h"
11 #include "test/test.h"
18 dummy_cb_fn(int severity
, log_domain_mask_t domain
, const char *msg
)
20 (void)severity
; (void)domain
; (void)msg
;
24 test_get_sigsafe_err_fds(void *arg
)
28 log_severity_list_t include_bug
, no_bug
, no_bug2
;
32 n
= tor_log_get_sigsafe_err_fds(&fds
);
33 tt_int_op(n
, OP_EQ
, 1);
34 tt_int_op(fds
[0], OP_EQ
, STDERR_FILENO
);
36 set_log_severity_config(LOG_WARN
, LOG_ERR
, &include_bug
);
37 set_log_severity_config(LOG_WARN
, LOG_ERR
, &no_bug
);
38 no_bug
.masks
[SEVERITY_MASK_IDX(LOG_ERR
)] &= ~(LD_BUG
|LD_GENERAL
);
39 set_log_severity_config(LOG_INFO
, LOG_NOTICE
, &no_bug2
);
41 /* Add some logs; make sure the output is as expected. */
43 add_stream_log(&include_bug
, "dummy-1", 3);
44 add_stream_log(&no_bug
, "dummy-2", 4);
45 add_stream_log(&no_bug2
, "dummy-3", 5);
46 add_callback_log(&include_bug
, dummy_cb_fn
);
48 tor_log_update_sigsafe_err_fds();
50 n
= tor_log_get_sigsafe_err_fds(&fds
);
51 tt_int_op(n
, OP_EQ
, 2);
52 tt_int_op(fds
[0], OP_EQ
, STDERR_FILENO
);
53 tt_int_op(fds
[1], OP_EQ
, 3);
55 /* Allow STDOUT to replace STDERR. */
56 add_stream_log(&include_bug
, "dummy-4", STDOUT_FILENO
);
57 tor_log_update_sigsafe_err_fds();
58 n
= tor_log_get_sigsafe_err_fds(&fds
);
59 tt_int_op(n
, OP_EQ
, 2);
60 tt_int_op(fds
[0], OP_EQ
, 3);
61 tt_int_op(fds
[1], OP_EQ
, STDOUT_FILENO
);
63 /* But don't allow it to replace explicit STDERR. */
64 add_stream_log(&include_bug
, "dummy-5", STDERR_FILENO
);
65 tor_log_update_sigsafe_err_fds();
66 n
= tor_log_get_sigsafe_err_fds(&fds
);
67 tt_int_op(n
, OP_EQ
, 3);
68 tt_int_op(fds
[0], OP_EQ
, STDERR_FILENO
);
69 tt_int_op(fds
[1], OP_EQ
, STDOUT_FILENO
);
70 tt_int_op(fds
[2], OP_EQ
, 3);
72 /* Don't overflow the array. */
75 for (i
=5; i
<20; ++i
) {
76 add_stream_log(&include_bug
, "x-dummy", i
);
79 tor_log_update_sigsafe_err_fds();
80 n
= tor_log_get_sigsafe_err_fds(&fds
);
81 tt_int_op(n
, OP_EQ
, 8);
88 test_sigsafe_err(void *arg
)
90 const char *fn
=get_fname("sigsafe_err_log");
92 log_severity_list_t include_bug
;
93 smartlist_t
*lines
= smartlist_new();
96 set_log_severity_config(LOG_WARN
, LOG_ERR
, &include_bug
);
100 open_and_add_file_log(&include_bug
, fn
, 0);
101 tor_log_update_sigsafe_err_fds();
104 close(STDERR_FILENO
);
105 log_err(LD_BUG
, "Say, this isn't too cool.");
106 tor_log_err_sigsafe("Minimal.\n", NULL
);
108 set_log_time_granularity(100*1000);
109 tor_log_err_sigsafe("Testing any ",
110 "attempt to manually log ",
115 close(STDERR_FILENO
);
116 content
= read_file_to_str(fn
, 0, NULL
);
118 tt_ptr_op(content
, OP_NE
, NULL
);
119 smartlist_split_string(lines
, content
, "\n", 0, 0);
120 tt_int_op(smartlist_len(lines
), OP_GE
, 5);
122 if (strstr(smartlist_get(lines
, 0), "opening new log file")) {
123 void *item
= smartlist_get(lines
, 0);
124 smartlist_del_keeporder(lines
, 0);
128 tt_assert(strstr(smartlist_get(lines
, 0), "Say, this isn't too cool"));
129 tt_str_op(smartlist_get(lines
, 1), OP_EQ
, "");
130 tt_assert(!strcmpstart(smartlist_get(lines
, 2), "=============="));
131 tt_assert(!strcmpstart(smartlist_get(lines
, 3), "Minimal."));
132 tt_str_op(smartlist_get(lines
, 4), OP_EQ
, "");
133 tt_assert(!strcmpstart(smartlist_get(lines
, 5), "=============="));
134 tt_str_op(smartlist_get(lines
, 6), OP_EQ
,
135 "Testing any attempt to manually log from a signal.");
139 SMARTLIST_FOREACH(lines
, char *, x
, tor_free(x
));
140 smartlist_free(lines
);
144 test_ratelim(void *arg
)
147 ratelim_t ten_min
= RATELIM_INIT(10*60);
149 const time_t start
= 1466091600;
151 /* Initially, we're ready. */
155 msg
= rate_limit_log(&ten_min
, now
);
156 tt_ptr_op(msg
, OP_NE
, NULL
);
157 tt_str_op(msg
, OP_EQ
, ""); /* nothing was suppressed. */
159 tt_int_op(ten_min
.last_allowed
, OP_EQ
, now
);
163 time_t first_suppressed_at
= now
+ 60;
164 for (i
= 0; i
< 9; ++i
) {
165 now
+= 60; /* one minute has passed. */
166 msg
= rate_limit_log(&ten_min
, now
);
167 tt_ptr_op(msg
, OP_EQ
, NULL
);
168 tt_int_op(ten_min
.last_allowed
, OP_EQ
, start
);
169 tt_int_op(ten_min
.n_calls_since_last_time
, OP_EQ
, i
+ 1);
171 tt_i64_op(ten_min
.started_limiting
, OP_EQ
, first_suppressed_at
);
173 now
+= 240; /* Okay, we can be done. */
174 msg
= rate_limit_log(&ten_min
, now
);
175 tt_ptr_op(msg
, OP_NE
, NULL
);
176 tt_str_op(msg
, OP_EQ
,
177 " [9 similar message(s) suppressed in last 720 seconds]");
178 tt_i64_op(now
, OP_EQ
, first_suppressed_at
+ 720);
184 struct testcase_t logging_tests
[] = {
185 { "sigsafe_err_fds", test_get_sigsafe_err_fds
, TT_FORK
, NULL
, NULL
},
186 { "sigsafe_err", test_sigsafe_err
, TT_FORK
, NULL
, NULL
},
187 { "ratelim", test_ratelim
, 0, NULL
, NULL
},