Create more memory pools as needed (resolves #1074)

This commit is contained in:
Benoit Blanchon
2023-07-17 14:39:57 +02:00
parent 65c67d317a
commit 42b2840009
22 changed files with 396 additions and 312 deletions

View File

@ -26,6 +26,8 @@ TEST_CASE("JsonDocument assignment") {
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
<< AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(5)) // world
);
}
@ -41,8 +43,8 @@ TEST_CASE("JsonDocument assignment") {
REQUIRE(doc2.as<std::string>() == "[{\"hello\":\"world\"}]");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Deallocate(sizeofArray(1))
<< AllocatorLog::Allocate(capacity)
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(5)) // hello
<< AllocatorLog::Allocate(sizeofString(5)) // world
);
@ -59,9 +61,9 @@ TEST_CASE("JsonDocument assignment") {
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Deallocate(4096)
<< AllocatorLog::Allocate(capacity1)
<< AllocatorLog::Allocate(sizeofString(5)) // hello
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
<< AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(5)) // world
);
}
@ -69,21 +71,24 @@ TEST_CASE("JsonDocument assignment") {
SECTION("Move assign") {
{
JsonDocument doc1(4096, &spyingAllocator);
doc1.set(std::string("The size of this string is 32!!"));
doc1[std::string("hello")] = std::string("world");
JsonDocument doc2(128, &spyingAllocator);
doc2 = std::move(doc1);
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
REQUIRE(doc1.as<std::string>() == "null");
}
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Allocate(128)
<< AllocatorLog::Deallocate(128)
<< AllocatorLog::Deallocate(sizeofString(31))
<< AllocatorLog::Deallocate(4096));
REQUIRE(
spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
<< AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(5)) // world
<< AllocatorLog::Deallocate(sizeofString(5)) // hello
<< AllocatorLog::Deallocate(sizeofString(5)) // world
<< AllocatorLog::Deallocate(sizeofPool())
<< AllocatorLog::Deallocate(sizeofPoolList()));
}
SECTION("Assign from JsonObject") {

View File

@ -16,9 +16,7 @@ TEST_CASE("JsonDocument constructor") {
SECTION("JsonDocument(size_t)") {
{ JsonDocument doc(4096, &spyingAllocator); }
REQUIRE(spyingAllocator.log() == AllocatorLog()
<< AllocatorLog::Allocate(4096)
<< AllocatorLog::Deallocate(4096));
REQUIRE(spyingAllocator.log() == AllocatorLog());
}
SECTION("JsonDocument(const JsonDocument&)") {
@ -33,14 +31,10 @@ TEST_CASE("JsonDocument constructor") {
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
}
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(capacity)
<< AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Allocate(capacity)
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Deallocate(sizeofString(31))
<< AllocatorLog::Deallocate(capacity)
<< AllocatorLog::Deallocate(sizeofString(31))
<< AllocatorLog::Deallocate(capacity));
<< AllocatorLog::Deallocate(sizeofString(31)));
}
SECTION("JsonDocument(JsonDocument&&)") {
@ -54,10 +48,8 @@ TEST_CASE("JsonDocument constructor") {
REQUIRE(doc1.as<std::string>() == "null");
}
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Deallocate(sizeofString(31))
<< AllocatorLog::Deallocate(4096));
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Deallocate(sizeofString(31)));
}
SECTION("JsonDocument(JsonObject)") {
@ -69,7 +61,8 @@ TEST_CASE("JsonDocument constructor") {
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofObject(1)));
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool()));
}
SECTION("Construct from JsonArray") {
@ -80,8 +73,9 @@ TEST_CASE("JsonDocument constructor") {
JsonDocument doc2(arr, &spyingAllocator);
REQUIRE(doc2.as<std::string>() == "[\"hello\"]");
REQUIRE(spyingAllocator.log() == AllocatorLog() << AllocatorLog::Allocate(
addPadding(doc1.memoryUsage())));
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool()));
}
SECTION("Construct from JsonVariant") {
@ -92,8 +86,6 @@ TEST_CASE("JsonDocument constructor") {
REQUIRE(doc2.as<std::string>() == "hello");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(
sizeofString(5)) // TODO: remove
<< AllocatorLog::Allocate(sizeofString(5)));
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)));
}
}

View File

@ -30,10 +30,12 @@ TEST_CASE("JsonDocument::garbageCollect()") {
REQUIRE(doc.memoryUsage() == sizeofObject(1) + sizeofString(7));
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(capacity)
<< AllocatorLog::Allocate(sizeofString(7))
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Deallocate(sizeofString(7))
<< AllocatorLog::Deallocate(capacity));
<< AllocatorLog::Deallocate(sizeofPool())
<< AllocatorLog::Deallocate(sizeofPoolList()));
}
SECTION("when allocation fails") {
@ -50,7 +52,6 @@ TEST_CASE("JsonDocument::garbageCollect()") {
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::AllocateFail(capacity)
<< AllocatorLog::AllocateFail(sizeofString(7)));
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(7)));
}
}

View File

