88
99#include < executorch/extension/data_loader/file_data_loader.h>
1010
11- #include < atomic>
1211#include < cstring>
13- #include < new>
1412
1513#include < gtest/gtest.h>
1614
@@ -27,59 +25,6 @@ using executorch::runtime::Error;
2725using executorch::runtime::FreeableBuffer;
2826using executorch::runtime::Result;
2927
30- namespace {
31- // When set, the replacement nothrow aligned operator new below returns nullptr,
32- // simulating an allocation failure without needing a real OOM.
33- std::atomic<bool > g_fail_aligned_nothrow_alloc{false };
34-
35- // RAII guard to ensure flag is reset even if test asserts early.
36- struct FailAllocGuard {
37- FailAllocGuard () {
38- g_fail_aligned_nothrow_alloc.store (true , std::memory_order_relaxed);
39- }
40- ~FailAllocGuard () {
41- g_fail_aligned_nothrow_alloc.store (false , std::memory_order_relaxed);
42- }
43- };
44- } // namespace
45-
46- // Detect ASAN to avoid multiple definition link error and to skip test when
47- // ASAN runtime provides its own strong operator new.
48- #if defined(__SANITIZE_ADDRESS__) || \
49- (defined (__has_feature) && __has_feature(address_sanitizer))
50- #define ET_TEST_ASAN_ENABLED 1
51- #else
52- #define ET_TEST_ASAN_ENABLED 0
53- #endif
54-
55- #if !ET_TEST_ASAN_ENABLED
56- // Replaces the global nothrow aligned allocation function for this test binary
57- // so FileDataLoader's segment allocation can be made to fail on demand. When
58- // the toggle is off it forwards to the real aligned allocator. We call the
59- // throwing aligned new inside a try/catch and convert exceptions to nullptr
60- // to emulate nothrow semantics without recursing into this same nothrow
61- // overload (calling ::operator new(size, alignment, std::nothrow) here would
62- // infinite-loop). Memory allocated here is released through the default
63- // operator delete, which is not replaced.
64- // This is a strong (non-weak) replacement so it reliably overrides libc++'s
65- // default on all platforms (a weak definition loses to libc++'s own weak
66- // definition on Apple's linker, leaving the override silently unused). Under
67- // ASAN this whole block is excluded so it can't clash with ASAN's allocator.
68- void * operator new (
69- std::size_t size,
70- std::align_val_t alignment,
71- const std::nothrow_t & /* tag */ ) noexcept {
72- if (g_fail_aligned_nothrow_alloc.load (std::memory_order_relaxed)) {
73- return nullptr ;
74- }
75- try {
76- return ::operator new (size, alignment);
77- } catch (...) {
78- return nullptr ;
79- }
80- }
81- #endif // !ET_TEST_ASAN_ENABLED
82-
8328class FileDataLoaderTest : public ::testing::TestWithParam<size_t > {
8429 protected:
8530 void SetUp () override {
@@ -202,46 +147,6 @@ TEST_P(FileDataLoaderTest, OutOfBoundsLoadFails) {
202147 }
203148}
204149
205- #if !ET_TEST_ASAN_ENABLED
206- TEST_P (FileDataLoaderTest, AllocationFailureDuringLoadReturnsError) {
207- // Create a temp file; contents don't matter.
208- uint8_t data[256 ] = {};
209- TempFile tf (data, sizeof (data));
210-
211- Result<FileDataLoader> fdl =
212- FileDataLoader::from (tf.path ().c_str (), alignment ());
213- ASSERT_EQ (fdl.error (), Error::Ok);
214-
215- // Force the segment allocation inside load() to fail. The loader must surface
216- // Error::MemoryAllocationFailed rather than letting std::bad_alloc escape,
217- // which would abort the process in the exception-free runtime.
218- FailAllocGuard fail_guard;
219- Result<FreeableBuffer> fb = fdl->load (
220- /* offset=*/ 0 ,
221- /* size=*/ sizeof (data),
222- DataLoader::SegmentInfo (DataLoader::SegmentInfo::Type::Program));
223-
224- EXPECT_EQ (fb.error (), Error::MemoryAllocationFailed);
225- }
226- #endif // !ET_TEST_ASAN_ENABLED
227-
228- #if !ET_TEST_ASAN_ENABLED
229- TEST_P (FileDataLoaderTest, AllocationFailureDuringFromReturnsError) {
230- // Create a temp file; contents don't matter.
231- uint8_t data[256 ] = {};
232- TempFile tf (data, sizeof (data));
233-
234- // Force the filename allocation inside from() to fail. FileDataLoader::from
235- // copies the filename using et_aligned_alloc and must return
236- // Error::MemoryAllocationFailed on nullptr rather than throwing.
237- FailAllocGuard fail_guard;
238- Result<FileDataLoader> fdl =
239- FileDataLoader::from (tf.path ().c_str (), alignment ());
240-
241- EXPECT_EQ (fdl.error (), Error::MemoryAllocationFailed);
242- }
243- #endif // !ET_TEST_ASAN_ENABLED
244-
245150TEST_P (FileDataLoaderTest, FromMissingFileFails) {
246151 // Wrapping a file that doesn't exist should fail.
247152 Result<FileDataLoader> fdl = FileDataLoader::from (
0 commit comments