diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-12 22:09:45 -0700 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-12 22:09:45 -0700 | 
| commit | 054b0b447eff82327c37a617849c3e20fbbb9789 (patch) | |
| tree | 3055ee4603f8a05ca8dd04f8056573aac3cf4123 /tests | |
| parent | 6c11a0c693da9ccf38225471d614bde162312427 (diff) | |
| parent | 9539c488c29e7c2c06afa63abce70785cb5d15c5 (diff) | |
Merge branch 'master' into compact
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/main.cpp | 36 | ||||
| -rw-r--r-- | tests/test.hpp | 4 | ||||
| -rw-r--r-- | tests/test_document.cpp | 37 | ||||
| -rw-r--r-- | tests/test_dom_modify.cpp | 3 | ||||
| -rw-r--r-- | tests/test_parse.cpp | 25 | 
5 files changed, 92 insertions, 13 deletions
| diff --git a/tests/main.cpp b/tests/main.cpp index 6996eb9..00016a6 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -50,6 +50,18 @@ static void* custom_allocate(size_t size)  	}  } +#ifndef PUGIXML_NO_EXCEPTIONS +static void* custom_allocate_throw(size_t size) +{ +	void* result = custom_allocate(size); + +	if (!result) +		throw std::bad_alloc(); + +	return result; +} +#endif +  static void custom_deallocate(void* ptr)  {  	assert(ptr); @@ -82,7 +94,7 @@ namespace std  }  #endif -static bool run_test(test_runner* test) +static bool run_test(test_runner* test, const char* test_name, pugi::allocation_function allocate)  {  #ifndef PUGIXML_NO_EXCEPTIONS  	try @@ -94,7 +106,7 @@ static bool run_test(test_runner* test)  		test_runner::_memory_fail_threshold = 0;  		test_runner::_memory_fail_triggered = false; -		pugi::set_memory_management_functions(custom_allocate, custom_deallocate); +		pugi::set_memory_management_functions(allocate, custom_deallocate);  #ifdef _MSC_VER  #	pragma warning(push) @@ -110,7 +122,7 @@ static bool run_test(test_runner* test)  		if (result)  		{ -			printf("Test %s failed: %s\n", test->_name, test_runner::_failure_message); +			printf("Test %s failed: %s\n", test_name, test_runner::_failure_message);  			return false;  		} @@ -118,13 +130,13 @@ static bool run_test(test_runner* test)  		if (test_runner::_memory_fail_triggered)  		{ -			printf("Test %s failed: unguarded memory fail triggered\n", test->_name); +			printf("Test %s failed: unguarded memory fail triggered\n", test_name);  			return false;  		}  		if (g_memory_total_size != 0 || g_memory_total_count != 0)  		{ -			printf("Test %s failed: memory leaks found (%u bytes in %u allocations)\n", test->_name, static_cast<unsigned int>(g_memory_total_size), static_cast<unsigned int>(g_memory_total_count)); +			printf("Test %s failed: memory leaks found (%u bytes in %u allocations)\n", test_name, static_cast<unsigned int>(g_memory_total_size), static_cast<unsigned int>(g_memory_total_count));  			return false;  		} @@ -133,12 +145,12 @@ static bool run_test(test_runner* test)  	}  	catch (const std::exception& e)  	{ -		printf("Test %s failed: exception %s\n", test->_name, e.what()); +		printf("Test %s failed: exception %s\n", test_name, e.what());  		return false;  	}  	catch (...)  	{ -		printf("Test %s failed for unknown reason\n", test->_name); +		printf("Test %s failed for unknown reason\n", test_name);  		return false;  	}  #endif @@ -176,7 +188,15 @@ int main(int, char** argv)  	for (test = test_runner::_tests; test; test = test->_next)  	{  		total++; -		passed += run_test(test); +		passed += run_test(test, test->_name, custom_allocate); + +	#ifndef PUGIXML_NO_EXCEPTIONS +		if (g_memory_fail_triggered) +		{ +			total++; +			passed += run_test(test, (test->_name + std::string(" (throw)")).c_str(), custom_allocate_throw); +		} +	#endif  	}  	unsigned int failed = total - passed; diff --git a/tests/test.hpp b/tests/test.hpp index 46c3330..d0fd0ca 100644 --- a/tests/test.hpp +++ b/tests/test.hpp @@ -143,9 +143,9 @@ struct dummy_fixture {};  #endif  #ifdef PUGIXML_NO_EXCEPTIONS -#define CHECK_ALLOC_FAIL(code) CHECK(!test_runner::_memory_fail_triggered); code; CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false +#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); code; CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)  #else -#define CHECK_ALLOC_FAIL(code) CHECK(!test_runner::_memory_fail_triggered); try { code; } catch (std::bad_alloc&) {} CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false +#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); try { code; } catch (std::bad_alloc&) {} CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)  #endif  #define STR(text) PUGIXML_TEXT(text) diff --git a/tests/test_document.cpp b/tests/test_document.cpp index 1545e19..9c8c860 100644 --- a/tests/test_document.cpp +++ b/tests/test_document.cpp @@ -319,9 +319,7 @@ TEST(document_load_file_out_of_memory_file_leak)  	pugi::xml_document doc;  	for (int i = 0; i < 256; ++i) -	{  		CHECK_ALLOC_FAIL(CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory)); -	}  	test_runner::_memory_fail_threshold = 0; @@ -329,6 +327,21 @@ TEST(document_load_file_out_of_memory_file_leak)  	CHECK_NODE(doc, STR("<node />"));  } +TEST(document_load_file_wide_out_of_memory_file_leak) +{ +	test_runner::_memory_fail_threshold = 256; + +	pugi::xml_document doc; + +	for (int i = 0; i < 256; ++i) +		CHECK_ALLOC_FAIL(CHECK(doc.load_file(L"tests/data/small.xml").status == status_out_of_memory)); + +	test_runner::_memory_fail_threshold = 0; + +	CHECK(doc.load_file(L"tests/data/small.xml")); +	CHECK_NODE(doc, STR("<node />")); +} +  TEST(document_load_file_error_previous)  {  	pugi::xml_document doc; @@ -556,6 +569,26 @@ TEST_XML(document_save_file_wide_text, "<node/>")      CHECK(test_file_contents(f.path, "<node />\n", 9));  } +TEST_XML(document_save_file_leak, "<node/>") +{ +	temp_file f; + +	for (int i = 0; i < 256; ++i) +		CHECK(doc.save_file(f.path)); +} + +TEST_XML(document_save_file_wide_leak, "<node/>") +{ +	temp_file f; + +	// widen the path +	wchar_t wpath[sizeof(f.path)]; +	std::copy(f.path, f.path + strlen(f.path) + 1, wpath + 0); + +	for (int i = 0; i < 256; ++i) +		CHECK(doc.save_file(wpath)); +} +  TEST(document_load_buffer)  {  	const pugi::char_t text[] = STR("<?xml?><node/>"); diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 071b798..54bbee4 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -905,7 +905,8 @@ TEST(dom_node_out_of_memory)  	xml_attribute a = n.append_attribute(STR("a"));  	CHECK(a); -	CHECK_ALLOC_FAIL(while (n.append_child(node_comment) || n.append_attribute(STR("b"))) { /* nop */ }); +	CHECK_ALLOC_FAIL(while (n.append_child(node_comment)) { /* nop */ }); +	CHECK_ALLOC_FAIL(while (n.append_attribute(STR("b"))) { /* nop */ });  	// verify all node modification operations  	CHECK_ALLOC_FAIL(CHECK(!n.append_child())); diff --git a/tests/test_parse.cpp b/tests/test_parse.cpp index 08ddee4..393e14c 100644 --- a/tests/test_parse.cpp +++ b/tests/test_parse.cpp @@ -935,6 +935,31 @@ TEST(parse_out_of_memory_conversion)  	CHECK(!doc.first_child());  } +TEST(parse_out_of_memory_allocator_state_sync) +{ +	const unsigned int count = 10000; +	static char_t text[count * 4]; + +	for (unsigned int i = 0; i < count; ++i) +	{ +		text[4*i + 0] = '<'; +		text[4*i + 1] = 'n'; +		text[4*i + 2] = '/'; +		text[4*i + 3] = '>'; +	} + +	test_runner::_memory_fail_threshold = 65536; + +	xml_document doc; +	CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory)); +	CHECK_NODE(doc.first_child(), STR("<n />")); + +	test_runner::_memory_fail_threshold = 0; + +	for (unsigned int i = 0; i < count; ++i) +		CHECK(doc.append_child(STR("n"))); +} +  static bool test_offset(const char_t* contents, unsigned int options, pugi::xml_parse_status status, ptrdiff_t offset)  {  	xml_document doc; | 
