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. */
|
2016-08-02 19:33:41 +02:00
|
|
|
tt_int_op(0, OP_EQ, buf_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);
|
2016-08-02 19:33:41 +02:00
|
|
|
tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
|
2014-11-12 19:28:07 +01:00
|
|
|
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;
|
2016-08-02 19:33:41 +02:00
|
|
|
tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
|
2014-11-12 19:28:07 +01:00
|
|
|
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);
|
|
|
|
}
|
2016-08-02 19:33:41 +02:00
|
|
|
tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
|
2014-11-12 19:28:07 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-06-02 15:46:12 +02:00
|
|
|
static const uint8_t *tls_read_ptr;
|
|
|
|
static int n_remaining;
|
|
|
|
static int next_reply_val[16];
|
2014-09-18 20:03:49 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|