Skip to content

Commit 497fd2c

Browse files
committed
Increase coverage; fix Sonar issue
1 parent 7465a58 commit 497fd2c

File tree

4 files changed

+146
-13
lines changed

4 files changed

+146
-13
lines changed

include/libcyphal/transport/udp/delegate.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ class UdpardMemory final : public ScatteredBuffer::IStorage
197197
const auto& frag_view = fragment->view;
198198
if ((nullptr != frag_view.data) && (frag_view.size > 0))
199199
{
200-
observer.onNext({static_cast<const cetl::byte*>(frag_view.data), frag_view.size});
200+
observer.onNext({static_cast<const cetl::byte*>(frag_view.data), // NOSONAR cpp:S5356 cpp:S5357
201+
frag_view.size});
201202
}
202203

203204
fragment = fragment->next;

test/unittest/transport/can/test_can_delegate.cpp

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
/// Copyright Amazon.com Inc. or its affiliates.
44
/// SPDX-License-Identifier: MIT
55

6+
#include "cetl_gtest_helpers.hpp" // NOLINT(misc-include-cleaner)
67
#include "memory_resource_mock.hpp"
78
#include "tracking_memory_resource.hpp"
9+
#include "transport/scattered_buffer_storage_mock.hpp"
810
#include "verification_utilities.hpp"
911

1012
#include <canard.h>
@@ -103,17 +105,13 @@ class TestCanDelegate : public testing::Test
103105

104106
TEST_F(TestCanDelegate, CanardMemory_copy)
105107
{
106-
TransportDelegateImpl delegate{mr_};
107-
auto& canard_instance = delegate.canardInstance();
108-
109108
constexpr std::size_t payload_size = 4;
110109
constexpr std::size_t allocated_size = payload_size + 1;
111-
auto* const payload =
112-
static_cast<byte*>(canard_instance.memory.allocate(static_cast<TransportDelegate*>(&delegate), allocated_size));
110+
auto* const payload = static_cast<byte*>(mr_.allocate(allocated_size));
113111
fillIotaBytes({payload, allocated_size}, b('0'));
114112

115113
CanardMutablePayload canard_payload{payload_size, payload, allocated_size};
116-
const CanardMemory canard_memory{mr_, canard_payload};
114+
const CanardMemory canard_memory{mr_, canard_payload};
117115
EXPECT_THAT(canard_memory.size(), payload_size);
118116
EXPECT_THAT(canard_payload.size, 0);
119117
EXPECT_THAT(canard_payload.data, nullptr);
@@ -165,16 +163,12 @@ TEST_F(TestCanDelegate, CanardMemory_copy)
165163

166164
TEST_F(TestCanDelegate, CanardMemory_copy_on_moved)
167165
{
168-
TransportDelegateImpl delegate{mr_};
169-
auto& canard_instance = delegate.canardInstance();
170-
171166
constexpr std::size_t payload_size = 4;
172-
auto* const payload =
173-
static_cast<byte*>(canard_instance.memory.allocate(static_cast<TransportDelegate*>(&delegate), payload_size));
167+
auto* const payload = static_cast<byte*>(mr_.allocate(payload_size));
174168
fillIotaBytes({payload, payload_size}, b('0'));
175169

176170
CanardMutablePayload canard_payload{payload_size, payload, payload_size};
177-
CanardMemory old_canard_memory{mr_, canard_payload};
171+
CanardMemory old_canard_memory{mr_, canard_payload};
178172
EXPECT_THAT(old_canard_memory.size(), payload_size);
179173
EXPECT_THAT(canard_payload.size, 0);
180174
EXPECT_THAT(canard_payload.data, nullptr);
@@ -201,6 +195,46 @@ TEST_F(TestCanDelegate, CanardMemory_copy_on_moved)
201195
}
202196
}
203197

