⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_alloc.c

📁 最新的LINUX平台上的DHCP服务器|客户端|代理
💻 C
字号:
/* * We test the functions provided in alloc.c here. These are very  * basic functions, and it is very important that they work correctly. * * You can see two different styles of testing: * * - In the first, we have a single test for each function that tests *   all of the possible ways it can operate. (This is the case for *   the buffer tests.) * * - In the second, we have a separate test for each of the ways a *   function can operate. (This is the case for the data_string *   tests.) * * The advantage of a single test per function is that you have fewer * tests, and less duplicated and extra code. The advantage of having * a separate test is that each test is simpler. Plus if you need to * allow certain tests to fail for some reason (known bugs that are * hard to fix for example), then  *//* TODO: dmalloc() test */#include "config.h"#include "t_api.h"#include "dhcpd.h"static void test_buffer_allocate(void);static void test_buffer_reference(void);static void test_buffer_dereference(void);static void test_data_string_forget(void);static void test_data_string_forget_nobuf(void);static void test_data_string_copy(void);static void test_data_string_copy_nobuf(void);/* * T_testlist is a list of tests that are invoked. */testspec_t T_testlist[] = {	{ test_buffer_allocate,		"buffer_allocate()" },	{ test_buffer_reference,		"buffer_reference()" },	{ test_buffer_dereference,		"buffer_dereference()" },	{ test_data_string_forget,		"data_string_forget()" },	{ test_data_string_forget_nobuf,		"data_string_forget(), no buffer" },	{ test_data_string_copy,		"data_string_copy()" },	{ test_data_string_copy_nobuf,		"data_string_copy(), no buffer" },	{ NULL,	NULL }};static voidtest_buffer_allocate(void) {	static const char *test_desc = 		"buffer_allocate basic test";		struct buffer *buf;	t_assert("buffer_allocate", 1, T_REQUIRED, test_desc);	/*	 * Check a 0-length buffer.	 */	buf = NULL;	if (!buffer_allocate(&buf, 0, MDL)) {		t_info("failed on 0-len buffer\n");		t_result(T_FAIL);		return;	}	if (!buffer_dereference(&buf, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	if (buf != NULL) {		t_info("buffer_dereference() did not NULL-out buffer\n");		t_result(T_FAIL);		return;	}	/*	 * Check an actual buffer.	 */	buf = NULL;	if (!buffer_allocate(&buf, 100, MDL)) {		t_info("failed on allocate\n");		t_result(T_FAIL);		return;	}	if (!buffer_dereference(&buf, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	if (buf != NULL) {		t_info("buffer_dereference() did not NULL-out buffer\n");		t_result(T_FAIL);		return;	}	/*	 * Okay, we're happy.	 */	t_result(T_PASS);}static voidtest_buffer_reference(void) {	static const char *test_desc = 		"buffer_reference basic test";	int result = T_PASS;		struct buffer *a, *b;	t_assert("buffer_reference", 1, T_REQUIRED, test_desc);	/*	 * Create a buffer.	 */	a = NULL;	if (!buffer_allocate(&a, 100, MDL)) {		t_info("failed on allocate\n");		t_result(T_FAIL);		return;	}	/*	 * Confirm buffer_reference() doesn't work if we pass in NULL.	 *	 * TODO: we should confirm we get an error message here.	 */	if (buffer_reference(NULL, a, MDL)) {		t_info("succeeded on an error input\n");		t_result(T_FAIL);		return;	}	/*	 * TODO: we should confirm we get an error message if we pass	 *       a non-NULL target.	 */	/*	 * Confirm we work under normal circumstances.	 */	b = NULL;	if (!buffer_reference(&b, a, MDL)) {		t_info("buffer_reference() failed\n");		t_result(T_FAIL);		return;	}	if (b != a) {		t_info("incorrect pointer\n");		result = T_FAIL;	}	if (b->refcnt != 2) {		t_info("incorrect refcnt\n");		result = T_FAIL;	}	/*	 * Clean up.	 */	if (!buffer_dereference(&b, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	if (!buffer_dereference(&a, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	t_result(result);}static voidtest_buffer_dereference(void) {	static const char *test_desc = 		"buffer_dereference basic test";		struct buffer *a, *b;	t_assert("buffer_dereference", 1, T_REQUIRED, test_desc);	/*	 * Confirm buffer_dereference() doesn't work if we pass in NULL.	 *	 * TODO: we should confirm we get an error message here.	 */	if (buffer_dereference(NULL, MDL)) {		t_info("succeeded on an error input\n");		t_result(T_FAIL);		return;	}	/*	 * Confirm buffer_dereference() doesn't work if we pass in 	 * a pointer to NULL.	 *	 * TODO: we should confirm we get an error message here.	 */	a = NULL;	if (buffer_dereference(&a, MDL)) {		t_info("succeeded on an error input\n");		t_result(T_FAIL);		return;	}	/*	 * Confirm we work under normal circumstances.	 */	a = NULL;	if (!buffer_allocate(&a, 100, MDL)) {		t_info("failed on allocate\n");		t_result(T_FAIL);		return;	}	if (!buffer_dereference(&a, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	if (a != NULL) {		t_info("non-null buffer after buffer_dereference()\n");		t_result(T_FAIL);		return;	}	/*	 * Confirm we get an error from negative refcnt.	 *	 * TODO: we should confirm we get an error message here.	 */	a = NULL;	if (!buffer_allocate(&a, 100, MDL)) {		t_info("failed on allocate\n");		t_result(T_FAIL);		return;	}	b = NULL;	if (!buffer_reference(&b, a, MDL)) {		t_info("buffer_reference() failed\n");		t_result(T_FAIL);		return;	}	a->refcnt = 0;	/* purposely set to invalid value */	if (buffer_dereference(&a, MDL)) {		t_info("buffer_dereference() succeeded on error input\n");		t_result(T_FAIL);		return;	}	a->refcnt = 2;	if (!buffer_dereference(&b, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	if (!buffer_dereference(&a, MDL)) {		t_info("buffer_dereference() failed\n");		t_result(T_FAIL);		return;	}	t_result(T_PASS);}static voidtest_data_string_forget(void) {	static const char *test_desc = 		"data_string_forget basic test";	int result = T_PASS;		struct buffer *buf;	struct data_string a;	const char *str = "Lorem ipsum dolor sit amet turpis duis.";	t_assert("data_string_forget", 1, T_REQUIRED, test_desc);	/* 	 * Create the string we want to forget.	 */	memset(&a, 0, sizeof(a));	a.len = strlen(str);	buf = NULL;	if (!buffer_allocate(&buf, a.len, MDL)) {		t_info("out of memory\n");		t_result(T_FAIL);		return;	}	if (!buffer_reference(&a.buffer, buf, MDL)) {		t_info("buffer_reference() failed\n");		t_result(T_FAIL);		return;	}	a.data = a.buffer->data;	memcpy(a.buffer->data, str, a.len);	/*	 * Forget and confirm we've forgotten.	 */	data_string_forget(&a, MDL);	if (a.len != 0) {		t_info("incorrect length\n");		result = T_FAIL;	}	if (a.data != NULL) {		t_info("incorrect data\n");		result = T_FAIL;	}	if (a.terminated) {		t_info("incorrect terminated\n");		result = T_FAIL;	}	if (a.buffer != NULL) {		t_info("incorrect buffer\n");		result = T_FAIL;	}	if (buf->refcnt != 1) {		t_info("too many references to buf\n");		result = T_FAIL;	}	/*	 * Clean up buffer.	 */	if (!buffer_dereference(&buf, MDL)) {		t_info("buffer_reference() failed\n");		t_result(T_FAIL);		return;	}	t_result(result);}static voidtest_data_string_forget_nobuf(void) {	static const char *test_desc = 		"data_string_forget test, data_string without buffer";	int result = T_PASS;		struct data_string a;	const char *str = "Lorem ipsum dolor sit amet massa nunc.";	t_assert("data_string_forget, no buffer", 1, T_REQUIRED, test_desc);	/* 	 * Create the string we want to forget.	 */	memset(&a, 0, sizeof(a));	a.len = strlen(str);	a.data = (const unsigned char *)str;	a.terminated = 1;	/*	 * Forget and confirm we've forgotten.	 */	data_string_forget(&a, MDL);	if (a.len != 0) {		t_info("incorrect length\n");		result = T_FAIL;	}	if (a.data != NULL) {		t_info("incorrect data\n");		result = T_FAIL;	}	if (a.terminated) {		t_info("incorrect terminated\n");		result = T_FAIL;	}	if (a.buffer != NULL) {		t_info("incorrect buffer\n");		result = T_FAIL;	}	t_result(result);}static voidtest_data_string_copy(void) {	static const char *test_desc = 		"data_string_copy basic test";	int result = T_PASS;	struct data_string a, b;	const char *str = "Lorem ipsum dolor sit amet orci aliquam.";	t_assert("data_string_copy", 1, T_REQUIRED, test_desc);	/* 	 * Create the string we want to copy.	 */	memset(&a, 0, sizeof(a));	a.len = strlen(str);	if (!buffer_allocate(&a.buffer, a.len, MDL)) {		t_info("out of memory\n");		t_result(T_FAIL);		return;	}	a.data = a.buffer->data;	memcpy(a.buffer->data, str, a.len);	/*	 * Copy the string, and confirm it works.	 */	memset(&b, 0, sizeof(b));	data_string_copy(&b, &a, MDL);	if (b.len != a.len) {		t_info("incorrect length\n");		result = T_FAIL;	}	if (b.data != a.data) {		t_info("incorrect data\n");		result = T_FAIL;	}	if (b.terminated != a.terminated) {		t_info("incorrect terminated\n");		result = T_FAIL;	}	if (b.buffer != a.buffer) {		t_info("incorrect buffer\n");		result = T_FAIL;	}	/*	 * Clean up.	 */	data_string_forget(&b, MDL);	data_string_forget(&a, MDL);	t_result(result);}static voidtest_data_string_copy_nobuf(void) {	static const char *test_desc = 		"data_string_copy test, data_string without buffer";	int result = T_PASS;	struct data_string a, b;	const char *str = "Lorem ipsum dolor sit amet cras amet.";	t_assert("data_string_copy, no buffer", 1, T_REQUIRED, test_desc);	/* 	 * Create the string we want to copy.	 */	memset(&a, 0, sizeof(a));	a.len = strlen(str);	a.data = (const unsigned char *)str;	a.terminated = 1;	/*	 * Copy the string, and confirm it works.	 */	memset(&b, 0, sizeof(b));	data_string_copy(&b, &a, MDL);	if (b.len != a.len) {		t_info("incorrect length\n");		result = T_FAIL;	}	if (b.data != a.data) {		t_info("incorrect data\n");		result = T_FAIL;	}	if (b.terminated != a.terminated) {		t_info("incorrect terminated\n");		result = T_FAIL;	}	if (b.buffer != a.buffer) {		t_info("incorrect buffer\n");		result = T_FAIL;	}	/*	 * Clean up.	 */	data_string_forget(&b, MDL);	data_string_forget(&a, MDL);	t_result(result);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -