realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

"Too many open files" using per-test-case In-Memory Realms

Open LeffelMania opened this issue 8 years ago • 14 comments

Goals

I'd like to stand up a new Realm for each test case as described in the documentation.

Expected Results

Each test case creates a new in-memory Realm instance to be used in isolation for only that test case.

Actual Results

After ~500 test cases, subsequent tests fail with RLMException: open() failed: too many open files.

Steps to Reproduce

  • Implement a subclass of XCTestCase that stands up an in-memory Realm for each test case using the name of the test as the inMemoryIdentifier.
  • Write more than 500 test case methods.
  • Run test suite

Code Sample

This is our test case setup method:

- (void)setUp
{
    [super setUp];

    RLMRealmConfiguration *config = [RLMRealmConfiguration new];
    config.inMemoryIdentifier = [self name];
    [RLMRealmConfiguration setDefaultConfiguration:config];

    _realm = [RLMRealm realmWithConfiguration:config error:NULL];
}

(That Realm instance is then injected generally throughout the codebase)

I know the documentation on in-memory Realms says:

In-memory Realms create several files in a temporary directory for coordinating things like cross-process notifications. No data is actually written to the files unless the operating system needs to swap to disk due to memory pressure.

So I assume those are the files that are building up. Is there some kind of tear-down I need to perform to clean up any files associated with the in-memory Realms?

Version of Realm and Tooling

ProductName:    Mac OS X
ProductVersion: 10.10.5
BuildVersion:   14F1605

/Applications/Xcode.app/Contents/Developer
Xcode 7.2.1
Build version 7C1002

/Users/alexleffelman/.rbenv/shims/pod
0.39.0.beta.5
Realm (0.98.3)

/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)

/usr/local/bin/carthage
0.6.3
(not in use here)

/usr/bin/git
git version 2.5.4 (Apple Git-61)

LeffelMania avatar Mar 18 '16 17:03 LeffelMania

I've set up a test project that reproduces this issue with 1600 test cases that are all just XCTAssertTrue(YES), but with the same general setUp logic.

https://github.com/LeffelMania/Realm-Unit-Test-Repro

(They start failing with the exception after about 600 tests usually...)

LeffelMania avatar Mar 18 '16 20:03 LeffelMania

In Realm's unit tests we call the private +[RLMRealm resetRealmState] method after each test to clean up any cached realm instances. If you add a call to that method in -tearDown does the problem you're seeing go away?

bdash avatar Mar 18 '16 21:03 bdash

That method doesn't appear to exposed in the public interface of RLMRealm, but when I do add it in an extension for testing, the tests in my sample project do indeed complete. :+1:

LeffelMania avatar Mar 18 '16 21:03 LeffelMania

Thanks for confirming. We should consider exposing +resetRealmState, or something like it, for sake of people writing unit tests that use Realm.

bdash avatar Mar 18 '16 21:03 bdash

Any updates on this one? We are experiencing the exact same issue and not sure how to tackle this at the moment. We have over 500 tests and most of them are using Realm with the in-memory configuration. The tests are flaky and we can't rely on them at the moment. Its a biggie for us.

kmpnz avatar Sep 25 '19 09:09 kmpnz

Here are more issues that are related to this:

  • https://github.com/realm/realm-cocoa/issues/6033
  • https://github.com/realm/realm-cocoa/issues/4435

kmpnz avatar Sep 25 '19 09:09 kmpnz

Same problem here after adding some more test cases and apparently passing the threshold now. Is my assumption correct that there is no Swift way to achieve a workaround similar to the performSelector with resetRealmState approach in Objective-C that bdash mentioned? Any help would be greatly appreciated.

jaenthemaen avatar Jun 10 '21 11:06 jaenthemaen

Clearing the tmp folder that is getting flooded with DB files periodically (e.g. in a tearDown call) has no effect since the error seems to originate from an internal threshold or cache limit I guess?

jaenthemaen avatar Jun 10 '21 13:06 jaenthemaen

Hi, do have any updates on this one? Keen to create a fresh inMemory realm while unit testing.

Fragki avatar Aug 18 '22 10:08 Fragki