mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-22 22:25:51 +01:00
r12468@Kushana: nickm | 2007-03-06 15:24:00 -0500
More unit tests: gcov is fun. svn:r9748
This commit is contained in:
parent
c9e2766e75
commit
5d1bee87ff
8 changed files with 239 additions and 33 deletions
|
@ -6,6 +6,9 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
|
||||||
o Minor features (logging):
|
o Minor features (logging):
|
||||||
- Always prepend "Bug: " to any log message about a bug.
|
- Always prepend "Bug: " to any log message about a bug.
|
||||||
|
|
||||||
|
o Minor features (other):
|
||||||
|
- More unit tests.
|
||||||
|
|
||||||
o Removed features:
|
o Removed features:
|
||||||
- Removed support for the old binary "version 0" controller protocol.
|
- Removed support for the old binary "version 0" controller protocol.
|
||||||
This has been deprecated since 0.1.1, and warnings have been issued
|
This has been deprecated since 0.1.1, and warnings have been issued
|
||||||
|
|
|
@ -99,12 +99,16 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
|
||||||
#define ATTR_MALLOC __attribute__((malloc))
|
#define ATTR_MALLOC __attribute__((malloc))
|
||||||
#define ATTR_NONNULL(x) __attribute__((nonnull x))
|
#define ATTR_NONNULL(x) __attribute__((nonnull x))
|
||||||
#define PREDICT(exp, val) __builtin_expect((exp), (val))
|
#define PREDICT(exp, val) __builtin_expect((exp), (val))
|
||||||
|
#define PREDICT_LIKELY(exp) PREDICT((exp), 1)
|
||||||
|
#define PREDICT_UNLIKELY(exp) PREDICT((exp), 0)
|
||||||
#else
|
#else
|
||||||
#define ATTR_NORETURN
|
#define ATTR_NORETURN
|
||||||
#define ATTR_PURE
|
#define ATTR_PURE
|
||||||
#define ATTR_MALLOC
|
#define ATTR_MALLOC
|
||||||
#define ATTR_NONNULL(x)
|
#define ATTR_NONNULL(x)
|
||||||
#define PREDICT(exp, val) (exp)
|
#define PREDICT(exp, val) (exp)
|
||||||
|
#define PREDICT_LIKELY(exp) (exp)
|
||||||
|
#define PREDICT_UNLIKELY(exp) (exp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ===== String compatibility */
|
/* ===== String compatibility */
|
||||||
|
|
|
@ -129,10 +129,10 @@ void _log_fn(int severity, uint32_t domain,
|
||||||
* of the current function name. */
|
* of the current function name. */
|
||||||
#define log_fn(severity, domain, args...) \
|
#define log_fn(severity, domain, args...) \
|
||||||
_log_fn(severity, domain, __PRETTY_FUNCTION__, args)
|
_log_fn(severity, domain, __PRETTY_FUNCTION__, args)
|
||||||
#define log_debug(domain, args...) \
|
#define log_debug(domain, args...) \
|
||||||
do { \
|
do { \
|
||||||
if (PREDICT(_log_global_min_severity == LOG_DEBUG, 0)) \
|
if (PREDICT_UNLIKELY(_log_global_min_severity == LOG_DEBUG)) \
|
||||||
_log_fn(LOG_DEBUG, domain, __PRETTY_FUNCTION__, args); \
|
_log_fn(LOG_DEBUG, domain, __PRETTY_FUNCTION__, args); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define log_info(domain, args...) \
|
#define log_info(domain, args...) \
|
||||||
_log_fn(LOG_INFO, domain, __PRETTY_FUNCTION__, args)
|
_log_fn(LOG_INFO, domain, __PRETTY_FUNCTION__, args)
|
||||||
|
|
|
@ -71,21 +71,28 @@ extern int have_failed;
|
||||||
#define test_eq_ptr(expr1, expr2) \
|
#define test_eq_ptr(expr1, expr2) \
|
||||||
test_eq_type(void*, "%p", expr1, expr2)
|
test_eq_type(void*, "%p", expr1, expr2)
|
||||||
|
|
||||||
#define test_neq(expr1, expr2) \
|
#define test_neq_type(tp, fmt, expr1, expr2) \
|
||||||
STMT_BEGIN \
|
STMT_BEGIN \
|
||||||
long v1=(long)(expr1), v2=(long)(expr2); \
|
tp v1=(tp)(expr1); \
|
||||||
if (v1!=v2) { printf("."); fflush(stdout); } else { \
|
tp v2=(tp)(expr2); \
|
||||||
have_failed = 1; \
|
if (v1!=v2) { printf("."); fflush(stdout); } else { \
|
||||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
|
have_failed = 1; \
|
||||||
" (%ld == %ld)\n", \
|
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n" \
|
||||||
_SHORT_FILE_, \
|
" ("fmt" == "fmt")\n", \
|
||||||
__LINE__, \
|
_SHORT_FILE_, \
|
||||||
PRETTY_FUNCTION, \
|
__LINE__, \
|
||||||
#expr1, #expr2, \
|
PRETTY_FUNCTION, \
|
||||||
v1, v2); \
|
#expr1, #expr2, \
|
||||||
return; \
|
v1, v2); \
|
||||||
|
return; \
|
||||||
} STMT_END
|
} 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) \
|
#define test_streq(expr1, expr2) \
|
||||||
STMT_BEGIN \
|
STMT_BEGIN \
|
||||||
const char *v1=(expr1), *v2=(expr2); \
|
const char *v1=(expr1), *v2=(expr2); \
|
||||||
|
|
|
@ -115,7 +115,7 @@ _tor_malloc(size_t size DMALLOC_PARAMS)
|
||||||
#endif
|
#endif
|
||||||
result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0);
|
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.");
|
log_err(LD_MM,"Out of memory on malloc(). Dying.");
|
||||||
/* If these functions die within a worker process, they won't call
|
/* 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
|
* spawn_exit, but that's ok, since the parent will run out of memory soon
|
||||||
|
@ -147,7 +147,7 @@ _tor_realloc(void *ptr, size_t size DMALLOC_PARAMS)
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
|
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.");
|
log_err(LD_MM,"Out of memory on realloc(). Dying.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ _tor_strdup(const char *s DMALLOC_PARAMS)
|
||||||
tor_assert(s);
|
tor_assert(s);
|
||||||
|
|
||||||
dup = dmalloc_strdup(file, line, s, 0);
|
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.");
|
log_err(LD_MM,"Out of memory on strdup(). Dying.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ tor_parse_long(const char *s, int base, long min, long max,
|
||||||
CHECK_STRTOX_RESULT();
|
CHECK_STRTOX_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** As tor_parse_log, but return an unsigned long. */
|
/** As tor_parse_long, but return an unsigned long. */
|
||||||
unsigned long
|
unsigned long
|
||||||
tor_parse_ulong(const char *s, int base, unsigned long min,
|
tor_parse_ulong(const char *s, int base, unsigned long min,
|
||||||
unsigned long max, int *ok, char **next)
|
unsigned long max, int *ok, char **next)
|
||||||
|
@ -615,6 +615,7 @@ int
|
||||||
base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
|
base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
|
||||||
{
|
{
|
||||||
const char *end;
|
const char *end;
|
||||||
|
|
||||||
int v1,v2;
|
int v1,v2;
|
||||||
if ((srclen % 2) != 0)
|
if ((srclen % 2) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -812,7 +813,7 @@ wrap_string(smartlist_t *out, const char *string, size_t width,
|
||||||
/** Return the number of microseconds elapsed between *start and *end.
|
/** Return the number of microseconds elapsed between *start and *end.
|
||||||
*/
|
*/
|
||||||
long
|
long
|
||||||
tv_udiff(struct timeval *start, struct timeval *end)
|
tv_udiff(const struct timeval *start, const struct timeval *end)
|
||||||
{
|
{
|
||||||
long udiff;
|
long udiff;
|
||||||
long secdiff = end->tv_sec - start->tv_sec;
|
long secdiff = end->tv_sec - start->tv_sec;
|
||||||
|
@ -829,7 +830,7 @@ tv_udiff(struct timeval *start, struct timeval *end)
|
||||||
/** Return -1 if *a \< *b, 0 if *a==*b, and 1 if *a \> *b.
|
/** Return -1 if *a \< *b, 0 if *a==*b, and 1 if *a \> *b.
|
||||||
*/
|
*/
|
||||||
int
|
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)
|
if (a->tv_sec > b->tv_sec)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -845,7 +846,7 @@ tv_cmp(struct timeval *a, struct timeval *b)
|
||||||
/** Increment *a by the number of seconds and microseconds in *b.
|
/** Increment *a by the number of seconds and microseconds in *b.
|
||||||
*/
|
*/
|
||||||
void
|
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_usec += b->tv_usec;
|
||||||
a->tv_sec += b->tv_sec + (a->tv_usec / 1000000);
|
a->tv_sec += b->tv_sec + (a->tv_usec / 1000000);
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/** Macro: evaluate the expression x, which we expect to be false.
|
/** Macro: evaluate the expression x, which we expect to be false.
|
||||||
* Used to hint the compiler that a branch won't be taken. */
|
* 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
|
#else
|
||||||
#define PREDICT_FALSE(x) !(x)
|
#define PREDICT_FALSE(x) !(x)
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,14 +85,18 @@ void _tor_free(void *mem);
|
||||||
extern int dmalloc_free(const char *file, const int line, void *pnt,
|
extern int dmalloc_free(const char *file, const int line, void *pnt,
|
||||||
const int func_id);
|
const int func_id);
|
||||||
#define tor_free(p) do { \
|
#define tor_free(p) do { \
|
||||||
if (PREDICT((p)!=NULL, 1)) { \
|
if (PREDICT_LIKELY((p)!=NULL)) { \
|
||||||
dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \
|
dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \
|
||||||
(p)=NULL; \
|
(p)=NULL; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define tor_free(p) do { if (PREDICT((p)!=NULL,1)) { free(p); (p)=NULL;} } \
|
#define tor_free(p) do { \
|
||||||
while (0)
|
if (PREDICT_LIKELY((p)!=NULL)) { \
|
||||||
|
free(p); \
|
||||||
|
(p)=NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define tor_malloc(size) _tor_malloc(size DMALLOC_ARGS)
|
#define tor_malloc(size) _tor_malloc(size DMALLOC_ARGS)
|
||||||
|
@ -172,10 +176,10 @@ void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
|
||||||
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
|
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
|
||||||
|
|
||||||
/* Time helpers */
|
/* 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_addms(struct timeval *a, long ms);
|
||||||
void tv_add(struct timeval *a, struct timeval *b);
|
void tv_add(struct timeval *a, const struct timeval *b);
|
||||||
int tv_cmp(struct timeval *a, struct timeval *b);
|
int tv_cmp(const struct timeval *a, const struct timeval *b);
|
||||||
time_t tor_timegm(struct tm *tm);
|
time_t tor_timegm(struct tm *tm);
|
||||||
#define RFC1123_TIME_LEN 29
|
#define RFC1123_TIME_LEN 29
|
||||||
void format_rfc1123_time(char *buf, time_t t);
|
void format_rfc1123_time(char *buf, time_t t);
|
||||||
|
|
|
@ -4178,7 +4178,7 @@ static int need_to_update_have_min_dir_info = 1;
|
||||||
int
|
int
|
||||||
router_have_minimum_dir_info(void)
|
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();
|
update_router_have_minimum_dir_info();
|
||||||
need_to_update_have_min_dir_info = 0;
|
need_to_update_have_min_dir_info = 0;
|
||||||
}
|
}
|
||||||
|
|
189
src/or/test.c
189
src/or/test.c
|
@ -535,6 +535,12 @@ test_crypto(void)
|
||||||
test_eq(i,0);
|
test_eq(i,0);
|
||||||
test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
|
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(data1);
|
||||||
tor_free(data2);
|
tor_free(data2);
|
||||||
tor_free(data3);
|
tor_free(data3);
|
||||||
|
@ -606,6 +612,10 @@ test_util(void)
|
||||||
|
|
||||||
end.tv_usec = 7000;
|
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));
|
test_eq(2000L, tv_udiff(&start, &end));
|
||||||
|
|
||||||
end.tv_sec = 6;
|
end.tv_sec = 6;
|
||||||
|
@ -620,6 +630,17 @@ test_util(void)
|
||||||
|
|
||||||
test_eq(-1005000L, tv_udiff(&start, &end));
|
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
|
/* The test values here are confirmed to be correct on a platform
|
||||||
* with a working timegm. */
|
* with a working timegm. */
|
||||||
a_time.tm_year = 2003-1900;
|
a_time.tm_year = 2003-1900;
|
||||||
|
@ -644,6 +665,8 @@ test_util(void)
|
||||||
i = parse_rfc1123_time(timestr, &t_res);
|
i = parse_rfc1123_time(timestr, &t_res);
|
||||||
test_eq(i,0);
|
test_eq(i,0);
|
||||||
test_eq(t_res, (time_t)1091580502UL);
|
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() */
|
/* Test tor_strstrip() */
|
||||||
strlcpy(buf, "Testing 1 2 3", sizeof(buf));
|
strlcpy(buf, "Testing 1 2 3", sizeof(buf));
|
||||||
|
@ -694,6 +717,11 @@ test_util(void)
|
||||||
/* Test tor_parse_long. */
|
/* Test tor_parse_long. */
|
||||||
test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
|
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(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 tor_parse_uint64. */
|
||||||
test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
|
test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
|
||||||
|
@ -772,6 +800,26 @@ test_util(void)
|
||||||
test_assert(strcmpend("abcdef", "dee")>0);
|
test_assert(strcmpend("abcdef", "dee")>0);
|
||||||
test_assert(strcmpend("ab", "abb")<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];
|
char tmpbuf[INET_NTOA_BUF_LEN];
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
|
@ -785,6 +833,58 @@ test_util(void)
|
||||||
test_streq("\"abcd\"", escaped("abcd"));
|
test_streq("\"abcd\"", escaped("abcd"));
|
||||||
test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
|
test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
|
||||||
test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
|
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 */
|
/* Test wrap_string */
|
||||||
{
|
{
|
||||||
|
@ -809,6 +909,11 @@ test_util(void)
|
||||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||||
smartlist_clear(sl);
|
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
|
static void
|
||||||
|
@ -983,9 +1088,11 @@ test_smartlist(void)
|
||||||
test_streq(cp, "50,a,canal,man,noon,panama,plan,radar");
|
test_streq(cp, "50,a,canal,man,noon,panama,plan,radar");
|
||||||
tor_free(cp);
|
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, "noon"));
|
||||||
test_assert(!smartlist_string_isin(sl, "noonoon"));
|
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, 50));
|
||||||
test_assert(!smartlist_string_num_isin(sl, 60));
|
test_assert(!smartlist_string_num_isin(sl, 60));
|
||||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||||
|
@ -1061,6 +1168,85 @@ test_smartlist(void)
|
||||||
smartlist_free(sl);
|
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
|
static int
|
||||||
_compare_strings_for_pqueue(const void *s1, const void *s2)
|
_compare_strings_for_pqueue(const void *s1, const void *s2)
|
||||||
{
|
{
|
||||||
|
@ -1959,6 +2145,7 @@ main(int c, char**v)
|
||||||
test_control_formats();
|
test_control_formats();
|
||||||
test_pqueue();
|
test_pqueue();
|
||||||
test_mmap();
|
test_mmap();
|
||||||
|
test_threads();
|
||||||
puts("\n========================= Onion Skins =====================");
|
puts("\n========================= Onion Skins =====================");
|
||||||
test_onion_handshake();
|
test_onion_handshake();
|
||||||
puts("\n========================= Directory Formats ===============");
|
puts("\n========================= Directory Formats ===============");
|
||||||
|
|
Loading…
Add table
Reference in a new issue