From 8ee550cf4c2720e3535c67495831285369976965 Mon Sep 17 00:00:00 2001 From: Jonathan Reams Date: Thu, 1 Sep 2022 19:29:45 -0400 Subject: [PATCH] Detect sync termination with new endpoints (#5815) --- CHANGELOG.md | 1 + test/object-store/sync/sync_test_utils.cpp | 8 +++- test/object-store/util/baas_admin_api.cpp | 44 +++++++++++++++++++--- test/object-store/util/baas_admin_api.hpp | 5 ++- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 403091aa3d4..082bd689299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ ### Internals * `util::Any` is now just a typedef for `std::any`. `util::any_cast()` remains for deployment support on older Apple platforms. Outside of niche ADL implications, this should not have any visible effects. ([PR #5665](https://github.com/realm/realm-core/pull/5665)) +* Use correct endpoints for checking if sync has been terminated in client reset tests ([#5815](https://github.com/realm/realm-core/pull/5815)) ---------------------------------------------- diff --git a/test/object-store/sync/sync_test_utils.cpp b/test/object-store/sync/sync_test_utils.cpp index 6fd4070a45b..c4599e0c00f 100644 --- a/test/object-store/sync/sync_test_utils.cpp +++ b/test/object-store/sync/sync_test_utils.cpp @@ -418,7 +418,9 @@ struct BaasClientReset : public TestClientReset { auto baas_sync_config = app_session.admin_api.get_config(app_session.server_app_id, baas_sync_service); REQUIRE(app_session.admin_api.is_sync_enabled(app_session.server_app_id)); app_session.admin_api.disable_sync(app_session.server_app_id, baas_sync_service.id, baas_sync_config); - REQUIRE(!app_session.admin_api.is_sync_enabled(app_session.server_app_id)); + timed_sleeping_wait_for([&] { + return app_session.admin_api.is_sync_terminated(app_session.server_app_id); + }); app_session.admin_api.enable_sync(app_session.server_app_id, baas_sync_service.id, baas_sync_config); REQUIRE(app_session.admin_api.is_sync_enabled(app_session.server_app_id)); if (app_session.config.dev_mode_enabled) { // dev mode is not sticky across a reset @@ -524,7 +526,9 @@ struct BaasFLXClientReset : public TestClientReset { auto baas_sync_config = app_session.admin_api.get_config(app_session.server_app_id, baas_sync_service); REQUIRE(app_session.admin_api.is_sync_enabled(app_session.server_app_id)); app_session.admin_api.disable_sync(app_session.server_app_id, baas_sync_service.id, baas_sync_config); - REQUIRE(!app_session.admin_api.is_sync_enabled(app_session.server_app_id)); + timed_sleeping_wait_for([&] { + return app_session.admin_api.is_sync_terminated(app_session.server_app_id); + }); app_session.admin_api.enable_sync(app_session.server_app_id, baas_sync_service.id, baas_sync_config); REQUIRE(app_session.admin_api.is_sync_enabled(app_session.server_app_id)); if (app_session.config.dev_mode_enabled) { // dev mode is not sticky across a reset diff --git a/test/object-store/util/baas_admin_api.cpp b/test/object-store/util/baas_admin_api.cpp index a4cc6fde84c..35412428478 100644 --- a/test/object-store/util/baas_admin_api.cpp +++ b/test/object-store/util/baas_admin_api.cpp @@ -352,18 +352,39 @@ AdminAPIEndpoint AdminAPIEndpoint::operator[](StringData name) const app::Response AdminAPIEndpoint::do_request(app::Request request) const { - request.url = util::format("%1?bypass_service_change=DestructiveSyncProtocolVersionIncrease", request.url); + if (request.url.find('?') == std::string::npos) { + request.url = util::format("%1?bypass_service_change=DestructiveSyncProtocolVersionIncrease", request.url); + } + else { + request.url = util::format("%1&bypass_service_change=DestructiveSyncProtocolVersionIncrease", request.url); + } request.headers["Content-Type"] = "application/json;charset=utf-8"; request.headers["Accept"] = "application/json"; request.headers["Authorization"] = util::format("Bearer %1", m_access_token); return do_http_request(std::move(request)); } -app::Response AdminAPIEndpoint::get() const +app::Response AdminAPIEndpoint::get(const std::vector>& params) const { app::Request req; req.method = app::HttpMethod::get; - req.url = m_url; + std::stringstream ss; + bool needs_and = false; + ss << m_url; + if (!params.empty() && m_url.find('?') != std::string::npos) { + needs_and = true; + } + for (const auto& param : params) { + if (needs_and) { + ss << "&"; + } + else { + ss << "?"; + } + needs_and = true; + ss << param.first << "=" << param.second; + } + req.url = ss.str(); return do_request(std::move(req)); } @@ -375,9 +396,9 @@ app::Response AdminAPIEndpoint::del() const return do_request(std::move(req)); } -nlohmann::json AdminAPIEndpoint::get_json() const +nlohmann::json AdminAPIEndpoint::get_json(const std::vector>& params) const { - auto resp = get(); + auto resp = get(params); REALM_ASSERT_EX(resp.http_status_code >= 200 && resp.http_status_code < 300, util::format("url: %1, reply: %2", m_url, resp.body)); return nlohmann::json::parse(resp.body.empty() ? "{}" : resp.body); @@ -652,6 +673,19 @@ bool AdminAPISession::is_sync_enabled(const std::string& app_id) const return config.state == "enabled"; } +bool AdminAPISession::is_sync_terminated(const std::string& app_id) const +{ + auto sync_service = get_sync_service(app_id); + auto config = get_config(app_id, sync_service); + if (config.state == "enabled") { + return false; + } + auto state_endpoint = apps()[app_id]["sync"]["state"]; + auto state_result = state_endpoint.get_json( + {{"sync_type", config.mode == ServiceConfig::SyncMode::Flexible ? "flexible" : "partition"}}); + return state_result["state"].get().empty(); +} + AdminAPIEndpoint AdminAPISession::apps() const { return AdminAPIEndpoint(util::format("%1/api/admin/v3.0/groups/%2/apps", m_base_url, m_group_id), m_access_token); diff --git a/test/object-store/util/baas_admin_api.hpp b/test/object-store/util/baas_admin_api.hpp index 915261c3b6e..a155bef93cf 100644 --- a/test/object-store/util/baas_admin_api.hpp +++ b/test/object-store/util/baas_admin_api.hpp @@ -35,12 +35,12 @@ app::Response do_http_request(app::Request&& request); class AdminAPIEndpoint { public: - app::Response get() const; + app::Response get(const std::vector>& params = {}) const; app::Response patch(std::string body) const; app::Response post(std::string body) const; app::Response put(std::string body) const; app::Response del() const; - nlohmann::json get_json() const; + nlohmann::json get_json(const std::vector>& params = {}) const; nlohmann::json patch_json(nlohmann::json body) const; nlohmann::json post_json(nlohmann::json body) const; nlohmann::json put_json(nlohmann::json body) const; @@ -112,6 +112,7 @@ class AdminAPISession { ServiceConfig set_disable_recovery_to(const std::string& app_id, const std::string& service_id, ServiceConfig sync_config, bool disable) const; bool is_sync_enabled(const std::string& app_id) const; + bool is_sync_terminated(const std::string& app_id) const; const std::string& base_url() const noexcept {