Conversation
wc_KeyPemToDer decrypts PEM keys and wc_DecryptPKCS8Key handles encrypted DER, avoiding wolfSSL_CTX_set_default_passwd_cb which requires OPENSSL_EXTRA.
Automatically detect and enable Link Time Optimization for both Corosio and Asio benchmarks. This ensures fair comparisons and optimal performance measurement.
Remove the separate lambda-based benchmark and keep only the coroutine version for fair comparison with corosio. Both libraries now benchmark coroutine dispatch rather than comparing coroutines against callbacks.
Replace per-iteration timeout calculation with Linux timerfd for kernel-managed timer expiry. Add task operation sentinel pattern to interleave reactor runs with handler execution, preventing timer starvation.
- Remove unused any_completed variable - Skip redundant error handling when EPOLLIN/EPOLLOUT already processed ops - Simplify thread notification: notify_one for single completion, notify_all for multiple completions
- Add task sentinel pattern for timer starvation prevention - Simplify do_one() by removing deadline tracking - Optimize thread notification logic - Remove unused includes
Use initiator coroutines for read/write operations to ensure the caller's coroutine is fully suspended before I/O starts. This prevents a race condition in multi-threaded scenarios where immediate completion could try to resume a coroutine that isn't fully suspended yet. - Add read_initiator and write_initiator coroutine types with cached frame allocation to avoid per-operation heap allocations - Move I/O logic to do_read_io() and do_write_io() methods - Modify read_some/write_some to return initiator handles for symmetric transfer - Add destructor to clean up initiator frames and handles
Consistent with other syscall error handling in this file.
Combine four separate benchmark executables into one for each library: - asio_bench: unified Asio benchmarks with --category and --bench filters - corosio_bench: unified Corosio benchmarks with --backend, --category, and --bench filters Extract make_socket_pair into shared socket_utils.hpp to reduce duplication.
- Add warmup phase to all benchmarks to reduce variance - Remove category headers from output - Increase iterations for more stable results: - io_context: 5M handlers - socket_latency: 1M iterations - socket_throughput: 4GB transfer - http_server: 1M requests
The NT wait completion packet API requires one-shot re-association after every wakeup, causing ~60% CPU overhead in timer-free workloads. Switch to thread-based implementation which has lower per-iteration cost. Also tidy up NT function pointer loading to cast once at init time.
Reduce mutex contention by processing events into a local queue without holding the mutex. The mutex is only acquired briefly when splicing completions into the completed_ops_ queue. Changes: - Process events into a local op_queue without holding the mutex - Only acquire mutex for completed_ops_ splice operation - Add check_timers flag to only process timers when timerfd fires - Cache last timerfd expiry to skip redundant timerfd_settime calls
Only wake idle threads, and only as many as we have work available. This prevents waking all threads when only a few completions arrive.
When posting work from within the scheduler's run loop, use a thread-local queue instead of acquiring the global mutex. This matches Asio's thread_info::private_op_queue optimization. - Extend scheduler_context with private_queue and work counter - Fast path in post() detects same-thread via context_stack - Drain points: before blocking, after reactor splice, on exit - Reduces futex calls from ~450K to 1 in multi-threaded benchmarks
- Consume timerfd on expiry to prevent epoll busy-spinning (level-triggered fd must be read to clear readable state) - Remove last_timerfd_expiry_ caching optimization to match Asio (eliminates data race between timer callback and reactor thread)
Free functions in boost/corosio/connect.hpp that try each endpoint in a range (or iterator pair) until one connects, with optional connect-condition predicate. Mirrors Boost.Asio's async_connect semantics adapted to corosio's coroutine model.
…arison Add _lockless variants to asio and asio_callback across socket_throughput, socket_latency, local_socket_throughput, local_socket_latency, fan_out, accept_churn, http_server, and timer, mirroring corosio's single-threaded configurations by constructing the io_context with BOOST_ASIO_CONCURRENCY_HINT_UNSAFE. Follows the existing pattern in io_context_bench.cpp. Move throughput byte accounting out of the read loop into a local int64_t accumulator, calling state.add_bytes once after ioc.run() returns. The previous per-read state.add_bytes was an atomic fetch_add on every completion, which added ~20ns × N_reads to the measured elapsed time and structurally disadvantaged the faster library at small chunk sizes. Multithread benches still use atomic aggregation (required for correctness across N runner threads).
Add --warmup <secs> flag (default 0, disabled) that runs every benchmark
once with a throwaway state before the real measurement. The self-warmup
exercises the exact code path being measured, eliminating the sync-vs-async
warmup asymmetry in the previous scheme where corosio's set_warmup lambdas
exercised async I/O paths while asio's used synchronous asio::write/read.
Removes benchmark_suite::set_warmup and all 18 .set_warmup([]{...}) call
sites across corosio, asio coroutine, and asio callback. For benches with
needs_conntrack_drain, drain runs before both warmup and real measurement.
Replace unique_ptr<tcp_socket> with value-typed sockets across all asio accept_churn benchmarks (coroutine and callback variants). Vectors are pre-reserved so no reallocation invalidates references held by pending async operations. This matches the corosio benchmark's allocation pattern for an apples-to-apples comparison.
Adds 4.guide/4q.udp.adoc covering the corosio UDP API: udp protocol tag, open/bind, connectionless and connected modes, message flags, socket options, multicast, cancellation, and a TCP-vs-UDP comparison. Wires the new page into nav.adoc after Unix Domain Sockets.
The windows-2025 runner label transiently resolved to a windows-2025-vs2026 image (Visual Studio 18 preview, MSVC 14.50) instead of the documented VS 2022 image, breaking the configure step because the hardcoded "Visual Studio 17 2022" generator can't match a VS 18 install. Pin the latest MSVC entry to windows-2022, which has VS 2022 stable, until VS 18 reaches RTM and CMake ships the corresponding generator. Also bump the matrix version label from 14.42 to 14.44 so the job name matches the toolset actually shipped on windows-2022 (14.44.35207).
When the speculative read/write only has one buffer, dispatch to recv()/
send() instead of readv()/writev()/sendmsg() so the kernel can skip the
iov_iter setup. The single-buffer path is the common case in HTTP and
streaming workloads.
The single-buffer write goes through a new write_policy::write_one
backend hook so each reactor backend picks the right SIGPIPE strategy:
- epoll: send(MSG_NOSIGNAL)
- kqueue: write() -- macOS lacks MSG_NOSIGNAL; SIGPIPE is suppressed
by the mandatory SO_NOSIGPIPE set in accept_policy and
set_fd_options
- select: send(MSG_NOSIGNAL) where defined, else write() with
SO_NOSIGPIPE as the SIGPIPE fallback
The single-buffer read uses recv() inline -- flag=0 is portable across
all reactor platforms, so no read_policy is needed.
Two related improvements to io_context construction:
1. Static heuristic for inline budget defaults: when concurrency_hint
> 1 and the user has not customized budget options, override
(init, max, unassisted) to (0, 0, 0). Multi-thread workloads
benefit from cross-thread work-stealing, which "post everything"
enables; single-thread keeps the (2, 16, 4) chaining defaults.
2. Tie concurrency_hint == 1 to single_threaded mode (asio precedent):
constructing an io_context with concurrency_hint == 1 now forces
opts.single_threaded = true, eliminating scheduler locking on the
hot path. Matches asio's one_thread_ behavior. To opt out, pass
concurrency_hint > 1.
Supporting changes:
- reactor_scheduler: short-circuit try_consume_inline_budget and
reset_inline_budget when inline_budget_max_ == 0 so post-everything
mode skips TLS-list walks; relax configure_reactor validation to
allow budget_max == 0; fix max(1, x) * 2 in ramp-up to escape zero.
- io_context: apply_options_pre_/post_ now take concurrency_hint;
new private configure_single_threaded_() helper used by the
bare-hint and template no-opts constructors.
- docs: update 4c2.configuration.adoc and io_context_options field
docs to describe the queue-empty gating and new defaults.
Sets each worker's thread name via capy::set_current_thread_name so they show up in debuggers and system tools as tpool-svc-1, tpool-svc-2, etc. Format fits Linux's 15-char pthread name limit for indices up to 9999.
Adds boost::corosio::host_name(), a synchronous free function returning the local machine's hostname as a UTF-8 std::string. Common uses: logging, default Host: headers, cluster registration, identifying a node. A single overload that throws std::runtime_error on failure. No std::error_code variant: failures of the underlying syscalls are pathological on a configured machine, and the throwing form is sufficient. POSIX path uses gethostname(2) with a 256-byte stack buffer, which comfortably exceeds the _POSIX_HOST_NAME_MAX floor of 255 and every mainstream OS's actual cap. errno is captured immediately on failure. POSIX does not guarantee NUL termination on truncation, so the implementation checks for a NUL anywhere in the buffer and throws otherwise. Windows path uses GetComputerNameExW(ComputerNameDnsHostname, ...) followed by WideCharToMultiByte(CP_UTF8, ...) to produce UTF-8. Chosen over winsock gethostname() so the function works without WSAStartup(); in corosio winsock is initialized lazily inside io_context, so a winsock-based implementation would tie host_name() to io_context lifetime, contradicting the "no io_context needed" design goal. Adds five unit tests covering: non-empty result, stability across calls, reasonable length (<= 255 octets), no-io_context-needed (load-bearing regression guard for the Windows implementation choice), and charset sanity (catches UTF-16 -> UTF-8 regressions).
cppalliance/capy#262 removes the `const_buffer_pair` / `mutable_buffer_pair` aliases and demotes `buffer_array<N, IsConst>` from `capy::` to `capy::detail::`. corosio migrates: - `test/unit/buffer_param.cpp`: replace `capy::const_buffer_pair` / `capy::mutable_buffer_pair` with `std::array<capy::const_buffer, 2>` / `std::array<capy::mutable_buffer, 2>`. Drop the `buffers/buffer_pair.hpp` include. - tls_stream.hpp / wolfssl_stream.{hpp,cpp} / openssl_stream.{hpp,cpp}: replace `capy::mutable_buffer_array<N>` / `capy::const_buffer_array<N>` with `capy::detail::mutable_buffer_array<N>` / `capy::detail::const_buffer_array<N>` and update include paths to `boost/capy/detail/buffer_array.hpp`. corosio's TLS stream interface acknowledges that this scatter/gather fixed-capacity helper is now capy-internal; using `detail::` from corosio is the explicit choice made when buffer_array became internal machinery. Coordinated with capy PR cppalliance/capy#262.
Both headers are standalone public APIs not reached transitively from anything else in the umbrella, so users who include only <boost/corosio.hpp> could not call corosio::connect or corosio::host_name without an extra include.
Exposes an asio-style wait(wait_type) awaitable on tcp_socket, udp_socket, local_stream_socket, local_datagram_socket, tcp_acceptor, and local_stream_acceptor. The operation suspends until the descriptor is ready in the chosen direction (read / write / error) without transferring any bytes; useful for wrapping nonblocking C libraries (libssh, libpq async, etc.) that own their own recv/send and only need readiness notification. POSIX backends share a new reactor_wait_op<Base> template that parks in three new wait_*_op slots on reactor_descriptor_state. Dispatch in invoke_deferred_io completes the matching slot on each event bit without performing any I/O syscall. wait_type::write completes immediately on a connected socket on every backend, matching asio's IOCP contract. Corosio's reactor backends use edge-triggered EPOLLOUT/EVFILT_WRITE; parking would never fire on an already-writable socket, and backpressure is surfaced through write_some()'s return value as usual. On IOCP, stream-socket wait_read uses a zero-byte WSARecv. All other waits (datagram wait_read, acceptor wait_read, every wait_error) route through a new win_wait_reactor: a dedicated WSAPoll thread woken via a loopback Winsock socket pair, bridging readiness into the IOCP queue via PostQueuedCompletionStatus. The reactor is lazily constructed via std::call_once and stopped early in win_scheduler::shutdown() so parked ops do not block work-counter drain. socket.cancel() / close_socket() / shutdown all route through the same cancel_wait_if_constructed path so reactor-parked ops are cleaned up without forcing reactor construction on hot paths that never used it. Doxygen on every new public symbol; new Antora guide page (4r.wait.adoc) covers the readiness pattern, acceptor semantics, cancellation, and the wait_type::write immediate-ready contract. Tests parameterised across backends cover the no-consume promise on TCP, immediate write completion, local_stream wait_read (POSIX), UDP wait_read (exercises the aux reactor on IOCP), cancellation through the standard reactor (wait_read on TCP), cancellation while parked in the aux reactor (UDP wait_read), and acceptor wait_read. wait_type::error is plumbed but unexercised by tests; kernel error semantics are non-portable and the contract is documented as best-effort.
Extend the shadow pattern (concrete-class method names hidden by
derived native_*<Backend> templates that return strongly-typed
awaitables instead of dispatching virtually) so every async
operation on every public I/O type has a native_* counterpart.
Before this branch, only a subset of the async surface was
shadowed. native_tcp_socket and native_tcp_acceptor shadowed
their read/write/accept/connect ops, but native_udp_socket
covered only send_to/recv_from, and the local-socket and file
types had no shadow at all. Code holding a native_X<Backend>
reference therefore went through the virtual io_object dispatch
for any non-shadowed call, defeating the point of using the
typed wrapper.
This commit closes the gap:
- native_udp_socket gains connect, send, recv shadows.
- New native_local_stream_socket shadows read_some, write_some,
connect.
- New native_local_stream_acceptor shadows accept(peer&) and
the move-accept overload (returning a
native_local_stream_socket<Backend>).
- New native_local_datagram_socket shadows send_to, recv_from,
connect, send, recv.
- New native_stream_file shadows read_some, write_some.
- New native_random_access_file shadows read_some_at,
write_some_at.
- Every shadow type also gets wait() returning a typed
native_wait_awaitable.
Tests under test/unit/native/ exercise each new shadow with a
static_assert that pins the shadowing contract (the native op
must return a type distinct from the concrete base op), plus
runtime checks of the awaitable path and a polymorphic-slice
test that verifies the base class still works via virtual
dispatch when the object is used through its non-native
interface.
Supporting bits:
- backend.hpp gains the file-type tag typedefs (stream_file_type,
random_access_file_type, and *_service_type) for every
backend so create_handle<service_type>(ctx) compiles in the
new native_*_file wrappers.
- stream_file and random_access_file grow protected constructors
so the native virtual-base initialization works (io_stream
virtually inherits io_object; only the most-derived class
initializes it).
- local_stream_acceptor::bind now honors bind_option::unlink_existing
on Windows via DeleteFileA — the option was previously a no-op
in the non-POSIX branch, which broke testUnlinkExisting on the
iocp variant.
- win_tcp_service::connect_ex / accept_ex getters move into the
class body so TUs that include only the service header (the
new native_local_stream_socket test among them) get the
inline definitions.
- win_local_stream_service.hpp pulls in the acceptor header
directly so its inline shutdown() sees the full
win_local_stream_acceptor_internal type regardless of
consumer include order.
- A portable test/unit/local_temp.hpp helper replaces the old
POSIX-only mkdtemp/unlink pattern in the local-socket tests,
using std::filesystem + a random_device-seeded RNG so
parallel ctest processes don't collide on /tmp paths.
Known platform gaps documented in-file:
- local_datagram_socket tests stay POSIX-only at the
top-of-file. Windows has never shipped AF_UNIX SOCK_DGRAM;
the very first WSASocket(AF_UNIX, SOCK_DGRAM, ...) returns
WSAESOCKTNOSUPPORT.
- local_stream_socket's three socketpair-based tests
(testReadWrite, testSocketPair, testAvailable) and the
raw-fd testRelease remain per-test POSIX-gated;
make_local_stream_pair is gated POSIX-only in the public
header because socketpair() doesn't exist on Windows. TCP
socket tests already exercise the equivalent read/write
paths on Windows IOCP.
…unt tests Replace the 10ms delay timer that sequenced waiter registration before the reset with explicit poll() drains. The previous structure relied on the IOCP scheduler dispatching the two t.wait() suspensions before the delay timer expired; on Windows release builds the order isn't guaranteed and the test would intermittently observe zero canceled waiters.
- Add Windows make_local_stream_pair() via temp-listener emulation of socketpair(), enabling socket-pair tests on IOCP - Implement assign_socket() in win_local_stream_service so raw SOCKET handles can be registered with the IOCP port - Replace ConnectEx/AcceptEx with blocking connect()/accept() on worker threads for AF_UNIX — the IOCP extension functions are not reliable for AF_UNIX on all Windows versions - Add portable temp_socket_dir helper using std::filesystem for temp paths across platforms - Guard local datagram code (SOCK_DGRAM) as POSIX-only at compile time — Windows does not support AF_UNIX SOCK_DGRAM - Remove dead IOCP datagram implementation files (win_local_dgram_service.hpp, win_local_dgram_socket.hpp) - Document Windows limitation on local_datagram_socket and local_datagram headers
- socket_option: IP_MULTICAST_LOOP and IP_MULTICAST_TTL are u_char options on BSD-derived kernels; the previous int storage caused setsockopt to return EINVAL on macOS. Add byte_boolean_option / byte_integer_option (public ABI) and byte_boolean<> / byte_integer<> (native templates) with single-byte storage; rebase multicast_loop_v4 and multicast_hops_v4 onto them. IPv6 variants are unaffected. - native_local_datagram_socket: include of the deleted IOCP datagram service was reachable in any IOCP build. Wrap the whole header in BOOST_COROSIO_POSIX to mirror local_datagram_socket.hpp. - posix_resolver_service and win_resolver_service: replace make_service<thread_pool>() with use_service<thread_pool>(). The original call threw 'invalid argument' whenever io_context_options.thread_pool_size != 1 because pre_create_services had already constructed the pool with non-default args. - iocp wait_reactor and tcp_acceptor_service: resolve a pre-cancelled stop_token race in wait() and accept() paths that caused tests to hang on Windows IOCP under specific completion orderings.
Adds targeted unit tests across the public API and native shadow layers to close the largest line-coverage gaps in the develop baseline. Major areas: - tls_context: cover malformed PEM, mismatched cert/key, cipher list, protocol version round-trip, verify mode/depth, hostname, SNI/ALPN, CRL, OCSP staple, password callback (24% to 100%). - io_context and scheduler detail: backend tag construction, run_for, run_until, restart, post-throws, deterministic multithreaded notify_one + wait_for coverage. - socket_option: set/get round-trip for every public option plus the native templated variants; wrong-protocol error paths. - local sockets: connect/accept error paths, abstract namespace, path-length boundary, mid-flight cancel, datagram send/recv. Adopt the temp_socket_dir helper introduced upstream. - reactor internals: concurrent read/write on same descriptor, mid-flight cancel, close-during-op, wait_type::error paths, stop-token cancellation. Add reactor_paths.cpp aggregating these scenarios. - tcp_server, posix_resolver_service, host_name, file services: lifecycle, accept loop, flag variants, error mapping. - Add testConstructionWithThreadPoolSize regression for the resolver use_service fix. Cross-platform reconciliation observed in CI: - BSD-family kernels reject multicast set_option values (zero buffer sizes, leave-without-route, IPV6 ifindex 0) that Linux accepts; wrap in try/catch with documented platform variation. - macOS returns EMSGSIZE for zero-length UDP datagrams; broaden the expectation to any error so MinGW and others pass too. - Windows IOCP: gate testIoContextOptionsMaxEventsZero/BudgetInitClamp and the single-threaded resolver tests as POSIX-only; relax buffer size assertions to permit Windows's accept-zero-as-zero contract. - POSIX-guard local socket tests that exercise abstract namespace and related Linux-only behavior. - testMultithreadedNotifyAndWaitFor restructured to depend only on a work guard and counter drain, not on wall-clock timing, so it remains deterministic under thread-sanitizer. - Signal-set shutdown test switched from POSIX-only SIGUSR1/2 to the portable SIGINT/SIGTERM pair.
The public make_local_stream_pair / make_local_datagram_pair were primarily used to construct test fixtures; production callers exist in theory but are vanishingly rare compared to test and benchmark usage. PR #252's Windows implementation was specifically motivated by tests on IOCP. Move both helpers into include/boost/corosio/test/local_socket_pair.hpp under boost::corosio::test, alongside the existing templated stream variant that the perf benchmarks already use. The test/ helper drives bind+accept+connect via the public acceptor API, which works on every backend after PR #252 enabled AF_UNIX SOCK_STREAM on Windows IOCP -- so the bespoke socketpair-emulation Windows code in src/corosio/src/local_socket_pair.cpp is no longer needed. - Delete include/boost/corosio/local_socket_pair.hpp - Delete src/corosio/src/local_socket_pair.cpp - Remove the umbrella include in boost/corosio.hpp - Add make_local_datagram_pair to test/local_socket_pair.hpp (POSIX-only) - Migrate the three test files that called the public helpers (local_stream_socket.cpp, local_datagram_socket.cpp, reactor_paths.cpp) via using-declarations so call sites stay identical
Mirror asio::local::connect_pair as a free function in boost::corosio. POSIX uses socketpair(); Windows performs a private bind/listen/accept on the caller thread paired with a connect on a short-lived worker thread, so the caller's io_context is never driven. Returns std::error_code (noexcept). Stream and POSIX-only datagram overloads. native_local_stream_socket<Backend> slices to the base parameter; assign() routes through the backend service. Replaces the test-only make_local_*_pair helpers from 4b952ec; tests, benchmarks, and the user guide are migrated.
…hang The auxiliary wait reactor blocked in WSAPoll(-1, infinite), relying entirely on the self-pipe wakeup. wake_self() coalesces wakes via the wake_pending_ flag and ignores send()'s return value, so a failed or lost wakeup leaves wake_pending_ stuck true: every subsequent wake is coalesced away and the reactor never re-checks pending_register_ / pending_cancel_ / stop_. A newly registered wait fd then never enters the poll set and its readiness is never detected, hanging ioc.run() forever. This surfaced as Windows coverage-build (gcc + gcov) timeouts in the local_stream_socket.iocp, native.local_stream_socket.iocp, and wait.iocp suites, whose newly enabled local-stream-on-IOCP tests exercise acceptor wait readiness through the reactor. The heavy gcov instrumentation widens the timing window; the regular (clang/msvc) CI and uninstrumented builds pass. Use a bounded 500 ms WSAPoll timeout as a safety net so a missed wakeup costs at most one poll interval of latency instead of a permanent hang. This mirrors the existing 500 ms GQCS safety timeout in win_scheduler.
temp_socket_dir's destructor used std::filesystem::remove_all() on a directory holding a bound AF_UNIX socket file. remove_all() stats each entry via symlink_status(), which on Windows libstdc++ opens the file with CreateFileW; opening an AF_UNIX socket file hangs in ZwCreateFile, deadlocking teardown. This timed out the MinGW gcov coverage build (1500s) in local_stream_socket.iocp, native.local_stream_socket.iocp and wait.iocp -- the only suites that bind AF_UNIX paths. MSVC STL stats without opening the file, so the regular CI and non-coverage builds were unaffected; the wait-reactor WSAPoll change in ca33581 addressed an unrelated subsystem (the hang is in test teardown). Unlink the socket file with std::remove (deletes by name without opening it) before remove_all walks the now-empty directory. Portable, no platform branch.
…psed run_one_until wrapped wait_one in a `while (now < abs_time)` loop, but the "no outstanding work -> stop" logic lives inside wait_one. When the deadline had already passed at the first loop check, the body was skipped, wait_one was never called, and the function returned 0 with stopped() == false, violating the documented contract. Rewrite the loop to always issue at least one wait_one, clamping the relative timeout to [0, 1s] and rechecking the deadline at the bottom. This also prevents a negative timeout from mapping to an indefinite block when outstanding work is present. Surfaced as a flaky testRunOneFor failure under valgrind, where the thread can be preempted past a 10ms deadline before the first check. Add deterministic regression tests using an already-elapsed deadline.
Add test/** to the code-coverage workflow path filter so test-only pushes to master/develop refresh the coverage badges. Previously the reported score could drift until an unrelated src/ or include/ change triggered a rebuild.
|
An automated preview of the documentation is available at https://265.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-06-02 18:43:41 UTC |
Add a strict total ordering to endpoint so it can be used as a key in std::map and std::set without a custom comparator. Endpoints order by address family (IPv4 before IPv6), then address value, then port, consistent with operator==. Drop the now-redundant explicit operator!=; C++20 synthesizes it from operator==, matching local_endpoint's comparison surface. Closes #258
Add unit tests for local_endpoint's operator== and operator<=>, which were previously untested public API. Covers empty-first ordering, prefix-before-extension, abstract-socket sorting (leading null byte), the path-too-long boundary, and use as a std::map key.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #265 +/- ##
==========================================
- Coverage 80.82% 77.78% -3.05%
==========================================
Files 61 96 +35
Lines 5268 7256 +1988
Branches 0 1769 +1769
==========================================
+ Hits 4258 5644 +1386
- Misses 1010 1102 +92
- Partials 0 510 +510
... and 58 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.