/** Test destroy cell queue with no interference from other queues. */ static void test_cmux_destroy_cell_queue(void *arg) { circuitmux_t *cmux = NULL; channel_t *ch = NULL; circuit_t *circ = NULL; cell_queue_t *cq = NULL; packed_cell_t *pc = NULL; tor_libevent_cfg cfg; memset(&cfg, 0, sizeof(cfg)); tor_libevent_initialize(&cfg); scheduler_init(); #ifdef ENABLE_MEMPOOLS init_cell_pool(); #endif /* ENABLE_MEMPOOLS */ (void) arg; cmux = circuitmux_alloc(); tt_assert(cmux); ch = new_fake_channel(); ch->has_queued_writes = has_queued_writes; ch->wide_circ_ids = 1; circ = circuitmux_get_first_active_circuit(cmux, &cq); tt_assert(!circ); tt_assert(!cq); circuitmux_append_destroy_cell(ch, cmux, 100, 10); circuitmux_append_destroy_cell(ch, cmux, 190, 6); circuitmux_append_destroy_cell(ch, cmux, 30, 1); tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 3); circ = circuitmux_get_first_active_circuit(cmux, &cq); tt_assert(!circ); tt_assert(cq); tt_int_op(cq->n, OP_EQ, 3); pc = cell_queue_pop(cq); tt_assert(pc); tt_mem_op(pc->body, OP_EQ, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9); packed_cell_free(pc); pc = NULL; tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 2); done: circuitmux_free(cmux); channel_free(ch); packed_cell_free(pc); #ifdef ENABLE_MEMPOOLS free_cell_pool(); #endif /* ENABLE_MEMPOOLS */ }
static void test_cq_manip(void *arg) { packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc_tmp=NULL; cell_queue_t cq; cell_t cell; (void) arg; cell_queue_init(&cq); tt_int_op(cq.n, OP_EQ, 0); pc1 = packed_cell_new(); pc2 = packed_cell_new(); pc3 = packed_cell_new(); pc4 = packed_cell_new(); tt_assert(pc1 && pc2 && pc3 && pc4); tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq)); /* Add and remove a singleton. */ cell_queue_append(&cq, pc1); tt_int_op(cq.n, OP_EQ, 1); tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq)); tt_int_op(cq.n, OP_EQ, 0); /* Add and remove four items */ cell_queue_append(&cq, pc4); cell_queue_append(&cq, pc3); cell_queue_append(&cq, pc2); cell_queue_append(&cq, pc1); tt_int_op(cq.n, OP_EQ, 4); tt_ptr_op(pc4, OP_EQ, cell_queue_pop(&cq)); tt_ptr_op(pc3, OP_EQ, cell_queue_pop(&cq)); tt_ptr_op(pc2, OP_EQ, cell_queue_pop(&cq)); tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq)); tt_int_op(cq.n, OP_EQ, 0); tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq)); /* Try a packed copy (wide, then narrow, which is a bit of a cheat, since a * real cell queue has only one type.) */ memset(&cell, 0, sizeof(cell)); cell.circ_id = 0x12345678; cell.command = 10; strlcpy((char*)cell.payload, "Lorax ipsum gruvvulus thneed amet, snergelly " "once-ler lerkim, sed do barbaloot tempor gluppitus ut labore et " "truffula magna aliqua.", sizeof(cell.payload)); cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell, 1 /*wide*/, 0 /*stats*/); cell.circ_id = 0x2013; cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell, 0 /*wide*/, 0 /*stats*/); tt_int_op(cq.n, OP_EQ, 2); pc_tmp = cell_queue_pop(&cq); tt_int_op(cq.n, OP_EQ, 1); tt_ptr_op(pc_tmp, OP_NE, NULL); tt_mem_op(pc_tmp->body, OP_EQ, "\x12\x34\x56\x78\x0a", 5); tt_mem_op(pc_tmp->body+5, OP_EQ, cell.payload, sizeof(cell.payload)); packed_cell_free(pc_tmp); pc_tmp = cell_queue_pop(&cq); tt_int_op(cq.n, OP_EQ, 0); tt_ptr_op(pc_tmp, OP_NE, NULL); tt_mem_op(pc_tmp->body, OP_EQ, "\x20\x13\x0a", 3); tt_mem_op(pc_tmp->body+3, OP_EQ, cell.payload, sizeof(cell.payload)); packed_cell_free(pc_tmp); pc_tmp = NULL; tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq)); /* Now make sure cell_queue_clear works. */ cell_queue_append(&cq, pc2); cell_queue_append(&cq, pc1); tt_int_op(cq.n, OP_EQ, 2); cell_queue_clear(&cq); pc2 = pc1 = NULL; /* prevent double-free */ tt_int_op(cq.n, OP_EQ, 0); done: packed_cell_free(pc1); packed_cell_free(pc2); packed_cell_free(pc3); packed_cell_free(pc4); packed_cell_free(pc_tmp); cell_queue_clear(&cq); }