3 * Copyright (c) 2020-2021 Project CHIP Authors
4 * Copyright (c) 2016-2017 Nest Labs, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file implements a unit test suite for
22 * <tt>chip::System::PacketBuffer</tt>, a class that provides
23 * structure for network packet buffer management.
26 #ifndef __STDC_LIMIT_MACROS
27 #define __STDC_LIMIT_MACROS
37 #include <support/CHIPMem.h>
38 #include <support/CodeUtils.h>
39 #include <support/UnitTestRegistration.h>
40 #include <system/SystemPacketBuffer.h>
42 #if CHIP_SYSTEM_CONFIG_USE_LWIP
43 #include <lwip/init.h>
44 #include <lwip/tcpip.h>
45 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
47 #include <nlunit-test.h>
49 #if CHIP_SYSTEM_CONFIG_USE_LWIP
50 #if (LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 1)
51 #define PBUF_TYPE(pbuf) (pbuf)->type_internal
53 #define PBUF_TYPE(pbuf) (pbuf)->type
54 #endif // (LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 1)
55 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
57 using ::chip::Encoding::PacketBufferWriter;
58 using ::chip::System::PacketBuffer;
59 using ::chip::System::PacketBufferHandle;
61 #if !CHIP_SYSTEM_CONFIG_USE_LWIP
62 using ::chip::System::pbuf;
67 #define TO_LWIP_PBUF(x) (reinterpret_cast<struct pbuf *>(reinterpret_cast<void *>(x)))
68 #define OF_LWIP_PBUF(x) (reinterpret_cast<PacketBuffer *>(reinterpret_cast<void *>(x)))
71 void ScrambleData(uint8_t * start, uint16_t length)
73 for (uint16_t i = 0; i < length; ++i)
79 * An instance of this class created for the test suite.
80 * It is a friend class of `PacketBuffer` and `PacketBufferHandle` because some tests
81 * use or check private methods or properties.
83 class PacketBufferTest
88 const uint16_t * const reserved_sizes;
89 size_t reserved_size_count;
90 const uint16_t * const lengths;
92 PacketBufferTest * test;
95 static int TestSetup(void * inContext);
96 static int TestTeardown(void * inContext);
97 static int TestInitialize(void * inContext);
98 static int TestTerminate(void * inContext);
100 static void CheckNew(nlTestSuite * inSuite, void * inContext);
101 static void CheckStart(nlTestSuite * inSuite, void * inContext);
102 static void CheckSetStart(nlTestSuite * inSuite, void * inContext);
103 static void CheckDataLength(nlTestSuite * inSuite, void * inContext);
104 static void CheckSetDataLength(nlTestSuite * inSuite, void * inContext);
105 static void CheckTotalLength(nlTestSuite * inSuite, void * inContext);
106 static void CheckMaxDataLength(nlTestSuite * inSuite, void * inContext);
107 static void CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext);
108 static void CheckReservedSize(nlTestSuite * inSuite, void * inContext);
109 static void CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext);
110 static void CheckAddToEnd(nlTestSuite * inSuite, void * inContext);
111 static void CheckPopHead(nlTestSuite * inSuite, void * inContext);
112 static void CheckCompactHead(nlTestSuite * inSuite, void * inContext);
113 static void CheckConsumeHead(nlTestSuite * inSuite, void * inContext);
114 static void CheckConsume(nlTestSuite * inSuite, void * inContext);
115 static void CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext);
116 static void CheckAlignPayload(nlTestSuite * inSuite, void * inContext);
117 static void CheckNext(nlTestSuite * inSuite, void * inContext);
118 static void CheckLast(nlTestSuite * inSuite, void * inContext);
119 static void CheckRead(nlTestSuite * inSuite, void * inContext);
120 static void CheckAddRef(nlTestSuite * inSuite, void * inContext);
121 static void CheckFree(nlTestSuite * inSuite, void * inContext);
122 static void CheckFreeHead(nlTestSuite * inSuite, void * inContext);
123 static void CheckHandleConstruct(nlTestSuite * inSuite, void * inContext);
124 static void CheckHandleMove(nlTestSuite * inSuite, void * inContext);
125 static void CheckHandleRelease(nlTestSuite * inSuite, void * inContext);
126 static void CheckHandleFree(nlTestSuite * inSuite, void * inContext);
127 static void CheckHandleRetain(nlTestSuite * inSuite, void * inContext);
128 static void CheckHandleAdopt(nlTestSuite * inSuite, void * inContext);
129 static void CheckHandleHold(nlTestSuite * inSuite, void * inContext);
130 static void CheckHandleAdvance(nlTestSuite * inSuite, void * inContext);
131 static void CheckHandleRightSize(nlTestSuite * inSuite, void * inContext);
132 static void CheckHandleCloneData(nlTestSuite * inSuite, void * inContext);
133 static void CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext);
134 static void CheckBuildFreeList(nlTestSuite * inSuite, void * inContext);
136 static void PrintHandle(const char * tag, const PacketBuffer * buffer)
138 printf("%s %p ref=%u len=%-4u next=%p\n", tag, buffer, buffer ? buffer->ref : 0, buffer ? buffer->len : 0,
139 buffer ? buffer->next : 0);
141 static void PrintHandle(const char * tag, const PacketBufferHandle & handle) { PrintHandle(tag, handle.mBuffer); }
143 static constexpr uint16_t kBlockSize = PacketBuffer::kBlockSize;
146 struct BufferConfiguration
148 BufferConfiguration(uint16_t aReservedSize = 0) :
149 init_len(0), reserved_size(aReservedSize), start_buffer(nullptr), end_buffer(nullptr), payload_ptr(nullptr),
154 uint16_t reserved_size;
155 uint8_t * start_buffer;
156 uint8_t * end_buffer;
157 uint8_t * payload_ptr;
158 PacketBufferHandle handle;
161 static void PrintHandle(const char * tag, const BufferConfiguration & config) { PrintHandle(tag, config.handle); }
162 static void PrintConfig(const char * tag, const BufferConfiguration & config)
164 printf("%s pay=%-4zu len=%-4u res=%-4u:", tag, config.payload_ptr - config.start_buffer, config.init_len,
165 config.reserved_size);
166 PrintHandle("", config.handle);
169 PacketBufferTest(TestContext * context);
172 int InitializeTest(TestContext * context);
173 int TerminateTest(TestContext * context);
176 * Buffers allocated through PrepareTestBuffer with kRecordHandle set will be recorded in `handles` so that their
177 * reference counts can be verified by ResetHandles(). Initially they have two refs: the recorded one and the returned one.
179 static constexpr int kRecordHandle = 0x01;
180 static constexpr int kAllowHandleReuse = 0x02;
181 void PrepareTestBuffer(BufferConfiguration * config, int flags = 0);
184 * Checks and clears the recorded handles. Returns true if it detects no leaks or double frees.
185 * Called from `TerminateTest()`, but tests may choose to call it more often to verify reference counts.
189 TestContext * mContext;
190 std::vector<BufferConfiguration> configurations;
191 std::vector<PacketBufferHandle> handles;
194 const uint16_t sTestReservedSizes[] = { 0, 10, 128, 1536, PacketBufferTest::kBlockSize };
195 const uint16_t sTestLengths[] = { 0, 1, 10, 128, PacketBufferTest::kBlockSize, UINT16_MAX };
197 PacketBufferTest::TestContext sContext = {
199 sizeof(sTestReservedSizes) / sizeof(uint16_t),
201 sizeof(sTestLengths) / sizeof(uint16_t),
204 PacketBufferTest::PacketBufferTest(TestContext * context) : mContext(context)
206 // Set up the buffer configuration vector for this suite.
207 configurations.resize(0);
208 for (size_t i = 0; i < mContext->reserved_size_count; ++i)
210 configurations.emplace_back<BufferConfiguration>(mContext->reserved_sizes[i]);
214 int PacketBufferTest::TestSetup(void * inContext)
216 chip::Platform::MemoryInit();
217 TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
218 theContext->test = new PacketBufferTest(theContext);
219 if (theContext->test == nullptr)
226 int PacketBufferTest::TestTeardown(void * inContext)
231 int PacketBufferTest::TestInitialize(void * inContext)
233 TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
234 if (theContext->test == nullptr)
238 return theContext->test->InitializeTest(theContext);
241 int PacketBufferTest::InitializeTest(TestContext * context)
243 if (context != mContext)
250 int PacketBufferTest::TestTerminate(void * inContext)
252 TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
253 if (theContext->test == nullptr)
257 return theContext->test->TerminateTest(theContext);
260 int PacketBufferTest::TerminateTest(TestContext * context)
262 const bool context_ok = (context == mContext);
263 // Clear the configurations' bufffer handles.
264 for (size_t i = 0; i < configurations.size(); ++i)
266 configurations[i].handle = nullptr;
268 const bool handles_ok = ResetHandles();
269 return (context_ok && handles_ok) ? SUCCESS : FAILURE;
273 * Allocate memory for a test buffer and configure according to test buffer configuration.
275 void PacketBufferTest::PrepareTestBuffer(BufferConfiguration * config, int flags)
277 if (config->handle.IsNull())
279 config->handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
280 if (config->handle.IsNull())
282 printf("NewPacketBuffer: Failed to allocate packet buffer (%zu retained): %s\n", handles.size(), strerror(errno));
285 if (flags & kRecordHandle)
287 handles.push_back(config->handle.Retain());
290 else if ((flags & kAllowHandleReuse) == 0)
292 printf("Dirty test configuration\n");
296 const size_t lInitialSize = PacketBuffer::kStructureSize + config->reserved_size;
297 const size_t lAllocSize = kBlockSize;
299 uint8_t * const raw = reinterpret_cast<uint8_t *>(config->handle.Get());
300 memset(raw + PacketBuffer::kStructureSize, 0, lAllocSize - PacketBuffer::kStructureSize);
302 config->start_buffer = raw;
303 config->end_buffer = raw + lAllocSize;
305 if (lInitialSize > lAllocSize)
307 config->payload_ptr = config->end_buffer;
311 config->payload_ptr = config->start_buffer + lInitialSize;
314 if (config->handle->HasChainedBuffer())
316 // This should not happen.
317 PacketBuffer::Free(config->handle->ChainedBuffer());
318 config->handle->next = nullptr;
320 config->handle->payload = config->payload_ptr;
321 config->handle->len = config->init_len;
322 config->handle->tot_len = config->init_len;
325 bool PacketBufferTest::ResetHandles()
327 // Check against leaks or double-frees in tests: every handle obtained through
328 // PacketBufferTest::NewPacketBuffer should have a reference count of 1.
329 bool handles_ok = true;
330 for (size_t i = 0; i < handles.size(); ++i)
332 const PacketBufferHandle & handle = handles[i];
333 if (handle.Get() == nullptr)
335 printf("TestTerminate: handle %zu null\n", i);
338 else if (handle->ref != 1)
340 printf("TestTerminate: handle %zu buffer=%p ref=%u\n", i, handle.Get(), handle->ref);
342 while (handle->ref > 1)
344 PacketBuffer::Free(handle.Get());
352 // Test functions invoked from the suite.
355 * Test PacketBufferHandle::New() function.
357 * Description: For every buffer-configuration from inContext, create a buffer's instance
358 * using the New() method. Then, verify that when the size of the reserved space
359 * passed to New() is greater than PacketBuffer::kMaxSizeWithoutReserve,
360 * the method returns nullptr. Otherwise, check for correctness of initializing
361 * the new buffer's internal state.
363 void PacketBufferTest::CheckNew(nlTestSuite * inSuite, void * inContext)
365 TestContext * const theContext = static_cast<TestContext *>(inContext);
366 PacketBufferTest * const test = theContext->test;
367 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
369 for (const auto & config : test->configurations)
371 const PacketBufferHandle buffer = PacketBufferHandle::New(0, config.reserved_size);
373 if (config.reserved_size > PacketBuffer::kMaxSizeWithoutReserve)
375 NL_TEST_ASSERT(inSuite, buffer.IsNull());
379 NL_TEST_ASSERT(inSuite, config.reserved_size <= buffer->AllocSize());
380 NL_TEST_ASSERT(inSuite, !buffer.IsNull());
382 if (!buffer.IsNull())
384 const pbuf * const pb = TO_LWIP_PBUF(buffer.Get());
386 NL_TEST_ASSERT(inSuite, pb->len == 0);
387 NL_TEST_ASSERT(inSuite, pb->tot_len == 0);
388 NL_TEST_ASSERT(inSuite, pb->next == nullptr);
389 NL_TEST_ASSERT(inSuite, pb->ref == 1);
393 #if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE != 0
394 // Use the rest of the buffer space
395 std::vector<PacketBufferHandle> allocate_all_the_things;
398 PacketBufferHandle buffer = PacketBufferHandle::New(0, 0);
403 // Hold on to the buffer, to use up all the buffer space.
404 allocate_all_the_things.push_back(std::move(buffer));
406 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE != 0
410 * Test PacketBuffer::Start() function.
412 void PacketBufferTest::CheckStart(nlTestSuite * inSuite, void * inContext)
414 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
415 PacketBufferTest * const test = theContext->test;
416 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
418 for (auto & config : test->configurations)
420 test->PrepareTestBuffer(&config, kRecordHandle);
421 NL_TEST_ASSERT(inSuite, config.handle->Start() == config.payload_ptr);
426 * Test PacketBuffer::SetStart() function.
428 * Description: For every buffer-configuration from inContext, create a
429 * buffer's instance according to the configuration. Next,
430 * for any offset value from start_offset[], pass it to the
431 * buffer's instance through SetStart method. Then, verify that
432 * the beginning of the buffer has been correctly internally
433 * adjusted according to the offset value passed into the
436 void PacketBufferTest::CheckSetStart(nlTestSuite * inSuite, void * inContext)
438 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
439 PacketBufferTest * const test = theContext->test;
440 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
442 static constexpr ptrdiff_t sSizePacketBuffer = kBlockSize;
444 for (auto & config : test->configurations)
447 static constexpr ptrdiff_t start_offset[] =
459 for (ptrdiff_t offset : start_offset)
461 test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
462 uint8_t * const test_start = config.payload_ptr + offset;
463 uint8_t * verify_start = test_start;
465 config.handle->SetStart(test_start);
467 if (verify_start < config.start_buffer + PacketBuffer::kStructureSize)
469 // Set start before valid payload beginning.
470 verify_start = config.start_buffer + PacketBuffer::kStructureSize;
473 if (verify_start > config.end_buffer)
475 // Set start after valid payload beginning.
476 verify_start = config.end_buffer;
479 NL_TEST_ASSERT(inSuite, config.handle->payload == verify_start);
481 if ((verify_start - config.payload_ptr) > config.init_len)
483 // Set start to the beginning of payload, right after handle's header.
484 NL_TEST_ASSERT(inSuite, config.handle->len == 0);
488 // Set start to somewhere between the end of the handle's
489 // header and the end of payload.
490 NL_TEST_ASSERT(inSuite, config.handle->len == (config.init_len - (verify_start - config.payload_ptr)));
497 * Test PacketBuffer::DataLength() function.
499 void PacketBufferTest::CheckDataLength(nlTestSuite * inSuite, void * inContext)
501 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
502 PacketBufferTest * const test = theContext->test;
503 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
505 for (auto & config : test->configurations)
507 test->PrepareTestBuffer(&config, kRecordHandle);
509 NL_TEST_ASSERT(inSuite, config.handle->DataLength() == config.handle->len);
514 * Test PacketBuffer::SetDataLength() function.
516 * Description: Take two initial configurations of PacketBuffer from
517 * inContext and create two PacketBuffer instances based on those
518 * configurations. For any two buffers, call SetDataLength with
519 * different value from sLength[]. If two buffers are created with
520 * the same configuration, test SetDataLength on one buffer,
521 * without specifying the head of the buffer chain. Otherwise,
522 * test SetDataLength with one buffer being down the chain and the
523 * other one being passed as the head of the chain. After calling
524 * the method verify that data lenghts were correctly adjusted.
526 void PacketBufferTest::CheckSetDataLength(nlTestSuite * inSuite, void * inContext)
528 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
529 PacketBufferTest * const test = theContext->test;
530 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
532 for (auto & config_1 : test->configurations)
534 for (auto & config_2 : test->configurations)
536 for (size_t i = 0; i < theContext->length_count; ++i)
538 const uint16_t length = theContext->lengths[i];
539 test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
540 test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);
542 if (&config_1 == &config_2)
544 // headOfChain (the second arg) is NULL
545 config_2.handle->SetDataLength(length, nullptr);
547 if (length > (config_2.end_buffer - config_2.payload_ptr))
549 NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
550 NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
551 NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
555 NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
556 NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
557 NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
562 // headOfChain (the second arg) is config_1.handle
563 config_2.handle->SetDataLength(length, config_1.handle);
565 if (length > (config_2.end_buffer - config_2.payload_ptr))
567 NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
568 NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
569 NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
571 NL_TEST_ASSERT(inSuite,
572 config_1.handle->tot_len ==
573 (config_1.init_len + static_cast<int32_t>(config_2.end_buffer - config_2.payload_ptr) -
574 static_cast<int32_t>(config_2.init_len)));
578 NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
579 NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
580 NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
584 config_1.handle->tot_len ==
585 (config_1.init_len + static_cast<int32_t>(length) - static_cast<int32_t>(config_2.init_len)));
594 * Test PacketBuffer::TotalLength() function.
596 void PacketBufferTest::CheckTotalLength(nlTestSuite * inSuite, void * inContext)
598 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
599 PacketBufferTest * const test = theContext->test;
600 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
602 for (auto & config : test->configurations)
604 test->PrepareTestBuffer(&config, kRecordHandle);
605 NL_TEST_ASSERT(inSuite, config.handle->TotalLength() == config.init_len);
610 * Test PacketBuffer::MaxDataLength() function.
612 void PacketBufferTest::CheckMaxDataLength(nlTestSuite * inSuite, void * inContext)
614 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
615 PacketBufferTest * const test = theContext->test;
616 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
618 for (auto & config : test->configurations)
620 test->PrepareTestBuffer(&config, kRecordHandle);
622 NL_TEST_ASSERT(inSuite, config.handle->MaxDataLength() == (config.end_buffer - config.payload_ptr));
627 * Test PacketBuffer::AvailableDataLength() function.
629 void PacketBufferTest::CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext)
631 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
632 PacketBufferTest * const test = theContext->test;
633 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
635 for (auto & config : test->configurations)
637 test->PrepareTestBuffer(&config, kRecordHandle);
639 NL_TEST_ASSERT(inSuite,
640 config.handle->AvailableDataLength() == ((config.end_buffer - config.payload_ptr) - config.init_len));
645 * Test PacketBuffer::ReservedSize() function.
647 void PacketBufferTest::CheckReservedSize(nlTestSuite * inSuite, void * inContext)
649 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
650 PacketBufferTest * const test = theContext->test;
651 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
653 for (auto & config : test->configurations)
655 test->PrepareTestBuffer(&config, kRecordHandle);
656 const size_t kAllocSize = config.handle->AllocSize();
658 if (config.reserved_size > kAllocSize)
660 NL_TEST_ASSERT(inSuite, config.handle->ReservedSize() == kAllocSize);
664 NL_TEST_ASSERT(inSuite, config.handle->ReservedSize() == config.reserved_size);
670 * Test PacketBuffer::HasChainedBuffer() function.
672 void PacketBufferTest::CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext)
674 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
675 PacketBufferTest * const test = theContext->test;
676 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
678 for (auto & config_1 : test->configurations)
680 for (auto & config_2 : test->configurations)
682 if (&config_1 == &config_2)
687 test->PrepareTestBuffer(&config_1);
688 test->PrepareTestBuffer(&config_2);
690 NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == false);
691 NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);
693 config_1.handle->AddToEnd(config_2.handle.Retain());
694 NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == true);
695 NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);
697 config_1.handle = nullptr;
698 config_2.handle = nullptr;
704 * Test PacketBuffer::AddToEnd() function.
706 * Description: Take three initial configurations of PacketBuffer from
707 * inContext, create three PacketBuffers based on those
708 * configurations and then link those buffers together with
709 * PacketBuffer:AddToEnd(). Then, assert that after connecting
710 * buffers together, their internal states are correctly updated.
711 * This test function tests linking any combination of three
712 * buffer-configurations passed within inContext.
714 void PacketBufferTest::CheckAddToEnd(nlTestSuite * inSuite, void * inContext)
716 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
717 PacketBufferTest * const test = theContext->test;
718 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
720 for (auto & config_1 : test->configurations)
722 for (auto & config_2 : test->configurations)
724 for (auto & config_3 : test->configurations)
726 if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
731 test->PrepareTestBuffer(&config_1);
732 test->PrepareTestBuffer(&config_2);
733 test->PrepareTestBuffer(&config_3);
734 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
735 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
736 NL_TEST_ASSERT(inSuite, config_3.handle->ref == 1);
738 config_1.handle->AddToEnd(config_2.handle.Retain());
739 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1); // config_1.handle
740 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
741 NL_TEST_ASSERT(inSuite, config_3.handle->ref == 1); // config_3.handle
743 NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == (config_1.init_len + config_2.init_len));
744 NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
745 NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
746 NL_TEST_ASSERT(inSuite, config_3.handle->next == nullptr);
748 config_1.handle->AddToEnd(config_3.handle.Retain());
749 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1); // config_1.handle
750 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
751 NL_TEST_ASSERT(inSuite, config_3.handle->ref == 2); // config_3.handle and config_2.handle->next
753 NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == (config_1.init_len + config_2.init_len + config_3.init_len));
754 NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
755 NL_TEST_ASSERT(inSuite, config_2.handle->next == config_3.handle.Get());
756 NL_TEST_ASSERT(inSuite, config_3.handle->next == nullptr);
758 config_1.handle = nullptr;
759 config_2.handle = nullptr;
760 config_3.handle = nullptr;
767 * Test PacketBuffer::PopHead() function.
769 * Description: Take two initial configurations of PacketBuffer from
770 * inContext and create two PacketBuffer instances based on those
771 * configurations. Next, link those buffers together, with the first
772 * buffer instance pointing to the second one. Then, call PopHead()
773 * on the first buffer to unlink the second buffer. After the call,
774 * verify correct internal state of the first buffer.
776 void PacketBufferTest::CheckPopHead(nlTestSuite * inSuite, void * inContext)
778 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
779 PacketBufferTest * const test = theContext->test;
780 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
782 // Single buffer test.
783 for (auto & config_1 : test->configurations)
785 test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
786 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
788 const PacketBuffer * const buffer_1 = config_1.handle.mBuffer;
790 const PacketBufferHandle popped = config_1.handle.PopHead();
792 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
793 NL_TEST_ASSERT(inSuite, popped.mBuffer == buffer_1);
794 NL_TEST_ASSERT(inSuite, popped->next == nullptr);
795 NL_TEST_ASSERT(inSuite, popped->tot_len == config_1.init_len);
796 NL_TEST_ASSERT(inSuite, popped->ref == 2);
798 test->ResetHandles();
800 // Chained buffers test.
801 for (auto & config_1 : test->configurations)
803 for (auto & config_2 : test->configurations)
805 if (&config_1 == &config_2)
810 test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
811 test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);
813 config_1.handle->AddToEnd(config_2.handle.Retain());
815 const PacketBufferHandle popped = config_1.handle.PopHead();
817 NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
818 NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
819 NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == config_1.init_len);
825 * Test PacketBuffer::CompactHead() function.
827 * Description: Take two initial configurations of PacketBuffer from
828 * inContext and create two PacketBuffer instances based on those
829 * configurations. Next, set both buffers' data length to any
830 * combination of values from sLengths[] and link those buffers
831 * into a chain. Then, call CompactHead() on the first buffer in
832 * the chain. After calling the method, verify correctly adjusted
833 * state of the first buffer.
835 void PacketBufferTest::CheckCompactHead(nlTestSuite * inSuite, void * inContext)
837 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
838 PacketBufferTest * const test = theContext->test;
839 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
841 // Single buffer test.
842 for (auto & config : test->configurations)
844 for (size_t i = 0; i < theContext->length_count; ++i)
846 const uint16_t length = theContext->lengths[i];
848 test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
849 config.handle->SetDataLength(length, config.handle);
850 const uint16_t data_length = config.handle->DataLength();
852 config.handle->CompactHead();
854 NL_TEST_ASSERT(inSuite, config.handle->payload == (config.start_buffer + PacketBuffer::kStructureSize));
855 NL_TEST_ASSERT(inSuite, config.handle->tot_len == data_length);
858 config.handle = nullptr;
860 NL_TEST_ASSERT(inSuite, test->ResetHandles());
862 // Chained buffers test.
863 for (auto & config_1 : test->configurations)
865 for (auto & config_2 : test->configurations)
867 if (&config_1 == &config_2)
872 // start with various initial length for the first buffer
873 for (size_t i = 0; i < theContext->length_count; ++i)
875 const uint16_t length_1 = theContext->lengths[i];
877 // start with various initial length for the second buffer
878 for (size_t j = 0; j < theContext->length_count; ++j)
880 const uint16_t length_2 = theContext->lengths[j];
882 test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
883 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
885 // CompactHead requires that there be no other references to the chained buffer,
886 // so we manage it manually.
887 test->PrepareTestBuffer(&config_2);
888 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
889 PacketBuffer * buffer_2 = std::move(config_2.handle).UnsafeRelease();
890 NL_TEST_ASSERT(inSuite, config_2.handle.IsNull());
892 config_1.handle->SetDataLength(length_1, config_1.handle);
893 const uint16_t data_length_1 = config_1.handle->DataLength();
895 // This chain will cause buffer_2 to be freed.
896 config_1.handle->next = buffer_2;
898 // Add various lengths to the second buffer
899 buffer_2->SetDataLength(length_2, config_1.handle);
900 const uint16_t data_length_2 = buffer_2->DataLength();
902 config_1.handle->CompactHead();
904 NL_TEST_ASSERT(inSuite, config_1.handle->payload == (config_1.start_buffer + PacketBuffer::kStructureSize));
906 if (config_1.handle->tot_len > config_1.handle->MaxDataLength())
908 NL_TEST_ASSERT(inSuite, config_1.handle->len == config_1.handle->MaxDataLength());
909 NL_TEST_ASSERT(inSuite, buffer_2->len == config_1.handle->tot_len - config_1.handle->MaxDataLength());
910 NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
911 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
912 NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
916 NL_TEST_ASSERT(inSuite, config_1.handle->len == config_1.handle->tot_len);
917 if (data_length_1 >= config_1.handle->MaxDataLength() && data_length_2 == 0)
919 /* make sure the second buffer is not freed */
920 NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
921 NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
925 /* make sure the second buffer is freed */
926 NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
931 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
932 config_1.handle = nullptr;
934 // Verify and release handles.
935 NL_TEST_ASSERT(inSuite, test->ResetHandles());
943 * Test PacketBuffer::ConsumeHead() function.
945 * Description: For every buffer-configuration from inContext, create a
946 * buffer's instance according to the configuration. Next,
947 * for any value from sLengths[], pass it to the buffer's
948 * instance through ConsumeHead() method. Then, verify that
949 * the internal state of the buffer has been correctly
950 * adjusted according to the value passed into the method.
952 void PacketBufferTest::CheckConsumeHead(nlTestSuite * inSuite, void * inContext)
954 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
955 PacketBufferTest * const test = theContext->test;
956 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
958 for (auto & config : test->configurations)
960 for (size_t i = 0; i < theContext->length_count; ++i)
962 const uint16_t length = theContext->lengths[i];
963 test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
965 config.handle->ConsumeHead(length);
967 if (length > config.init_len)
969 NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + config.init_len));
970 NL_TEST_ASSERT(inSuite, config.handle->len == 0);
971 NL_TEST_ASSERT(inSuite, config.handle->tot_len == 0);
975 NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + length));
976 NL_TEST_ASSERT(inSuite, config.handle->len == (config.handle->len - length));
977 NL_TEST_ASSERT(inSuite, config.handle->tot_len == (config.handle->tot_len - length));
984 * Test PacketBuffer::Consume() function.
986 * Description: Take two different initial configurations of PacketBuffer from
987 * inContext and create two PacketBuffer instances based on those
988 * configurations. Next, set both buffers' data length to any
989 * combination of values from sLengths[] and link those buffers
990 * into a chain. Then, call Consume() on the first buffer in
991 * the chain with all values from sLengths[]. After calling the
992 * method, verify correctly adjusted the state of the first
993 * buffer and appropriate return pointer from the method's call.
995 void PacketBufferTest::CheckConsume(nlTestSuite * inSuite, void * inContext)
997 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
998 PacketBufferTest * const test = theContext->test;
999 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1001 for (auto & config_1 : test->configurations)
1003 for (auto & config_2 : test->configurations)
1005 if (&config_1 == &config_2)
1010 // consume various amounts of memory
1011 for (size_t i = 0; i < theContext->length_count; ++i)
1013 const uint16_t consumeLength = theContext->lengths[i];
1014 // start with various initial length for the first buffer
1015 for (size_t j = 0; j < theContext->length_count; ++j)
1017 const uint16_t len_1 = theContext->lengths[j];
1018 // start with various initial length for the second buffer
1019 for (size_t k = 0; k < theContext->length_count; ++k)
1021 const uint16_t len_2 = theContext->lengths[k];
1023 test->PrepareTestBuffer(&config_1);
1024 test->PrepareTestBuffer(&config_2);
1025 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
1026 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
1028 config_1.handle->AddToEnd(config_2.handle.Retain());
1030 // Add various lengths to buffers
1031 config_1.handle->SetDataLength(len_1, config_1.handle);
1032 config_2.handle->SetDataLength(len_2, config_1.handle);
1034 const uint16_t buf_1_len = config_1.handle->len;
1035 const uint16_t buf_2_len = config_2.handle->len;
1037 PacketBufferHandle original_handle_1 = config_1.handle.Retain();
1038 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
1039 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
1041 config_1.handle.Consume(consumeLength);
1043 if (consumeLength == 0)
1045 NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
1046 NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len);
1047 NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
1048 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
1049 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
1051 else if (consumeLength < buf_1_len)
1053 NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
1054 NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len - consumeLength);
1055 NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
1056 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
1057 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
1059 else if ((consumeLength < buf_1_len + buf_2_len ||
1060 (consumeLength == buf_1_len + buf_2_len && buf_2_len == 0)))
1062 NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
1063 NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_1_len + buf_2_len - consumeLength);
1064 NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
1065 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_1.handle and config_2.handle
1069 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1070 NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
1071 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1); // config_2.handle
1074 original_handle_1 = nullptr;
1075 config_1.handle = nullptr;
1076 config_2.handle = nullptr;
1085 * Test PacketBuffer::EnsureReservedSize() function.
1087 * Description: For every buffer-configuration from inContext, create a
1088 * buffer's instance according to the configuration. Next,
1089 * manually specify how much space is reserved in the buffer.
1090 * Then, verify that EnsureReservedSize() method correctly
1091 * retrieves the amount of the reserved space.
1093 void PacketBufferTest::CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext)
1095 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1096 PacketBufferTest * const test = theContext->test;
1097 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1099 for (auto & config : test->configurations)
1101 for (size_t i = 0; i < theContext->length_count; ++i)
1103 const uint16_t length = theContext->lengths[i];
1105 test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
1106 const uint16_t kAllocSize = config.handle->AllocSize();
1107 uint16_t reserved_size = config.reserved_size;
1109 if (PacketBuffer::kStructureSize + config.reserved_size > kAllocSize)
1111 reserved_size = static_cast<uint16_t>(kAllocSize - PacketBuffer::kStructureSize);
1114 if (length <= reserved_size)
1116 NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == true);
1120 if ((length + config.init_len) > (kAllocSize - PacketBuffer::kStructureSize))
1122 NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == false);
1126 NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == true);
1127 NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + length - reserved_size));
1133 * Test PacketBuffer::AlignPayload() function.
1135 * Description: For every buffer-configuration from inContext, create a
1136 * buffer's instance according to the configuration. Next,
1137 * manually specify how much space is reserved and the
1138 * required payload shift. Then, verify that AlignPayload()
1139 * method correctly aligns the payload start pointer.
1141 void PacketBufferTest::CheckAlignPayload(nlTestSuite * inSuite, void * inContext)
1143 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1144 PacketBufferTest * const test = theContext->test;
1145 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1147 for (auto & config : test->configurations)
1149 for (size_t n = 0; n < theContext->length_count; ++n)
1151 test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
1152 const uint16_t kAllocSize = config.handle->AllocSize();
1154 if (theContext->lengths[n] == 0)
1156 NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
1160 uint16_t reserved_size = config.reserved_size;
1161 if (config.reserved_size > kAllocSize)
1163 reserved_size = kAllocSize;
1166 const uint16_t payload_offset =
1167 static_cast<uint16_t>(reinterpret_cast<uintptr_t>(config.handle->Start()) % theContext->lengths[n]);
1168 uint16_t payload_shift = 0;
1169 if (payload_offset > 0)
1170 payload_shift = static_cast<uint16_t>(theContext->lengths[n] - payload_offset);
1172 if (payload_shift <= kAllocSize - reserved_size)
1174 NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == true);
1175 NL_TEST_ASSERT(inSuite, ((unsigned long) config.handle->Start() % theContext->lengths[n]) == 0);
1179 NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
1186 * Test PacketBuffer::Next() function.
1188 void PacketBufferTest::CheckNext(nlTestSuite * inSuite, void * inContext)
1190 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1191 PacketBufferTest * const test = theContext->test;
1192 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1194 for (auto & config_1 : test->configurations)
1196 for (auto & config_2 : test->configurations)
1198 test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
1199 test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);
1201 if (&config_1 != &config_2)
1203 NL_TEST_ASSERT(inSuite, config_1.handle->Next().IsNull());
1205 config_1.handle->AddToEnd(config_2.handle.Retain());
1207 NL_TEST_ASSERT(inSuite, config_1.handle->Next() == config_2.handle);
1208 NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
1212 NL_TEST_ASSERT(inSuite, !config_1.handle->HasChainedBuffer());
1215 NL_TEST_ASSERT(inSuite, !config_2.handle->HasChainedBuffer());
1221 * Test PacketBuffer::Last() function.
1223 void PacketBufferTest::CheckLast(nlTestSuite * inSuite, void * inContext)
1225 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1226 PacketBufferTest * const test = theContext->test;
1227 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1229 for (auto & config_1 : test->configurations)
1231 for (auto & config_2 : test->configurations)
1233 for (auto & config_3 : test->configurations)
1235 if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
1240 test->PrepareTestBuffer(&config_1);
1241 test->PrepareTestBuffer(&config_2);
1242 test->PrepareTestBuffer(&config_3);
1244 NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_1.handle);
1245 NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
1246 NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);
1248 config_1.handle->AddToEnd(config_2.handle.Retain());
1250 NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_2.handle);
1251 NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
1252 NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);
1254 config_1.handle->AddToEnd(config_3.handle.Retain());
1256 NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_3.handle);
1257 NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_3.handle);
1258 NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);
1260 config_1.handle = nullptr;
1261 config_2.handle = nullptr;
1262 config_3.handle = nullptr;
1269 * Test PacketBuffer::Read() function.
1271 void PacketBufferTest::CheckRead(nlTestSuite * inSuite, void * inContext)
1273 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1274 PacketBufferTest * const test = theContext->test;
1275 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1277 uint8_t payloads[2 * kBlockSize] = { 1 };
1278 uint8_t result[2 * kBlockSize];
1279 for (size_t i = 1; i < sizeof(payloads); ++i)
1281 payloads[i] = static_cast<uint8_t>(random());
1284 for (auto & config_1 : test->configurations)
1286 for (auto & config_2 : test->configurations)
1288 if (&config_1 == &config_2)
1293 test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
1294 test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
1296 const uint16_t length_1 = config_1.handle->MaxDataLength();
1297 const uint16_t length_2 = config_2.handle->MaxDataLength();
1298 const size_t length_sum = length_1 + length_2;
1299 const uint16_t length_total = static_cast<uint16_t>(length_sum);
1300 NL_TEST_ASSERT(inSuite, length_total == length_sum);
1302 memcpy(config_1.handle->Start(), payloads, length_1);
1303 memcpy(config_2.handle->Start(), payloads + length_1, length_2);
1304 config_1.handle->SetDataLength(length_1);
1305 config_2.handle->SetDataLength(length_2);
1306 config_1.handle->AddToEnd(config_2.handle.Retain());
1307 NL_TEST_ASSERT(inSuite, config_1.handle->TotalLength() == length_total);
1311 // Check a read that does not span packet buffers.
1312 CHIP_ERROR err = config_1.handle->Read(result, 1);
1313 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1314 NL_TEST_ASSERT(inSuite, result[0] == payloads[0]);
1317 // Check a read that spans packet buffers.
1318 CHIP_ERROR err = config_1.handle->Read(result, length_total);
1319 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1320 NL_TEST_ASSERT(inSuite, memcmp(payloads, result, length_total) == 0);
1322 // Check a read that is too long fails.
1323 err = config_1.handle->Read(result, length_total + 1);
1324 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
1326 // Check that running off the end of a corrupt buffer chain is detected.
1327 if (length_total < UINT16_MAX)
1329 // First case: TotalLength() is wrong.
1330 config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len + 1);
1331 err = config_1.handle->Read(result, length_total + 1);
1332 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INTERNAL);
1333 config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len - 1);
1337 // Second case: an individual buffer's DataLength() is wrong.
1338 config_1.handle->len = static_cast<uint16_t>(config_1.handle->len - 1);
1339 err = config_1.handle->Read(result, length_total);
1340 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INTERNAL);
1341 config_1.handle->len = static_cast<uint16_t>(config_1.handle->len + 1);
1344 config_1.handle = nullptr;
1345 config_2.handle = nullptr;
1351 * Test PacketBuffer::AddRef() function.
1353 void PacketBufferTest::CheckAddRef(nlTestSuite * inSuite, void * inContext)
1355 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1356 PacketBufferTest * const test = theContext->test;
1357 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1359 for (auto & config : test->configurations)
1361 test->PrepareTestBuffer(&config, kRecordHandle);
1362 const auto refs = config.handle->ref;
1363 config.handle->AddRef();
1364 NL_TEST_ASSERT(inSuite, config.handle->ref == refs + 1);
1365 config.handle->ref = refs; // Don't leak buffers.
1370 * Test PacketBuffer::Free() function.
1372 * Description: Take two different initial configurations of PacketBuffer from
1373 * inContext and create two PacketBuffer instances based on those
1374 * configurations. Next, chain two buffers together and set each
1375 * buffer's reference count to one of the values from
1376 * init_ret_count[]. Then, call Free() on the first buffer in
1377 * the chain and verify correctly adjusted states of the two
1380 void PacketBufferTest::CheckFree(nlTestSuite * inSuite, void * inContext)
1382 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1383 PacketBufferTest * const test = theContext->test;
1384 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1386 const decltype(PacketBuffer::ref) init_ref_count[] = { 1, 2, 3 };
1387 constexpr size_t kRefs = sizeof(init_ref_count) / sizeof(init_ref_count[0]);
1389 for (auto & config_1 : test->configurations)
1391 for (auto & config_2 : test->configurations)
1393 if (&config_1 == &config_2)
1398 // start with various buffer ref counts
1399 for (size_t r = 0; r < kRefs; r++)
1401 config_1.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
1402 config_2.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
1403 NL_TEST_ASSERT(inSuite, !config_1.handle.IsNull());
1404 NL_TEST_ASSERT(inSuite, !config_2.handle.IsNull());
1406 test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
1407 test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
1408 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
1409 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
1412 config_1.handle->next = config_2.handle.Get();
1414 // Add various buffer ref counts.
1415 const auto initial_refs_1 = config_1.handle->ref = init_ref_count[r];
1416 const auto initial_refs_2 = config_2.handle->ref = init_ref_count[(r + 1) % kRefs];
1419 PacketBuffer::Free(config_1.handle.mBuffer);
1420 if (initial_refs_1 == 1)
1422 config_1.handle.mBuffer = nullptr;
1426 if (initial_refs_1 > 1)
1428 // Verify that head ref count is decremented.
1429 NL_TEST_ASSERT(inSuite, config_1.handle->ref == initial_refs_1 - 1);
1430 // Verify that chain is maintained.
1431 NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
1432 // Verify that chained buffer ref count has not changed.
1433 NL_TEST_ASSERT(inSuite, config_2.handle->ref == initial_refs_2);
1437 if (initial_refs_2 > 1)
1439 // Verify that chained buffer ref count is decremented.
1440 NL_TEST_ASSERT(inSuite, config_2.handle->ref == initial_refs_2 - 1);
1444 // Since the test used fake ref counts, config_2.handle now points
1445 // to a freed buffer; clear the handle's internal pointer.
1446 config_2.handle.mBuffer = nullptr;
1451 if (!config_1.handle.IsNull())
1453 config_1.handle->next = nullptr;
1454 config_1.handle->ref = 1;
1455 config_1.handle = nullptr;
1457 if (!config_2.handle.IsNull())
1459 config_2.handle->ref = 1;
1460 config_2.handle = nullptr;
1468 * Test PacketBuffer::FreeHead() function.
1470 * Description: Take two different initial configurations of PacketBuffer from
1471 * inContext and create two PacketBuffer instances based on those
1472 * configurations. Next, chain two buffers together. Then, call
1473 * FreeHead() on the first buffer in the chain and verify that
1474 * the method returned pointer to the second buffer.
1476 void PacketBufferTest::CheckFreeHead(nlTestSuite * inSuite, void * inContext)
1478 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1479 PacketBufferTest * const test = theContext->test;
1480 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1482 for (auto & config_1 : test->configurations)
1484 for (auto & config_2 : test->configurations)
1486 if (&config_1 == &config_2)
1491 // Test PacketBuffer::FreeHead
1493 test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
1494 test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
1495 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
1496 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
1498 PacketBufferHandle handle_1 = config_1.handle.Retain();
1499 config_1.handle->AddToEnd(config_2.handle.Retain());
1500 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
1501 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
1503 PacketBuffer * const returned = PacketBuffer::FreeHead(std::move(config_1.handle).UnsafeRelease());
1505 NL_TEST_ASSERT(inSuite, handle_1->ref == 1);
1506 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and returned
1507 NL_TEST_ASSERT(inSuite, returned == config_2.handle.Get());
1509 config_1.handle = nullptr;
1510 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2);
1511 config_2.handle = nullptr;
1512 NL_TEST_ASSERT(inSuite, returned->ref == 1);
1513 PacketBuffer::Free(returned);
1515 // Test PacketBufferHandle::FreeHead
1517 test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
1518 test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
1519 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
1520 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
1522 handle_1 = config_1.handle.Retain();
1523 config_1.handle->AddToEnd(config_2.handle.Retain());
1524 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
1525 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
1527 PacketBuffer * const buffer_1 = config_1.handle.Get();
1529 config_1.handle.FreeHead();
1531 NL_TEST_ASSERT(inSuite, buffer_1->ref == 1);
1532 NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
1533 NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle
1535 config_1.handle = nullptr;
1536 config_2.handle = nullptr;
1541 void PacketBufferTest::CheckHandleConstruct(nlTestSuite * inSuite, void * inContext)
1543 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1544 PacketBufferTest * const test = theContext->test;
1545 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1547 PacketBufferHandle handle_1;
1548 NL_TEST_ASSERT(inSuite, handle_1.IsNull());
1550 PacketBufferHandle handle_2(nullptr);
1551 NL_TEST_ASSERT(inSuite, handle_2.IsNull());
1553 PacketBufferHandle handle_3(PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
1554 NL_TEST_ASSERT(inSuite, !handle_3.IsNull());
1556 // Private constructor.
1557 PacketBuffer * const buffer_3 = std::move(handle_3).UnsafeRelease();
1558 PacketBufferHandle handle_4(buffer_3);
1559 NL_TEST_ASSERT(inSuite, handle_4.Get() == buffer_3);
1562 void PacketBufferTest::CheckHandleMove(nlTestSuite * inSuite, void * inContext)
1564 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1565 PacketBufferTest * const test = theContext->test;
1566 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1568 for (auto & config_1 : test->configurations)
1570 for (auto & config_2 : test->configurations)
1572 if (&config_1 == &config_2)
1577 test->PrepareTestBuffer(&config_1, kRecordHandle);
1578 test->PrepareTestBuffer(&config_2, kRecordHandle);
1580 const PacketBuffer * const buffer_1 = config_1.handle.Get();
1581 const PacketBuffer * const buffer_2 = config_2.handle.Get();
1582 NL_TEST_ASSERT(inSuite, buffer_1 != buffer_2);
1583 NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and config_1.handle
1584 NL_TEST_ASSERT(inSuite, buffer_2->ref == 2); // test.handles and config_2.handle
1586 config_1.handle = std::move(config_2.handle);
1587 NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_2);
1588 NL_TEST_ASSERT(inSuite, config_2.handle.Get() == nullptr);
1589 NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles
1590 NL_TEST_ASSERT(inSuite, buffer_2->ref == 2); // test.handles and config_1.handle
1592 config_1.handle = nullptr;
1594 // Verify and release handles.
1595 NL_TEST_ASSERT(inSuite, test->ResetHandles());
1599 void PacketBufferTest::CheckHandleRelease(nlTestSuite * inSuite, void * inContext)
1601 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1602 PacketBufferTest * const test = theContext->test;
1603 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1605 for (auto & config_1 : test->configurations)
1607 test->PrepareTestBuffer(&config_1);
1609 PacketBuffer * const buffer_1 = config_1.handle.Get();
1610 PacketBuffer * const taken_1 = std::move(config_1.handle).UnsafeRelease();
1612 NL_TEST_ASSERT(inSuite, buffer_1 == taken_1);
1613 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1614 NL_TEST_ASSERT(inSuite, buffer_1->ref == 1);
1615 PacketBuffer::Free(buffer_1);
1619 void PacketBufferTest::CheckHandleFree(nlTestSuite * inSuite, void * inContext)
1621 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1622 PacketBufferTest * const test = theContext->test;
1623 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1625 for (auto & config_1 : test->configurations)
1627 test->PrepareTestBuffer(&config_1, kRecordHandle);
1629 const PacketBuffer * const buffer_1 = config_1.handle.Get();
1630 NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and config_1.handle
1632 config_1.handle = nullptr;
1633 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1634 NL_TEST_ASSERT(inSuite, config_1.handle.Get() == nullptr);
1635 NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles only
1639 void PacketBufferTest::CheckHandleRetain(nlTestSuite * inSuite, void * inContext)
1641 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1642 PacketBufferTest * const test = theContext->test;
1643 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1645 for (auto & config_1 : test->configurations)
1647 test->PrepareTestBuffer(&config_1, kRecordHandle);
1649 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // test.handles and config_1.handle
1651 PacketBufferHandle handle_1 = config_1.handle.Retain();
1653 NL_TEST_ASSERT(inSuite, config_1.handle == handle_1);
1654 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 3); // test.handles and config_1.handle and handle_1
1658 void PacketBufferTest::CheckHandleAdopt(nlTestSuite * inSuite, void * inContext)
1660 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1661 PacketBufferTest * const test = theContext->test;
1662 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1664 for (auto & config_1 : test->configurations)
1666 test->PrepareTestBuffer(&config_1, kRecordHandle);
1667 PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();
1669 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1670 NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1
1672 config_1.handle = PacketBufferHandle::Adopt(buffer_1);
1673 NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_1);
1674 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // test.handles and config_1.handle
1676 config_1.handle = nullptr;
1677 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1678 NL_TEST_ASSERT(inSuite, buffer_1->ref == 1); // test.handles only
1682 void PacketBufferTest::CheckHandleHold(nlTestSuite * inSuite, void * inContext)
1684 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1685 PacketBufferTest * const test = theContext->test;
1686 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1688 for (auto & config_1 : test->configurations)
1690 test->PrepareTestBuffer(&config_1, kRecordHandle);
1691 PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();
1693 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1694 NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1
1696 config_1.handle = PacketBufferHandle::Hold(buffer_1);
1697 NL_TEST_ASSERT(inSuite, config_1.handle.Get() == buffer_1);
1698 NL_TEST_ASSERT(inSuite, config_1.handle->ref == 3); // test.handles and config_1.handle and buffer_1
1700 config_1.handle = nullptr;
1701 NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
1702 NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles only and buffer_1
1704 PacketBuffer::Free(buffer_1);
1708 void PacketBufferTest::CheckHandleAdvance(nlTestSuite * inSuite, void * inContext)
1710 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1711 PacketBufferTest * const test = theContext->test;
1712 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1714 for (auto & config_1 : test->configurations)
1716 for (auto & config_2 : test->configurations)
1718 for (auto & config_3 : test->configurations)
1720 if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
1725 test->PrepareTestBuffer(&config_1);
1726 test->PrepareTestBuffer(&config_2);
1727 test->PrepareTestBuffer(&config_3);
1729 PacketBufferHandle handle_1 = config_1.handle.Retain();
1730 PacketBufferHandle handle_2 = config_2.handle.Retain();
1731 PacketBufferHandle handle_3 = config_3.handle.Retain();
1733 config_1.handle->AddToEnd(config_2.handle.Retain());
1734 config_1.handle->AddToEnd(config_3.handle.Retain());
1736 NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
1737 NL_TEST_ASSERT(inSuite, config_2.handle->ChainedBuffer() == config_3.handle.Get());
1738 NL_TEST_ASSERT(inSuite, config_3.handle->HasChainedBuffer() == false);
1739 NL_TEST_ASSERT(inSuite, handle_1->ref == 2); // handle_1 and config_1.handle
1740 NL_TEST_ASSERT(inSuite, handle_2->ref == 3); // handle_2 and config_2.handle and config_1.handle->next
1741 NL_TEST_ASSERT(inSuite, handle_3->ref == 3); // handle_3 and config_3.handle and config_2.handle->next
1743 config_1.handle.Advance();
1745 NL_TEST_ASSERT(inSuite, config_1.handle == handle_2);
1746 NL_TEST_ASSERT(inSuite, handle_1->ref == 1); // handle_1 only
1747 NL_TEST_ASSERT(inSuite, handle_2->ref == 4); // handle_2, config_[12].handle, handle_1->next
1748 NL_TEST_ASSERT(inSuite, handle_3->ref == 3); // handle_3, config_3.handle, config_2.handle->next
1750 config_1.handle.Advance();
1752 NL_TEST_ASSERT(inSuite, config_1.handle == handle_3);
1753 NL_TEST_ASSERT(inSuite, handle_1->ref == 1); // handle_1 only
1754 NL_TEST_ASSERT(inSuite, handle_2->ref == 3); // handle_2, config_2.handle, handle_1->next
1755 NL_TEST_ASSERT(inSuite, handle_3->ref == 4); // handle_3, config_[13].handle, handle_2->next
1757 config_1.handle = nullptr;
1758 config_2.handle = nullptr;
1759 config_3.handle = nullptr;
1765 void PacketBufferTest::CheckHandleRightSize(nlTestSuite * inSuite, void * inContext)
1767 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1768 PacketBufferTest * const test = theContext->test;
1769 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1771 const char kPayload[] = "Joy!";
1772 PacketBufferHandle handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
1773 PacketBuffer * buffer = handle.mBuffer;
1775 memcpy(handle->Start(), kPayload, sizeof kPayload);
1776 buffer->SetDataLength(sizeof kPayload);
1777 NL_TEST_ASSERT(inSuite, handle->ref == 1);
1779 // RightSize should do nothing if there is another reference to the buffer.
1781 PacketBufferHandle anotherHandle = handle.Retain();
1783 NL_TEST_ASSERT(inSuite, handle.mBuffer == buffer);
1786 #if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHT_SIZE
1789 NL_TEST_ASSERT(inSuite, handle.mBuffer != buffer);
1790 NL_TEST_ASSERT(inSuite, handle->DataLength() == sizeof kPayload);
1791 NL_TEST_ASSERT(inSuite, memcmp(handle->Start(), kPayload, sizeof kPayload) == 0);
1793 #else // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHT_SIZE
1795 // For this configuration, RightSize() does nothing.
1797 NL_TEST_ASSERT(inSuite, handle.mBuffer == buffer);
1799 #endif // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHT_SIZE
1802 void PacketBufferTest::CheckHandleCloneData(nlTestSuite * inSuite, void * inContext)
1804 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1805 PacketBufferTest * const test = theContext->test;
1806 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1808 uint8_t lPayload[2 * PacketBuffer::kMaxSizeWithoutReserve];
1809 for (size_t i = 0; i < sizeof(lPayload); ++i)
1811 lPayload[i] = static_cast<uint8_t>(random());
1814 for (auto & config_1 : test->configurations)
1816 for (auto & config_2 : test->configurations)
1818 if (&config_1 == &config_2)
1823 test->PrepareTestBuffer(&config_1);
1824 test->PrepareTestBuffer(&config_2);
1826 const uint8_t * payload_1 = lPayload;
1827 memcpy(config_1.handle->Start(), payload_1, config_1.handle->MaxDataLength());
1828 config_1.handle->SetDataLength(config_1.handle->MaxDataLength());
1830 const uint8_t * payload_2 = lPayload + config_1.handle->MaxDataLength();
1831 memcpy(config_2.handle->Start(), payload_2, config_2.handle->MaxDataLength());
1832 config_2.handle->SetDataLength(config_2.handle->MaxDataLength());
1834 // Clone single buffer.
1835 PacketBufferHandle clone_1 = config_1.handle.CloneData();
1836 NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
1837 NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
1838 NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) == 0);
1839 if (clone_1->DataLength())
1841 // Verify that modifying the clone does not affect the original.
1842 ScrambleData(clone_1->Start(), clone_1->DataLength());
1843 NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
1844 NL_TEST_ASSERT(inSuite, memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()) == 0);
1847 // Clone buffer chain.
1848 config_1.handle->AddToEnd(config_2.handle.Retain());
1849 NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer());
1850 clone_1 = config_1.handle.CloneData();
1851 PacketBufferHandle clone_1_next = clone_1->Next();
1852 NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
1853 NL_TEST_ASSERT(inSuite, clone_1->HasChainedBuffer());
1854 NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
1855 NL_TEST_ASSERT(inSuite, clone_1->TotalLength() == config_1.handle->TotalLength());
1856 NL_TEST_ASSERT(inSuite, clone_1_next->DataLength() == config_2.handle->DataLength());
1857 NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) == 0);
1858 NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) == 0);
1859 if (clone_1->DataLength())
1861 ScrambleData(clone_1->Start(), clone_1->DataLength());
1862 NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
1863 NL_TEST_ASSERT(inSuite, memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()) == 0);
1865 if (clone_1_next->DataLength())
1867 ScrambleData(clone_1_next->Start(), clone_1_next->DataLength());
1868 NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) != 0);
1869 NL_TEST_ASSERT(inSuite, memcmp(config_2.handle->Start(), payload_2, config_2.handle->DataLength()) == 0);
1872 config_1.handle = nullptr;
1873 config_2.handle = nullptr;
1878 void PacketBufferTest::CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext)
1880 struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
1881 PacketBufferTest * const test = theContext->test;
1882 NL_TEST_ASSERT(inSuite, test->mContext == theContext);
1884 const char kPayload[] = "Hello, world!";
1886 PacketBufferWriter yay(PacketBufferHandle::New(sizeof(kPayload)));
1887 PacketBufferWriter nay(PacketBufferHandle::New(sizeof(kPayload)), sizeof(kPayload) - 2);
1888 NL_TEST_ASSERT(inSuite, !yay.IsNull());
1889 NL_TEST_ASSERT(inSuite, !nay.IsNull());
1895 NL_TEST_ASSERT(inSuite, yay.Fit());
1896 NL_TEST_ASSERT(inSuite, !nay.Fit());
1898 PacketBufferHandle yayBuffer = yay.Finalize();
1899 PacketBufferHandle nayBuffer = nay.Finalize();
1900 NL_TEST_ASSERT(inSuite, yay.IsNull());
1901 NL_TEST_ASSERT(inSuite, nay.IsNull());
1902 NL_TEST_ASSERT(inSuite, !yayBuffer.IsNull());
1903 NL_TEST_ASSERT(inSuite, nayBuffer.IsNull());
1904 NL_TEST_ASSERT(inSuite, memcmp(yayBuffer->Start(), kPayload, sizeof kPayload) == 0);
1908 * Test Suite. It lists all the test functions.
1911 const nlTest sTests[] =
1913 NL_TEST_DEF("PacketBuffer::New", PacketBufferTest::CheckNew),
1914 NL_TEST_DEF("PacketBuffer::Start", PacketBufferTest::CheckStart),
1915 NL_TEST_DEF("PacketBuffer::SetStart", PacketBufferTest::CheckSetStart),
1916 NL_TEST_DEF("PacketBuffer::DataLength", PacketBufferTest::CheckDataLength),
1917 NL_TEST_DEF("PacketBuffer::SetDataLength", PacketBufferTest::CheckSetDataLength),
1918 NL_TEST_DEF("PacketBuffer::TotalLength", PacketBufferTest::CheckTotalLength),
1919 NL_TEST_DEF("PacketBuffer::MaxDataLength", PacketBufferTest::CheckMaxDataLength),
1920 NL_TEST_DEF("PacketBuffer::AvailableDataLength", PacketBufferTest::CheckAvailableDataLength),
1921 NL_TEST_DEF("PacketBuffer::HasChainedBuffer", PacketBufferTest::CheckHasChainedBuffer),
1922 NL_TEST_DEF("PacketBuffer::ReservedSize", PacketBufferTest::CheckReservedSize),
1923 NL_TEST_DEF("PacketBuffer::AddToEnd", PacketBufferTest::CheckAddToEnd),
1924 NL_TEST_DEF("PacketBuffer::PopHead", PacketBufferTest::CheckPopHead),
1925 NL_TEST_DEF("PacketBuffer::CompactHead", PacketBufferTest::CheckCompactHead),
1926 NL_TEST_DEF("PacketBuffer::ConsumeHead", PacketBufferTest::CheckConsumeHead),
1927 NL_TEST_DEF("PacketBuffer::Consume", PacketBufferTest::CheckConsume),
1928 NL_TEST_DEF("PacketBuffer::EnsureReservedSize", PacketBufferTest::CheckEnsureReservedSize),
1929 NL_TEST_DEF("PacketBuffer::AlignPayload", PacketBufferTest::CheckAlignPayload),
1930 NL_TEST_DEF("PacketBuffer::Next", PacketBufferTest::CheckNext),
1931 NL_TEST_DEF("PacketBuffer::Last", PacketBufferTest::CheckLast),
1932 NL_TEST_DEF("PacketBuffer::Read", PacketBufferTest::CheckRead),
1933 NL_TEST_DEF("PacketBuffer::AddRef", PacketBufferTest::CheckAddRef),
1934 NL_TEST_DEF("PacketBuffer::Free", PacketBufferTest::CheckFree),
1935 NL_TEST_DEF("PacketBuffer::FreeHead", PacketBufferTest::CheckFreeHead),
1936 NL_TEST_DEF("PacketBuffer::HandleConstruct", PacketBufferTest::CheckHandleConstruct),
1937 NL_TEST_DEF("PacketBuffer::HandleMove", PacketBufferTest::CheckHandleMove),
1938 NL_TEST_DEF("PacketBuffer::HandleRelease", PacketBufferTest::CheckHandleRelease),
1939 NL_TEST_DEF("PacketBuffer::HandleFree", PacketBufferTest::CheckHandleFree),
1940 NL_TEST_DEF("PacketBuffer::HandleRetain", PacketBufferTest::CheckHandleRetain),
1941 NL_TEST_DEF("PacketBuffer::HandleAdopt", PacketBufferTest::CheckHandleAdopt),
1942 NL_TEST_DEF("PacketBuffer::HandleHold", PacketBufferTest::CheckHandleHold),
1943 NL_TEST_DEF("PacketBuffer::HandleAdvance", PacketBufferTest::CheckHandleAdvance),
1944 NL_TEST_DEF("PacketBuffer::HandleRightSize", PacketBufferTest::CheckHandleRightSize),
1945 NL_TEST_DEF("PacketBuffer::HandleCloneData", PacketBufferTest::CheckHandleCloneData),
1946 NL_TEST_DEF("PacketBuffer::PacketBufferWriter", PacketBufferTest::CheckPacketBufferWriter),
1952 int TestSystemPacketBuffer(void)
1955 nlTestSuite theSuite = {
1956 .name ="chip-system-packetbuffer",
1957 .tests = &sTests[0],
1958 .setup = PacketBufferTest::TestSetup,
1959 .tear_down = PacketBufferTest::TestTeardown,
1960 // .initialize = PacketBufferTest::TestInitialize,
1961 .terminate = PacketBufferTest::TestTerminate
1965 // Run test suit againt one context.
1966 nlTestRunner(&theSuite, &sContext);
1968 return (nlTestRunnerStats(&theSuite));
1971 CHIP_REGISTER_TEST_SUITE(TestSystemPacketBuffer)