12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2015 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#include "memchunk_test.h" 262c593315Sopenharmony_ci 272c593315Sopenharmony_ci#include <CUnit/CUnit.h> 282c593315Sopenharmony_ci 292c593315Sopenharmony_ci#include <nghttp2/nghttp2.h> 302c593315Sopenharmony_ci 312c593315Sopenharmony_ci#include "memchunk.h" 322c593315Sopenharmony_ci#include "util.h" 332c593315Sopenharmony_ci 342c593315Sopenharmony_cinamespace nghttp2 { 352c593315Sopenharmony_ci 362c593315Sopenharmony_civoid test_pool_recycle(void) { 372c593315Sopenharmony_ci MemchunkPool pool; 382c593315Sopenharmony_ci 392c593315Sopenharmony_ci CU_ASSERT(!pool.pool); 402c593315Sopenharmony_ci CU_ASSERT(0 == pool.poolsize); 412c593315Sopenharmony_ci CU_ASSERT(nullptr == pool.freelist); 422c593315Sopenharmony_ci 432c593315Sopenharmony_ci auto m1 = pool.get(); 442c593315Sopenharmony_ci 452c593315Sopenharmony_ci CU_ASSERT(m1 == pool.pool); 462c593315Sopenharmony_ci CU_ASSERT(MemchunkPool::value_type::size == pool.poolsize); 472c593315Sopenharmony_ci CU_ASSERT(nullptr == pool.freelist); 482c593315Sopenharmony_ci 492c593315Sopenharmony_ci auto m2 = pool.get(); 502c593315Sopenharmony_ci 512c593315Sopenharmony_ci CU_ASSERT(m2 == pool.pool); 522c593315Sopenharmony_ci CU_ASSERT(2 * MemchunkPool::value_type::size == pool.poolsize); 532c593315Sopenharmony_ci CU_ASSERT(nullptr == pool.freelist); 542c593315Sopenharmony_ci CU_ASSERT(m1 == m2->knext); 552c593315Sopenharmony_ci CU_ASSERT(nullptr == m1->knext); 562c593315Sopenharmony_ci 572c593315Sopenharmony_ci auto m3 = pool.get(); 582c593315Sopenharmony_ci 592c593315Sopenharmony_ci CU_ASSERT(m3 == pool.pool); 602c593315Sopenharmony_ci CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); 612c593315Sopenharmony_ci CU_ASSERT(nullptr == pool.freelist); 622c593315Sopenharmony_ci 632c593315Sopenharmony_ci pool.recycle(m3); 642c593315Sopenharmony_ci 652c593315Sopenharmony_ci CU_ASSERT(m3 == pool.pool); 662c593315Sopenharmony_ci CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); 672c593315Sopenharmony_ci CU_ASSERT(m3 == pool.freelist); 682c593315Sopenharmony_ci 692c593315Sopenharmony_ci auto m4 = pool.get(); 702c593315Sopenharmony_ci 712c593315Sopenharmony_ci CU_ASSERT(m3 == m4); 722c593315Sopenharmony_ci CU_ASSERT(m4 == pool.pool); 732c593315Sopenharmony_ci CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); 742c593315Sopenharmony_ci CU_ASSERT(nullptr == pool.freelist); 752c593315Sopenharmony_ci 762c593315Sopenharmony_ci pool.recycle(m2); 772c593315Sopenharmony_ci pool.recycle(m1); 782c593315Sopenharmony_ci 792c593315Sopenharmony_ci CU_ASSERT(m1 == pool.freelist); 802c593315Sopenharmony_ci CU_ASSERT(m2 == m1->next); 812c593315Sopenharmony_ci CU_ASSERT(nullptr == m2->next); 822c593315Sopenharmony_ci} 832c593315Sopenharmony_ci 842c593315Sopenharmony_ciusing Memchunk16 = Memchunk<16>; 852c593315Sopenharmony_ciusing MemchunkPool16 = Pool<Memchunk16>; 862c593315Sopenharmony_ciusing Memchunks16 = Memchunks<Memchunk16>; 872c593315Sopenharmony_ciusing PeekMemchunks16 = PeekMemchunks<Memchunk16>; 882c593315Sopenharmony_ci 892c593315Sopenharmony_civoid test_memchunks_append(void) { 902c593315Sopenharmony_ci MemchunkPool16 pool; 912c593315Sopenharmony_ci Memchunks16 chunks(&pool); 922c593315Sopenharmony_ci 932c593315Sopenharmony_ci chunks.append("012"); 942c593315Sopenharmony_ci 952c593315Sopenharmony_ci auto m = chunks.tail; 962c593315Sopenharmony_ci 972c593315Sopenharmony_ci CU_ASSERT(3 == m->len()); 982c593315Sopenharmony_ci CU_ASSERT(13 == m->left()); 992c593315Sopenharmony_ci 1002c593315Sopenharmony_ci chunks.append("3456789abcdef@"); 1012c593315Sopenharmony_ci 1022c593315Sopenharmony_ci CU_ASSERT(16 == m->len()); 1032c593315Sopenharmony_ci CU_ASSERT(0 == m->left()); 1042c593315Sopenharmony_ci 1052c593315Sopenharmony_ci m = chunks.tail; 1062c593315Sopenharmony_ci 1072c593315Sopenharmony_ci CU_ASSERT(1 == m->len()); 1082c593315Sopenharmony_ci CU_ASSERT(15 == m->left()); 1092c593315Sopenharmony_ci CU_ASSERT(17 == chunks.rleft()); 1102c593315Sopenharmony_ci 1112c593315Sopenharmony_ci char buf[16]; 1122c593315Sopenharmony_ci size_t nread; 1132c593315Sopenharmony_ci 1142c593315Sopenharmony_ci nread = chunks.remove(buf, 8); 1152c593315Sopenharmony_ci 1162c593315Sopenharmony_ci CU_ASSERT(8 == nread); 1172c593315Sopenharmony_ci CU_ASSERT(0 == memcmp("01234567", buf, nread)); 1182c593315Sopenharmony_ci CU_ASSERT(9 == chunks.rleft()); 1192c593315Sopenharmony_ci 1202c593315Sopenharmony_ci nread = chunks.remove(buf, sizeof(buf)); 1212c593315Sopenharmony_ci 1222c593315Sopenharmony_ci CU_ASSERT(9 == nread); 1232c593315Sopenharmony_ci CU_ASSERT(0 == memcmp("89abcdef@", buf, nread)); 1242c593315Sopenharmony_ci CU_ASSERT(0 == chunks.rleft()); 1252c593315Sopenharmony_ci CU_ASSERT(nullptr == chunks.head); 1262c593315Sopenharmony_ci CU_ASSERT(nullptr == chunks.tail); 1272c593315Sopenharmony_ci CU_ASSERT(32 == pool.poolsize); 1282c593315Sopenharmony_ci} 1292c593315Sopenharmony_ci 1302c593315Sopenharmony_civoid test_memchunks_drain(void) { 1312c593315Sopenharmony_ci MemchunkPool16 pool; 1322c593315Sopenharmony_ci Memchunks16 chunks(&pool); 1332c593315Sopenharmony_ci 1342c593315Sopenharmony_ci chunks.append("0123456789"); 1352c593315Sopenharmony_ci 1362c593315Sopenharmony_ci size_t nread; 1372c593315Sopenharmony_ci 1382c593315Sopenharmony_ci nread = chunks.drain(3); 1392c593315Sopenharmony_ci 1402c593315Sopenharmony_ci CU_ASSERT(3 == nread); 1412c593315Sopenharmony_ci 1422c593315Sopenharmony_ci char buf[16]; 1432c593315Sopenharmony_ci 1442c593315Sopenharmony_ci nread = chunks.remove(buf, sizeof(buf)); 1452c593315Sopenharmony_ci 1462c593315Sopenharmony_ci CU_ASSERT(7 == nread); 1472c593315Sopenharmony_ci CU_ASSERT(0 == memcmp("3456789", buf, nread)); 1482c593315Sopenharmony_ci} 1492c593315Sopenharmony_ci 1502c593315Sopenharmony_civoid test_memchunks_riovec(void) { 1512c593315Sopenharmony_ci MemchunkPool16 pool; 1522c593315Sopenharmony_ci Memchunks16 chunks(&pool); 1532c593315Sopenharmony_ci 1542c593315Sopenharmony_ci std::array<char, 3 * 16> buf{}; 1552c593315Sopenharmony_ci 1562c593315Sopenharmony_ci chunks.append(buf.data(), buf.size()); 1572c593315Sopenharmony_ci 1582c593315Sopenharmony_ci std::array<struct iovec, 2> iov; 1592c593315Sopenharmony_ci auto iovcnt = chunks.riovec(iov.data(), iov.size()); 1602c593315Sopenharmony_ci 1612c593315Sopenharmony_ci auto m = chunks.head; 1622c593315Sopenharmony_ci 1632c593315Sopenharmony_ci CU_ASSERT(2 == iovcnt); 1642c593315Sopenharmony_ci CU_ASSERT(m->buf.data() == iov[0].iov_base); 1652c593315Sopenharmony_ci CU_ASSERT(m->len() == iov[0].iov_len); 1662c593315Sopenharmony_ci 1672c593315Sopenharmony_ci m = m->next; 1682c593315Sopenharmony_ci 1692c593315Sopenharmony_ci CU_ASSERT(m->buf.data() == iov[1].iov_base); 1702c593315Sopenharmony_ci CU_ASSERT(m->len() == iov[1].iov_len); 1712c593315Sopenharmony_ci 1722c593315Sopenharmony_ci chunks.drain(2 * 16); 1732c593315Sopenharmony_ci 1742c593315Sopenharmony_ci iovcnt = chunks.riovec(iov.data(), iov.size()); 1752c593315Sopenharmony_ci 1762c593315Sopenharmony_ci CU_ASSERT(1 == iovcnt); 1772c593315Sopenharmony_ci 1782c593315Sopenharmony_ci m = chunks.head; 1792c593315Sopenharmony_ci CU_ASSERT(m->buf.data() == iov[0].iov_base); 1802c593315Sopenharmony_ci CU_ASSERT(m->len() == iov[0].iov_len); 1812c593315Sopenharmony_ci} 1822c593315Sopenharmony_ci 1832c593315Sopenharmony_civoid test_memchunks_recycle(void) { 1842c593315Sopenharmony_ci MemchunkPool16 pool; 1852c593315Sopenharmony_ci { 1862c593315Sopenharmony_ci Memchunks16 chunks(&pool); 1872c593315Sopenharmony_ci std::array<char, 32> buf{}; 1882c593315Sopenharmony_ci chunks.append(buf.data(), buf.size()); 1892c593315Sopenharmony_ci } 1902c593315Sopenharmony_ci CU_ASSERT(32 == pool.poolsize); 1912c593315Sopenharmony_ci CU_ASSERT(nullptr != pool.freelist); 1922c593315Sopenharmony_ci 1932c593315Sopenharmony_ci auto m = pool.freelist; 1942c593315Sopenharmony_ci m = m->next; 1952c593315Sopenharmony_ci 1962c593315Sopenharmony_ci CU_ASSERT(nullptr != m); 1972c593315Sopenharmony_ci CU_ASSERT(nullptr == m->next); 1982c593315Sopenharmony_ci} 1992c593315Sopenharmony_ci 2002c593315Sopenharmony_civoid test_memchunks_reset(void) { 2012c593315Sopenharmony_ci MemchunkPool16 pool; 2022c593315Sopenharmony_ci Memchunks16 chunks(&pool); 2032c593315Sopenharmony_ci 2042c593315Sopenharmony_ci std::array<uint8_t, 32> b{}; 2052c593315Sopenharmony_ci 2062c593315Sopenharmony_ci chunks.append(b.data(), b.size()); 2072c593315Sopenharmony_ci 2082c593315Sopenharmony_ci CU_ASSERT(32 == chunks.rleft()); 2092c593315Sopenharmony_ci 2102c593315Sopenharmony_ci chunks.reset(); 2112c593315Sopenharmony_ci 2122c593315Sopenharmony_ci CU_ASSERT(0 == chunks.rleft()); 2132c593315Sopenharmony_ci CU_ASSERT(nullptr == chunks.head); 2142c593315Sopenharmony_ci CU_ASSERT(nullptr == chunks.tail); 2152c593315Sopenharmony_ci 2162c593315Sopenharmony_ci auto m = pool.freelist; 2172c593315Sopenharmony_ci 2182c593315Sopenharmony_ci CU_ASSERT(nullptr != m); 2192c593315Sopenharmony_ci CU_ASSERT(nullptr != m->next); 2202c593315Sopenharmony_ci CU_ASSERT(nullptr == m->next->next); 2212c593315Sopenharmony_ci} 2222c593315Sopenharmony_ci 2232c593315Sopenharmony_civoid test_peek_memchunks_append(void) { 2242c593315Sopenharmony_ci MemchunkPool16 pool; 2252c593315Sopenharmony_ci PeekMemchunks16 pchunks(&pool); 2262c593315Sopenharmony_ci 2272c593315Sopenharmony_ci std::array<uint8_t, 32> b{ 2282c593315Sopenharmony_ci '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 2292c593315Sopenharmony_ci '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', 2302c593315Sopenharmony_ci }, 2312c593315Sopenharmony_ci d; 2322c593315Sopenharmony_ci 2332c593315Sopenharmony_ci pchunks.append(b.data(), b.size()); 2342c593315Sopenharmony_ci 2352c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft()); 2362c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft_buffered()); 2372c593315Sopenharmony_ci 2382c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.remove(nullptr, 0)); 2392c593315Sopenharmony_ci 2402c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft()); 2412c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft_buffered()); 2422c593315Sopenharmony_ci 2432c593315Sopenharmony_ci CU_ASSERT(12 == pchunks.remove(d.data(), 12)); 2442c593315Sopenharmony_ci 2452c593315Sopenharmony_ci CU_ASSERT(std::equal(std::begin(b), std::begin(b) + 12, std::begin(d))); 2462c593315Sopenharmony_ci 2472c593315Sopenharmony_ci CU_ASSERT(20 == pchunks.rleft()); 2482c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft_buffered()); 2492c593315Sopenharmony_ci 2502c593315Sopenharmony_ci CU_ASSERT(20 == pchunks.remove(d.data(), d.size())); 2512c593315Sopenharmony_ci 2522c593315Sopenharmony_ci CU_ASSERT(std::equal(std::begin(b) + 12, std::end(b), std::begin(d))); 2532c593315Sopenharmony_ci 2542c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft()); 2552c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft_buffered()); 2562c593315Sopenharmony_ci} 2572c593315Sopenharmony_ci 2582c593315Sopenharmony_civoid test_peek_memchunks_disable_peek_drain(void) { 2592c593315Sopenharmony_ci MemchunkPool16 pool; 2602c593315Sopenharmony_ci PeekMemchunks16 pchunks(&pool); 2612c593315Sopenharmony_ci 2622c593315Sopenharmony_ci std::array<uint8_t, 32> b{ 2632c593315Sopenharmony_ci '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 2642c593315Sopenharmony_ci '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', 2652c593315Sopenharmony_ci }, 2662c593315Sopenharmony_ci d; 2672c593315Sopenharmony_ci 2682c593315Sopenharmony_ci pchunks.append(b.data(), b.size()); 2692c593315Sopenharmony_ci 2702c593315Sopenharmony_ci CU_ASSERT(12 == pchunks.remove(d.data(), 12)); 2712c593315Sopenharmony_ci 2722c593315Sopenharmony_ci pchunks.disable_peek(true); 2732c593315Sopenharmony_ci 2742c593315Sopenharmony_ci CU_ASSERT(!pchunks.peeking); 2752c593315Sopenharmony_ci CU_ASSERT(20 == pchunks.rleft()); 2762c593315Sopenharmony_ci CU_ASSERT(20 == pchunks.rleft_buffered()); 2772c593315Sopenharmony_ci 2782c593315Sopenharmony_ci CU_ASSERT(20 == pchunks.remove(d.data(), d.size())); 2792c593315Sopenharmony_ci 2802c593315Sopenharmony_ci CU_ASSERT(std::equal(std::begin(b) + 12, std::end(b), std::begin(d))); 2812c593315Sopenharmony_ci 2822c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft()); 2832c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft_buffered()); 2842c593315Sopenharmony_ci} 2852c593315Sopenharmony_ci 2862c593315Sopenharmony_civoid test_peek_memchunks_disable_peek_no_drain(void) { 2872c593315Sopenharmony_ci MemchunkPool16 pool; 2882c593315Sopenharmony_ci PeekMemchunks16 pchunks(&pool); 2892c593315Sopenharmony_ci 2902c593315Sopenharmony_ci std::array<uint8_t, 32> b{ 2912c593315Sopenharmony_ci '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 2922c593315Sopenharmony_ci '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', 2932c593315Sopenharmony_ci }, 2942c593315Sopenharmony_ci d; 2952c593315Sopenharmony_ci 2962c593315Sopenharmony_ci pchunks.append(b.data(), b.size()); 2972c593315Sopenharmony_ci 2982c593315Sopenharmony_ci CU_ASSERT(12 == pchunks.remove(d.data(), 12)); 2992c593315Sopenharmony_ci 3002c593315Sopenharmony_ci pchunks.disable_peek(false); 3012c593315Sopenharmony_ci 3022c593315Sopenharmony_ci CU_ASSERT(!pchunks.peeking); 3032c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft()); 3042c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.rleft_buffered()); 3052c593315Sopenharmony_ci 3062c593315Sopenharmony_ci CU_ASSERT(32 == pchunks.remove(d.data(), d.size())); 3072c593315Sopenharmony_ci 3082c593315Sopenharmony_ci CU_ASSERT(std::equal(std::begin(b), std::end(b), std::begin(d))); 3092c593315Sopenharmony_ci 3102c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft()); 3112c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft_buffered()); 3122c593315Sopenharmony_ci} 3132c593315Sopenharmony_ci 3142c593315Sopenharmony_civoid test_peek_memchunks_reset(void) { 3152c593315Sopenharmony_ci MemchunkPool16 pool; 3162c593315Sopenharmony_ci PeekMemchunks16 pchunks(&pool); 3172c593315Sopenharmony_ci 3182c593315Sopenharmony_ci std::array<uint8_t, 32> b{ 3192c593315Sopenharmony_ci '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 3202c593315Sopenharmony_ci '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', 3212c593315Sopenharmony_ci }, 3222c593315Sopenharmony_ci d; 3232c593315Sopenharmony_ci 3242c593315Sopenharmony_ci pchunks.append(b.data(), b.size()); 3252c593315Sopenharmony_ci 3262c593315Sopenharmony_ci CU_ASSERT(12 == pchunks.remove(d.data(), 12)); 3272c593315Sopenharmony_ci 3282c593315Sopenharmony_ci pchunks.disable_peek(true); 3292c593315Sopenharmony_ci pchunks.reset(); 3302c593315Sopenharmony_ci 3312c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft()); 3322c593315Sopenharmony_ci CU_ASSERT(0 == pchunks.rleft_buffered()); 3332c593315Sopenharmony_ci 3342c593315Sopenharmony_ci CU_ASSERT(nullptr == pchunks.cur); 3352c593315Sopenharmony_ci CU_ASSERT(nullptr == pchunks.cur_pos); 3362c593315Sopenharmony_ci CU_ASSERT(nullptr == pchunks.cur_last); 3372c593315Sopenharmony_ci CU_ASSERT(pchunks.peeking); 3382c593315Sopenharmony_ci} 3392c593315Sopenharmony_ci 3402c593315Sopenharmony_ci} // namespace nghttp2 341