test_logging.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* Copyright (c) 2013-2018, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define CONFIG_PRIVATE
  4. #include "orconfig.h"
  5. #include "core/or/or.h"
  6. #include "app/config/config.h"
  7. #include "lib/err/torerr.h"
  8. #include "lib/log/log.h"
  9. #include "test/test.h"
  10. #include "lib/process/subprocess.h"
  11. #ifdef HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. static void
  15. dummy_cb_fn(int severity, uint32_t domain, const char *msg)
  16. {
  17. (void)severity; (void)domain; (void)msg;
  18. }
  19. static void
  20. test_get_sigsafe_err_fds(void *arg)
  21. {
  22. const int *fds;
  23. int n;
  24. log_severity_list_t include_bug, no_bug, no_bug2;
  25. (void) arg;
  26. init_logging(1);
  27. n = tor_log_get_sigsafe_err_fds(&fds);
  28. tt_int_op(n, OP_EQ, 1);
  29. tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
  30. set_log_severity_config(LOG_WARN, LOG_ERR, &include_bug);
  31. set_log_severity_config(LOG_WARN, LOG_ERR, &no_bug);
  32. no_bug.masks[0] &= ~(LD_BUG|LD_GENERAL);
  33. set_log_severity_config(LOG_INFO, LOG_NOTICE, &no_bug2);
  34. /* Add some logs; make sure the output is as expected. */
  35. mark_logs_temp();
  36. add_stream_log(&include_bug, "dummy-1", 3);
  37. add_stream_log(&no_bug, "dummy-2", 4);
  38. add_stream_log(&no_bug2, "dummy-3", 5);
  39. add_callback_log(&include_bug, dummy_cb_fn);
  40. close_temp_logs();
  41. tor_log_update_sigsafe_err_fds();
  42. n = tor_log_get_sigsafe_err_fds(&fds);
  43. tt_int_op(n, OP_EQ, 2);
  44. tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
  45. tt_int_op(fds[1], OP_EQ, 3);
  46. /* Allow STDOUT to replace STDERR. */
  47. add_stream_log(&include_bug, "dummy-4", STDOUT_FILENO);
  48. tor_log_update_sigsafe_err_fds();
  49. n = tor_log_get_sigsafe_err_fds(&fds);
  50. tt_int_op(n, OP_EQ, 2);
  51. tt_int_op(fds[0], OP_EQ, 3);
  52. tt_int_op(fds[1], OP_EQ, STDOUT_FILENO);
  53. /* But don't allow it to replace explicit STDERR. */
  54. add_stream_log(&include_bug, "dummy-5", STDERR_FILENO);
  55. tor_log_update_sigsafe_err_fds();
  56. n = tor_log_get_sigsafe_err_fds(&fds);
  57. tt_int_op(n, OP_EQ, 3);
  58. tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
  59. tt_int_op(fds[1], OP_EQ, STDOUT_FILENO);
  60. tt_int_op(fds[2], OP_EQ, 3);
  61. /* Don't overflow the array. */
  62. {
  63. int i;
  64. for (i=5; i<20; ++i) {
  65. add_stream_log(&include_bug, "x-dummy", i);
  66. }
  67. }
  68. tor_log_update_sigsafe_err_fds();
  69. n = tor_log_get_sigsafe_err_fds(&fds);
  70. tt_int_op(n, OP_EQ, 8);
  71. done:
  72. ;
  73. }
  74. static void
  75. test_sigsafe_err(void *arg)
  76. {
  77. const char *fn=get_fname("sigsafe_err_log");
  78. char *content=NULL;
  79. log_severity_list_t include_bug;
  80. smartlist_t *lines = smartlist_new();
  81. (void)arg;
  82. set_log_severity_config(LOG_WARN, LOG_ERR, &include_bug);
  83. init_logging(1);
  84. mark_logs_temp();
  85. open_and_add_file_log(&include_bug, fn, 0);
  86. tor_log_update_sigsafe_err_fds();
  87. close_temp_logs();
  88. close(STDERR_FILENO);
  89. log_err(LD_BUG, "Say, this isn't too cool.");
  90. tor_log_err_sigsafe("Minimal.\n", NULL);
  91. set_log_time_granularity(100*1000);
  92. tor_log_err_sigsafe("Testing any ",
  93. "attempt to manually log ",
  94. "from a signal.\n",
  95. NULL);
  96. mark_logs_temp();
  97. close_temp_logs();
  98. close(STDERR_FILENO);
  99. content = read_file_to_str(fn, 0, NULL);
  100. tt_ptr_op(content, OP_NE, NULL);
  101. tor_split_lines(lines, content, (int)strlen(content));
  102. tt_int_op(smartlist_len(lines), OP_GE, 5);
  103. if (strstr(smartlist_get(lines, 0), "opening new log file"))
  104. smartlist_del_keeporder(lines, 0);
  105. tt_assert(strstr(smartlist_get(lines, 0), "Say, this isn't too cool"));
  106. /* Next line is blank. */
  107. tt_assert(!strcmpstart(smartlist_get(lines, 1), "=============="));
  108. tt_assert(!strcmpstart(smartlist_get(lines, 2), "Minimal."));
  109. /* Next line is blank. */
  110. tt_assert(!strcmpstart(smartlist_get(lines, 3), "=============="));
  111. tt_str_op(smartlist_get(lines, 4), OP_EQ,
  112. "Testing any attempt to manually log from a signal.");
  113. done:
  114. tor_free(content);
  115. smartlist_free(lines);
  116. }
  117. static void
  118. test_ratelim(void *arg)
  119. {
  120. (void) arg;
  121. ratelim_t ten_min = RATELIM_INIT(10*60);
  122. const time_t start = 1466091600;
  123. time_t now = start;
  124. /* Initially, we're ready. */
  125. char *msg = NULL;
  126. msg = rate_limit_log(&ten_min, now);
  127. tt_ptr_op(msg, OP_NE, NULL);
  128. tt_str_op(msg, OP_EQ, ""); /* nothing was suppressed. */
  129. tt_int_op(ten_min.last_allowed, OP_EQ, now);
  130. tor_free(msg);
  131. int i;
  132. for (i = 0; i < 9; ++i) {
  133. now += 60; /* one minute has passed. */
  134. msg = rate_limit_log(&ten_min, now);
  135. tt_ptr_op(msg, OP_EQ, NULL);
  136. tt_int_op(ten_min.last_allowed, OP_EQ, start);
  137. tt_int_op(ten_min.n_calls_since_last_time, OP_EQ, i + 1);
  138. }
  139. now += 240; /* Okay, we can be done. */
  140. msg = rate_limit_log(&ten_min, now);
  141. tt_ptr_op(msg, OP_NE, NULL);
  142. tt_str_op(msg, OP_EQ,
  143. " [9 similar message(s) suppressed in last 600 seconds]");
  144. done:
  145. tor_free(msg);
  146. }
  147. struct testcase_t logging_tests[] = {
  148. { "sigsafe_err_fds", test_get_sigsafe_err_fds, TT_FORK, NULL, NULL },
  149. { "sigsafe_err", test_sigsafe_err, TT_FORK, NULL, NULL },
  150. { "ratelim", test_ratelim, 0, NULL, NULL },
  151. END_OF_TESTCASES
  152. };