198+
TEST_F(TestCanDelegate, CanardMemory_observeFragments)
199+
{
200+
// Valid payload
201+
{
202+
StrictMock<ScatteredBufferObserverMock> observer_mock;
203+
204+
constexpr std::size_t payload_size = 4;
205+
auto* const payload = static_cast<byte*>(mr_.allocate(payload_size));
206+
fillIotaBytes({payload, payload_size}, b('0'));
207+
208+
CanardMutablePayload canard_payload{payload_size, payload, payload_size};
209+
const CanardMemory canard_memory{mr_, canard_payload};
210+
211+
EXPECT_CALL(observer_mock, onNext(ElementsAre(b('0'), b('1'), b('2'), b('3'))));
212+
canard_memory.observeFragments(observer_mock);
213+
}
214+
215+
// Zero size
216+
{
217+
StrictMock<ScatteredBufferObserverMock> observer_mock;
218+
219+
constexpr std::size_t payload_size = 0;
220+
auto* const payload = static_cast<byte*>(mr_.allocate(payload_size));
221+
fillIotaBytes({payload, payload_size}, b('0'));
222+
223+
CanardMutablePayload canard_payload{payload_size, payload, payload_size};
224+
const CanardMemory canard_memory{mr_, canard_payload};
225+
canard_memory.observeFragments(observer_mock);
226+
}
227+
228+
// Null
229+
{
230+
StrictMock<ScatteredBufferObserverMock> observer_mock;
231+
232+
CanardMutablePayload canard_payload{0, nullptr, 0};
233+
const CanardMemory canard_memory{mr_, canard_payload};
234+
canard_memory.observeFragments(observer_mock);
235+
}
236+
}
237+
204238
TEST_F(TestCanDelegate, optAnyFailureFromCanard)
205239
{
206240
EXPECT_THAT(TransportDelegate::optAnyFailureFromCanard(-CANARD_ERROR_OUT_OF_MEMORY),

test/unittest/transport/scattered_buffer_storage_mock.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,21 @@ class ScatteredBufferStorageMock : public ScatteredBuffer::IStorage
113113

114114
}; // ScatteredBufferStorageMock
115115

116+
class ScatteredBufferObserverMock : public ScatteredBuffer::IFragmentsObserver
117+
{
118+
public:
119+
ScatteredBufferObserverMock() = default;
120+
virtual ~ScatteredBufferObserverMock() = default;
121+
122+
ScatteredBufferObserverMock(const ScatteredBufferObserverMock&) = delete;
123+
ScatteredBufferObserverMock(ScatteredBufferObserverMock&&) noexcept = delete;
124+
ScatteredBufferObserverMock& operator=(const ScatteredBufferObserverMock&) = delete;
125+
ScatteredBufferObserverMock& operator=(ScatteredBufferObserverMock&&) noexcept = delete;
126+
127+
MOCK_METHOD(void, onNext, (const PayloadFragment fragment), (override));
128+
129+
}; // ScatteredBufferObserverMock
130+
116131
} // namespace transport
117132
} // namespace libcyphal
118133

test/unittest/transport/udp/test_udp_delegate.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
/// Copyright Amazon.com Inc. or its affiliates.
44
/// SPDX-License-Identifier: MIT
55

6+
#include "cetl_gtest_helpers.hpp" // NOLINT(misc-include-cleaner)
67
#include "memory_resource_mock.hpp"
78
#include "tracking_memory_resource.hpp"
9+
#include "transport/scattered_buffer_storage_mock.hpp"
810
#include "verification_utilities.hpp"
911

1012
#include <cetl/pf17/cetlpf.hpp>
@@ -340,6 +342,87 @@ TEST_F(TestUdpDelegate, UdpardMemory_copy_empty)
340342
EXPECT_THAT(udpard_memory.copy(1, buffer.data(), 3), 0);
341343
}
342344

