Skip to content

Commit 7fd8fba

Browse files
author
Damian Duy
committed
[umf] add out of memory test
1 parent 333cfc2 commit 7fd8fba

File tree

5 files changed

+79
-10
lines changed

5 files changed

+79
-10
lines changed

test/unified_malloc_framework/common/pool.hpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@ struct proxy_pool : public pool_base {
131131

132132
memset(ptr, 0, num * size);
133133

134-
if (ptr) {
135-
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
136-
}
134+
umf::getPoolLastStatusRef<proxy_pool>() = ret;
137135
return ptr;
138136
}
139137
void *realloc(void *ptr, size_t size) noexcept {
@@ -145,9 +143,7 @@ struct proxy_pool : public pool_base {
145143
void *aligned_malloc(size_t size, size_t alignment) noexcept {
146144
void *ptr;
147145
auto ret = umfMemoryProviderAlloc(provider, size, alignment, &ptr);
148-
if (ptr) {
149-
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
150-
}
146+
umf::getPoolLastStatusRef<proxy_pool>() = ret;
151147
return ptr;
152148
}
153149
size_t malloc_usable_size(void *ptr) noexcept {
@@ -156,7 +152,6 @@ struct proxy_pool : public pool_base {
156152
}
157153
enum umf_result_t free(void *ptr) noexcept {
158154
auto ret = umfMemoryProviderFree(provider, ptr, 0);
159-
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
160155
return ret;
161156
}
162157
enum umf_result_t get_last_allocation_error() {

test/unified_malloc_framework/common/provider.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,28 @@ struct provider_malloc : public provider_base {
7676
const char *get_name() noexcept { return "malloc"; }
7777
};
7878

79+
struct provider_mock_out_of_mem : public provider_base {
80+
provider_malloc helper_prov;
81+
int allocNum = 0;
82+
umf_result_t initialize(int allocNum) noexcept {
83+
this->allocNum = allocNum;
84+
return UMF_RESULT_SUCCESS;
85+
}
86+
enum umf_result_t alloc(size_t size, size_t align, void **ptr) noexcept {
87+
if (allocNum <= 0) {
88+
*ptr = nullptr;
89+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
90+
}
91+
allocNum--;
92+
93+
return helper_prov.alloc(size, align, ptr);
94+
}
95+
enum umf_result_t free(void *ptr, size_t size) noexcept {
96+
return helper_prov.free(ptr, size);
97+
}
98+
const char *get_name() noexcept { return "mock_out_of_mem"; }
99+
};
100+
79101
} // namespace umf_test
80102

81103
#endif /* UMF_TEST_PROVIDER_HPP */

test/unified_malloc_framework/memoryPool.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// See LICENSE.TXT
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55

6+
#include "disjoint_pool.hpp"
67
#include "pool.hpp"
8+
#include "provider.hpp"
79

810
#include <array>
911
#include <cstring>
@@ -53,6 +55,11 @@ struct umfMultiPoolTest : umfPoolTest {
5355
std::vector<umf::pool_unique_handle_t> pools;
5456
};
5557

58+
struct umfMemTest : umfPoolTest {
59+
void SetUp() override { umfPoolTest::SetUp(); }
60+
void TearDown() override { umfPoolTest::TearDown(); }
61+
};
62+
5663
TEST_P(umfPoolTest, allocFree) {
5764
static constexpr size_t allocSize = 64;
5865
auto *ptr = umfPoolMalloc(pool.get(), allocSize);
@@ -251,6 +258,31 @@ TEST_P(umfPoolTest, multiThreadedMallocFreeRandomSizes) {
251258
}
252259
}
253260

261+
TEST_P(umfMemTest, outOfMem) {
262+
static constexpr size_t allocSize = 16;
263+
auto hPool = pool.get();
264+
265+
std::vector<void *> allocations;
266+
267+
while (true) {
268+
allocations.emplace_back(umfPoolMalloc(hPool, allocSize));
269+
if (allocations.back() == nullptr &&
270+
umfPoolGetLastAllocationError(hPool) ==
271+
UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY) {
272+
break;
273+
}
274+
ASSERT_NE(allocations.back(), nullptr);
275+
}
276+
277+
// remove last nullptr from the allocations vector
278+
ASSERT_EQ(allocations.back(), nullptr);
279+
allocations.pop_back();
280+
281+
for (auto allocation : allocations) {
282+
umfPoolFree(hPool, allocation);
283+
}
284+
}
285+
254286
#ifdef UMF_ENABLE_POOL_TRACKING_TESTS
255287
// TODO: add similar tests for realloc/aligned_alloc, etc.
256288
// TODO: add multithreaded tests

test/unified_malloc_framework/memoryPoolAPI.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ TEST_F(test, memoryPoolTrace) {
8282
ASSERT_EQ(providerCalls.size(), provider_call_count);
8383

8484
ret = umfPoolGetLastAllocationError(tracingPool.get());
85-
ASSERT_EQ(ret, UMF_RESULT_ERROR_NOT_SUPPORTED);
85+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
8686
ASSERT_EQ(poolCalls["get_last_native_error"], 1);
8787
ASSERT_EQ(poolCalls.size(), ++pool_call_count);
8888

@@ -157,6 +157,15 @@ INSTANTIATE_TEST_SUITE_P(
157157
.second;
158158
}));
159159

160+
INSTANTIATE_TEST_SUITE_P(
161+
proxyPoolOOMTest, umfMemTest, ::testing::Values([] {
162+
return umf::poolMakeUnique<umf_test::proxy_pool, 1>(
163+
{umf::memoryProviderMakeUnique<
164+
umf_test::provider_mock_out_of_mem>(10)
165+
.second})
166+
.second;
167+
}));
168+
160169
////////////////// Negative test cases /////////////////
161170

162171
TEST_F(test, memoryPoolInvalidProvidersNullptr) {
@@ -254,10 +263,8 @@ TEST_F(test, getLastFailedMemoryProvider) {
254263
auto [ret, pool] = umf::poolMakeUnique<umf_test::proxy_pool>(&hProvider, 1);
255264
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
256265

257-
ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
258266
auto ptr = umfPoolMalloc(pool.get(), allocSize);
259267
ASSERT_NE(ptr, nullptr);
260-
ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
261268
umfPoolFree(pool.get(), ptr);
262269

263270
// make provider return an error during allocation

test/unified_malloc_framework/umf_pools/disjoint_pool.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ static auto makePool() {
3333
return std::move(pool);
3434
}
3535

36+
static auto makePoolOOMProvider() {
37+
auto [ret, provider] =
38+
umf::memoryProviderMakeUnique<umf_test::provider_mock_out_of_mem>(10);
39+
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
40+
auto [retp, pool] = umf::poolMakeUnique<usm::DisjointPool, 1>(
41+
{std::move(provider)}, poolConfig());
42+
EXPECT_EQ(retp, UMF_RESULT_SUCCESS);
43+
return std::move(pool);
44+
}
45+
3646
using umf_test::test;
3747

3848
TEST_F(test, freeErrorPropagation) {
@@ -72,6 +82,9 @@ TEST_F(test, freeErrorPropagation) {
7282
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfPoolTest,
7383
::testing::Values(makePool));
7484

85+
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfMemTest,
86+
::testing::Values(makePoolOOMProvider));
87+
7588
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(umfMultiPoolTest);
7689
INSTANTIATE_TEST_SUITE_P(disjointMultiPoolTests, umfMultiPoolTest,
7790
::testing::Values(makePool));

0 commit comments

Comments
 (0)