Skip to content

Commit 18adeda

Browse files
RCORE-1493 Test roundtrip of collections in Mixed (#7592)
* Test roundtrip of collections in Mixed * Code review changes
1 parent 2e6477c commit 18adeda

File tree

2 files changed

+138
-8
lines changed

2 files changed

+138
-8
lines changed

test/object-store/sync/flx_sync.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727

2828
#include <realm/object_id.hpp>
2929
#include <realm/query_expression.hpp>
30+
#include <realm/list.hpp>
3031

3132
#include <realm/object-store/binding_context.hpp>
3233
#include <realm/object-store/impl/object_accessor_impl.hpp>
3334
#include <realm/object-store/impl/realm_coordinator.hpp>
35+
#include <realm/object-store/list.hpp>
3436
#include <realm/object-store/schema.hpp>
3537
#include <realm/object-store/sync/generic_network_transport.hpp>
3638
#include <realm/object-store/sync/mongo_client.hpp>
@@ -4788,6 +4790,140 @@ TEST_CASE("flx: pause and resume bootstrapping at query version 0", "[sync][flx]
47884790
REQUIRE(active_sub_set.state() == sync::SubscriptionSet::State::Complete);
47894791
}
47904792

4793+
TEST_CASE("flx: collections in mixed - merge lists", "[sync][flx][baas]") {
4794+
Schema schema{{"TopLevel",
4795+
{{"_id", PropertyType::ObjectId, Property::IsPrimary{true}},
4796+
{"queryable_str_field", PropertyType::String | PropertyType::Nullable},
4797+
{"any", PropertyType::Mixed | PropertyType::Nullable}}}};
4798+
4799+
FLXSyncTestHarness::ServerSchema server_schema{schema, {"queryable_str_field"}};
4800+
FLXSyncTestHarness harness("flx_collections_in_mixed", server_schema);
4801+
SyncTestFile config(harness.app()->current_user(), harness.schema(), SyncConfig::FLXSyncEnabled{});
4802+
4803+
auto set_list_and_insert_element = [](Obj& obj, ColKey col_any, Mixed value) {
4804+
obj.set_collection(col_any, CollectionType::List);
4805+
auto list = obj.get_list_ptr<Mixed>(col_any);
4806+
list->add(value);
4807+
};
4808+
4809+
// Client 1 creates an object and sets property 'any' to an integer value.
4810+
auto foo_obj_id = ObjectId::gen();
4811+
harness.load_initial_data([&](SharedRealm realm) {
4812+
CppContext c(realm);
4813+
Object::create(c, realm, "TopLevel",
4814+
std::any(AnyDict{{"_id", foo_obj_id}, {"queryable_str_field", "foo"s}, {"any", 42}}));
4815+
});
4816+
4817+
// Client 2 opens the realm and downloads schema and object created by Client 1.
4818+
auto realm = Realm::get_shared_realm(config);
4819+
subscribe_to_all_and_bootstrap(*realm);
4820+
realm->sync_session()->pause();
4821+
4822+
// Client 3 sets property 'any' to List and inserts two integers in the list.
4823+
harness.load_initial_data([&](SharedRealm realm) {
4824+
auto table = realm->read_group().get_table("class_TopLevel");
4825+
auto obj = table->get_object_with_primary_key(Mixed{foo_obj_id});
4826+
auto col_any = table->get_column_key("any");
4827+
set_list_and_insert_element(obj, col_any, 1);
4828+
set_list_and_insert_element(obj, col_any, 2);
4829+
});
4830+
4831+
// While its session is paused, Client 2 sets property 'any' to List and inserts two integers in the list.
4832+
CppContext c(realm);
4833+
realm->begin_transaction();
4834+
auto table = realm->read_group().get_table("class_TopLevel");
4835+
auto obj = table->get_object_with_primary_key(Mixed{foo_obj_id});
4836+
auto col_any = table->get_column_key("any");
4837+
set_list_and_insert_element(obj, col_any, 3);
4838+
set_list_and_insert_element(obj, col_any, 4);
4839+
realm->commit_transaction();
4840+
4841+
realm->sync_session()->resume();
4842+
wait_for_upload(*realm);
4843+
wait_for_download(*realm);
4844+
wait_for_advance(*realm);
4845+
4846+
// Client 2 ends up with four integers in the list (in the correct order).
4847+
auto list = obj.get_list_ptr<Mixed>(col_any);
4848+
CHECK(list->size() == 4);
4849+
CHECK(list->get(0) == 1);
4850+
CHECK(list->get(1) == 2);
4851+
CHECK(list->get(2) == 3);
4852+
CHECK(list->get(3) == 4);
4853+
}
4854+
4855+
TEST_CASE("flx: nested collections in mixed", "[sync][flx][baas]") {
4856+
Schema schema{{"TopLevel",
4857+
{{"_id", PropertyType::Int, Property::IsPrimary{true}},
4858+
{"queryable_str_field", PropertyType::String | PropertyType::Nullable},
4859+
{"any", PropertyType::Mixed | PropertyType::Nullable}}}};
4860+
4861+
FLXSyncTestHarness::ServerSchema server_schema{schema, {"queryable_str_field"}};
4862+
FLXSyncTestHarness harness("flx_collections_in_mixed", server_schema);
4863+
SyncTestFile config(harness.app()->current_user(), harness.schema(), SyncConfig::FLXSyncEnabled{});
4864+
4865+
// Client 1: {_id: 1, any: ["abc", [42]]}
4866+
harness.load_initial_data([&](SharedRealm realm) {
4867+
CppContext c(realm);
4868+
auto obj = Object::create(c, realm, "TopLevel",
4869+
std::any(AnyDict{{"_id", INT64_C(1)}, {"queryable_str_field", "foo"s}}));
4870+
auto table = realm->read_group().get_table("class_TopLevel");
4871+
auto col_any = table->get_column_key("any");
4872+
obj.get_obj().set_collection(col_any, CollectionType::List);
4873+
List list(obj, obj.get_object_schema().property_for_name("any"));
4874+
list.insert_any(0, "abc");
4875+
list.insert_collection(1, CollectionType::List);
4876+
auto list2 = list.get_list(1);
4877+
list2.insert_any(0, 42);
4878+
});
4879+
4880+
// Client 2 opens the realm and downloads schema and object created by Client 1.
4881+
// {_id: 1, any: ["abc", [42]]}
4882+
auto realm = Realm::get_shared_realm(config);
4883+
subscribe_to_all_and_bootstrap(*realm);
4884+
realm->sync_session()->pause();
4885+
4886+
// Client 3 adds a dictionary with an element to list 'any'
4887+
// {_id: 1, any: [{{"key": 6}}, "abc", [42]]}
4888+
harness.load_initial_data([&](SharedRealm realm) {
4889+
CppContext c(realm);
4890+
auto obj = Object::get_for_primary_key(c, realm, "TopLevel", std::any(INT64_C(1)));
4891+
List list(obj, obj.get_object_schema().property_for_name("any"));
4892+
list.insert_collection(PathElement(0), CollectionType::Dictionary);
4893+
auto dict = list.get_dictionary(PathElement(0));
4894+
dict.insert_any("key", INT64_C(6));
4895+
});
4896+
4897+
// While its session is paused, Client 2 makes a change to a nested list
4898+
// {_id: 1, any: ["abc", [42, "foo"]]}
4899+
CppContext c(realm);
4900+
realm->begin_transaction();
4901+
auto obj = Object::get_for_primary_key(c, realm, "TopLevel", std::any(INT64_C(1)));
4902+
List list(obj, obj.get_object_schema().property_for_name("any"));
4903+
List list2 = list.get_list(PathElement(1));
4904+
list2.insert_any(list2.size(), "foo");
4905+
realm->commit_transaction();
4906+
4907+
realm->sync_session()->resume();
4908+
wait_for_upload(*realm);
4909+
wait_for_download(*realm);
4910+
wait_for_advance(*realm);
4911+
4912+
// Client 2 after the session is resumed
4913+
// {_id: 1, any: [{{"key": 6}}, "abc", [42, "foo"]]}
4914+
CHECK(list.size() == 3);
4915+
auto nested_dict = list.get_dictionary(0);
4916+
CHECK(nested_dict.size() == 1);
4917+
CHECK(nested_dict.get<Int>("key") == 6);
4918+
4919+
CHECK(list.get_any(1) == "abc");
4920+
4921+
auto nested_list = list.get_list(2);
4922+
CHECK(nested_list.size() == 2);
4923+
CHECK(nested_list.get_any(0) == 42);
4924+
CHECK(nested_list.get_any(1) == "foo");
4925+
}
4926+
47914927
} // namespace realm::app
47924928

47934929
#endif // REALM_ENABLE_AUTH_TESTS

test/object-store/util/sync/baas_admin_api.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,14 +1081,8 @@ bool AdminAPISession::is_initial_sync_complete(const std::string& app_id) const
10811081
{
10821082
auto progress_endpoint = apps()[app_id]["sync"]["progress"];
10831083
auto progress_result = progress_endpoint.get_json();
1084-
if (auto it = progress_result.find("progress"); it != progress_result.end() && it->is_object() && !it->empty()) {
1085-
for (auto& elem : *it) {
1086-
auto is_complete = elem["complete"];
1087-
if (!is_complete.is_boolean() || !is_complete.get<bool>()) {
1088-
return false;
1089-
}
1090-
}
1091-
return true;
1084+
if (auto it = progress_result.find("accepting_clients"); it != progress_result.end()) {
1085+
return it->get<bool>();
10921086
}
10931087
return false;
10941088
}

0 commit comments

Comments
 (0)