Commit 1fa0fc14 authored by Nick Mathewson's avatar Nick Mathewson 🐻
Browse files

Introduce a few unit tests (from older code), refactor compression setup/teardown


svn:r232
parent 7df5caad
......@@ -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:
*/
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -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");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment