LCOV - code coverage report
Current view: top level - test - test_circuitmux.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 273 273 100.0 %
Date: 2021-11-24 03:28:48 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2013-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #define CHANNEL_OBJECT_PRIVATE
       5             : #define CIRCUITMUX_PRIVATE
       6             : #define CIRCUITMUX_EWMA_PRIVATE
       7             : #define RELAY_PRIVATE
       8             : 
       9             : #include "core/or/or.h"
      10             : #include "core/or/channel.h"
      11             : #include "core/or/circuitmux.h"
      12             : #include "core/or/circuitmux_ewma.h"
      13             : #include "core/or/destroy_cell_queue_st.h"
      14             : #include "core/or/relay.h"
      15             : #include "core/or/scheduler.h"
      16             : 
      17             : #include "test/fakechans.h"
      18             : #include "test/fakecircs.h"
      19             : #include "test/test.h"
      20             : 
      21             : #include <math.h>
      22             : 
      23             : static int
      24           4 : mock_has_queued_writes_true(channel_t *c)
      25             : {
      26           4 :   (void) c;
      27           4 :   return 1;
      28             : }
      29             : 
      30             : /** Test destroy cell queue with no interference from other queues. */
      31             : static void
      32           1 : test_cmux_destroy_cell_queue(void *arg)
      33             : {
      34           1 :   circuitmux_t *cmux = NULL;
      35           1 :   channel_t *ch = NULL;
      36           1 :   circuit_t *circ = NULL;
      37           1 :   destroy_cell_queue_t *cq = NULL;
      38           1 :   packed_cell_t *pc = NULL;
      39           1 :   destroy_cell_t *dc = NULL;
      40             : 
      41           1 :   MOCK(scheduler_release_channel, scheduler_release_channel_mock);
      42             : 
      43           1 :   (void) arg;
      44             : 
      45           1 :   ch = new_fake_channel();
      46           1 :   ch->has_queued_writes = mock_has_queued_writes_true;
      47           1 :   ch->wide_circ_ids = 1;
      48           1 :   cmux = ch->cmux;
      49             : 
      50           1 :   circ = circuitmux_get_first_active_circuit(cmux, &cq);
      51           1 :   tt_ptr_op(circ, OP_EQ, NULL);
      52           1 :   tt_ptr_op(cq, OP_EQ, NULL);
      53             : 
      54           1 :   circuitmux_append_destroy_cell(ch, cmux, 100, 10);
      55           1 :   circuitmux_append_destroy_cell(ch, cmux, 190, 6);
      56           1 :   circuitmux_append_destroy_cell(ch, cmux, 30, 1);
      57             : 
      58           1 :   tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 3);
      59             : 
      60           1 :   circ = circuitmux_get_first_active_circuit(cmux, &cq);
      61           1 :   tt_ptr_op(circ, OP_EQ, NULL);
      62           1 :   tt_assert(cq);
      63             : 
      64           1 :   tt_int_op(cq->n, OP_EQ, 3);
      65             : 
      66           1 :   dc = destroy_cell_queue_pop(cq);
      67           1 :   tt_assert(dc);
      68           1 :   tt_uint_op(dc->circid, OP_EQ, 100);
      69             : 
      70           1 :   tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 2);
      71             : 
      72           1 :  done:
      73           1 :   free_fake_channel(ch);
      74           1 :   packed_cell_free(pc);
      75           1 :   tor_free(dc);
      76             : 
      77           1 :   UNMOCK(scheduler_release_channel);
      78           1 : }
      79             : 
      80             : static void
      81           1 : test_cmux_compute_ticks(void *arg)
      82             : {
      83           1 :   const int64_t NS_PER_S = 1000 * 1000 * 1000;
      84           1 :   const int64_t START_NS = UINT64_C(1217709000)*NS_PER_S;
      85           1 :   int64_t now;
      86           1 :   double rem;
      87           1 :   unsigned tick;
      88           1 :   (void)arg;
      89           1 :   circuitmux_ewma_free_all();
      90           1 :   monotime_enable_test_mocking();
      91             : 
      92           1 :   monotime_coarse_set_mock_time_nsec(START_NS);
      93           1 :   cell_ewma_initialize_ticks();
      94           1 :   const unsigned tick_zero = cell_ewma_get_current_tick_and_fraction(&rem);
      95           1 :   tt_double_op(rem, OP_GT, -1e-9);
      96           1 :   tt_double_op(rem, OP_LT, 1e-9);
      97             : 
      98             :   /* 1.5 second later and we should still be in the same tick. */
      99           1 :   now = START_NS + NS_PER_S + NS_PER_S/2;
     100           1 :   monotime_coarse_set_mock_time_nsec(now);
     101           1 :   tick = cell_ewma_get_current_tick_and_fraction(&rem);
     102           1 :   tt_uint_op(tick, OP_EQ, tick_zero);
     103             : #ifdef USING_32BIT_MSEC_HACK
     104             :   const double tolerance = .0005;
     105             : #else
     106           1 :   const double tolerance = .00000001;
     107             : #endif
     108           1 :   tt_double_op(fabs(rem - .15), OP_LT, tolerance);
     109             : 
     110             :   /* 25 second later and we should be in another tick. */
     111           1 :   now = START_NS + NS_PER_S * 25;
     112           1 :   monotime_coarse_set_mock_time_nsec(now);
     113           1 :   tick = cell_ewma_get_current_tick_and_fraction(&rem);
     114           1 :   tt_uint_op(tick, OP_EQ, tick_zero + 2);
     115           1 :   tt_double_op(fabs(rem - .5), OP_LT, tolerance);
     116             : 
     117           1 :  done:
     118           1 :   ;
     119           1 : }
     120             : 
     121             : static void
     122           1 : test_cmux_allocate(void *arg)
     123             : {
     124           1 :   circuitmux_t *cmux = NULL;
     125             : 
     126           1 :   (void) arg;
     127             : 
     128           1 :   cmux = circuitmux_alloc();
     129           1 :   tt_assert(cmux);
     130           1 :   tt_assert(cmux->chanid_circid_map);
     131           1 :   tt_int_op(HT_SIZE(cmux->chanid_circid_map), OP_EQ, 0);
     132           1 :   tt_uint_op(cmux->n_circuits, OP_EQ, 0);
     133           1 :   tt_uint_op(cmux->n_active_circuits, OP_EQ, 0);
     134           1 :   tt_uint_op(cmux->n_cells, OP_EQ, 0);
     135           1 :   tt_uint_op(cmux->last_cell_was_destroy, OP_EQ, 0);
     136           1 :   tt_i64_op(cmux->destroy_ctr, OP_EQ, 0);
     137           1 :   tt_ptr_op(cmux->policy, OP_EQ, NULL);
     138           1 :   tt_ptr_op(cmux->policy_data, OP_EQ, NULL);
     139             : 
     140           1 :   tt_assert(TOR_SIMPLEQ_EMPTY(&cmux->destroy_cell_queue.head));
     141             : 
     142           1 :  done:
     143           1 :   circuitmux_free(cmux);
     144           1 : }
     145             : 
     146             : static void
     147           1 : test_cmux_attach_circuit(void *arg)
     148             : {
     149           1 :   circuit_t *circ = NULL;
     150           1 :   or_circuit_t *orcirc = NULL;
     151           1 :   channel_t *pchan = NULL, *nchan = NULL;
     152           1 :   cell_direction_t cdir;
     153           1 :   unsigned int n_cells;
     154             : 
     155           1 :   (void) arg;
     156             : 
     157           1 :   pchan = new_fake_channel();
     158           1 :   tt_assert(pchan);
     159           1 :   nchan = new_fake_channel();
     160           1 :   tt_assert(nchan);
     161             : 
     162           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     163           1 :   tt_assert(orcirc);
     164           1 :   circ = TO_CIRCUIT(orcirc);
     165             : 
     166             :   /* While assigning a new circuit IDs, the circuitmux_attach_circuit() is
     167             :    * called for a new channel on the circuit. This means, we should now have
     168             :    * the created circuit attached on both the pchan and nchan cmux. */
     169           1 :   tt_uint_op(circuitmux_num_circuits(pchan->cmux), OP_EQ, 1);
     170           1 :   tt_uint_op(circuitmux_num_circuits(nchan->cmux), OP_EQ, 1);
     171             : 
     172             :   /* There should be _no_ active circuit due to no queued cells. */
     173           1 :   tt_uint_op(circuitmux_num_active_circuits(pchan->cmux), OP_EQ, 0);
     174           1 :   tt_uint_op(circuitmux_num_active_circuits(nchan->cmux), OP_EQ, 0);
     175             : 
     176             :   /* Circuit should not be active on the cmux. */
     177           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 0);
     178           1 :   tt_int_op(circuitmux_is_circuit_active(nchan->cmux, circ), OP_EQ, 0);
     179             : 
     180             :   /* Not active so no cells. */
     181           1 :   n_cells = circuitmux_num_cells_for_circuit(pchan->cmux, circ);
     182           1 :   tt_uint_op(n_cells, OP_EQ, 0);
     183           1 :   n_cells = circuitmux_num_cells(pchan->cmux);
     184           1 :   tt_uint_op(n_cells, OP_EQ, 0);
     185           1 :   n_cells = circuitmux_num_cells_for_circuit(nchan->cmux, circ);
     186           1 :   tt_uint_op(n_cells, OP_EQ, 0);
     187           1 :   n_cells = circuitmux_num_cells(nchan->cmux);
     188           1 :   tt_uint_op(n_cells, OP_EQ, 0);
     189             : 
     190             :   /* So it should be attached :) */
     191           1 :   tt_int_op(circuitmux_is_circuit_attached(pchan->cmux, circ), OP_EQ, 1);
     192           1 :   tt_int_op(circuitmux_is_circuit_attached(nchan->cmux, circ), OP_EQ, 1);
     193             : 
     194             :   /* Query the chanid<->circid map in the cmux subsystem with what we just
     195             :    * created and validate the cell direction. */
     196           1 :   cdir = circuitmux_attached_circuit_direction(pchan->cmux, circ);
     197           1 :   tt_int_op(cdir, OP_EQ, CELL_DIRECTION_IN);
     198           1 :   cdir = circuitmux_attached_circuit_direction(nchan->cmux, circ);
     199           1 :   tt_int_op(cdir, OP_EQ, CELL_DIRECTION_OUT);
     200             : 
     201             :   /*
     202             :    * We'll activate->deactivate->activate to test all code paths of
     203             :    * circuitmux_set_num_cells().
     204             :    */
     205             : 
     206             :   /* Activate circuit. */
     207           1 :   circuitmux_set_num_cells(pchan->cmux, circ, 4);
     208           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 1);
     209             : 
     210             :   /* Deactivate. */
     211           1 :   circuitmux_clear_num_cells(pchan->cmux, circ);
     212           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 0);
     213           1 :   tt_uint_op(circuitmux_num_cells_for_circuit(pchan->cmux, circ), OP_EQ, 0);
     214             : 
     215             :   /* Re-activate. */
     216           1 :   circuitmux_set_num_cells(pchan->cmux, circ, 4);
     217           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 1);
     218             : 
     219             :   /* Once re-attached, it should become inactive because the circuit has no
     220             :    * cells while the chanid<->circid object has some. The attach code will
     221             :    * reset the count on the cmux for that circuit:
     222             :    *
     223             :    * if (chanid_circid_muxinfo_t->muxinfo.cell_count > 0 && cell_count == 0) {
     224             :    */
     225           1 :   circuitmux_attach_circuit(pchan->cmux, circ, CELL_DIRECTION_IN);
     226           1 :   n_cells = circuitmux_num_cells_for_circuit(pchan->cmux, circ);
     227           1 :   tt_uint_op(n_cells, OP_EQ, 0);
     228           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 0);
     229           1 :   tt_uint_op(circuitmux_num_active_circuits(pchan->cmux), OP_EQ, 0);
     230             : 
     231             :   /* Lets queue a cell on the circuit now so it becomes active when
     232             :    * re-attaching:
     233             :    *
     234             :    * else if (chanid_circid_muxinfo_t->muxinfo.cell_count == 0 &&
     235             :    *          cell_count > 0) {
     236             :    */
     237           1 :   orcirc->p_chan_cells.n = 1;
     238           1 :   circuitmux_attach_circuit(pchan->cmux, circ, CELL_DIRECTION_IN);
     239           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 1);
     240             : 
     241           1 :  done:
     242           1 :   free_fake_orcirc(orcirc);
     243           1 :   free_fake_channel(pchan);
     244           1 :   free_fake_channel(nchan);
     245           1 : }
     246             : 
     247             : static void
     248           1 : test_cmux_detach_circuit(void *arg)
     249             : {
     250           1 :   circuit_t *circ = NULL;
     251           1 :   or_circuit_t *orcirc = NULL;
     252           1 :   channel_t *pchan = NULL, *nchan = NULL;
     253             : 
     254           1 :   (void) arg;
     255             : 
     256           1 :   pchan = new_fake_channel();
     257           1 :   tt_assert(pchan);
     258           1 :   nchan = new_fake_channel();
     259           1 :   tt_assert(nchan);
     260             : 
     261           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     262           1 :   tt_assert(orcirc);
     263           1 :   circ = TO_CIRCUIT(orcirc);
     264             : 
     265             :   /* While assigning a new circuit IDs, the circuitmux_attach_circuit() is
     266             :    * called for a new channel on the circuit. This means, we should now have
     267             :    * the created circuit attached on both the pchan and nchan cmux. */
     268           1 :   tt_uint_op(circuitmux_num_circuits(pchan->cmux), OP_EQ, 1);
     269           1 :   tt_uint_op(circuitmux_num_circuits(nchan->cmux), OP_EQ, 1);
     270           1 :   tt_int_op(circuitmux_is_circuit_attached(pchan->cmux, circ), OP_EQ, 1);
     271           1 :   tt_int_op(circuitmux_is_circuit_attached(nchan->cmux, circ), OP_EQ, 1);
     272             : 
     273             :   /* Now, detach the circuit from pchan and then nchan. */
     274           1 :   circuitmux_detach_circuit(pchan->cmux, circ);
     275           1 :   tt_uint_op(circuitmux_num_circuits(pchan->cmux), OP_EQ, 0);
     276           1 :   tt_int_op(circuitmux_is_circuit_attached(pchan->cmux, circ), OP_EQ, 0);
     277           1 :   circuitmux_detach_circuit(nchan->cmux, circ);
     278           1 :   tt_uint_op(circuitmux_num_circuits(nchan->cmux), OP_EQ, 0);
     279           1 :   tt_int_op(circuitmux_is_circuit_attached(nchan->cmux, circ), OP_EQ, 0);
     280             : 
     281           1 :  done:
     282           1 :   free_fake_orcirc(orcirc);
     283           1 :   free_fake_channel(pchan);
     284           1 :   free_fake_channel(nchan);
     285           1 : }
     286             : 
     287             : static void
     288           1 : test_cmux_detach_all_circuits(void *arg)
     289             : {
     290           1 :   circuit_t *circ = NULL;
     291           1 :   or_circuit_t *orcirc = NULL;
     292           1 :   channel_t *pchan = NULL, *nchan = NULL;
     293           1 :   smartlist_t *detached_out = smartlist_new();
     294             : 
     295           1 :   (void) arg;
     296             : 
     297             :   /* Channels need to be registered in order for the detach all circuit
     298             :    * function to find them. */
     299           1 :   pchan = new_fake_channel();
     300           1 :   tt_assert(pchan);
     301           1 :   channel_register(pchan);
     302           1 :   nchan = new_fake_channel();
     303           1 :   tt_assert(nchan);
     304           1 :   channel_register(nchan);
     305             : 
     306           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     307           1 :   tt_assert(orcirc);
     308           1 :   circ = TO_CIRCUIT(orcirc);
     309             : 
     310             :   /* Just make sure it is attached. */
     311           1 :   tt_uint_op(circuitmux_num_circuits(pchan->cmux), OP_EQ, 1);
     312           1 :   tt_uint_op(circuitmux_num_circuits(nchan->cmux), OP_EQ, 1);
     313           1 :   tt_int_op(circuitmux_is_circuit_attached(pchan->cmux, circ), OP_EQ, 1);
     314           1 :   tt_int_op(circuitmux_is_circuit_attached(nchan->cmux, circ), OP_EQ, 1);
     315             : 
     316             :   /* Queue some cells so we can test if the circuit becomes inactive on the
     317             :    * cmux after the mass detach. */
     318           1 :   circuitmux_set_num_cells(pchan->cmux, circ, 4);
     319           1 :   circuitmux_set_num_cells(nchan->cmux, circ, 4);
     320             : 
     321             :   /* Detach all on pchan and then nchan. */
     322           1 :   circuitmux_detach_all_circuits(pchan->cmux, detached_out);
     323           1 :   tt_uint_op(circuitmux_num_circuits(pchan->cmux), OP_EQ, 0);
     324           1 :   tt_int_op(circuitmux_is_circuit_attached(pchan->cmux, circ), OP_EQ, 0);
     325           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 0);
     326           1 :   tt_int_op(smartlist_len(detached_out), OP_EQ, 1);
     327           1 :   circuitmux_detach_all_circuits(nchan->cmux, NULL);
     328           1 :   tt_uint_op(circuitmux_num_circuits(nchan->cmux), OP_EQ, 0);
     329           1 :   tt_int_op(circuitmux_is_circuit_attached(nchan->cmux, circ), OP_EQ, 0);
     330           1 :   tt_int_op(circuitmux_is_circuit_active(nchan->cmux, circ), OP_EQ, 0);
     331             : 
     332           1 :  done:
     333           1 :   smartlist_free(detached_out);
     334           1 :   free_fake_orcirc(orcirc);
     335           1 :   free_fake_channel(pchan);
     336           1 :   free_fake_channel(nchan);
     337           1 : }
     338             : 
     339             : static void
     340           1 : test_cmux_policy(void *arg)
     341             : {
     342           1 :   circuit_t *circ = NULL;
     343           1 :   or_circuit_t *orcirc = NULL;
     344           1 :   channel_t *pchan = NULL, *nchan = NULL;
     345             : 
     346           1 :   (void) arg;
     347             : 
     348           1 :   pchan = new_fake_channel();
     349           1 :   tt_assert(pchan);
     350           1 :   channel_register(pchan);
     351           1 :   nchan = new_fake_channel();
     352           1 :   tt_assert(nchan);
     353           1 :   channel_register(nchan);
     354             : 
     355           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     356           1 :   tt_assert(orcirc);
     357           1 :   circ = TO_CIRCUIT(orcirc);
     358             : 
     359             :   /* Confirm we have the EWMA policy by default for new channels. */
     360           1 :   tt_ptr_op(circuitmux_get_policy(pchan->cmux), OP_EQ, &ewma_policy);
     361           1 :   tt_ptr_op(circuitmux_get_policy(nchan->cmux), OP_EQ, &ewma_policy);
     362             : 
     363             :   /* Putting cell on the cmux means will make the notify policy code path to
     364             :    * trigger. */
     365           1 :   circuitmux_set_num_cells(pchan->cmux, circ, 4);
     366             : 
     367             :   /* Clear it out. */
     368           1 :   circuitmux_clear_policy(pchan->cmux);
     369             : 
     370             :   /* Set back the EWMA policy. */
     371           1 :   circuitmux_set_policy(pchan->cmux, &ewma_policy);
     372             : 
     373           1 :  done:
     374           1 :   free_fake_orcirc(orcirc);
     375           1 :   free_fake_channel(pchan);
     376           1 :   free_fake_channel(nchan);
     377           1 : }
     378             : 
     379             : static void
     380           1 : test_cmux_xmit_cell(void *arg)
     381             : {
     382           1 :   circuit_t *circ = NULL;
     383           1 :   or_circuit_t *orcirc = NULL;
     384           1 :   channel_t *pchan = NULL, *nchan = NULL;
     385             : 
     386           1 :   (void) arg;
     387             : 
     388           1 :   pchan = new_fake_channel();
     389           1 :   tt_assert(pchan);
     390           1 :   nchan = new_fake_channel();
     391           1 :   tt_assert(nchan);
     392             : 
     393           1 :   orcirc = new_fake_orcirc(nchan, pchan);
     394           1 :   tt_assert(orcirc);
     395           1 :   circ = TO_CIRCUIT(orcirc);
     396             : 
     397             :   /* Queue 4 cells on the circuit. */
     398           1 :   circuitmux_set_num_cells(pchan->cmux, circ, 4);
     399           1 :   tt_uint_op(circuitmux_num_cells_for_circuit(pchan->cmux, circ), OP_EQ, 4);
     400           1 :   tt_uint_op(circuitmux_num_cells(pchan->cmux), OP_EQ, 4);
     401           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 1);
     402           1 :   tt_uint_op(circuitmux_num_active_circuits(pchan->cmux), OP_EQ, 1);
     403             : 
     404             :   /* Emit the first cell. Circuit should still be active. */
     405           1 :   circuitmux_notify_xmit_cells(pchan->cmux, circ, 1);
     406           1 :   tt_uint_op(circuitmux_num_cells(pchan->cmux), OP_EQ, 3);
     407           1 :   tt_uint_op(circuitmux_num_cells_for_circuit(pchan->cmux, circ), OP_EQ, 3);
     408           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 1);
     409           1 :   tt_uint_op(circuitmux_num_active_circuits(pchan->cmux), OP_EQ, 1);
     410             : 
     411             :   /* Emit the last 3 cells. Circuit should become inactive. */
     412           1 :   circuitmux_notify_xmit_cells(pchan->cmux, circ, 3);
     413           1 :   tt_uint_op(circuitmux_num_cells(pchan->cmux), OP_EQ, 0);
     414           1 :   tt_uint_op(circuitmux_num_cells_for_circuit(pchan->cmux, circ), OP_EQ, 0);
     415           1 :   tt_int_op(circuitmux_is_circuit_active(pchan->cmux, circ), OP_EQ, 0);
     416           1 :   tt_uint_op(circuitmux_num_active_circuits(pchan->cmux), OP_EQ, 0);
     417             : 
     418             :   /* Queue a DESTROY cell. */
     419           1 :   pchan->has_queued_writes = mock_has_queued_writes_true;
     420           1 :   circuitmux_append_destroy_cell(pchan, pchan->cmux, orcirc->p_circ_id, 0);
     421           1 :   tt_i64_op(pchan->cmux->destroy_ctr, OP_EQ, 1);
     422           1 :   tt_int_op(pchan->cmux->destroy_cell_queue.n, OP_EQ, 1);
     423           1 :   tt_i64_op(circuitmux_count_queued_destroy_cells(pchan, pchan->cmux),
     424             :             OP_EQ, 1);
     425             : 
     426             :   /* Emit the DESTROY cell. */
     427           1 :   circuitmux_notify_xmit_destroy(pchan->cmux);
     428           1 :   tt_i64_op(pchan->cmux->destroy_ctr, OP_EQ, 0);
     429             : 
     430           1 :  done:
     431           1 :   free_fake_orcirc(orcirc);
     432           1 :   free_fake_channel(pchan);
     433           1 :   free_fake_channel(nchan);
     434           1 : }
     435             : 
     436             : static void *
     437           8 : cmux_setup_test(const struct testcase_t *tc)
     438             : {
     439           8 :   static int whatever;
     440             : 
     441           8 :   (void) tc;
     442             : 
     443           8 :   cell_ewma_initialize_ticks();
     444           8 :   return &whatever;
     445             : }
     446             : 
     447             : static int
     448           8 : cmux_cleanup_test(const struct testcase_t *tc, void *ptr)
     449             : {
     450           8 :   (void) tc;
     451           8 :   (void) ptr;
     452             : 
     453           8 :   circuitmux_ewma_free_all();
     454             : 
     455           8 :   return 1;
     456             : }
     457             : 
     458             : static struct testcase_setup_t cmux_test_setup = {
     459             :   .setup_fn = cmux_setup_test,
     460             :   .cleanup_fn = cmux_cleanup_test,
     461             : };
     462             : 
     463             : #define TEST_CMUX(name) \
     464             :   { #name, test_cmux_##name, TT_FORK, &cmux_test_setup, NULL }
     465             : 
     466             : struct testcase_t circuitmux_tests[] = {
     467             :   /* Test circuitmux_t object */
     468             :   TEST_CMUX(allocate),
     469             :   TEST_CMUX(attach_circuit),
     470             :   TEST_CMUX(detach_circuit),
     471             :   TEST_CMUX(detach_all_circuits),
     472             :   TEST_CMUX(policy),
     473             :   TEST_CMUX(xmit_cell),
     474             : 
     475             :   /* Misc. */
     476             :   TEST_CMUX(compute_ticks),
     477             :   TEST_CMUX(destroy_cell_queue),
     478             : 
     479             :   END_OF_TESTCASES
     480             : };

Generated by: LCOV version 1.14