summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-12 22:09:45 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-12 22:09:45 -0700
commit054b0b447eff82327c37a617849c3e20fbbb9789 (patch)
tree3055ee4603f8a05ca8dd04f8056573aac3cf4123 /tests
parent6c11a0c693da9ccf38225471d614bde162312427 (diff)
parent9539c488c29e7c2c06afa63abce70785cb5d15c5 (diff)
Merge branch 'master' into compact
Diffstat (limited to 'tests')
-rw-r--r--tests/main.cpp36
-rw-r--r--tests/test.hpp4
-rw-r--r--tests/test_document.cpp37
-rw-r--r--tests/test_dom_modify.cpp3
-rw-r--r--tests/test_parse.cpp25
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;