diff options
author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-12 21:46:48 -0700 |
---|---|---|
committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-04-12 21:46:48 -0700 |
commit | f04b56e178a93960c89c5ca1b7d6ebdd19416cb8 (patch) | |
tree | adbd01bf680e2cfbd55d890b0c3edc783f3cb5ce /tests/main.cpp | |
parent | 5edeaf67658a3ab27e9ace87ccff37aba8352607 (diff) |
Permit custom allocation function to throw
Ensure that all the necessary cleanup is performed in case the allocation fails
with an exception - files are closed, buffers are reclaimed, etc.
Any test that triggers a simulated out-of-memory condition is ran once again
with a throwing allocation function. Unobserved std::bad_alloc count as test
failures and require CHECK_ALLOC_FAIL macro.
Fixes #17.
Diffstat (limited to 'tests/main.cpp')
-rw-r--r-- | tests/main.cpp | 36 |
1 files changed, 28 insertions, 8 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; |