@ -10,80 +10,81 @@
using ArduinoJson::detail::sizeofArray;
TEST_CASE("JsonDocument::overflowed()") {
TimebombAllocator allocator(10);
JsonDocument doc(0, &allocator);
SECTION("returns false on a fresh object") {
JsonDocument doc(0);
allocator.setCountdown(0);
CHECK(doc.overflowed() == false);
}
SECTION("returns true after a failed insertion") {
JsonDocument doc(0);
allocator.setCountdown(0);
doc.add(0);
CHECK(doc.overflowed() == true);
}
SECTION("returns false after successful insertion") {
JsonDocument doc(sizeofArray(1));
allocator.setCountdown(2);
doc.add(0);
CHECK(doc.overflowed() == false);
}
SECTION("returns true after a failed string copy") {
ControllableAllocator allocator;
JsonDocument doc(sizeofArray(1), &allocator);
allocator.disable();
allocator.setCountdown(0);
doc.add(std::string("example"));
CHECK(doc.overflowed() == true);
}
SECTION("returns false after a successful string copy") {
JsonDocument doc(sizeofArray(1));
allocator.setCountdown(3);
doc.add(std::string("example"));
CHECK(doc.overflowed() == false);
}
SECTION("returns true after a failed member add") {
JsonDocument doc(1);
allocator.setCountdown(0);
doc["example"] = true;
CHECK(doc.overflowed() == true);
}
SECTION("returns true after a failed deserialization") {
JsonDocument doc(sizeofArray(1));
allocator.setCountdown(1);
deserializeJson(doc, "[1, 2]");
CHECK(doc.overflowed() == true);
}
SECTION("returns false after a successful deserialization") {
JsonDocument doc(sizeofArray(1));
allocator.setCountdown(4);
deserializeJson(doc, "[\"example\"]");
CHECK(doc.overflowed() == false);
}
SECTION("returns false after clear()") {
JsonDocument doc(0);
allocator.setCountdown(0);
doc.add(0);
doc.clear();
CHECK(doc.overflowed() == false);
}
SECTION("remains false after shrinkToFit()") {
JsonDocument doc(sizeofArray(1));
allocator.setCountdown(2);
doc.add(0);
allocator.setCountdown(2);
doc.shrinkToFit();
CHECK(doc.overflowed() == false);
}
SECTION("remains true after shrinkToFit()") {
JsonDocument doc(sizeofArray(1));
doc.add(0);
allocator.setCountdown(0);
doc.add(0);
allocator.setCountdown(2);
doc.shrinkToFit();
CHECK(doc.overflowed() == true);
}
SECTION("return false after garbageCollect()") {
JsonDocument doc(sizeofArray(1));
doc.add(0);
allocator.setCountdown(0);
doc.add(0);
doc.garbageCollect();
CHECK(doc.overflowed() == false);

View File

@ -48,9 +48,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "null");
REQUIRE(spyingAllocator.log() == AllocatorLog()
<< AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, 0));
REQUIRE(spyingAllocator.log() == AllocatorLog());
}
SECTION("empty object") {
@ -59,9 +57,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "{}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, sizeofObject(0)));
REQUIRE(spyingAllocator.log() == AllocatorLog());
}
SECTION("empty array") {
@ -70,9 +66,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "[]");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, sizeofArray(0)));
REQUIRE(spyingAllocator.log() == AllocatorLog());
}
SECTION("linked string") {
@ -81,9 +75,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "hello");
REQUIRE(spyingAllocator.log() == AllocatorLog()
<< AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, 0));
REQUIRE(spyingAllocator.log() == AllocatorLog());
}
SECTION("owned string") {
@ -94,9 +86,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
REQUIRE(doc.as<std::string>() == "abcdefg");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(4096, 0));
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7)));
}
SECTION("raw string") {
@ -106,9 +96,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
REQUIRE(doc.as<std::string>() == "[{},12]");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(4096, 0));
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7)));
}
SECTION("linked key") {
@ -118,8 +106,12 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
REQUIRE(doc.as<std::string>() == "{\"key\":42}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Reallocate(sizeofPool(),
sizeofObject(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
SECTION("owned key") {
@ -129,9 +121,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
REQUIRE(doc.as<std::string>() == "{\"abcdefg\":42}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Reallocate(sizeofPool(),
sizeofObject(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
SECTION("linked string in array") {
@ -140,9 +136,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "[\"hello\"]");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, sizeofArray(1)));
REQUIRE(
spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Reallocate(sizeofPool(), sizeofArray(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
SECTION("owned string in array") {
@ -151,10 +151,14 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "[\"abcdefg\"]");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(4096, sizeofArray(1)));
REQUIRE(
spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(sizeofPool(), sizeofArray(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
SECTION("linked string in object") {
@ -164,8 +168,12 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
REQUIRE(doc.as<std::string>() == "{\"key\":\"hello\"}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Reallocate(sizeofPool(),
sizeofObject(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
SECTION("owned string in object") {
@ -174,9 +182,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
doc.shrinkToFit();
REQUIRE(doc.as<std::string>() == "{\"key\":\"abcdefg\"}");
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(4096)
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
REQUIRE(
spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
<< AllocatorLog::Allocate(sizeofPool())
<< AllocatorLog::Allocate(sizeofString(7))
<< AllocatorLog::Reallocate(sizeofPool(), sizeofPool(1))
<< AllocatorLog::Reallocate(sizeofPoolList(),
sizeofPoolList(1)));
}
}