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

realm / realm-core / daniel.tabacaru_565

26 Sep 2023 08:24AM CUT coverage: 91.211% (+0.02%) from 91.188%
daniel.tabacaru_565

Pull #7002

Evergreen

danieltabacaru
Integration test for write_not_allowed(230) error
Pull Request #7002: Fix optional field in json error

95888 of 175734 branches covered (0.0%)

85 of 85 new or added lines in 3 files covered. (100.0%)

91 existing lines in 17 files now uncovered.

232521 of 254927 relevant lines covered (91.21%)

6844992.69 hits per line

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

70.59
/src/realm/object-store/c_api/socket_provider.cpp
1
#include <realm/error_codes.hpp>
2
#include <realm/status.hpp>
3
#include <realm/object-store/c_api/util.hpp>
4
#include <realm/sync/socket_provider.hpp>
5
#include <realm/sync/network/websocket.hpp>
6

7
namespace realm::c_api {
8
namespace {
9

10
struct CAPITimer : sync::SyncSocketProvider::Timer {
11
public:
12
    CAPITimer(realm_userdata_t userdata, int64_t delay_ms, realm_sync_socket_callback_t* handler,
13
              realm_sync_socket_create_timer_func_t create_timer_func,
14
              realm_sync_socket_timer_canceled_func_t cancel_timer_func,
15
              realm_sync_socket_timer_free_func_t free_timer_func)
16
        : m_handler(handler)
17
        , m_timer_create(create_timer_func)
18
        , m_timer_cancel(cancel_timer_func)
19
        , m_timer_free(free_timer_func)
20
    {
12✔
21
        m_timer = m_timer_create(userdata, delay_ms, handler);
12✔
22
    }
12✔
23

24
    /// Cancels the timer and destroys the timer instance.
25
    ~CAPITimer()
26
    {
12✔
27
        m_timer_cancel(m_userdata, m_timer);
12✔
28
        m_timer_free(m_userdata, m_timer);
12✔
29
        realm_release(m_handler);
12✔
30
    }
12✔
31

32
    /// Cancel the timer immediately.
33
    void cancel() override
UNCOV
34
    {
×
UNCOV
35
        m_timer_cancel(m_userdata, m_timer);
×
UNCOV
36
    }
×
37

38
private:
39
    realm_sync_socket_timer_t m_timer = nullptr;
40

41
    realm_userdata_t m_userdata = nullptr;
42
    realm_sync_socket_callback_t* m_handler = nullptr;
43
    realm_sync_socket_create_timer_func_t m_timer_create = nullptr;
44
    realm_sync_socket_timer_canceled_func_t m_timer_cancel = nullptr;
45
    realm_sync_socket_timer_free_func_t m_timer_free = nullptr;
46
};
47

48
struct CAPIWebSocket : sync::WebSocketInterface {
49
public:
50
    CAPIWebSocket(realm_userdata_t userdata, realm_sync_socket_connect_func_t websocket_connect_func,
51
                  realm_sync_socket_websocket_async_write_func_t websocket_write_func,
52
                  realm_sync_socket_websocket_free_func_t websocket_free_func, realm_websocket_observer_t* observer,
53
                  sync::WebSocketEndpoint&& endpoint)
54
        : m_observer(observer)
55
        , m_userdata(userdata)
56
        , m_websocket_connect(websocket_connect_func)
57
        , m_websocket_async_write(websocket_write_func)
58
        , m_websocket_free(websocket_free_func)
59
    {
2✔
60
        realm_websocket_endpoint_t capi_endpoint;
2✔
61
        capi_endpoint.address = endpoint.address.c_str();
2✔
62
        capi_endpoint.port = endpoint.port;
2✔
63
        capi_endpoint.path = endpoint.path.c_str();
2✔
64

1✔
65
        std::vector<const char*> protocols;
2✔
66
        for (size_t i = 0; i < endpoint.protocols.size(); ++i) {
20✔
67
            auto& protocol = endpoint.protocols[i];
18✔
68
            protocols.push_back(protocol.c_str());
18✔
69
        }
18✔
70
        capi_endpoint.protocols = protocols.data();
2✔
71
        capi_endpoint.num_protocols = protocols.size();
2✔
72
        capi_endpoint.is_ssl = endpoint.is_ssl;
2✔
73

1✔
74
        m_socket = m_websocket_connect(m_userdata, capi_endpoint, observer);
2✔
75
    }
2✔
76

77
    /// Destroys the web socket instance.
78
    ~CAPIWebSocket()
79
    {
2✔
80
        m_websocket_free(m_userdata, m_socket);
2✔
81
        realm_release(m_observer);
2✔
82
    }
2✔
83

84
    void async_write_binary(util::Span<const char> data, sync::SyncSocketProvider::FunctionHandler&& handler) final
85
    {
14✔
86
        auto shared_handler = std::make_shared<sync::SyncSocketProvider::FunctionHandler>(std::move(handler));
14✔
87
        m_websocket_async_write(m_userdata, m_socket, data.data(), data.size(),
14✔
88
                                new realm_sync_socket_callback_t(std::move(shared_handler)));
14✔
89
    }
14✔
90

91
private:
92
    realm_sync_socket_websocket_t m_socket = nullptr;
93
    realm_websocket_observer_t* m_observer = nullptr;
94
    realm_userdata_t m_userdata = nullptr;
95

96
    realm_sync_socket_connect_func_t m_websocket_connect = nullptr;
97
    realm_sync_socket_websocket_async_write_func_t m_websocket_async_write = nullptr;
98
    realm_sync_socket_websocket_free_func_t m_websocket_free = nullptr;
99
};
100

101
struct CAPIWebSocketObserver : sync::WebSocketObserver {
102
public:
103
    CAPIWebSocketObserver(std::unique_ptr<sync::WebSocketObserver> observer)
104
        : m_observer(std::move(observer))
105
    {
2✔
106
    }
2✔
107

108
    ~CAPIWebSocketObserver() = default;
2✔
109

110
    void websocket_connected_handler(const std::string& protocol) final
111
    {
2✔
112
        m_observer->websocket_connected_handler(protocol);
2✔
113
    }
2✔
114

115
    void websocket_error_handler() final
UNCOV
116
    {
×
UNCOV
117
        m_observer->websocket_error_handler();
×
UNCOV
118
    }
×
119

120
    bool websocket_binary_message_received(util::Span<const char> data) final
121
    {
8✔
122
        return m_observer->websocket_binary_message_received(data);
8✔
123
    }
8✔
124

125
    bool websocket_closed_handler(bool was_clean, sync::websocket::WebSocketError code, std::string_view msg) final
UNCOV
126
    {
×
UNCOV
127
        return m_observer->websocket_closed_handler(was_clean, code, msg);
×
UNCOV
128
    }
×
129

130
private:
131
    std::unique_ptr<sync::WebSocketObserver> m_observer;
132
};
133

134
struct CAPISyncSocketProvider : sync::SyncSocketProvider {
135
    realm_userdata_t m_userdata = nullptr;
136
    realm_free_userdata_func_t m_free = nullptr;
137
    realm_sync_socket_post_func_t m_post = nullptr;
138
    realm_sync_socket_create_timer_func_t m_timer_create = nullptr;
139
    realm_sync_socket_timer_canceled_func_t m_timer_cancel = nullptr;
140
    realm_sync_socket_timer_free_func_t m_timer_free = nullptr;
141
    realm_sync_socket_connect_func_t m_websocket_connect = nullptr;
142
    realm_sync_socket_websocket_async_write_func_t m_websocket_async_write = nullptr;
143
    realm_sync_socket_websocket_free_func_t m_websocket_free = nullptr;
144

145
    CAPISyncSocketProvider() = default;
2✔
146
    CAPISyncSocketProvider(CAPISyncSocketProvider&& other)
147
        : m_userdata(std::exchange(other.m_userdata, nullptr))
148
        , m_free(std::exchange(other.m_free, nullptr))
149
        , m_post(std::exchange(other.m_post, nullptr))
150
        , m_timer_create(std::exchange(other.m_timer_create, nullptr))
151
        , m_timer_cancel(std::exchange(other.m_timer_cancel, nullptr))
152
        , m_timer_free(std::exchange(other.m_timer_free, nullptr))
153
        , m_websocket_connect(std::exchange(other.m_websocket_connect, nullptr))
154
        , m_websocket_async_write(std::exchange(other.m_websocket_async_write, nullptr))
155
        , m_websocket_free(std::exchange(other.m_websocket_free, nullptr))
UNCOV
156
    {
×
UNCOV
157
        REALM_ASSERT(m_free);
×
UNCOV
158
        REALM_ASSERT(m_post);
×
UNCOV
159
        REALM_ASSERT(m_timer_create);
×
UNCOV
160
        REALM_ASSERT(m_timer_cancel);
×
UNCOV
161
        REALM_ASSERT(m_timer_free);
×
UNCOV
162
        REALM_ASSERT(m_websocket_connect);
×
UNCOV
163
        REALM_ASSERT(m_websocket_async_write);
×
UNCOV
164
        REALM_ASSERT(m_websocket_free);
×
UNCOV
165
    }
×
166

167
    ~CAPISyncSocketProvider()
168
    {
2✔
169
        m_free(m_userdata);
2✔
170
    }
2✔
171

172
    std::unique_ptr<sync::WebSocketInterface> connect(std::unique_ptr<sync::WebSocketObserver> observer,
173
                                                      sync::WebSocketEndpoint&& endpoint) final
174
    {
2✔
175
        auto capi_observer = std::make_shared<CAPIWebSocketObserver>(std::move(observer));
2✔
176
        return std::make_unique<CAPIWebSocket>(m_userdata, m_websocket_connect, m_websocket_async_write,
2✔
177
                                               m_websocket_free, new realm_websocket_observer_t(capi_observer),
2✔
178
                                               std::move(endpoint));
2✔
179
    }
2✔
180

181
    void post(FunctionHandler&& handler) final
182
    {
16✔
183
        auto shared_handler = std::make_shared<FunctionHandler>(std::move(handler));
16✔
184
        m_post(m_userdata, new realm_sync_socket_callback_t(std::move(shared_handler)));
16✔
185
    }
16✔
186

187
    SyncTimer create_timer(std::chrono::milliseconds delay, FunctionHandler&& handler) final
188
    {
12✔
189
        auto shared_handler = std::make_shared<FunctionHandler>(std::move(handler));
12✔
190
        return std::make_unique<CAPITimer>(m_userdata, delay.count(),
12✔
191
                                           new realm_sync_socket_callback_t(std::move(shared_handler)),
12✔
192
                                           m_timer_create, m_timer_cancel, m_timer_free);
12✔
193
    }
12✔
194
};
195

196
} // namespace
197

198
RLM_API realm_sync_socket_t* realm_sync_socket_new(
199
    realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, realm_sync_socket_post_func_t post_func,
200
    realm_sync_socket_create_timer_func_t create_timer_func,
201
    realm_sync_socket_timer_canceled_func_t cancel_timer_func, realm_sync_socket_timer_free_func_t free_timer_func,
202
    realm_sync_socket_connect_func_t websocket_connect_func,
203
    realm_sync_socket_websocket_async_write_func_t websocket_write_func,
204
    realm_sync_socket_websocket_free_func_t websocket_free_func)
205
{
2✔
206
    return wrap_err([&]() {
2✔
207
        auto capi_socket_provider = std::make_shared<CAPISyncSocketProvider>();
2✔
208
        capi_socket_provider->m_userdata = userdata;
2✔
209
        capi_socket_provider->m_free = userdata_free;
2✔
210
        capi_socket_provider->m_post = post_func;
2✔
211
        capi_socket_provider->m_timer_create = create_timer_func;
2✔
212
        capi_socket_provider->m_timer_cancel = cancel_timer_func;
2✔
213
        capi_socket_provider->m_timer_free = free_timer_func;
2✔
214
        capi_socket_provider->m_websocket_connect = websocket_connect_func;
2✔
215
        capi_socket_provider->m_websocket_async_write = websocket_write_func;
2✔
216
        capi_socket_provider->m_websocket_free = websocket_free_func;
2✔
217
        return new realm_sync_socket_t(std::move(capi_socket_provider));
2✔
218
    });
2✔
219
}
2✔
220

221
RLM_API void realm_sync_socket_callback_complete(realm_sync_socket_callback* realm_callback, realm_errno_e code,
222
                                                 const char* reason)
223
{
16✔
224
    auto complete_status =
16✔
225
        code == realm_errno_e::RLM_ERR_NONE ? Status::OK() : Status{static_cast<ErrorCodes::Error>(code), reason};
16✔
226
    (*(realm_callback->get()))(complete_status);
16✔
227
    realm_release(realm_callback);
16✔
228
}
16✔
229

230
RLM_API void realm_sync_socket_websocket_connected(realm_websocket_observer_t* realm_websocket_observer,
231
                                                   const char* protocol)
UNCOV
232
{
×
UNCOV
233
    realm_websocket_observer->get()->websocket_connected_handler(protocol);
×
UNCOV
234
}
×
235

236
RLM_API void realm_sync_socket_websocket_error(realm_websocket_observer_t* realm_websocket_observer)
UNCOV
237
{
×
UNCOV
238
    realm_websocket_observer->get()->websocket_error_handler();
×
UNCOV
239
}
×
240

241
RLM_API void realm_sync_socket_websocket_message(realm_websocket_observer_t* realm_websocket_observer,
242
                                                 const char* data, size_t data_size)
UNCOV
243
{
×
UNCOV
244
    realm_websocket_observer->get()->websocket_binary_message_received(util::Span{data, data_size});
×
UNCOV
245
}
×
246

247
RLM_API void realm_sync_socket_websocket_closed(realm_websocket_observer_t* realm_websocket_observer, bool was_clean,
248
                                                realm_web_socket_errno_e code, const char* reason)
UNCOV
249
{
×
UNCOV
250
    realm_websocket_observer->get()->websocket_closed_handler(
×
UNCOV
251
        was_clean, static_cast<sync::websocket::WebSocketError>(code), reason);
×
UNCOV
252
}
×
253

254
RLM_API void realm_sync_client_config_set_sync_socket(realm_sync_client_config_t* config,
255
                                                      realm_sync_socket_t* sync_socket) RLM_API_NOEXCEPT
UNCOV
256
{
×
UNCOV
257
    config->socket_provider = *sync_socket;
×
UNCOV
258
}
×
259

260
} // namespace realm::c_api
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

© 2025 Coveralls, Inc