[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r9748: More unit tests: gcov is fun. (in tor/trunk: . src/common src/or)



Author: nickm
Date: 2007-03-06 15:25:44 -0500 (Tue, 06 Mar 2007)
New Revision: 9748

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/common/
   tor/trunk/src/common/compat.h
   tor/trunk/src/common/log.h
   tor/trunk/src/common/test.h
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/test.c
Log:
 r12468@Kushana:  nickm | 2007-03-06 15:24:00 -0500
 More unit tests: gcov is fun.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12468] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/ChangeLog	2007-03-06 20:25:44 UTC (rev 9748)
@@ -6,6 +6,9 @@
   o Minor features (logging):
     - Always prepend "Bug: " to any log message about a bug.
 
+  o Minor features (other):
+    - More unit tests.
+
   o Removed features:
     - Removed support for the old binary "version 0" controller protocol.
       This has been deprecated since 0.1.1, and warnings have been issued


Property changes on: tor/trunk/src/common
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
.deps
libor.a
libor-crypto.a

   + Makefile
Makefile.in
.deps
libor.a
libor-crypto.a
*.gcov
*.gcda
*.gcno


Modified: tor/trunk/src/common/compat.h
===================================================================
--- tor/trunk/src/common/compat.h	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/common/compat.h	2007-03-06 20:25:44 UTC (rev 9748)
@@ -99,12 +99,16 @@
 #define ATTR_MALLOC __attribute__((malloc))
 #define ATTR_NONNULL(x) __attribute__((nonnull x))
 #define PREDICT(exp, val) __builtin_expect((exp), (val))
+#define PREDICT_LIKELY(exp) PREDICT((exp), 1)
+#define PREDICT_UNLIKELY(exp) PREDICT((exp), 0)
 #else
 #define ATTR_NORETURN
 #define ATTR_PURE
 #define ATTR_MALLOC
 #define ATTR_NONNULL(x)
 #define PREDICT(exp, val) (exp)
+#define PREDICT_LIKELY(exp) (exp)
+#define PREDICT_UNLIKELY(exp) (exp)
 #endif
 
 /* ===== String compatibility */

Modified: tor/trunk/src/common/log.h
===================================================================
--- tor/trunk/src/common/log.h	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/common/log.h	2007-03-06 20:25:44 UTC (rev 9748)
@@ -129,10 +129,10 @@
  * of the current function name. */
 #define log_fn(severity, domain, args...)               \
   _log_fn(severity, domain, __PRETTY_FUNCTION__, args)
