mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Introduce a few unit tests (from older code), refactor compression setup/teardown
svn:r232
This commit is contained in:
+36
-12
@@ -5,16 +5,22 @@
|
||||
#ifndef __TEST_H
|
||||
#define __TEST_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define STMT_BEGIN do {
|
||||
#define STMT_END } while (0)
|
||||
|
||||
#define test_fail() \
|
||||
if (1) { \
|
||||
STMT_BEGIN \
|
||||
printf("\nFile %s: line %d (%s): assertion failed.", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__); \
|
||||
return; \
|
||||
}
|
||||
STMT_END
|
||||
|
||||
#define test_assert(expr) \
|
||||
STMT_BEGIN \
|
||||
if(expr) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): assertion failed: (%s)\n", \
|
||||
__FILE__, \
|
||||
@@ -22,10 +28,10 @@
|
||||
__PRETTY_FUNCTION__, \
|
||||
#expr); \
|
||||
return; \
|
||||
}
|
||||
} STMT_END
|
||||
|
||||
#define test_eq(expr1, expr2) \
|
||||
if(expr1==expr2) { printf("."); } else { \
|
||||
STMT_BEGIN if(expr1==expr2) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n"\
|
||||
" (%ld != %ld)\n", \
|
||||
__FILE__, \
|
||||
@@ -34,10 +40,10 @@
|
||||
#expr1, #expr2, \
|
||||
(long)expr1, (long)expr2); \
|
||||
return; \
|
||||
}
|
||||
} STMT_END
|
||||
|
||||
#define test_neq(expr1, expr2) \
|
||||
if(expr1!=expr2) { printf("."); } else { \
|
||||
STMT_BEGIN if(expr1!=expr2) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
|
||||
" (%ld == %ld)\n", \
|
||||
__FILE__, \
|
||||
@@ -46,22 +52,22 @@
|
||||
#expr1, #expr2, \
|
||||
(long)expr1, (long)expr2); \
|
||||
return; \
|
||||
}
|
||||
} STMT_END
|
||||
|
||||
#define test_streq(expr1, expr2) \
|
||||
if(!strcmp(expr1,expr2)) { printf("."); } else { \
|
||||
STMT_BEGIN if(!strcmp(expr1,expr2)) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n"\
|
||||
" (%s != %s)\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#expr1, #expr2, \
|
||||
(long)expr1, (long)expr2); \
|
||||
expr1, expr2); \
|
||||
return; \
|
||||
}
|
||||
} STMT_END
|
||||
|
||||
#define test_strneq(expr1, expr2) \
|
||||
if(strcmp(expr1,expr2)) { printf("."); } else { \
|
||||
STMT_BEGIN if(strcmp(expr1,expr2)) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n"\
|
||||
" (%s == %s)\n", \
|
||||
__FILE__, \
|
||||
@@ -70,6 +76,24 @@
|
||||
#expr1, #expr2, \
|
||||
expr1, expr2); \
|
||||
return; \
|
||||
}
|
||||
} STMT_END
|
||||
|
||||
#define test_memeq(expr1, expr2, len) \
|
||||
STMT_BEGIN if(!memcmp(expr1,expr2,len)) { printf("."); } else { \
|
||||
printf("\nFile %s: line %d (%s): Assertion failed: (%s==%s)\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__PRETTY_FUNCTION__, \
|
||||
#expr1, #expr2); \
|
||||
return; \
|
||||
} STMT_END
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode:c
|
||||
indent-tabs-mode:nil
|
||||
c-basic-offset:2
|
||||
End:
|
||||
*/
|
||||
|
||||
+56
-3
@@ -136,7 +136,57 @@ int write_to_buf(char *string, int string_len,
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
z_stream *zstream_new(int compression)
|
||||
{
|
||||
z_stream* stream;
|
||||
stream = malloc(sizeof(z_stream));
|
||||
if (!stream)
|
||||
return NULL;
|
||||
memset(stream, 0, sizeof(z_stream));
|
||||
if (compression) {
|
||||
if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
|
||||
log(LOG_ERR, "Error initializing zlib: %s", stream->msg);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (inflateInit(stream) != Z_OK) {
|
||||
log(LOG_ERR, "Error initializing zlib: %s", stream->msg);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
z_compression *compression_new()
|
||||
{
|
||||
return (z_compression *) zstream_new(1);
|
||||
}
|
||||
|
||||
z_decompression *decompression_new()
|
||||
{
|
||||
return (z_compression *) zstream_new(0);
|
||||
}
|
||||
|
||||
void compression_free(z_stream *stream)
|
||||
{
|
||||
int r;
|
||||
r = deflateEnd(stream);
|
||||
if (r != Z_OK)
|
||||
log(LOG_ERR, "while closing zlib: %d (%s)", r, stream->msg);
|
||||
free(stream);
|
||||
}
|
||||
|
||||
void decompression_free(z_stream *stream)
|
||||
{
|
||||
int r;
|
||||
r = inflateEnd(stream);
|
||||
if (r != Z_OK)
|
||||
log(LOG_ERR, "while closing zlib: %d (%s)", r, stream->msg);
|
||||
free(stream);
|
||||
}
|
||||
|
||||
int compress_from_buf(char *string, int string_len,
|
||||
char **buf_in, int *buflen_in, int *buf_datalen_in,
|
||||
z_stream *zstream, int flush) {
|
||||
@@ -209,13 +259,16 @@ int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int fetch_from_buf(char *string, int string_len,
|
||||
char **buf, int *buflen, int *buf_datalen) {
|
||||
|
||||
/* if there are string_len bytes in buf, write them onto string,
|
||||
* then memmove buf back (that is, remove them from buf) */
|
||||
* then memmove buf back (that is, remove them from buf).
|
||||
*
|
||||
* If there are not enough bytes on the buffer to fill string, return -1.
|
||||
*
|
||||
* Return the number of bytes still on the buffer. */
|
||||
|
||||
assert(string && buf && *buf && buflen && buf_datalen);
|
||||
|
||||
|
||||
+4
-20
@@ -130,20 +130,10 @@ connection_t *connection_new(int type) {
|
||||
if (type == CONN_TYPE_AP || type == CONN_TYPE_EXIT) {
|
||||
if (buf_new(&conn->z_outbuf, &conn->z_outbuflen, &conn->z_outbuf_datalen) < 0)
|
||||
return NULL;
|
||||
if (! (conn->compression = malloc(sizeof(z_stream))))
|
||||
if (! (conn->compression = compression_new()))
|
||||
return NULL;
|
||||
if (! (conn->decompression = malloc(sizeof(z_stream))))
|
||||
if (! (conn->decompression = decompression_new()))
|
||||
return NULL;
|
||||
memset(conn->compression, 0, sizeof(z_stream));
|
||||
memset(conn->decompression, 0, sizeof(z_stream));
|
||||
if (deflateInit(conn->compression, Z_DEFAULT_COMPRESSION) != Z_OK) {
|
||||
log(LOG_ERR, "Error initializing zlib: %s", conn->compression->msg);
|
||||
return NULL;
|
||||
}
|
||||
if (inflateInit(conn->decompression) != Z_OK) {
|
||||
log(LOG_ERR, "Error initializing zlib: %s", conn->decompression->msg);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
conn->compression = conn->decompression = NULL;
|
||||
}
|
||||
@@ -181,14 +171,8 @@ void connection_free(connection_t *conn) {
|
||||
}
|
||||
#ifdef USE_ZLIB
|
||||
if (conn->compression) {
|
||||
if (inflateEnd(conn->decompression) != Z_OK)
|
||||
log(LOG_ERR,"connection_free(): while closing zlib: %s",
|
||||
conn->decompression->msg);
|
||||
if (deflateEnd(conn->compression) != Z_OK)
|
||||
log(LOG_ERR,"connection_free(): while closing zlib: %s",
|
||||
conn->compression->msg);
|
||||
free(conn->compression);
|
||||
free(conn->decompression);
|
||||
decompression_free(conn->decompression);
|
||||
compression_free(conn->compression);
|
||||
buf_free(conn->z_outbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
+12
-6
@@ -36,11 +36,11 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#ifdef USE_ZLIB
|
||||
|
||||
#define free_func zlib_free_func
|
||||
#include <zlib.h>
|
||||
#undef free_func
|
||||
#endif
|
||||
|
||||
|
||||
#include "../common/crypto.h"
|
||||
#include "../common/log.h"
|
||||
@@ -174,6 +174,9 @@
|
||||
/* legal characters in a filename */
|
||||
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"
|
||||
|
||||
typedef z_stream z_compression;
|
||||
typedef z_stream z_decompression;
|
||||
|
||||
struct config_line {
|
||||
char *key;
|
||||
char *value;
|
||||
@@ -446,10 +449,14 @@ int fetch_from_buf(char *string, int string_len,
|
||||
* then memmove buf back (that is, remove them from buf)
|
||||
*/
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
z_compression* compression_new();
|
||||
z_decompression* decompression_new();
|
||||
void compression_free(z_compression *);
|
||||
void decompression_free(z_decompression *);
|
||||
|
||||
int compress_from_buf(char *string, int string_len,
|
||||
char **buf_in, int *buflen_in, int *buf_datalen_in,
|
||||
z_stream *zstream, int flush);
|
||||
z_compression *compression, int flush);
|
||||
/* read and compress as many characters as possible from buf, writing up to
|
||||
* string_len of them onto string, then memmove buf back. Return number of
|
||||
* characters written.
|
||||
@@ -457,10 +464,9 @@ int compress_from_buf(char *string, int string_len,
|
||||
|
||||
int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in,
|
||||
char **buf_out, int *buflen_out, int *buf_datalen_out,
|
||||
z_stream *zstream, int flush);
|
||||
z_decompression *decompression, int flush);
|
||||
/* XXX document this NM
|
||||
*/
|
||||
#endif
|
||||
|
||||
int find_on_inbuf(char *string, int string_len,
|
||||
char *buf, int buf_datalen);
|
||||
|
||||
+185
-2
@@ -2,28 +2,211 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "or.h"
|
||||
#include "../common/test.h"
|
||||
|
||||
void
|
||||
setup_directory() {
|
||||
char buf[256];
|
||||
sprintf(buf, "/tmp/tor_test");
|
||||
if (mkdir(buf, 0700) && errno != EEXIST)
|
||||
fprintf(stderr, "Can't create directory %s", buf);
|
||||
}
|
||||
|
||||
void
|
||||
test_buffers() {
|
||||
char str[256];
|
||||
char str2[256];
|
||||
|
||||
char *buf;
|
||||
int buflen, buf_datalen;
|
||||
|
||||
if (buf_new(&buf, &buflen, &buf_datalen)) {
|
||||
char *buf2;
|
||||
int buf2len, buf2_datalen;
|
||||
|
||||
int s, i, j, eof;
|
||||
z_compression *comp;
|
||||
z_decompression *decomp;
|
||||
|
||||
/****
|
||||
* buf_new
|
||||
****/
|
||||
if (buf_new(&buf, &buflen, &buf_datalen))
|
||||
test_fail();
|
||||
}
|
||||
|
||||
test_eq(buflen, MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen, 0);
|
||||
|
||||
/****
|
||||
* read_to_buf
|
||||
****/
|
||||
s = open("/tmp/tor_test/data", O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
||||
for (j=0;j<256;++j) {
|
||||
str[j] = (char)j;
|
||||
}
|
||||
write(s, str, 256);
|
||||
close(s);
|
||||
|
||||
s = open("/tmp/tor_test/data", O_RDONLY, 0);
|
||||
eof = 0;
|
||||
i = read_to_buf(s, 10, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(buflen, MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen, 10);
|
||||
test_eq(eof, 0);
|
||||
test_eq(i, 10);
|
||||
test_memeq(str, buf, 10);
|
||||
|
||||
/* Test reading 0 bytes. */
|
||||
i = read_to_buf(s, 0, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(buflen, MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen, 10);
|
||||
test_eq(eof, 0);
|
||||
test_eq(i, 0);
|
||||
|
||||
/* Now test when buffer is filled exactly. */
|
||||
buflen = 16;
|
||||
i = read_to_buf(s, 6, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(buflen, 16);
|
||||
test_eq(buf_datalen, 16);
|
||||
test_eq(eof, 0);
|
||||
test_eq(i, 6);
|
||||
test_memeq(str, buf, 16);
|
||||
|
||||
/* Now test when buffer is filled with more data to read. */
|
||||
buflen = 32;
|
||||
i = read_to_buf(s, 128, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(buflen, 32);
|
||||
test_eq(buf_datalen, 32);
|
||||
test_eq(eof, 0);
|
||||
test_eq(i, 16);
|
||||
test_memeq(str, buf, 32);
|
||||
|
||||
/* Now read to eof. */
|
||||
buflen = MAX_BUF_SIZE;
|
||||
test_assert(buflen > 256);
|
||||
i = read_to_buf(s, 1024, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(i, (256-32));
|
||||
test_eq(buflen, MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen, 256);
|
||||
test_memeq(str, buf, 256);
|
||||
test_eq(eof, 0);
|
||||
|
||||
i = read_to_buf(s, 1024, &buf, &buflen, &buf_datalen, &eof);
|
||||
test_eq(i, 0);
|
||||
test_eq(buflen, MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen, 256);
|
||||
test_eq(eof, 1);
|
||||
|
||||
close(s);
|
||||
|
||||
/****
|
||||
* find_on_inbuf
|
||||
****/
|
||||
|
||||
test_eq(((int)'d') + 1, find_on_inbuf("abcd", 4, buf, buf_datalen));
|
||||
test_eq(-1, find_on_inbuf("xyzzy", 5, buf, buf_datalen));
|
||||
/* Make sure we don't look off the end of the buffef */
|
||||
buf[256] = 'A';
|
||||
buf[257] = 'X';
|
||||
test_eq(-1, find_on_inbuf("\xff" "A", 2, buf, buf_datalen));
|
||||
test_eq(-1, find_on_inbuf("AX", 2, buf, buf_datalen));
|
||||
/* Make sure we use the string length */
|
||||
test_eq(((int)'d')+1, find_on_inbuf("abcdX", 4, buf, buf_datalen));
|
||||
|
||||
/****
|
||||
* fetch_from_buf
|
||||
****/
|
||||
memset(str2, 255, 256);
|
||||
test_eq(246, fetch_from_buf(str2, 10, &buf, &buflen, &buf_datalen));
|
||||
test_memeq(str2, str, 10);
|
||||
test_memeq(str+10,buf,246);
|
||||
test_eq(buf_datalen,246);
|
||||
|
||||
test_eq(-1, fetch_from_buf(str2, 247, &buf, &buflen, &buf_datalen));
|
||||
test_memeq(str+10,buf,246);
|
||||
test_eq(buf_datalen, 246);
|
||||
|
||||
test_eq(0, fetch_from_buf(str2, 246, &buf, &buflen, &buf_datalen));
|
||||
test_memeq(str2, str+10, 246);
|
||||
test_eq(buflen,MAX_BUF_SIZE);
|
||||
test_eq(buf_datalen,0);
|
||||
|
||||
/****
|
||||
* write_to_buf
|
||||
****/
|
||||
memset(buf, (int)'-', 256);
|
||||
i = write_to_buf("Hello world", 11, &buf, &buflen, &buf_datalen);
|
||||
test_eq(i, 11);
|
||||
test_eq(buf_datalen, 11);
|
||||
test_memeq(buf, "Hello world", 11);
|
||||
i = write_to_buf("XYZZY", 5, &buf, &buflen, &buf_datalen);
|
||||
test_eq(i, 16);
|
||||
test_eq(buf_datalen, 16);
|
||||
test_memeq(buf, "Hello worldXYZZY", 16);
|
||||
/* Test when buffer is overfull. */
|
||||
buflen = 18;
|
||||
test_eq(-1, write_to_buf("This string will not fit.", 25,
|
||||
&buf, &buflen, &buf_datalen));
|
||||
test_eq(buf_datalen, 16);
|
||||
test_memeq(buf, "Hello worldXYZZY--", 18);
|
||||
buflen = MAX_BUF_SIZE;
|
||||
|
||||
/****
|
||||
* flush_buf
|
||||
****/
|
||||
|
||||
/***
|
||||
* compress_from_buf (simple)
|
||||
***/
|
||||
buf_datalen = 0;
|
||||
comp = compression_new();
|
||||
for (i = 0; i < 20; ++i) {
|
||||
write_to_buf("Hello world. ", 14, &buf, &buflen, &buf_datalen);
|
||||
}
|
||||
i = compress_from_buf(str, 256, &buf, &buflen, &buf_datalen, comp, 1);
|
||||
test_eq(buf_datalen, 0);
|
||||
/*
|
||||
for (j = 0; j <i ; ++j) {
|
||||
printf("%x '%c'\n", ((int) str[j])&0xff, str[j]);
|
||||
}
|
||||
*/
|
||||
/* Now try decompressing. */
|
||||
decomp = decompression_new();
|
||||
if (buf_new(&buf2, &buf2len, &buf2_datalen))
|
||||
test_fail();
|
||||
buf_datalen = 0;
|
||||
test_eq(i, write_to_buf(str, i, &buf, &buflen, &buf_datalen));
|
||||
j = decompress_buf_to_buf(&buf, &buflen, &buf_datalen,
|
||||
&buf2, &buf2len, &buf2_datalen,
|
||||
decomp, 1);
|
||||
/*XXXX check result *
|
||||
|
||||
/* Now compress more, into less room. */
|
||||
for (i = 0; i < 20; ++i) {
|
||||
write_to_buf("Hello wxrlx. ", 14, &buf, &buflen, &buf_datalen);
|
||||
}
|
||||
i = compress_from_buf(str, 256, &buf, &buflen, &buf_datalen, comp, 1);
|
||||
|
||||
test_eq(buf_datalen, 0);
|
||||
|
||||
|
||||
|
||||
compression_free(comp);
|
||||
decompression_free(decomp);
|
||||
|
||||
|
||||
|
||||
buf_free(buf);
|
||||
buf_free(buf2);
|
||||
}
|
||||
|
||||
|
||||
int main(int c, char**v) {
|
||||
setup_directory();
|
||||
|
||||
test_buffers();
|
||||
|
||||
printf("\n");
|
||||
|
||||
Reference in New Issue
Block a user