2013-07-17 23:31:27 +02:00
|
|
|
/* Copyright (c) 2001-2004, Roger Dingledine.
|
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2016-02-27 18:48:19 +01:00
|
|
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
2013-07-17 23:31:27 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#define BUFFERS_PRIVATE
|
|
|
|
#include "or.h"
|
|
|
|
#include "buffers.h"
|
2013-07-17 23:51:21 +02:00
|
|
|
#include "ext_orport.h"
|
2013-07-17 23:31:27 +02:00
|
|
|
#include "test.h"
|
|
|
|
|
|
|
|
/** Run unit tests for buffers.c */
|
|
|
|
static void
|
|
|
|
test_buffers_basic(void *arg)
|
|
|
|
{
|
|
|
|
char str[256];
|
|
|
|
char str2[256];
|
|
|
|
|
|
|
|
buf_t *buf = NULL, *buf2 = NULL;
|
|
|
|
const char *cp;
|
|
|
|
|
|
|
|
int j;
|
|
|
|
size_t r;
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
/****
|
|
|
|
* buf_new
|
|
|
|
****/
|
|
|
|
if (!(buf = buf_new()))
|
Use coccinelle scripts to clean up our unit tests
This should get rid of most of the users of the old test_*
functions. Some are in macros and will need manual cleanup, though.
This patch is for 13119, and was automatically generated with these
scripts. The perl scripts are there because coccinelle hates
operators as macro arguments.
------------------------------
s/==,/_X_EQ_,/g;
s/!=,/_X_NE_,/g;
s/<,/_X_LT_,/g;
s/>,/_X_GT_,/g;
s/>=,/_X_GEQ_,/g;
s/<=,/_X_LEQ_,/g;
------------------------------
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_fail_msg
+TT_DIE
(
+(
a
+)
)
...>
}
@@
identifier func;
@@
func (...) {
<...
-test_fail()
+TT_DIE(("Assertion failed."))
...>
}
@@
expression a;
identifier func;
@@
func (...) {
<...
-test_assert
+tt_assert
(a)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq
+tt_int_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_neq
+tt_int_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_streq
+tt_str_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_strneq
+tt_str_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func (...) {
<...
-test_eq_ptr
+tt_ptr_op
(a,
+_X_EQ_,
b)
...>
}
@@
expression a, b;
identifier func;
@@
func() {
<...
-test_neq_ptr
+tt_ptr_op
(a,
+_X_NEQ_,
b)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memeq
+tt_mem_op
(a,
+_X_EQ_,
b, len)
...>
}
@@
expression a, b, len;
identifier func;
@@
func (...) {
<...
-test_memneq
+tt_mem_op
(a,
+_X_NEQ_,
b, len)
...>
}
------------------------------
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a == b
+a, _X_EQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a != b
+a, _X_NEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a >= b
+a, _X_GEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a <= b
+a, _X_LEQ_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a > b
+a, _X_GT_, b
)
...>
}
@@
char a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_int_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned int a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
@@
unsigned long a, b;
identifier func;
@@
func (...) {
<...
-tt_assert
+tt_uint_op
(
-a < b
+a, _X_LT_, b
)
...>
}
------------------------------
s/_X_NEQ_/!=/g;
s/_X_NE_/!=/g;
s/_X_EQ_/==/g;
s/_X_GT_/>/g;
s/_X_LT_/</g;
s/_X_GEQ_/>=/g;
s/_X_LEQ_/<=/g;
s/test_mem_op\(/tt_mem_op\(/g;
2014-09-16 03:18:21 +02:00
|
|
|
TT_DIE(("Assertion failed."));
|
2013-07-17 23:31:27 +02:00
|
|
|
|
|
|
|
//test_eq(buf_capacity(buf), 4096);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 0);
|
2013-07-17 23:31:27 +02:00
|
|
|
|
|
|
|
/****
|
|
|
|
* General pointer frobbing
|
|
|
|
*/
|
|
|
|
for (j=0;j<256;++j) {
|
|
|
|
str[j] = (char)j;
|
|
|
|
}
|
|
|
|
write_to_buf(str, 256, buf);
|
|
|
|
write_to_buf(str, 256, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 512);
|
2013-07-17 23:31:27 +02:00
|
|
|
fetch_from_buf(str2, 200, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str,OP_EQ, str2, 200);
|
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 312);
|
2013-07-17 23:31:27 +02:00
|
|
|
memset(str2, 0, sizeof(str2));
|
|
|
|
|
|
|
|
fetch_from_buf(str2, 256, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str+200,OP_EQ, str2, 56);
|
|
|
|
tt_mem_op(str,OP_EQ, str2+56, 200);
|
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 56);
|
2013-07-17 23:31:27 +02:00
|
|
|
memset(str2, 0, sizeof(str2));
|
|
|
|
/* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
|
|
|
|
* another 3584 bytes, we hit the end. */
|
|
|
|
for (j=0;j<15;++j) {
|
|
|
|
write_to_buf(str, 256, buf);
|
|
|
|
}
|
|
|
|
assert_buf_ok(buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 3896);
|
2013-07-17 23:31:27 +02:00
|
|
|
fetch_from_buf(str2, 56, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 3840);
|
|
|
|
tt_mem_op(str+200,OP_EQ, str2, 56);
|
2013-07-17 23:31:27 +02:00
|
|
|
for (j=0;j<15;++j) {
|
|
|
|
memset(str2, 0, sizeof(str2));
|
|
|
|
fetch_from_buf(str2, 256, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str,OP_EQ, str2, 256);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 0);
|
2013-07-17 23:31:27 +02:00
|
|
|
buf_free(buf);
|
|
|
|
buf = NULL;
|
|
|
|
|
|
|
|
/* Okay, now make sure growing can work. */
|
|
|
|
buf = buf_new_with_capacity(16);
|
|
|
|
//test_eq(buf_capacity(buf), 16);
|
|
|
|
write_to_buf(str+1, 255, buf);
|
|
|
|
//test_eq(buf_capacity(buf), 256);
|
|
|
|
fetch_from_buf(str2, 254, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str+1,OP_EQ, str2, 254);
|
2013-07-17 23:31:27 +02:00
|
|
|
//test_eq(buf_capacity(buf), 256);
|
|
|
|
assert_buf_ok(buf);
|
|
|
|
write_to_buf(str, 32, buf);
|
|
|
|
//test_eq(buf_capacity(buf), 256);
|
|
|
|
assert_buf_ok(buf);
|
|
|
|
write_to_buf(str, 256, buf);
|
|
|
|
assert_buf_ok(buf);
|
|
|
|
//test_eq(buf_capacity(buf), 512);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 33+256);
|
2013-07-17 23:31:27 +02:00
|
|
|
fetch_from_buf(str2, 33, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(*str2,OP_EQ, str[255]);
|
2013-07-17 23:31:27 +02:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2+1,OP_EQ, str, 32);
|
2013-07-17 23:31:27 +02:00
|
|
|
//test_eq(buf_capacity(buf), 512);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 256);
|
2013-07-17 23:31:27 +02:00
|
|
|
fetch_from_buf(str2, 256, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str,OP_EQ, str2, 256);
|
2013-07-17 23:31:27 +02:00
|
|
|
|
|
|
|
/* now try shrinking: case 1. */
|
|
|
|
buf_free(buf);
|
|
|
|
buf = buf_new_with_capacity(33668);
|
|
|
|
for (j=0;j<67;++j) {
|
|
|
|
write_to_buf(str,255, buf);
|
|
|
|
}
|
|
|
|
//test_eq(buf_capacity(buf), 33668);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 17085);
|
2013-07-17 23:31:27 +02:00
|
|
|
for (j=0; j < 40; ++j) {
|
|
|
|
fetch_from_buf(str2, 255,buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2,OP_EQ, str, 255);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* now try shrinking: case 2. */
|
|
|
|
buf_free(buf);
|
|
|
|
buf = buf_new_with_capacity(33668);
|
|
|
|
for (j=0;j<67;++j) {
|
|
|
|
write_to_buf(str,255, buf);
|
|
|
|
}
|
|
|
|
for (j=0; j < 20; ++j) {
|
|
|
|
fetch_from_buf(str2, 255,buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2,OP_EQ, str, 255);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
for (j=0;j<80;++j) {
|
|
|
|
write_to_buf(str,255, buf);
|
|
|
|
}
|
|
|
|
//test_eq(buf_capacity(buf),33668);
|
|
|
|
for (j=0; j < 120; ++j) {
|
|
|
|
fetch_from_buf(str2, 255,buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2,OP_EQ, str, 255);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Move from buf to buf. */
|
|
|
|
buf_free(buf);
|
|
|
|
buf = buf_new_with_capacity(4096);
|
|
|
|
buf2 = buf_new_with_capacity(4096);
|
|
|
|
for (j=0;j<100;++j)
|
|
|
|
write_to_buf(str, 255, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 25500);
|
2013-07-17 23:31:27 +02:00
|
|
|
for (j=0;j<100;++j) {
|
|
|
|
r = 10;
|
|
|
|
move_buf_to_buf(buf2, buf, &r);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(r,OP_EQ, 0);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf),OP_EQ, 24500);
|
|
|
|
tt_int_op(buf_datalen(buf2),OP_EQ, 1000);
|
2013-07-17 23:31:27 +02:00
|
|
|
for (j=0;j<3;++j) {
|
|
|
|
fetch_from_buf(str2, 255, buf2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2,OP_EQ, str, 255);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
r = 8192; /*big move*/
|
|
|
|
move_buf_to_buf(buf2, buf, &r);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(r,OP_EQ, 0);
|
2013-07-17 23:31:27 +02:00
|
|
|
r = 30000; /* incomplete move */
|
|
|
|
move_buf_to_buf(buf2, buf, &r);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(r,OP_EQ, 13692);
|
2013-07-17 23:31:27 +02:00
|
|
|
for (j=0;j<97;++j) {
|
|
|
|
fetch_from_buf(str2, 255, buf2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(str2,OP_EQ, str, 255);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
buf_free(buf);
|
|
|
|
buf_free(buf2);
|
|
|
|
buf = buf2 = NULL;
|
|
|
|
|
|
|
|
buf = buf_new_with_capacity(5);
|
|
|
|
cp = "Testing. This is a moderately long Testing string.";
|
|
|
|
for (j = 0; cp[j]; j++)
|
|
|
|
write_to_buf(cp+j, 1, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0,OP_EQ, buf_find_string_offset(buf, "Testing", 7));
|
|
|
|
tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "esting", 6));
|
|
|
|
tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "est", 3));
|
|
|
|
tt_int_op(39,OP_EQ, buf_find_string_offset(buf, "ing str", 7));
|
|
|
|
tt_int_op(35,OP_EQ, buf_find_string_offset(buf, "Testing str", 11));
|
|
|
|
tt_int_op(32,OP_EQ, buf_find_string_offset(buf, "ng ", 3));
|
|
|
|
tt_int_op(43,OP_EQ, buf_find_string_offset(buf, "string.", 7));
|
|
|
|
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "shrdlu", 6));
|
|
|
|
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "Testing thing", 13));
|
|
|
|
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "ngx", 3));
|
2013-07-17 23:31:27 +02:00
|
|
|
buf_free(buf);
|
|
|
|
buf = NULL;
|
|
|
|
|
|
|
|
/* Try adding a string too long for any freelist. */
|
|
|
|
{
|
|
|
|
char *cp = tor_malloc_zero(65536);
|
|
|
|
buf = buf_new();
|
|
|
|
write_to_buf(cp, 65536, buf);
|
|
|
|
tor_free(cp);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf), OP_EQ, 65536);
|
2013-07-17 23:31:27 +02:00
|
|
|
buf_free(buf);
|
|
|
|
buf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (buf)
|
|
|
|
buf_free(buf);
|
|
|
|
if (buf2)
|
|
|
|
buf_free(buf2);
|
|
|
|
}
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
test_buffer_pullup(void *arg)
|
|
|
|
{
|
|
|
|
buf_t *buf;
|
|
|
|
char *stuff, *tmp;
|
|
|
|
const char *cp;
|
|
|
|
size_t sz;
|
|
|
|
(void)arg;
|
|
|
|
stuff = tor_malloc(16384);
|
|
|
|
tmp = tor_malloc(16384);
|
|
|
|
|
|
|
|
buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
|
|
|
|
|
|
|
|
tt_assert(buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_default_chunk_size(buf), OP_EQ, 4096);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
/* There are a bunch of cases for pullup. One is the trivial case. Let's
|
|
|
|
mess around with an empty buffer. */
|
2015-09-01 20:36:25 +02:00
|
|
|
buf_pullup(buf, 16);
|
2014-01-04 19:30:56 +01:00
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_EQ, NULL);
|
|
|
|
tt_uint_op(sz, OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
/* Let's make sure nothing got allocated */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
/* Case 1: everything puts into the first chunk with some moving. */
|
|
|
|
|
|
|
|
/* Let's add some data. */
|
|
|
|
crypto_rand(stuff, 16384);
|
|
|
|
write_to_buf(stuff, 3000, buf);
|
|
|
|
write_to_buf(stuff+3000, 3000, buf);
|
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_int_op(sz, OP_LE, 4096);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
/* Make room for 3000 bytes in the first chunk, so that the pullup-move code
|
|
|
|
* can get tested. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 3000);
|
|
|
|
tt_mem_op(tmp,OP_EQ, stuff, 3000);
|
2015-09-01 20:36:25 +02:00
|
|
|
buf_pullup(buf, 2048);
|
2014-01-04 19:30:56 +01:00
|
|
|
assert_buf_ok(buf);
|
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_int_op(sz, OP_GE, 2048);
|
|
|
|
tt_mem_op(cp,OP_EQ, stuff+3000, 2048);
|
|
|
|
tt_int_op(3000, OP_EQ, buf_datalen(buf));
|
|
|
|
tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 0);
|
|
|
|
tt_mem_op(tmp,OP_EQ, stuff+3000, 2048);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
buf_free(buf);
|
|
|
|
|
|
|
|
/* Now try the large-chunk case. */
|
|
|
|
buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
|
|
|
|
write_to_buf(stuff, 4000, buf);
|
|
|
|
write_to_buf(stuff+4000, 4000, buf);
|
|
|
|
write_to_buf(stuff+8000, 4000, buf);
|
|
|
|
write_to_buf(stuff+12000, 4000, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_datalen(buf), OP_EQ, 16000);
|
2014-01-04 19:30:56 +01:00
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_int_op(sz, OP_LE, 4096);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
2015-09-01 20:36:25 +02:00
|
|
|
buf_pullup(buf, 12500);
|
2014-01-04 19:30:56 +01:00
|
|
|
assert_buf_ok(buf);
|
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_int_op(sz, OP_GE, 12500);
|
|
|
|
tt_mem_op(cp,OP_EQ, stuff, 12500);
|
|
|
|
tt_int_op(buf_datalen(buf), OP_EQ, 16000);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
fetch_from_buf(tmp, 12400, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(tmp,OP_EQ, stuff, 12400);
|
|
|
|
tt_int_op(buf_datalen(buf), OP_EQ, 3600);
|
2014-01-04 19:30:56 +01:00
|
|
|
fetch_from_buf(tmp, 3500, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(tmp,OP_EQ, stuff+12400, 3500);
|
2014-01-04 19:30:56 +01:00
|
|
|
fetch_from_buf(tmp, 100, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(tmp,OP_EQ, stuff+15900, 10);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
buf_free(buf);
|
|
|
|
|
|
|
|
/* Make sure that the pull-up-whole-buffer case works */
|
|
|
|
buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
|
|
|
|
write_to_buf(stuff, 4000, buf);
|
|
|
|
write_to_buf(stuff+4000, 4000, buf);
|
|
|
|
fetch_from_buf(tmp, 100, buf); /* dump 100 bytes from first chunk */
|
2015-09-01 20:36:25 +02:00
|
|
|
buf_pullup(buf, 16000); /* Way too much. */
|
2014-01-04 19:30:56 +01:00
|
|
|
assert_buf_ok(buf);
|
|
|
|
buf_get_first_chunk_data(buf, &cp, &sz);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_ptr_op(cp, OP_NE, NULL);
|
|
|
|
tt_int_op(sz, OP_EQ, 7900);
|
|
|
|
tt_mem_op(cp,OP_EQ, stuff+100, 7900);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
buf_free(buf);
|
|
|
|
buf = NULL;
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
done:
|
|
|
|
buf_free(buf);
|
|
|
|
tor_free(stuff);
|
|
|
|
tor_free(tmp);
|
|
|
|
}
|
|
|
|
|
2013-07-17 23:31:27 +02:00
|
|
|
static void
|
|
|
|
test_buffer_copy(void *arg)
|
|
|
|
{
|
|
|
|
generic_buffer_t *buf=NULL, *buf2=NULL;
|
|
|
|
const char *s;
|
|
|
|
size_t len;
|
|
|
|
char b[256];
|
|
|
|
int i;
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
buf = generic_buffer_new();
|
|
|
|
tt_assert(buf);
|
|
|
|
|
|
|
|
/* Copy an empty buffer. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
2013-07-17 23:31:27 +02:00
|
|
|
tt_assert(buf2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_len(buf2));
|
2013-07-17 23:31:27 +02:00
|
|
|
|
|
|
|
/* Now try with a short buffer. */
|
|
|
|
s = "And now comes an act of enormous enormance!";
|
|
|
|
len = strlen(s);
|
|
|
|
generic_buffer_add(buf, s, len);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(len, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:31:27 +02:00
|
|
|
/* Add junk to buf2 so we can test replacing.*/
|
|
|
|
generic_buffer_add(buf2, "BLARG", 5);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
|
|
|
tt_int_op(len, OP_EQ, generic_buffer_len(buf2));
|
2013-07-17 23:31:27 +02:00
|
|
|
generic_buffer_get(buf2, b, len);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(b, OP_EQ, s, len);
|
2013-07-17 23:31:27 +02:00
|
|
|
/* Now free buf2 and retry so we can test allocating */
|
|
|
|
generic_buffer_free(buf2);
|
|
|
|
buf2 = NULL;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
|
|
|
tt_int_op(len, OP_EQ, generic_buffer_len(buf2));
|
2013-07-17 23:31:27 +02:00
|
|
|
generic_buffer_get(buf2, b, len);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_mem_op(b, OP_EQ, s, len);
|
2013-07-17 23:31:27 +02:00
|
|
|
/* Clear buf for next test */
|
|
|
|
generic_buffer_get(buf, b, len);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(generic_buffer_len(buf),OP_EQ,0);
|
2013-07-17 23:31:27 +02:00
|
|
|
|
|
|
|
/* Okay, now let's try a bigger buffer. */
|
|
|
|
s = "Quis autem vel eum iure reprehenderit qui in ea voluptate velit "
|
|
|
|
"esse quam nihil molestiae consequatur, vel illum qui dolorem eum "
|
|
|
|
"fugiat quo voluptas nulla pariatur?";
|
|
|
|
len = strlen(s);
|
|
|
|
for (i = 0; i < 256; ++i) {
|
|
|
|
b[0]=i;
|
|
|
|
generic_buffer_add(buf, b, 1);
|
|
|
|
generic_buffer_add(buf, s, len);
|
|
|
|
}
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
|
|
|
tt_int_op(generic_buffer_len(buf2), OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:31:27 +02:00
|
|
|
for (i = 0; i < 256; ++i) {
|
|
|
|
generic_buffer_get(buf2, b, len+1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op((unsigned char)b[0],OP_EQ,i);
|
|
|
|
tt_mem_op(b+1, OP_EQ, s, len);
|
2013-07-17 23:31:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (buf)
|
|
|
|
generic_buffer_free(buf);
|
|
|
|
if (buf2)
|
|
|
|
generic_buffer_free(buf2);
|
|
|
|
}
|
|
|
|
|
2013-07-17 23:51:21 +02:00
|
|
|
static void
|
|
|
|
test_buffer_ext_or_cmd(void *arg)
|
|
|
|
{
|
|
|
|
ext_or_cmd_t *cmd = NULL;
|
|
|
|
generic_buffer_t *buf = generic_buffer_new();
|
|
|
|
char *tmp = NULL;
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
/* Empty -- should give "not there. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_EQ, cmd);
|
2013-07-17 23:51:21 +02:00
|
|
|
|
|
|
|
/* Three bytes: shouldn't work. */
|
|
|
|
generic_buffer_add(buf, "\x00\x20\x00", 3);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_EQ, cmd);
|
|
|
|
tt_int_op(3, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:51:21 +02:00
|
|
|
|
|
|
|
/* 0020 0000: That's a nil command. It should work. */
|
|
|
|
generic_buffer_add(buf, "\x00", 1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_NE, cmd);
|
|
|
|
tt_int_op(0x20, OP_EQ, cmd->cmd);
|
|
|
|
tt_int_op(0, OP_EQ, cmd->len);
|
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:51:21 +02:00
|
|
|
ext_or_cmd_free(cmd);
|
|
|
|
cmd = NULL;
|
|
|
|
|
|
|
|
/* Now try a length-6 command with one byte missing. */
|
|
|
|
generic_buffer_add(buf, "\x10\x21\x00\x06""abcde", 9);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_EQ, cmd);
|
2013-07-17 23:51:21 +02:00
|
|
|
generic_buffer_add(buf, "f", 1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_NE, cmd);
|
|
|
|
tt_int_op(0x1021, OP_EQ, cmd->cmd);
|
|
|
|
tt_int_op(6, OP_EQ, cmd->len);
|
|
|
|
tt_mem_op("abcdef", OP_EQ, cmd->body, 6);
|
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:51:21 +02:00
|
|
|
ext_or_cmd_free(cmd);
|
|
|
|
cmd = NULL;
|
|
|
|
|
|
|
|
/* Now try a length-10 command with 4 extra bytes. */
|
|
|
|
generic_buffer_add(buf, "\xff\xff\x00\x0a"
|
|
|
|
"loremipsum\x10\x00\xff\xff", 18);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_NE, cmd);
|
|
|
|
tt_int_op(0xffff, OP_EQ, cmd->cmd);
|
|
|
|
tt_int_op(10, OP_EQ, cmd->len);
|
|
|
|
tt_mem_op("loremipsum", OP_EQ, cmd->body, 10);
|
|
|
|
tt_int_op(4, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:51:21 +02:00
|
|
|
ext_or_cmd_free(cmd);
|
|
|
|
cmd = NULL;
|
|
|
|
|
|
|
|
/* Finally, let's try a maximum-length command. We already have the header
|
|
|
|
* waiting. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
2013-07-17 23:51:21 +02:00
|
|
|
tmp = tor_malloc_zero(65535);
|
|
|
|
generic_buffer_add(buf, tmp, 65535);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
|
|
|
tt_ptr_op(NULL, OP_NE, cmd);
|
|
|
|
tt_int_op(0x1000, OP_EQ, cmd->cmd);
|
|
|
|
tt_int_op(0xffff, OP_EQ, cmd->len);
|
|
|
|
tt_mem_op(tmp, OP_EQ, cmd->body, 65535);
|
|
|
|
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
2013-07-17 23:51:21 +02:00
|
|
|
ext_or_cmd_free(cmd);
|
|
|
|
cmd = NULL;
|
|
|
|
|
|
|
|
done:
|
|
|
|
ext_or_cmd_free(cmd);
|
|
|
|
generic_buffer_free(buf);
|
|
|
|
tor_free(tmp);
|
2014-01-04 19:30:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_buffer_allocation_tracking(void *arg)
|
|
|
|
{
|
2014-01-06 04:27:37 +01:00
|
|
|
char *junk = tor_malloc(16384);
|
2014-01-04 19:30:56 +01:00
|
|
|
buf_t *buf1 = NULL, *buf2 = NULL;
|
2014-01-06 04:27:37 +01:00
|
|
|
int i;
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
(void)arg;
|
|
|
|
|
2014-01-06 04:27:37 +01:00
|
|
|
crypto_rand(junk, 16384);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
buf1 = buf_new();
|
|
|
|
tt_assert(buf1);
|
|
|
|
buf2 = buf_new();
|
|
|
|
tt_assert(buf2);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf1), OP_EQ, 0);
|
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-06 04:27:37 +01:00
|
|
|
|
|
|
|
write_to_buf(junk, 4000, buf1);
|
|
|
|
write_to_buf(junk, 4000, buf1);
|
|
|
|
write_to_buf(junk, 4000, buf1);
|
|
|
|
write_to_buf(junk, 4000, buf1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf1), OP_EQ, 16384);
|
2014-01-06 04:27:37 +01:00
|
|
|
fetch_from_buf(junk, 100, buf1);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf1), OP_EQ, 16384); /* still 4 4k chunks */
|
2014-01-06 04:27:37 +01:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
|
2014-01-06 04:27:37 +01:00
|
|
|
|
|
|
|
fetch_from_buf(junk, 4096, buf1); /* drop a 1k chunk... */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf1), OP_EQ, 3*4096); /* now 3 4k chunks */
|
2014-01-06 04:27:37 +01:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 12288); /* that chunk was really
|
2014-04-29 11:18:34 +02:00
|
|
|
freed. */
|
2014-01-06 04:27:37 +01:00
|
|
|
|
|
|
|
write_to_buf(junk, 4000, buf2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf2), OP_EQ, 4096); /* another 4k chunk. */
|
2014-04-29 11:18:34 +02:00
|
|
|
/*
|
2015-02-11 15:03:50 +01:00
|
|
|
* We bounce back up to 16384 by allocating a new chunk.
|
2014-04-29 11:18:34 +02:00
|
|
|
*/
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
|
2014-01-06 04:27:37 +01:00
|
|
|
write_to_buf(junk, 4000, buf2);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf2), OP_EQ, 8192); /* another 4k chunk. */
|
2014-11-12 19:42:01 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(),
|
|
|
|
OP_EQ, 5*4096); /* that chunk was new. */
|
2014-01-06 04:27:37 +01:00
|
|
|
|
|
|
|
/* Make a really huge buffer */
|
|
|
|
for (i = 0; i < 1000; ++i) {
|
|
|
|
write_to_buf(junk, 4000, buf2);
|
|
|
|
}
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_allocation(buf2), OP_GE, 4008000);
|
|
|
|
tt_int_op(buf_get_total_allocation(), OP_GE, 4008000);
|
2014-01-06 04:27:37 +01:00
|
|
|
buf_free(buf2);
|
|
|
|
buf2 = NULL;
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_LT, 4008000);
|
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, buf_allocation(buf1));
|
2014-01-06 04:27:37 +01:00
|
|
|
buf_free(buf1);
|
|
|
|
buf1 = NULL;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
2014-01-04 19:30:56 +01:00
|
|
|
|
|
|
|
done:
|
|
|
|
buf_free(buf1);
|
|
|
|
buf_free(buf2);
|
2014-04-26 06:18:15 +02:00
|
|
|
tor_free(junk);
|
2013-07-17 23:51:21 +02:00
|
|
|
}
|
|
|
|
|
2014-01-09 18:47:24 +01:00
|
|
|
static void
|
|
|
|
test_buffer_time_tracking(void *arg)
|
|
|
|
{
|
|
|
|
buf_t *buf=NULL, *buf2=NULL;
|
|
|
|
struct timeval tv0;
|
|
|
|
const time_t START = 1389288246;
|
|
|
|
const uint32_t START_MSEC = (uint32_t) ((uint64_t)START * 1000);
|
|
|
|
int i;
|
|
|
|
char tmp[4096];
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
crypto_rand(tmp, sizeof(tmp));
|
|
|
|
|
|
|
|
tv0.tv_sec = START;
|
|
|
|
tv0.tv_usec = 0;
|
|
|
|
|
|
|
|
buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
|
|
|
|
tt_assert(buf);
|
|
|
|
|
|
|
|
/* Empty buffer means the timestamp is 0. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC));
|
|
|
|
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
tor_gettimeofday_cache_set(&tv0);
|
|
|
|
write_to_buf("ABCDEFG", 7, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(1000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
buf2 = buf_copy(buf);
|
|
|
|
tt_assert(buf2);
|
2014-11-12 19:42:01 +01:00
|
|
|
tt_int_op(1234, OP_EQ,
|
|
|
|
buf_get_oldest_chunk_timestamp(buf2, START_MSEC+1234));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
/* Now add more bytes; enough to overflow the first chunk. */
|
|
|
|
tv0.tv_usec += 123 * 1000;
|
|
|
|
tor_gettimeofday_cache_set(&tv0);
|
|
|
|
for (i = 0; i < 600; ++i)
|
|
|
|
write_to_buf("ABCDEFG", 7, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(4207, OP_EQ, buf_datalen(buf));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
/* The oldest bytes are still in the front. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
/* Once those bytes are dropped, the chunk is still on the first
|
|
|
|
* timestamp. */
|
|
|
|
fetch_from_buf(tmp, 100, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
/* But once we discard the whole first chunk, we get the data in the second
|
|
|
|
* chunk. */
|
|
|
|
fetch_from_buf(tmp, 4000, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(107, OP_EQ, buf_datalen(buf));
|
|
|
|
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
/* This time we'll be grabbing a chunk from the freelist, and making sure
|
|
|
|
its time gets updated */
|
|
|
|
tv0.tv_sec += 5;
|
|
|
|
tv0.tv_usec = 617*1000;
|
|
|
|
tor_gettimeofday_cache_set(&tv0);
|
|
|
|
for (i = 0; i < 600; ++i)
|
|
|
|
write_to_buf("ABCDEFG", 7, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(4307, OP_EQ, buf_datalen(buf));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
2014-01-09 18:47:24 +01:00
|
|
|
fetch_from_buf(tmp, 4000, buf);
|
|
|
|
fetch_from_buf(tmp, 306, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+5617));
|
|
|
|
tt_int_op(383, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+6000));
|
2014-01-09 18:47:24 +01:00
|
|
|
|
|
|
|
done:
|
|
|
|
buf_free(buf);
|
|
|
|
buf_free(buf2);
|
|
|
|
}
|
|
|
|
|
2014-05-07 01:29:56 +02:00
|
|
|
static void
|
2014-05-08 18:41:01 +02:00
|
|
|
test_buffers_zlib_impl(int finalize_with_nil)
|
2014-05-07 01:29:56 +02:00
|
|
|
{
|
|
|
|
char *msg = NULL;
|
|
|
|
char *contents = NULL;
|
|
|
|
char *expanded = NULL;
|
|
|
|
buf_t *buf = NULL;
|
|
|
|
tor_zlib_state_t *zlib_state = NULL;
|
|
|
|
size_t out_len, in_len;
|
2014-05-08 18:41:01 +02:00
|
|
|
int done;
|
2014-05-07 01:29:56 +02:00
|
|
|
|
|
|
|
buf = buf_new_with_capacity(128); /* will round up */
|
2014-11-17 17:43:50 +01:00
|
|
|
zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION);
|
2014-05-07 01:29:56 +02:00
|
|
|
|
|
|
|
msg = tor_malloc(512);
|
|
|
|
crypto_rand(msg, 512);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), OP_EQ, 0);
|
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), OP_EQ, 0);
|
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
done = !finalize_with_nil;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
if (finalize_with_nil) {
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
}
|
2014-05-07 01:29:56 +02:00
|
|
|
|
|
|
|
in_len = buf_datalen(buf);
|
|
|
|
contents = tor_malloc(in_len);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);
|
2014-05-07 01:29:56 +02:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
|
2014-05-07 01:29:56 +02:00
|
|
|
contents, in_len,
|
|
|
|
ZLIB_METHOD, 1,
|
|
|
|
LOG_WARN));
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(out_len, OP_GE, 128);
|
|
|
|
tt_mem_op(msg, OP_EQ, expanded, 128);
|
|
|
|
tt_int_op(out_len, OP_GE, 512);
|
|
|
|
tt_mem_op(msg, OP_EQ, expanded, 512);
|
|
|
|
tt_int_op(out_len, OP_EQ, 512+9);
|
|
|
|
tt_mem_op("all done", OP_EQ, expanded+512, 9);
|
2014-05-07 01:29:56 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
buf_free(buf);
|
|
|
|
tor_zlib_free(zlib_state);
|
|
|
|
tor_free(contents);
|
|
|
|
tor_free(expanded);
|
|
|
|
tor_free(msg);
|
|
|
|
}
|
|
|
|
|
2014-05-08 18:41:01 +02:00
|
|
|
static void
|
|
|
|
test_buffers_zlib(void *arg)
|
|
|
|
{
|
|
|
|
(void) arg;
|
|
|
|
test_buffers_zlib_impl(0);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
test_buffers_zlib_fin_with_nil(void *arg)
|
|
|
|
{
|
|
|
|
(void) arg;
|
|
|
|
test_buffers_zlib_impl(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_buffers_zlib_fin_at_chunk_end(void *arg)
|
|
|
|
{
|
|
|
|
char *msg = NULL;
|
|
|
|
char *contents = NULL;
|
|
|
|
char *expanded = NULL;
|
|
|
|
buf_t *buf = NULL;
|
|
|
|
tor_zlib_state_t *zlib_state = NULL;
|
|
|
|
size_t out_len, in_len;
|
|
|
|
size_t sz, headerjunk;
|
2014-05-08 19:16:08 +02:00
|
|
|
(void) arg;
|
2014-05-08 18:41:01 +02:00
|
|
|
|
|
|
|
buf = buf_new_with_capacity(128); /* will round up */
|
|
|
|
sz = buf_get_default_chunk_size(buf);
|
|
|
|
msg = tor_malloc_zero(sz);
|
|
|
|
|
|
|
|
write_to_buf(msg, 1, buf);
|
|
|
|
tt_assert(buf->head);
|
|
|
|
|
|
|
|
/* Fill up the chunk so the zlib stuff won't fit in one chunk. */
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_uint_op(buf->head->memlen, OP_LT, sz);
|
2014-05-08 18:41:01 +02:00
|
|
|
headerjunk = buf->head->memlen - 7;
|
|
|
|
write_to_buf(msg, headerjunk-1, buf);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_uint_op(buf->head->datalen, OP_EQ, headerjunk);
|
|
|
|
tt_uint_op(buf_datalen(buf), OP_EQ, headerjunk);
|
2014-05-08 18:41:01 +02:00
|
|
|
/* Write an empty string, with finalization on. */
|
2014-11-17 17:43:50 +01:00
|
|
|
zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION);
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
|
|
|
|
in_len = buf_datalen(buf);
|
|
|
|
contents = tor_malloc(in_len);
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_uint_op(in_len, OP_GT, headerjunk);
|
2014-05-08 18:41:01 +02:00
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
|
2014-05-08 18:41:01 +02:00
|
|
|
contents + headerjunk, in_len - headerjunk,
|
|
|
|
ZLIB_METHOD, 1,
|
|
|
|
LOG_WARN));
|
|
|
|
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(out_len, OP_EQ, 0);
|
2014-05-08 18:41:01 +02:00
|
|
|
tt_assert(expanded);
|
|
|
|
|
|
|
|
done:
|
|
|
|
buf_free(buf);
|
|
|
|
tor_zlib_free(zlib_state);
|
|
|
|
tor_free(contents);
|
|
|
|
tor_free(expanded);
|
|
|
|
tor_free(msg);
|
|
|
|
}
|
|
|
|
|
2014-09-18 20:03:49 +02:00
|
|
|
const uint8_t *tls_read_ptr;
|
|
|
|
int n_remaining;
|
|
|
|
int next_reply_val[16];
|
|
|
|
|
|
|
|
static int
|
|
|
|
mock_tls_read(tor_tls_t *tls, char *cp, size_t len)
|
|
|
|
{
|
|
|
|
(void)tls;
|
|
|
|
int rv = next_reply_val[0];
|
|
|
|
if (rv > 0) {
|
|
|
|
int max = rv > (int)len ? (int)len : rv;
|
|
|
|
if (max > n_remaining)
|
|
|
|
max = n_remaining;
|
|
|
|
memcpy(cp, tls_read_ptr, max);
|
|
|
|
rv = max;
|
|
|
|
n_remaining -= max;
|
|
|
|
tls_read_ptr += max;
|
|
|
|
}
|
|
|
|
|
|
|
|
memmove(next_reply_val, next_reply_val + 1, 15*sizeof(int));
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_buffers_tls_read_mocked(void *arg)
|
|
|
|
{
|
|
|
|
uint8_t *mem;
|
|
|
|
buf_t *buf;
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
mem = tor_malloc(64*1024);
|
|
|
|
crypto_rand((char*)mem, 64*1024);
|
|
|
|
tls_read_ptr = mem;
|
|
|
|
n_remaining = 64*1024;
|
|
|
|
|
|
|
|
MOCK(tor_tls_read, mock_tls_read);
|
|
|
|
|
|
|
|
buf = buf_new();
|
|
|
|
|
|
|
|
next_reply_val[0] = 1024;
|
|
|
|
tt_int_op(128, ==, read_to_buf_tls(NULL, 128, buf));
|
|
|
|
|
|
|
|
next_reply_val[0] = 5000;
|
|
|
|
next_reply_val[1] = 5000;
|
|
|
|
tt_int_op(6000, ==, read_to_buf_tls(NULL, 6000, buf));
|
|
|
|
|
|
|
|
done:
|
|
|
|
UNMOCK(tor_tls_read);
|
|
|
|
tor_free(mem);
|
|
|
|
buf_free(buf);
|
|
|
|
}
|
|
|
|
|
2013-07-17 23:31:27 +02:00
|
|
|
struct testcase_t buffer_tests[] = {
|
2014-01-04 19:30:56 +01:00
|
|
|
{ "basic", test_buffers_basic, TT_FORK, NULL, NULL },
|
|
|
|
{ "copy", test_buffer_copy, TT_FORK, NULL, NULL },
|
|
|
|
{ "pullup", test_buffer_pullup, TT_FORK, NULL, NULL },
|
|
|
|
{ "ext_or_cmd", test_buffer_ext_or_cmd, TT_FORK, NULL, NULL },
|
|
|
|
{ "allocation_tracking", test_buffer_allocation_tracking, TT_FORK,
|
|
|
|
NULL, NULL },
|
2014-01-09 18:47:24 +01:00
|
|
|
{ "time_tracking", test_buffer_time_tracking, TT_FORK, NULL, NULL },
|
2014-05-07 01:29:56 +02:00
|
|
|
{ "zlib", test_buffers_zlib, TT_FORK, NULL, NULL },
|
2014-05-08 18:41:01 +02:00
|
|
|
{ "zlib_fin_with_nil", test_buffers_zlib_fin_with_nil, TT_FORK, NULL, NULL },
|
|
|
|
{ "zlib_fin_at_chunk_end", test_buffers_zlib_fin_at_chunk_end, TT_FORK,
|
|
|
|
NULL, NULL},
|
2014-09-18 20:03:49 +02:00
|
|
|
{ "tls_read_mocked", test_buffers_tls_read_mocked, 0,
|
|
|
|
NULL, NULL },
|
2013-07-17 23:31:27 +02:00
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|
|
|
|
|