#include <iostream> #include <string> #include <scpp_os.hpp> #include <scpp_unittest.hpp> #include <scpp_memory.hpp> using namespace scpp; class MemoryTestHandler : public MemoryListener { private: int allocCounter; int freeCounter; int errorCounter; public: MemoryTestHandler() : allocCounter(0), freeCounter(0), errorCounter(0) { } ~MemoryTestHandler() { } void notifyAlloc(const MemoryInfo& info) { allocCounter++; } void notifyFree(const MemoryInfo& info) { freeCounter++; } void notifyError(const MemoryInfo& info, const std::string& msg) { errorCounter++; } int getAllocCount() { return allocCounter; } int getFreeCount() { return freeCounter; } int getErrorCount() { return errorCounter; } void reset() { allocCounter = 0; freeCounter = 0; errorCounter = 0; } }; namespace { void entriesFunc(const MemoryInfo& info) {} bool isCleanup(const MemoryInfo& info) { return false; } bool isCleanupTrue(const MemoryInfo& info) { return true; } } /*** * Memory 単体テスト. */ class MemoryTest : public TestCase { private: MemoryTestHandler handler; public: MemoryTest() { MemoryManager::setListener(&handler); } ~MemoryTest() { MemoryManager::setListener(0); } void setUp() { handler.reset(); } void testNew() { Assertion::assertEquals(0, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); // new にて 2回以上メモリ確保されることがあるため 1<= に変更 std::string* ptr = new std::string("TEST"); Assertion::assertTrue(1 <= handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); delete ptr; Assertion::assertTrue(1 <= handler.getAllocCount()); Assertion::assertTrue(1 <= handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); } void testNewArray() { Assertion::assertEquals(0, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); int* ptr = new int[3]; Assertion::assertEquals(1, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); delete[] ptr; Assertion::assertEquals(1, handler.getAllocCount()); Assertion::assertEquals(1, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); } void testNewNoThrow() { Assertion::assertEquals(0, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); try { throw new(std::nothrow) std::string("ERROR"); } catch (std::string* ptr) { Assertion::assertTrue(1 <= handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); Assertion::assertEquals("ERROR", *ptr); operator delete(ptr, std::nothrow); Assertion::assertTrue(1 <= handler.getAllocCount()); Assertion::assertTrue(1 <= handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); } } void testNewArrayNoThrow() { Assertion::assertEquals(0, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); try { throw new(std::nothrow) int[1]; } catch (int* ptr) { Assertion::assertEquals(1, handler.getAllocCount()); Assertion::assertEquals(0, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); operator delete[] (ptr, std::nothrow); Assertion::assertEquals(1, handler.getAllocCount()); Assertion::assertEquals(1, handler.getFreeCount()); Assertion::assertEquals(0, handler.getErrorCount()); } } void testCalloc() { void* ptr = calloc(10, 20); free(ptr); } void testRealloc() { void* ptr = malloc(10); ptr = realloc(ptr, 100); free(ptr); realloc(0, 100); ptr = malloc(10); realloc(ptr, 0); } void testNullFree() { void* ptr = 0; std::string* str = 0; int* intP= 0; free(ptr); delete str; delete[] intP; } void testDefaultMemoryListener() { MemoryInfo info; info.fileName = __FILE__; info.lineNumber = __LINE__; info.functionName = "UNITTEST (for test dummy)"; info.size = 0; DefaultMemoryListener* listener = new DefaultMemoryListener(); listener->notifyAlloc(info); listener->notifyFree(info); listener->notifyError(info, ""); delete listener; } void testEntries() { MemoryManager::entries(entriesFunc); } void testCleanup() { MemoryManager::cleanup(isCleanup); void* ptr = malloc(10); realloc(ptr, 100); // MemoryManager::cleanup(isCleanupTrue); } void testPrintMemoryInfo() { MemoryInfo memInfo; memInfo.fileName = __FILE__; memInfo.lineNumber = __LINE__; memInfo.functionName = "UNITTEST (for test dummy)"; memInfo.size = 0; MemoryManager::printMemoryInfo(memInfo); } void suite() { RUN_TEST(testNew); RUN_TEST(testNewArray); RUN_TEST(testNewNoThrow); RUN_TEST(testNewArrayNoThrow); RUN_TEST(testCalloc); RUN_TEST(testRealloc); RUN_TEST(testNullFree); RUN_TEST(testDefaultMemoryListener); RUN_TEST(testEntries); RUN_TEST(testCleanup); RUN_TEST(testPrintMemoryInfo); } };