345+
TEST_F(TestUdpDelegate, UdpardMemory_observeFragments)
346+
{
347+
const TransportDelegateImpl delegate{general_mr_, &fragment_mr_, &payload_mr_};
348+
349+
// Valid single-fragment payload
350+
{
351+
auto* const payload = allocateNewUdpardPayload(4);
352+
fillIotaBytes({payload, 4}, b('0'));
353+
354+
constexpr std::size_t payload_size = 4;
355+
UdpardRxTransfer rx_transfer{};
356+
rx_transfer.payload_size = payload_size;
357+
rx_transfer.payload = UdpardFragment{nullptr, {payload_size, payload}, {payload_size, payload}};
358+
359+
const UdpardMemory udpard_memory{delegate.memoryResources(), rx_transfer};
360+
361+
StrictMock<ScatteredBufferObserverMock> observer_mock;
362+
EXPECT_CALL(observer_mock, onNext(ElementsAre(b('0'), b('1'), b('2'), b('3'))));
363+
udpard_memory.observeFragments(observer_mock);
364+
}
365+
366+
// Valid multi-fragment payload
367+
{
368+
auto* const payload0 = allocateNewUdpardPayload(7);
369+
370+
UdpardRxTransfer rx_transfer{};
371+
rx_transfer.payload = UdpardFragment{nullptr, {7, payload0}, {7, payload0}};
372+
rx_transfer.payload.next = allocateNewUdpardFragment(8);
373+
rx_transfer.payload.next->next = allocateNewUdpardFragment(9);
374+
375+
auto* const payload1 = static_cast<byte*>(rx_transfer.payload.next->origin.data);
376+
auto* const payload2 = static_cast<byte*>(rx_transfer.payload.next->next->origin.data);
377+
fillIotaBytes({payload0, 7}, b('0'));
378+
fillIotaBytes({payload1, 8}, b('A'));
379+
fillIotaBytes({payload2, 9}, b('a'));
380+
381+
constexpr std::size_t payload_size = 3 + 4 + 2;
382+
rx_transfer.payload_size = payload_size;
383+
rx_transfer.payload.view = {3, payload0 + 2};
384+
rx_transfer.payload.next->view = {4, payload1 + 1};
385+
rx_transfer.payload.next->next->view = {2, payload2 + 3};
386+
387+
const UdpardMemory udpard_memory{delegate.memoryResources(), rx_transfer};
388+
389+
const testing::InSequence in_sequence;
390+
StrictMock<ScatteredBufferObserverMock> observer_mock;
391+
EXPECT_CALL(observer_mock, onNext(ElementsAre(b('2'), b('3'), b('4'))));
392+
EXPECT_CALL(observer_mock, onNext(ElementsAre(b('B'), b('C'), b('D'), b('E'))));
393+
EXPECT_CALL(observer_mock, onNext(ElementsAre(b('d'), b('e'))));
394+
udpard_memory.observeFragments(observer_mock);
395+
}
396+
397+
// Zero size
398+
{
399+
auto* const payload = allocateNewUdpardPayload(0);
400+
fillIotaBytes({payload, 0}, b('0'));
401+
402+
constexpr std::size_t payload_size = 0;
403+
UdpardRxTransfer rx_transfer{};
404+
rx_transfer.payload_size = payload_size;
405+
rx_transfer.payload = UdpardFragment{nullptr, {payload_size, payload}, {payload_size, payload}};
406+
407+
const UdpardMemory udpard_memory{delegate.memoryResources(), rx_transfer};
408+
409+
StrictMock<ScatteredBufferObserverMock> observer_mock;
410+
udpard_memory.observeFragments(observer_mock);
411+
}
412+
413+
// Null
414+
{
415+
UdpardRxTransfer rx_transfer{};
416+
rx_transfer.payload_size = 0;
417+
rx_transfer.payload = UdpardFragment{nullptr, {0, nullptr}, {0, nullptr}};
418+
419+
const UdpardMemory udpard_memory{delegate.memoryResources(), rx_transfer};
420+
421+
StrictMock<ScatteredBufferObserverMock> observer_mock;
422+
udpard_memory.observeFragments(observer_mock);
423+
}
424+
}
425+
343426
TEST_F(TestUdpDelegate, optAnyFailureFromUdpard)
344427
{
345428
EXPECT_THAT(TransportDelegate::optAnyFailureFromUdpard(-UDPARD_ERROR_MEMORY),

0 commit comments

Comments
 (0)