Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for schema version before client reset callbacks #8125

Merged
merged 8 commits into from
Feb 10, 2023

Conversation

ejm01
Copy link
Contributor

@ejm01 ejm01 commented Feb 9, 2023

It's possible for a realm with no schema version to experience a client reset. If this happens, the callback wrappers shouldn't be called. Otherwise a crash can occur at set_schema_subset in realmWithSharedRealm. From internal ticket 40981 and #8126

@ejm01 ejm01 marked this pull request as ready for review February 9, 2023 23:03
Copy link
Contributor

@leemaguire leemaguire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments, but looking good.

@@ -27,18 +27,20 @@
#import "RLMObjectSchema_Private.hpp"
#import "RLMRealm+Sync.h"
#import "RLMRealmConfiguration_Private.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not required as RLMRealmConfiguration_Private.hpp pulls it in

afterExpectation.inverted = true;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just remove the parameter names instead of suppressing warnings

Copy link
Contributor

@leemaguire leemaguire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more small comment but otherwise LGTM

Realm/RLMSyncConfiguration.mm Outdated Show resolved Hide resolved
Co-authored-by: Lee Maguire <lee.maguire@mongodb.com>

// Create a config that's not versioned.
RLMRealmConfiguration *configUnversioned = [RLMRealmConfiguration defaultConfiguration];
configUnversioned.configRef.schema_version = RLMNotVersioned; // Not strictly necessary. Already has no version because the realm's never been opened.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how this isn't strictly necessary? schema_version defaults to 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think once the realm is opened it by RLMRealmWithConfiguration the default is applied. But since this config is only ever used to make a sharedRealm I think 1527 isn't needed for the assert on 1541 to pass. I could remove the comment, but either way would like to leave line 1527 in.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

schemaVersion is set to 0 in RLMRealmConfiguration's initializer. The schema version is not used for anything though because there's no schema set, so this test will pass with the schema version set to any value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments removed. Or do you think the whole lines could be removed since the schema isn't set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's maybe misleading to have it, since it's not actually being used? Not really a big deal either way.

std::shared_ptr<realm::Realm> unversioned = realm::Realm::get_shared_realm(configUnversioned.config);

XCTestExpectation *beforeExpectation = [self expectationWithDescription:@"block called once"];
beforeExpectation.assertForOverFulfill = true; // asserts that fulfill isn't called more than once.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the default and only needs to be set when it's being disabled.

XCTestExpectation *beforeExpectation = [self expectationWithDescription:@"block called once"];
beforeExpectation.assertForOverFulfill = true; // asserts that fulfill isn't called more than once.

realm::BeforeClientResetWrapper beforeWrapper = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can avoid exposing these for testing by obtaining them via RLMSyncConfiguration:

    RLMSyncConfiguration *syncConfig = [[RLMSyncConfiguration alloc] initWithRawConfig:{} path:""];
    syncConfig.beforeClientReset = ^(RLMRealm *beforeFrozen) {
        XCTAssertNotEqual(RLMNotVersioned, beforeFrozen->_realm->schema_version());
        [beforeExpectation fulfill];
    };
    auto& beforeWrapper = syncConfig.rawConfiguration.notify_before_client_reset;

This makes the test a bit less coupled to the implementation details and avoids having to export the wrapper types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thanks. This clears up a ton.

bool dynamic;
std::string path;
RLMSchema *customSchema;
namespace realm {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The realm namespace is for core and we shouldn't be defining things in it.

return cached.schema;
}
return customSchema ?: RLMSchema.sharedSchema;
RLMSchema *CallbackSchema::getSchema(Realm& realm) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any reason for this to be a member function?

@ejm01
Copy link
Contributor Author

ejm01 commented Feb 10, 2023

Are the xcode cloud swiftlint and docs errors "real"?

@ejm01 ejm01 requested a review from tgoyne February 10, 2023 17:58
@ejm01 ejm01 merged commit 0a16b5b into master Feb 10, 2023
@ejm01 ejm01 deleted the em/client-reset-no-version branch February 10, 2023 20:21
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants