Skip to content

Commit 566ea97

Browse files
authored
Merge pull request #783 from DamianDuy/addOutOfMemTest
[umf] add out of memory test
2 parents 366bd77 + 7fd8fba commit 566ea97

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([[maybe_unused]] void *ptr,
@@ -146,9 +144,7 @@ struct proxy_pool : public pool_base {
146144
void *aligned_malloc(size_t size, size_t alignment) noexcept {
147145
void *ptr;
148146
auto ret = umfMemoryProviderAlloc(provider, size, alignment, &ptr);
149-
if (ptr) {
150-
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
151-
}
147+
umf::getPoolLastStatusRef<proxy_pool>() = ret;
152148
return ptr;
153149
}
154150
size_t malloc_usable_size([[maybe_unused]] void *ptr) noexcept {
@@ -157,7 +153,6 @@ struct proxy_pool : public pool_base {
157153
}
158154
enum umf_result_t free(void *ptr) noexcept {
159155
auto ret = umfMemoryProviderFree(provider, ptr, 0);
160-
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
161156
return ret;
162157
}
163158
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
@@ -82,6 +82,28 @@ struct provider_malloc : public provider_base {
8282
const char *get_name() noexcept { return "malloc"; }
8383
};
8484

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

87109
#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) {
@@ -256,10 +265,8 @@ TEST_F(test, getLastFailedMemoryProvider) {
256265
auto [ret, pool] = umf::poolMakeUnique<umf_test::proxy_pool>(&hProvider, 1);
257266
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
258267

259-
ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
260268
auto ptr = umfPoolMalloc(pool.get(), allocSize);
261269
ASSERT_NE(ptr, nullptr);
262-
ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
263270
umfPoolFree(pool.get(), ptr);
264271

265272
// 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) {
@@ -73,6 +83,9 @@ TEST_F(test, freeErrorPropagation) {
7383
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfPoolTest,
7484
::testing::Values(makePool));
7585

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

0 commit comments

Comments
 (0)