/
githubmirror
/
nghttp2
Обзор
Документация
Войти
/
githubmirror
/
nghttp2
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/memchunk_test.cc
354 строки
8 KB
Tatsuhiro Tsujikawa
Adopt Designated initializers part3
22 апр 2026, 13:13
22 апр 2026, 13:13
734d41f
Код
Авторство
О чём код?
/* * nghttp2 - HTTP/2 C Library * * Copyright (c) 2015 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "memchunk_test.h" #include "munitxx.h" #include <nghttp2/nghttp2.h> #include "memchunk.h" #include "util.h" using namespace std::literals; namespace nghttp2 { namespace { const MunitTest tests[]{ munit_void_test(test_pool_recycle), munit_void_test(test_memchunks_append), munit_void_test(test_memchunks_drain), munit_void_test(test_memchunks_remove), munit_void_test(test_memchunks_riovec), munit_void_test(test_memchunks_peek), munit_void_test(test_memchunks_recycle), munit_void_test(test_memchunks_reset), munit_void_test(test_memchunks_reserve), munit_void_test(test_memchunkbuffer_drain_reset), munit_void_test(test_memchunkbuffer_peek), munit_test_end(), }; } // namespace const MunitSuite memchunk_suite{ .prefix = "/memchunk", .tests = tests, }; void test_pool_recycle(void) { MemchunkPool pool; assert_null(pool.pool); assert_size(0, ==, pool.poolsize); assert_null(pool.freelist); auto m1 = pool.get(); assert_ptr_equal(m1, pool.pool); assert_size(MemchunkPool::value_type::size, ==, pool.poolsize); assert_null(pool.freelist); auto m2 = pool.get(); assert_ptr_equal(m2, pool.pool); assert_size(2 * MemchunkPool::value_type::size, ==, pool.poolsize); assert_null(pool.freelist); assert_ptr_equal(m1, m2->knext); assert_null(m1->knext); auto m3 = pool.get(); assert_ptr_equal(m3, pool.pool); assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize); assert_null(pool.freelist); pool.recycle(m3); assert_ptr_equal(m3, pool.pool); assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize); assert_ptr_equal(m3, pool.freelist); auto m4 = pool.get(); assert_ptr_equal(m3, m4); assert_ptr_equal(m4, pool.pool); assert_size(3 * MemchunkPool::value_type::size, ==, pool.poolsize); assert_null(pool.freelist); pool.recycle(m2); pool.recycle(m1); assert_ptr_equal(m1, pool.freelist); assert_ptr_equal(m2, m1->next); assert_null(m2->next); } using Memchunk16 = Memchunk<16>; using MemchunkPool16 = Pool<Memchunk16>; using Memchunks16 = Memchunks<Memchunk16>; using MemchunkBuffer16 = MemchunkBuffer<Memchunk16>; void test_memchunks_append(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); chunks.append("012"sv); auto m = chunks.tail; assert_size(3, ==, m->len()); assert_size(13, ==, m->left()); chunks.append("3456789abcdef@"sv); assert_size(16, ==, m->len()); assert_size(0, ==, m->left()); m = chunks.tail; assert_size(1, ==, m->len()); assert_size(15, ==, m->left()); assert_size(17, ==, chunks.rleft()); std::array<uint8_t, 16> buf; size_t nread; nread = chunks.remove(std::span{buf}.first(8)); assert_size(8, ==, nread); assert_memory_equal(nread, "01234567", buf.data()); assert_size(9, ==, chunks.rleft()); nread = chunks.remove(buf); assert_size(9, ==, nread); assert_memory_equal(nread, "89abcdef@", buf.data()); assert_size(0, ==, chunks.rleft()); assert_null(chunks.head); assert_null(chunks.tail); assert_size(32, ==, pool.poolsize); } void test_memchunks_drain(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); chunks.append("0123456789"sv); size_t nread; nread = chunks.drain(3); assert_size(3, ==, nread); std::array<uint8_t, 16> buf; nread = chunks.remove(buf); assert_size(7, ==, nread); assert_memory_equal(nread, "3456789", buf.data()); } void test_memchunks_remove(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); chunks.append("0123456789"sv); std::array<uint8_t, 16> buf; auto nread = chunks.remove(std::span{buf}.first(1)); assert_size(1, ==, nread); assert_memory_equal(nread, "0", buf.data()); nread = chunks.remove(buf); assert_size(9, ==, nread); assert_memory_equal(nread, "123456789", buf.data()); } void test_memchunks_riovec(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); std::array<char, 3 * 16> buf{}; chunks.append(buf.data(), buf.size()); std::array<struct iovec, 2> iovbuf; auto iov = chunks.riovec(iovbuf); auto m = chunks.head; assert_size(2, ==, iov.size()); assert_ptr_equal(m->buf.data(), iov[0].iov_base); assert_size(m->len(), ==, iov[0].iov_len); m = m->next; assert_ptr_equal(m->buf.data(), iov[1].iov_base); assert_size(m->len(), ==, iov[1].iov_len); chunks.drain(2 * 16); iov = chunks.riovec(iovbuf); assert_size(1, ==, iov.size()); m = chunks.head; assert_ptr_equal(m->buf.data(), iov[0].iov_base); assert_size(m->len(), ==, iov[0].iov_len); } void test_memchunks_peek(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); assert_true(chunks.peek().empty()); std::array<char, 3 * 16> buf{}; chunks.append(buf.data(), buf.size()); auto data = chunks.peek(); auto m = chunks.head; assert_ptr_equal(m->buf.data(), data.data()); assert_size(m->len(), ==, data.size()); } void test_memchunks_recycle(void) { MemchunkPool16 pool; { Memchunks16 chunks(&pool); std::array<char, 32> buf{}; chunks.append(buf.data(), buf.size()); } assert_size(32, ==, pool.poolsize); assert_not_null(pool.freelist); auto m = pool.freelist; m = m->next; assert_not_null(m); assert_null(m->next); } void test_memchunks_reset(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); std::array<uint8_t, 32> b{}; chunks.append(b.data(), b.size()); assert_size(32, ==, chunks.rleft()); chunks.reset(); assert_size(0, ==, chunks.rleft()); assert_null(chunks.head); assert_null(chunks.tail); auto m = pool.freelist; assert_not_null(m); assert_not_null(m->next); assert_null(m->next->next); } void test_memchunks_reserve(void) { MemchunkPool16 pool; Memchunks16 chunks(&pool); std::array<iovec, 2> iovbuf; chunks.append(8, [](auto result) { return std::ranges::copy("foobar00"sv, std::move(result)).out; }); assert_size(8, ==, chunks.rleft()); auto iov = chunks.riovec(iovbuf); assert_size(1, ==, iov.size()); assert_stdsv_equal( "foobar00"sv, (std::string_view{reinterpret_cast<const char *>(iov[0].iov_base), iov[0].iov_len})); chunks.reset(); chunks.append("012345678"sv); chunks.append(8, [](auto result) { return std::ranges::copy("foobar00"sv, std::move(result)).out; }); assert_size(17, ==, chunks.rleft()); iov = chunks.riovec(iovbuf); assert_size(2, ==, iov.size()); assert_stdsv_equal( "012345678"sv, (std::string_view{reinterpret_cast<const char *>(iov[0].iov_base), iov[0].iov_len})); assert_stdsv_equal( "foobar00"sv, (std::string_view{reinterpret_cast<const char *>(iov[1].iov_base), iov[1].iov_len})); } void test_memchunkbuffer_drain_reset(void) { MemchunkPool16 pool; MemchunkBuffer16 buf(&pool); buf.ensure_chunk(); auto data = "0123456789"sv; std::ranges::copy(data, buf.begin()); buf.write(data.size()); auto nread = buf.drain_reset(3); assert_size(3, ==, nread); assert_true(buf.begin() == buf.chunk->pos); assert_size(7, ==, buf.rleft()); assert_true(buf.begin() + buf.rleft() == buf.chunk->last); } void test_memchunkbuffer_peek(void) { MemchunkPool16 pool; MemchunkBuffer16 buf(&pool); buf.ensure_chunk(); auto data = "0123456789"sv; std::ranges::copy(data, buf.begin()); buf.write(data.size()); assert_stdsv_equal(data, as_string_view(buf.peek())); } } // namespace nghttp2