• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / 1833

14 Nov 2023 03:52AM UTC coverage: 91.644% (-0.05%) from 91.69%
1833

push

Evergreen

web-flow
Merge feature/network-faultiness branch into master (#7120)

* Add baas-network-tests nightly task for testing sync client operation with non-ideal network conditions (#6852)

* Added support for starting baas proxy
* Fixed some issues when running the scripts
* minor updates to install_baas.sh
* Updates to scripts to run on evergreen spawn host
* Added total time output to object store tests
* Increased initial ssh connect attempts; renamed proxy to 'baas_proxy'
* Minor updates to help output
* Added baas network test to run bass with the proxy
* Added support for separate baas admin api url value
* Minor port check adjustments
* Removed 'compile' task from network_tests
* Disable development mode by default
* Added baas remote host and network tests instructions doc
* Minor updates to the instructions
* Minor updates to documentation

* Add non-ideal transfer and network fault tests with non-ideal network conditions (#7063)

* Added non-ideal transfer and network fault tests
* Added baas-network-tests to be allowed for PR runs
* Updated changelog
* Updated curl command to be silent
* Updated changelog
* Reverted some changes and added descriptions to config.yml

* Fixed test extra delay

* Added some evergreen script updates from another branch

* Disabled baas network faults tests

* Update flx migration test to enable dev mode

* Fix baas branch for network tests

* add more time to 'too large sync message error handling' test

* Added network faults test and pulled nonideal out of nightly tests until fixes are added

92116 of 168852 branches covered (0.0%)

179 of 192 new or added lines in 14 files covered. (93.23%)

140 existing lines in 19 files now uncovered.

231053 of 252119 relevant lines covered (91.64%)

6637899.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.5
/test/object-store/util/sync/sync_test_utils.hpp
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2016 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
#pragma once
20

21
#include "util/event_loop.hpp"
22
#include "util/test_file.hpp"
23
#include "util/test_utils.hpp"
24

25
#include <realm/object-store/sync/app.hpp>
26
#include <realm/object-store/sync/generic_network_transport.hpp>
27
#include <realm/object-store/sync/impl/sync_file.hpp>
28
#include <realm/object-store/sync/impl/sync_metadata.hpp>
29
#include <realm/object-store/sync/sync_session.hpp>
30
#include <realm/object-store/thread_safe_reference.hpp>
31

32
#include <realm/util/functional.hpp>
33
#include <realm/util/function_ref.hpp>
34

35
#include <catch2/catch_test_macros.hpp>
36
#include <catch2/matchers/catch_matchers_templated.hpp>
37

38
#include <chrono>
39
#include <vector>
40

41
// disable the tests that rely on having baas available on the network
42
// but allow opt-in by building with REALM_ENABLE_AUTH_TESTS=1
43
#ifndef REALM_ENABLE_AUTH_TESTS
44
#define REALM_ENABLE_AUTH_TESTS 0
45
#endif
46

47
namespace realm {
48

49
bool results_contains_user(SyncUserMetadataResults& results, const std::string& identity);
50
bool results_contains_original_name(SyncFileActionMetadataResults& results, const std::string& original_name);
51

52
void timed_wait_for(util::FunctionRef<bool()> condition,
53
                    std::chrono::milliseconds max_ms = std::chrono::milliseconds(5000));
54

55
void timed_sleeping_wait_for(util::FunctionRef<bool()> condition,
56
                             std::chrono::milliseconds max_ms = std::chrono::seconds(30),
57
                             std::chrono::milliseconds sleep_ms = std::chrono::milliseconds(1));
58

59
class ReturnsTrueWithinTimeLimit : public Catch::Matchers::MatcherGenericBase {
60
public:
61
    ReturnsTrueWithinTimeLimit(std::chrono::milliseconds max_ms = std::chrono::milliseconds(5000))
62
        : m_max_ms(max_ms)
63
    {
4✔
64
    }
4✔
65

66
    bool match(util::FunctionRef<bool()> condition) const;
67

68
    std::string describe() const override
69
    {
×
70
        return util::format("PredicateReturnsTrueAfter %1ms", m_max_ms.count());
×
71
    }
×
72

73
private:
74
    std::chrono::milliseconds m_max_ms;
75
};
76

77
template <typename T>
78
struct TimedFutureState : public util::AtomicRefCountBase {
79
    TimedFutureState(util::Promise<T>&& promise)
80
        : promise(std::move(promise))
81
    {
64✔
82
    }
64✔
83

84
    util::Promise<T> promise;
85
    std::mutex mutex;
86
    std::condition_variable cv;
87
    bool finished = false;
88
};
89

90
template <typename T>
91
util::Future<T> wait_for_future(util::Future<T>&& input, std::chrono::milliseconds max_ms = std::chrono::seconds(60))
92
{
64✔
93
    auto pf = util::make_promise_future<T>();
64✔
94
    auto shared_state = util::make_bind<TimedFutureState<T>>(std::move(pf.promise));
64✔
95
    const auto delay = TEST_TIMEOUT_EXTRA > 0 ? max_ms + std::chrono::seconds(TEST_TIMEOUT_EXTRA) : max_ms;
64✔
96

32✔
97
    std::move(input).get_async([shared_state](StatusOrStatusWith<T> value) {
64✔
98
        std::unique_lock lk(shared_state->mutex);
64✔
99
        // If the state has already expired, then just return without doing anything.
32✔
100
        if (std::exchange(shared_state->finished, true)) {
64✔
101
            return;
×
102
        }
×
103

32✔
104
        shared_state->promise.set_from_status_with(std::move(value));
64✔
105
        shared_state->cv.notify_one();
64✔
106
        lk.unlock();
64✔
107
    });
64✔
108

32✔
109
    std::unique_lock lk(shared_state->mutex);
64✔
110
    if (!shared_state->cv.wait_for(lk, delay, [&] {
112✔
111
            return shared_state->finished;
112✔
112
        })) {
56✔
113
        shared_state->finished = true;
×
114
        shared_state->promise.set_error(
×
NEW
115
            {ErrorCodes::RuntimeError, util::format("wait_for_future exceeded %1 ms", delay.count())});
×
116
    }
×
117

32✔
118
    return std::move(pf.future);
64✔
119
}
64✔
120

121
struct ExpectedRealmPaths {
122
    ExpectedRealmPaths(const std::string& base_path, const std::string& app_id, const std::string& user_identity,
123
                       const std::vector<std::string>& legacy_identities, const std::string& partition);
124
    std::string current_preferred_path;
125
    std::string fallback_hashed_path;
126
    std::string legacy_local_id_path;
127
    std::string legacy_sync_path;
128
    std::vector<std::string> legacy_sync_directories_to_make;
129
};
130

131
#if REALM_ENABLE_SYNC
132

133
template <typename Transport>
134
const std::shared_ptr<app::GenericNetworkTransport> instance_of = std::make_shared<Transport>();
135

136
std::ostream& operator<<(std::ostream& os, util::Optional<app::AppError> error);
137

138
template <typename Transport>
139
TestSyncManager::Config get_config(Transport&& transport)
140
{
66✔
141
    TestSyncManager::Config config;
66✔
142
    config.transport = transport;
66✔
143
    return config;
66✔
144
}
66✔
145

146
void subscribe_to_all_and_bootstrap(Realm& realm);
147

148
#if REALM_ENABLE_AUTH_TESTS
149

150
#ifdef REALM_MONGODB_ENDPOINT
151
std::string get_base_url();
152
std::string get_admin_url();
153

154
#endif
155

156
struct AutoVerifiedEmailCredentials : app::AppCredentials {
157
    AutoVerifiedEmailCredentials();
158
    std::string email;
159
    std::string password;
160
};
161

162
AutoVerifiedEmailCredentials create_user_and_log_in(app::SharedApp app);
163

164
void wait_for_advance(Realm& realm);
165

166
void async_open_realm(const Realm::Config& config,
167
                      util::UniqueFunction<void(ThreadSafeReference&& ref, std::exception_ptr e)> finish);
168

169
#endif // REALM_ENABLE_AUTH_TESTS
170

171
#endif // REALM_ENABLE_SYNC
172

173
namespace reset_utils {
174

175
struct Partition {
176
    std::string property_name;
177
    std::string value;
178
};
179

180
Obj create_object(Realm& realm, StringData object_type, util::Optional<ObjectId> primary_key = util::none,
181
                  util::Optional<Partition> partition = util::none);
182

183
struct TestClientReset {
184
    using Callback = util::UniqueFunction<void(const SharedRealm&)>;
185
    using InitialObjectCallback = util::UniqueFunction<ObjectId(const SharedRealm&)>;
186
    TestClientReset(const Realm::Config& local_config, const Realm::Config& remote_config);
187
    virtual ~TestClientReset();
188
    TestClientReset* setup(Callback&& on_setup);
189

190
    // Only used in FLX sync client reset tests.
191
    TestClientReset* populate_initial_object(InitialObjectCallback&& callback);
192
    TestClientReset* make_local_changes(Callback&& changes_local);
193
    TestClientReset* make_remote_changes(Callback&& changes_remote);
194
    TestClientReset* on_post_local_changes(Callback&& post_local);
195
    TestClientReset* on_post_reset(Callback&& post_reset);
196
    void set_pk_of_object_driving_reset(const ObjectId& pk);
197
    ObjectId get_pk_of_object_driving_reset() const;
198
    void disable_wait_for_reset_completion();
199

200
    virtual TestClientReset* set_development_mode(bool enable = true);
201
    virtual void run() = 0;
202

203
protected:
204
    realm::Realm::Config m_local_config;
205
    realm::Realm::Config m_remote_config;
206

207
    Callback m_on_setup;
208
    InitialObjectCallback m_populate_initial_object;
209
    Callback m_make_local_changes;
210
    Callback m_make_remote_changes;
211
    Callback m_on_post_local;
212
    Callback m_on_post_reset;
213
    bool m_did_run = false;
214
    ObjectId m_pk_driving_reset = ObjectId::gen();
215
    bool m_wait_for_reset_completion = true;
216
};
217

218
#if REALM_ENABLE_SYNC
219

220
#if REALM_ENABLE_AUTH_TESTS
221
std::unique_ptr<TestClientReset> make_baas_client_reset(const Realm::Config& local_config,
222
                                                        const Realm::Config& remote_config,
223
                                                        TestAppSession& test_app_session);
224

225
std::unique_ptr<TestClientReset> make_baas_flx_client_reset(const Realm::Config& local_config,
226
                                                            const Realm::Config& remote_config,
227
                                                            const TestAppSession& test_app_session);
228

229
void wait_for_object_to_persist_to_atlas(std::shared_ptr<SyncUser> user, const AppSession& app_session,
230
                                         const std::string& schema_name, const bson::BsonDocument& filter_bson);
231

232
void wait_for_num_objects_in_atlas(std::shared_ptr<SyncUser> user, const AppSession& app_session,
233
                                   const std::string& schema_name, size_t expected_size);
234

235
void trigger_client_reset(const AppSession& app_session);
236
void trigger_client_reset(const AppSession& app_session, const SharedRealm& realm);
237
#endif // REALM_ENABLE_AUTH_TESTS
238

239
#endif // REALM_ENABLE_SYNC
240

241
std::unique_ptr<TestClientReset> make_fake_local_client_reset(const Realm::Config& local_config,
242
                                                              const Realm::Config& remote_config);
243

244
} // namespace reset_utils
245

246
} // namespace realm
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc