Explorar el Código

Unit tests for cell queues.

This removes some INLINE markers from functions that probably didn't
need them.
Nick Mathewson hace 10 años
padre
commit
ae64197195
Se han modificado 5 ficheros con 112 adiciones y 2 borrados
  1. 4 2
      src/or/relay.c
  2. 2 0
      src/or/relay.h
  3. 1 0
      src/test/include.am
  4. 2 0
      src/test/test.c
  5. 103 0
      src/test/test_cell_queue.c

+ 4 - 2
src/or/relay.c

@@ -2089,7 +2089,7 @@ packed_cell_free_unchecked(packed_cell_t *cell)
 }
 
 /** Allocate and return a new packed_cell_t. */
-static INLINE packed_cell_t *
+STATIC packed_cell_t *
 packed_cell_new(void)
 {
   ++total_cells_allocated;
@@ -2100,6 +2100,8 @@ packed_cell_new(void)
 void
 packed_cell_free(packed_cell_t *cell)
 {
+  if (!cell)
+    return;
   packed_cell_free_unchecked(cell);
 }
 
@@ -2210,7 +2212,7 @@ cell_queue_clear(cell_queue_t *queue)
 
 /** Extract and return the cell at the head of <b>queue</b>; return NULL if
  * <b>queue</b> is empty. */
-static INLINE packed_cell_t *
+STATIC packed_cell_t *
 cell_queue_pop(cell_queue_t *queue)
 {
   packed_cell_t *cell = TOR_SIMPLEQ_FIRST(&queue->head);

+ 2 - 0
src/or/relay.h

@@ -82,6 +82,8 @@ int relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction,
 #ifdef RELAY_PRIVATE
 STATIC int connected_cell_parse(const relay_header_t *rh, const cell_t *cell,
                          tor_addr_t *addr_out, int *ttl_out);
+STATIC packed_cell_t *packed_cell_new(void);
+STATIC packed_cell_t *cell_queue_pop(cell_queue_t *queue);
 #endif
 
 #endif

+ 1 - 0
src/test/include.am

@@ -22,6 +22,7 @@ src_test_test_SOURCES = \
 	src/test/test_circuitlist.c \
 	src/test/test_containers.c \
 	src/test/test_crypto.c \
+	src/test/test_cell_queue.c \
 	src/test/test_data.c \
 	src/test/test_dir.c \
 	src/test/test_introduce.c \

+ 2 - 0
src/test/test.c

@@ -2133,6 +2133,7 @@ extern struct testcase_t introduce_tests[];
 extern struct testcase_t replaycache_tests[];
 extern struct testcase_t cell_format_tests[];
 extern struct testcase_t circuitlist_tests[];
+extern struct testcase_t cell_queue_tests[];
 
 static struct testgroup_t testgroups[] = {
   { "", test_array },
@@ -2142,6 +2143,7 @@ static struct testgroup_t testgroups[] = {
   { "container/", container_tests },
   { "util/", util_tests },
   { "cellfmt/", cell_format_tests },
+  { "cellqueue/", cell_queue_tests },
   { "dir/", dir_tests },
   { "dir/md/", microdesc_tests },
   { "pt/", pt_tests },

+ 103 - 0
src/test/test_cell_queue.c

@@ -0,0 +1,103 @@
+/* Copyright (c) 2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define CIRCUITLIST_PRIVATE
+#define RELAY_PRIVATE
+#include "or.h"
+#include "circuitlist.h"
+#include "relay.h"
+#include "test.h"
+
+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;
+
+  init_cell_pool();
+  cell_queue_init(&cq);
+  tt_int_op(cq.n, ==, 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, ==, cell_queue_pop(&cq));
+
+  /* Add and remove a singleton. */
+  cell_queue_append(&cq, pc1);
+  tt_int_op(cq.n, ==, 1);
+  tt_ptr_op(pc1, ==, cell_queue_pop(&cq));
+  tt_int_op(cq.n, ==, 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, ==, 4);
+  tt_ptr_op(pc4, ==, cell_queue_pop(&cq));
+  tt_ptr_op(pc3, ==, cell_queue_pop(&cq));
+  tt_ptr_op(pc2, ==, cell_queue_pop(&cq));
+  tt_ptr_op(pc1, ==, cell_queue_pop(&cq));
+  tt_int_op(cq.n, ==, 0);
+  tt_ptr_op(NULL, ==, 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(&cq, &cell, 1 /*wide*/, 0 /*stats*/);
+  cell.circ_id = 0x2013;
+  cell_queue_append_packed_copy(&cq, &cell, 0 /*wide*/, 0 /*stats*/);
+  tt_int_op(cq.n, ==, 2);
+
+  pc_tmp = cell_queue_pop(&cq);
+  tt_int_op(cq.n, ==, 1);
+  tt_ptr_op(pc_tmp, !=, NULL);
+  test_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5);
+  test_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload));
+  packed_cell_free(pc_tmp);
+
+  pc_tmp = cell_queue_pop(&cq);
+  tt_int_op(cq.n, ==, 0);
+  tt_ptr_op(pc_tmp, !=, NULL);
+  test_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3);
+  test_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload));
+  packed_cell_free(pc_tmp);
+  pc_tmp = NULL;
+
+  tt_ptr_op(NULL, ==, 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, ==, 2);
+  cell_queue_clear(&cq);
+  pc2 = pc1 = NULL; /* prevent double-free */
+  tt_int_op(cq.n, ==, 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);
+  free_cell_pool();
+}
+
+struct testcase_t cell_queue_tests[] = {
+  { "basic", test_cq_manip, TT_FORK, NULL, NULL, },
+  END_OF_TESTCASES
+};