-#define log_debug(domain, args...)                              \
-  do {                                                          \
-    if (PREDICT(_log_global_min_severity == LOG_DEBUG, 0))      \
-      _log_fn(LOG_DEBUG, domain, __PRETTY_FUNCTION__, args);    \
+#define log_debug(domain, args...)                                      \
+  do {                                                                  \
+    if (PREDICT_UNLIKELY(_log_global_min_severity == LOG_DEBUG))        \
+      _log_fn(LOG_DEBUG, domain, __PRETTY_FUNCTION__, args);            \
   } while (0)
 #define log_info(domain, args...)                           \
   _log_fn(LOG_INFO, domain, __PRETTY_FUNCTION__, args)

Modified: tor/trunk/src/common/test.h
===================================================================
--- tor/trunk/src/common/test.h	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/common/test.h	2007-03-06 20:25:44 UTC (rev 9748)
@@ -71,21 +71,28 @@
 #define test_eq_ptr(expr1, expr2)               \
   test_eq_type(void*, "%p", expr1, expr2)
 
-#define test_neq(expr1, expr2)                                  \
-  STMT_BEGIN                                                    \
-    long v1=(long)(expr1), v2=(long)(expr2);                    \
-    if (v1!=v2) { printf("."); fflush(stdout); } else {         \
-    have_failed = 1;                                            \
-    printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
-           "      (%ld == %ld)\n",                              \
-      _SHORT_FILE_,                                             \
-      __LINE__,                                                 \
-      PRETTY_FUNCTION,                                          \
-      #expr1, #expr2,                                           \
-      v1, v2);                                                  \
-    return;                                                     \
+#define test_neq_type(tp, fmt, expr1, expr2)                            \
+  STMT_BEGIN                                                            \
+  tp v1=(tp)(expr1);                                                    \
+  tp v2=(tp)(expr2);                                                    \
+  if (v1!=v2) { printf("."); fflush(stdout); } else {                   \
+    have_failed = 1;                                                    \
+    printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"      \
+           "      ("fmt" == "fmt")\n",                                  \
+           _SHORT_FILE_,                                                \
+           __LINE__,                                                    \
+           PRETTY_FUNCTION,                                             \
+           #expr1, #expr2,                                              \
+             v1, v2);                                                   \
+    return;                                                             \
   } STMT_END
 
+#define test_neq(expr1, expr2)                  \
+  test_neq_type(long, "%ld", expr1, expr2)
+
+#define test_neq_ptr(expr1, expr2)              \
+  test_neq_type(void *, "%p", expr1, expr2)
+
 #define test_streq(expr1, expr2)                                \
   STMT_BEGIN                                                    \
     const char *v1=(expr1), *v2=(expr2);                        \

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/common/util.c	2007-03-06 20:25:44 UTC (rev 9748)
@@ -115,7 +115,7 @@
 #endif
   result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0);
 
-  if (PREDICT(result == NULL, 0)) {
+  if (PREDICT_UNLIKELY(result == NULL)) {
     log_err(LD_MM,"Out of memory on malloc(). Dying.");
     /* If these functions die within a worker process, they won't call
      * spawn_exit, but that's ok, since the parent will run out of memory soon
@@ -147,7 +147,7 @@
   void *result;
 
   result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
-  if (PREDICT(result == NULL, 0)) {
+  if (PREDICT_UNLIKELY(result == NULL)) {
     log_err(LD_MM,"Out of memory on realloc(). Dying.");
     exit(1);
   }
@@ -165,7 +165,7 @@
   tor_assert(s);
 
   dup = dmalloc_strdup(file, line, s, 0);
-  if (PREDICT(dup == NULL, 0)) {
+  if (PREDICT_UNLIKELY(dup == NULL)) {
     log_err(LD_MM,"Out of memory on strdup(). Dying.");
     exit(1);
   }
@@ -517,7 +517,7 @@
   CHECK_STRTOX_RESULT();
 }
 
-/** As tor_parse_log, but return an unsigned long. */
+/** As tor_parse_long, but return an unsigned long. */
 unsigned long
 tor_parse_ulong(const char *s, int base, unsigned long min,
                 unsigned long max, int *ok, char **next)
@@ -615,6 +615,7 @@
 base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
 {
   const char *end;
+
   int v1,v2;
   if ((srclen % 2) != 0)
     return -1;
@@ -812,7 +813,7 @@
 /** Return the number of microseconds elapsed between *start and *end.
  */
 long
-tv_udiff(struct timeval *start, struct timeval *end)
+tv_udiff(const struct timeval *start, const struct timeval *end)
 {
   long udiff;
   long secdiff = end->tv_sec - start->tv_sec;
@@ -829,7 +830,7 @@
 /** Return -1 if *a \< *b, 0 if *a==*b, and 1 if *a \> *b.
  */
 int
-tv_cmp(struct timeval *a, struct timeval *b)
+tv_cmp(const struct timeval *a, const struct timeval *b)
 {
   if (a->tv_sec > b->tv_sec)
     return 1;
@@ -845,7 +846,7 @@
 /** Increment *a by the number of seconds and microseconds in *b.
  */
 void
-tv_add(struct timeval *a, struct timeval *b)
+tv_add(struct timeval *a, const struct timeval *b)
 {
   a->tv_usec += b->tv_usec;
   a->tv_sec += b->tv_sec + (a->tv_usec / 1000000);

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/common/util.h	2007-03-06 20:25:44 UTC (rev 9748)
@@ -41,7 +41,7 @@
 #ifdef __GNUC__
 /** Macro: evaluate the expression x, which we expect to be false.
  * Used to hint the compiler that a branch won't be taken. */
-#define PREDICT_FALSE(x) PREDICT((x) == ((typeof(x)) 0), 0)
+#define PREDICT_FALSE(x) PREDICT_UNLIKELY((x) == ((typeof(x)) 0))
 #else
 #define PREDICT_FALSE(x) !(x)
 #endif
@@ -85,14 +85,18 @@
 extern int dmalloc_free(const char *file, const int line, void *pnt,
                         const int func_id);
 #define tor_free(p) do { \
-    if (PREDICT((p)!=NULL, 1)) {                     \
+    if (PREDICT_LIKELY((p)!=NULL)) {                \
       dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \
       (p)=NULL;                                     \
     }                                               \
   } while (0)
 #else
-#define tor_free(p) do { if (PREDICT((p)!=NULL,1)) { free(p); (p)=NULL;} } \
-  while (0)
+#define tor_free(p) do {                                       \
+    if (PREDICT_LIKELY((p)!=NULL)) {                           \
+      free(p);                                                 \
+      (p)=NULL;                                                \
+    }                                                          \
+  } while (0)
 #endif
 
 #define tor_malloc(size)       _tor_malloc(size DMALLOC_ARGS)
@@ -172,10 +176,10 @@
 int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
 
 /* Time helpers */
-long tv_udiff(struct timeval *start, struct timeval *end);
+long tv_udiff(const struct timeval *start, const struct timeval *end);
 void tv_addms(struct timeval *a, long ms);
-void tv_add(struct timeval *a, struct timeval *b);
-int tv_cmp(struct timeval *a, struct timeval *b);
+void tv_add(struct timeval *a, const struct timeval *b);
+int tv_cmp(const struct timeval *a, const struct timeval *b);
 time_t tor_timegm(struct tm *tm);
 #define RFC1123_TIME_LEN 29
 void format_rfc1123_time(char *buf, time_t t);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/or/routerlist.c	2007-03-06 20:25:44 UTC (rev 9748)
@@ -4178,7 +4178,7 @@
 int
 router_have_minimum_dir_info(void)
 {
-  if (PREDICT(need_to_update_have_min_dir_info, 0)) {
+  if (PREDICT_UNLIKELY(need_to_update_have_min_dir_info)) {
     update_router_have_minimum_dir_info();
     need_to_update_have_min_dir_info = 0;
   }

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-03-06 20:25:32 UTC (rev 9747)
+++ tor/trunk/src/or/test.c	2007-03-06 20:25:44 UTC (rev 9748)
@@ -535,6 +535,12 @@
   test_eq(i,0);
   test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
 
+  /* now try some failing base16 decodes */
+  test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
+  test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
+  strlcpy(data1, "f0dz!8affc000100", 1024);
+  test_eq(-1, base16_decode(data2, 8, data1, 16));
+
   tor_free(data1);
   tor_free(data2);
   tor_free(data3);
@@ -606,6 +612,10 @@
 
   end.tv_usec = 7000;
 
+  test_assert(tv_cmp(&start, &end)<0);
+  test_assert(tv_cmp(&end, &start)>0);
+  test_assert(tv_cmp(&end, &end)==0);
+
   test_eq(2000L, tv_udiff(&start, &end));
 
   end.tv_sec = 6;
@@ -620,6 +630,17 @@
 
   test_eq(-1005000L, tv_udiff(&start, &end));
 
+  tv_addms(&end, 5090);
+  test_eq(end.tv_sec, 9);
+  test_eq(end.tv_usec, 90000);
+
+  end.tv_usec = 999990;
+  start.tv_sec = 1;
+  start.tv_usec = 500;
+  tv_add(&start, &end);
+  test_eq(start.tv_sec, 11);
+  test_eq(start.tv_usec, 490);
+
   /* The test values here are confirmed to be correct on a platform
    * with a working timegm. */
   a_time.tm_year = 2003-1900;
@@ -644,6 +665,8 @@
   i = parse_rfc1123_time(timestr, &t_res);
   test_eq(i,0);
   test_eq(t_res, (time_t)1091580502UL);
+  test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
+  tor_gettimeofday(&start);
 
   /* Test tor_strstrip() */
   strlcpy(buf, "Testing 1 2 3", sizeof(buf));
@@ -694,7 +717,12 @@
   /* Test tor_parse_long. */
   test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
   test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
+  test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));
 
+  /* Test tor_parse_ulong */
+  test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
+  test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
+
   /* Test tor_parse_uint64. */
   test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
   test_assert(i == 1);
@@ -772,6 +800,26 @@
   test_assert(strcmpend("abcdef", "dee")>0);
   test_assert(strcmpend("ab", "abb")<0);
 
+  test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
+  test_assert(strcasecmpend("abcdef", "dEF")==0);
+  test_assert(strcasecmpend("abcDEf", "deg")<0);
+  test_assert(strcasecmpend("abcdef", "DEE")>0);
+  test_assert(strcasecmpend("ab", "abB")<0);
+
+  /* Test mem_is_zero */
+  memset(buf,0,128);
+  buf[128] = 'x';
+  test_assert(tor_digest_is_zero(buf));
+  test_assert(tor_mem_is_zero(buf, 10));
+  test_assert(tor_mem_is_zero(buf, 20));
+  test_assert(tor_mem_is_zero(buf, 128));
+  test_assert(!tor_mem_is_zero(buf, 129));
+  buf[60] = (char)255;
+  test_assert(!tor_mem_is_zero(buf, 128));
+  buf[0] = (char)1;
+  test_assert(!tor_mem_is_zero(buf, 10));
+
+  /* Test inet_ntoa */
   {
     char tmpbuf[INET_NTOA_BUF_LEN];
     struct in_addr in;
@@ -785,7 +833,59 @@
   test_streq("\"abcd\"", escaped("abcd"));
   test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
   test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
+  test_assert(NULL == escaped(NULL));
 
+  /* Test strndup and memdup */
+  {
+    const char *s = "abcdefghijklmnopqrstuvwxyz";
+    cp = tor_strndup(s, 30);
+    test_streq(cp, s); /* same string, */
+    test_neq(cp, s); /* but different pointers. */
+    tor_free(cp);
+
+    cp = tor_strndup(s, 5);
+    test_streq(cp, "abcde");
+    tor_free(cp);
+
+    s = "a\0b\0c\0d\0e\0";
+    cp = tor_memdup(s,10);
+    test_memeq(cp, s, 10); /* same ram, */
+    test_neq(cp, s); /* but different pointers. */
+    tor_free(cp);
+  }
+
+  /* Test str-foo functions */
+  cp = tor_strdup("abcdef");
+  test_assert(tor_strisnonupper(cp));
+  cp[3] = 'D';
+  test_assert(!tor_strisnonupper(cp));
+  tor_strupper(cp);
+  test_streq(cp, "ABCDEF");
+  test_assert(tor_strisprint(cp));
+  cp[3] = 3;
+  test_assert(!tor_strisprint(cp));
+  tor_free(cp);
+
+  /* Test eat_whitespace. */
+  {
+    const char *s = "  \n a";
+    test_eq_ptr(eat_whitespace(s), s+4);
+    s = "abcd";
+    test_eq_ptr(eat_whitespace(s), s);
+    s = "#xyz\nab";
+    test_eq_ptr(eat_whitespace(s), s+5);
+  }
+
+  /* Test memmem */
+  {
+    const char *haystack = "abcde";
+    tor_assert(!tor_memmem(haystack, 5, "ef", 2));
+    test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
+    test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
+    haystack = "ababcad";
+    test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
+  }
+
   /* Test wrap_string */
   {
     smartlist_t *sl = smartlist_create();
@@ -809,6 +909,11 @@
     SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
     smartlist_clear(sl);
   }
+
+  /* now make sure time works. */
+  tor_gettimeofday(&end);
+  /* We might've timewarped a little. */
+  test_assert(tv_udiff(&start, &end) >= -5000);
 }
 
 static void
@@ -983,9 +1088,11 @@
   test_streq(cp, "50,a,canal,man,noon,panama,plan,radar");
   tor_free(cp);
 
-  /* Test string_isin. */
+  /* Test string_isin and isin_case and num_isin */
   test_assert(smartlist_string_isin(sl, "noon"));
   test_assert(!smartlist_string_isin(sl, "noonoon"));
+  test_assert(smartlist_string_isin_case(sl, "nOOn"));
+  test_assert(!smartlist_string_isin_case(sl, "nooNooN"));
   test_assert(smartlist_string_num_isin(sl, 50));
   test_assert(!smartlist_string_num_isin(sl, 60));
   SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
@@ -1061,6 +1168,85 @@
   smartlist_free(sl);
 }
 
+/* stop threads running at once. */
+static tor_mutex_t *_thread_test_mutex = NULL;
+/* make sure that threads have to run at the same time. */
+static tor_mutex_t *_thread_test_start1 = NULL;
+static tor_mutex_t *_thread_test_start2 = NULL;
+static strmap_t *_thread_test_strmap = NULL;
+
+static void
+_thread_test_func(void* _s)
+{
+  char *s = _s;
+  int i;
+  tor_mutex_t *m;
+  if (!strcmp(s, "thread 1"))
+    m = _thread_test_start1;
+  else
+    m = _thread_test_start2;
+  tor_mutex_acquire(m);
+
+  for (i=0; i<1000; ++i) {
+    tor_mutex_acquire(_thread_test_mutex);
+    strmap_set(_thread_test_strmap, "last to run",
+               (void*)(int)tor_get_thread_id());
+    tor_mutex_release(_thread_test_mutex);
+  }
+  strmap_set(_thread_test_strmap, s, (void*)(int)tor_get_thread_id());
+
+  tor_mutex_release(m);
+
+  spawn_exit();
+}
+
+static void
+test_threads(void)
+{
+  char *s1, *s2;
+  int done = 0;
+#ifndef TOR_IS_MULTITHREADED
+  /* Skip this test if we aren't threading. We should be threading most
+   * everywhere by now. */
+  if (1)
+    return 0;
+#endif
+  _thread_test_mutex = tor_mutex_new();
+  _thread_test_start1 = tor_mutex_new();
+  _thread_test_start2 = tor_mutex_new();
+  _thread_test_strmap = strmap_new();
+  s1 = tor_strdup("thread 1");
+  s2 = tor_strdup("thread 2");
+  tor_mutex_acquire(_thread_test_start1);
+  tor_mutex_acquire(_thread_test_start2);
+  spawn_func(_thread_test_func, s1);
+  spawn_func(_thread_test_func, s2);
+  tor_mutex_release(_thread_test_start2);
+  tor_mutex_release(_thread_test_start1);
+  while (!done) {
+    tor_mutex_acquire(_thread_test_mutex);
+    strmap_assert_ok(_thread_test_strmap);
+    if (strmap_get(_thread_test_strmap, "thread 1") &&
+        strmap_get(_thread_test_strmap, "thread 2"))
+      done = 1;
+    tor_mutex_release(_thread_test_mutex);
+  }
+  tor_mutex_free(_thread_test_mutex);
+
+  /* different thread IDs. */
+  test_neq_ptr(strmap_get(_thread_test_strmap, "thread 1"),
+               strmap_get(_thread_test_strmap, "thread 2"));
+  test_assert(strmap_get(_thread_test_strmap, "thread 1") ==
+              strmap_get(_thread_test_strmap, "last to run") ||
+              strmap_get(_thread_test_strmap, "thread 2") ==
+              strmap_get(_thread_test_strmap, "last to run"));
+
+  strmap_free(_thread_test_strmap, NULL);
+
+  tor_free(s1);
+  tor_free(s2);
+}
+
 static int
 _compare_strings_for_pqueue(const void *s1, const void *s2)
 {
@@ -1959,6 +2145,7 @@
   test_control_formats();
   test_pqueue();
   test_mmap();
+  test_threads();
   puts("\n========================= Onion Skins =====================");
   test_onion_handshake();
   puts("\n========================= Directory Formats ===============");