test_controller_events.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /* Copyright (c) 2013-2018, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define CONNECTION_PRIVATE
  4. #define TOR_CHANNEL_INTERNAL_
  5. #define CONTROL_PRIVATE
  6. #include "or/or.h"
  7. #include "or/channel.h"
  8. #include "or/channeltls.h"
  9. #include "or/connection.h"
  10. #include "or/control.h"
  11. #include "test/test.h"
  12. #include "or/or_circuit_st.h"
  13. #include "or/origin_circuit_st.h"
  14. static void
  15. add_testing_cell_stats_entry(circuit_t *circ, uint8_t command,
  16. unsigned int waiting_time,
  17. unsigned int removed, unsigned int exitward)
  18. {
  19. testing_cell_stats_entry_t *ent = tor_malloc_zero(
  20. sizeof(testing_cell_stats_entry_t));
  21. ent->command = command;
  22. ent->waiting_time = waiting_time;
  23. ent->removed = removed;
  24. ent->exitward = exitward;
  25. if (!circ->testing_cell_stats)
  26. circ->testing_cell_stats = smartlist_new();
  27. smartlist_add(circ->testing_cell_stats, ent);
  28. }
  29. static void
  30. test_cntev_sum_up_cell_stats(void *arg)
  31. {
  32. or_circuit_t *or_circ;
  33. circuit_t *circ;
  34. cell_stats_t *cell_stats = NULL;
  35. (void)arg;
  36. /* This circuit is fake. */
  37. or_circ = tor_malloc_zero(sizeof(or_circuit_t));
  38. or_circ->base_.magic = OR_CIRCUIT_MAGIC;
  39. or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
  40. circ = TO_CIRCUIT(or_circ);
  41. /* A single RELAY cell was added to the appward queue. */
  42. cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
  43. add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 0);
  44. sum_up_cell_stats_by_command(circ, cell_stats);
  45. tt_u64_op(1, OP_EQ, cell_stats->added_cells_appward[CELL_RELAY]);
  46. /* A single RELAY cell was added to the exitward queue. */
  47. add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 1);
  48. sum_up_cell_stats_by_command(circ, cell_stats);
  49. tt_u64_op(1, OP_EQ, cell_stats->added_cells_exitward[CELL_RELAY]);
  50. /* A single RELAY cell was removed from the appward queue where it spent
  51. * 20 msec. */
  52. add_testing_cell_stats_entry(circ, CELL_RELAY, 2, 1, 0);
  53. sum_up_cell_stats_by_command(circ, cell_stats);
  54. tt_u64_op(20, OP_EQ, cell_stats->total_time_appward[CELL_RELAY]);
  55. tt_u64_op(1, OP_EQ, cell_stats->removed_cells_appward[CELL_RELAY]);
  56. /* A single RELAY cell was removed from the exitward queue where it
  57. * spent 30 msec. */
  58. add_testing_cell_stats_entry(circ, CELL_RELAY, 3, 1, 1);
  59. sum_up_cell_stats_by_command(circ, cell_stats);
  60. tt_u64_op(30, OP_EQ, cell_stats->total_time_exitward[CELL_RELAY]);
  61. tt_u64_op(1, OP_EQ, cell_stats->removed_cells_exitward[CELL_RELAY]);
  62. done:
  63. tor_free(cell_stats);
  64. tor_free(or_circ);
  65. }
  66. static void
  67. test_cntev_append_cell_stats(void *arg)
  68. {
  69. smartlist_t *event_parts;
  70. char *cp = NULL;
  71. const char *key = "Z";
  72. uint64_t include_if_non_zero[CELL_COMMAND_MAX_ + 1],
  73. number_to_include[CELL_COMMAND_MAX_ + 1];
  74. (void)arg;
  75. event_parts = smartlist_new();
  76. memset(include_if_non_zero, 0,
  77. (CELL_COMMAND_MAX_ + 1) * sizeof(uint64_t));
  78. memset(number_to_include, 0,
  79. (CELL_COMMAND_MAX_ + 1) * sizeof(uint64_t));
  80. /* All array entries empty. */
  81. append_cell_stats_by_command(event_parts, key,
  82. include_if_non_zero,
  83. number_to_include);
  84. tt_int_op(0, OP_EQ, smartlist_len(event_parts));
  85. /* There's a RELAY cell to include, but the corresponding field in
  86. * include_if_non_zero is still zero. */
  87. number_to_include[CELL_RELAY] = 1;
  88. append_cell_stats_by_command(event_parts, key,
  89. include_if_non_zero,
  90. number_to_include);
  91. tt_int_op(0, OP_EQ, smartlist_len(event_parts));
  92. /* Now include single RELAY cell. */
  93. include_if_non_zero[CELL_RELAY] = 2;
  94. append_cell_stats_by_command(event_parts, key,
  95. include_if_non_zero,
  96. number_to_include);
  97. cp = smartlist_pop_last(event_parts);
  98. tt_str_op("Z=relay:1", OP_EQ, cp);
  99. tor_free(cp);
  100. /* Add four CREATE cells. */
  101. include_if_non_zero[CELL_CREATE] = 3;
  102. number_to_include[CELL_CREATE] = 4;
  103. append_cell_stats_by_command(event_parts, key,
  104. include_if_non_zero,
  105. number_to_include);
  106. cp = smartlist_pop_last(event_parts);
  107. tt_str_op("Z=create:4,relay:1", OP_EQ, cp);
  108. done:
  109. tor_free(cp);
  110. smartlist_free(event_parts);
  111. }
  112. static void
  113. test_cntev_format_cell_stats(void *arg)
  114. {
  115. char *event_string = NULL;
  116. origin_circuit_t *ocirc = NULL;
  117. or_circuit_t *or_circ = NULL;
  118. cell_stats_t *cell_stats = NULL;
  119. channel_tls_t *n_chan=NULL, *p_chan=NULL;
  120. (void)arg;
  121. n_chan = tor_malloc_zero(sizeof(channel_tls_t));
  122. n_chan->base_.global_identifier = 1;
  123. ocirc = tor_malloc_zero(sizeof(origin_circuit_t));
  124. ocirc->base_.magic = ORIGIN_CIRCUIT_MAGIC;
  125. ocirc->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
  126. ocirc->global_identifier = 2;
  127. ocirc->base_.n_circ_id = 3;
  128. ocirc->base_.n_chan = &(n_chan->base_);
  129. /* Origin circuit was completely idle. */
  130. cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
  131. format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
  132. tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1", OP_EQ, event_string);
  133. tor_free(event_string);
  134. /* Origin circuit had 4 RELAY cells added to its exitward queue. */
  135. cell_stats->added_cells_exitward[CELL_RELAY] = 4;
  136. format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
  137. tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4",
  138. OP_EQ, event_string);
  139. tor_free(event_string);
  140. /* Origin circuit also had 5 CREATE2 cells added to its exitward
  141. * queue. */
  142. cell_stats->added_cells_exitward[CELL_CREATE2] = 5;
  143. format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
  144. tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
  145. "create2:5", OP_EQ, event_string);
  146. tor_free(event_string);
  147. /* Origin circuit also had 7 RELAY cells removed from its exitward queue
  148. * which together spent 6 msec in the queue. */
  149. cell_stats->total_time_exitward[CELL_RELAY] = 6;
  150. cell_stats->removed_cells_exitward[CELL_RELAY] = 7;
  151. format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
  152. tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
  153. "create2:5 OutboundRemoved=relay:7 OutboundTime=relay:6",
  154. OP_EQ, event_string);
  155. tor_free(event_string);
  156. p_chan = tor_malloc_zero(sizeof(channel_tls_t));
  157. p_chan->base_.global_identifier = 2;
  158. or_circ = tor_malloc_zero(sizeof(or_circuit_t));
  159. or_circ->base_.magic = OR_CIRCUIT_MAGIC;
  160. or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
  161. or_circ->p_circ_id = 8;
  162. or_circ->p_chan = &(p_chan->base_);
  163. or_circ->base_.n_circ_id = 9;
  164. or_circ->base_.n_chan = &(n_chan->base_);
  165. tor_free(cell_stats);
  166. /* OR circuit was idle. */
  167. cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
  168. format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
  169. tt_str_op("InboundQueue=8 InboundConn=2 OutboundQueue=9 OutboundConn=1",
  170. OP_EQ, event_string);
  171. tor_free(event_string);
  172. /* OR circuit had 3 RELAY cells added to its appward queue. */
  173. cell_stats->added_cells_appward[CELL_RELAY] = 3;
  174. format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
  175. tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
  176. "OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
  177. tor_free(event_string);
  178. /* OR circuit had 7 RELAY cells removed from its appward queue which
  179. * together spent 6 msec in the queue. */
  180. cell_stats->total_time_appward[CELL_RELAY] = 6;
  181. cell_stats->removed_cells_appward[CELL_RELAY] = 7;
  182. format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
  183. tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
  184. "InboundRemoved=relay:7 InboundTime=relay:6 "
  185. "OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
  186. done:
  187. tor_free(cell_stats);
  188. tor_free(event_string);
  189. tor_free(or_circ);
  190. tor_free(ocirc);
  191. tor_free(p_chan);
  192. tor_free(n_chan);
  193. }
  194. static void
  195. test_cntev_event_mask(void *arg)
  196. {
  197. unsigned int test_event, selected_event;
  198. (void)arg;
  199. /* Check that nothing is interesting when no events are set */
  200. control_testing_set_global_event_mask(EVENT_MASK_NONE_);
  201. /* Check that nothing is interesting between EVENT_MIN_ and EVENT_MAX_ */
  202. for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++)
  203. tt_assert(!control_event_is_interesting(test_event));
  204. /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
  205. * This will break if control_event_is_interesting() checks its arguments */
  206. for (test_event = 0; test_event < EVENT_MIN_; test_event++)
  207. tt_assert(!control_event_is_interesting(test_event));
  208. for (test_event = EVENT_MAX_ + 1;
  209. test_event < EVENT_CAPACITY_;
  210. test_event++)
  211. tt_assert(!control_event_is_interesting(test_event));
  212. /* Check that all valid events are interesting when all events are set */
  213. control_testing_set_global_event_mask(EVENT_MASK_ALL_);
  214. /* Check that everything is interesting between EVENT_MIN_ and EVENT_MAX_ */
  215. for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++)
  216. tt_assert(control_event_is_interesting(test_event));
  217. /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
  218. * This will break if control_event_is_interesting() checks its arguments */
  219. for (test_event = 0; test_event < EVENT_MIN_; test_event++)
  220. tt_assert(!control_event_is_interesting(test_event));
  221. for (test_event = EVENT_MAX_ + 1;
  222. test_event < EVENT_CAPACITY_;
  223. test_event++)
  224. tt_assert(!control_event_is_interesting(test_event));
  225. /* Check that only that event is interesting when a single event is set */
  226. for (selected_event = EVENT_MIN_;
  227. selected_event <= EVENT_MAX_;
  228. selected_event++) {
  229. control_testing_set_global_event_mask(EVENT_MASK_(selected_event));
  230. /* Check that only this event is interesting
  231. * between EVENT_MIN_ and EVENT_MAX_ */
  232. for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++) {
  233. if (test_event == selected_event) {
  234. tt_assert(control_event_is_interesting(test_event));
  235. } else {
  236. tt_assert(!control_event_is_interesting(test_event));
  237. }
  238. }
  239. /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
  240. * This will break if control_event_is_interesting checks its arguments */
  241. for (test_event = 0; test_event < EVENT_MIN_; test_event++)
  242. tt_assert(!control_event_is_interesting(test_event));
  243. for (test_event = EVENT_MAX_ + 1;
  244. test_event < EVENT_CAPACITY_;
  245. test_event++)
  246. tt_assert(!control_event_is_interesting(test_event));
  247. }
  248. /* Check that only that event is not-interesting
  249. * when a single event is un-set */
  250. for (selected_event = EVENT_MIN_;
  251. selected_event <= EVENT_MAX_;
  252. selected_event++) {
  253. control_testing_set_global_event_mask(
  254. EVENT_MASK_ALL_
  255. & ~(EVENT_MASK_(selected_event))
  256. );
  257. /* Check that only this event is not-interesting
  258. * between EVENT_MIN_ and EVENT_MAX_ */
  259. for (test_event = EVENT_MIN_; test_event <= EVENT_MAX_; test_event++) {
  260. if (test_event == selected_event) {
  261. tt_assert(!control_event_is_interesting(test_event));
  262. } else {
  263. tt_assert(control_event_is_interesting(test_event));
  264. }
  265. }
  266. /* Check that nothing is interesting outside EVENT_MIN_ to EVENT_MAX_
  267. * This will break if control_event_is_interesting checks its arguments */
  268. for (test_event = 0; test_event < EVENT_MIN_; test_event++)
  269. tt_assert(!control_event_is_interesting(test_event));
  270. for (test_event = EVENT_MAX_ + 1;
  271. test_event < EVENT_CAPACITY_;
  272. test_event++)
  273. tt_assert(!control_event_is_interesting(test_event));
  274. }
  275. done:
  276. ;
  277. }
  278. #define TEST(name, flags) \
  279. { #name, test_cntev_ ## name, flags, 0, NULL }
  280. struct testcase_t controller_event_tests[] = {
  281. TEST(sum_up_cell_stats, TT_FORK),
  282. TEST(append_cell_stats, TT_FORK),
  283. TEST(format_cell_stats, TT_FORK),
  284. TEST(event_mask, TT_FORK),
  285. END_OF_TESTCASES
  286. };