Imported Upstream version 1.0.0
[platform/upstream/nghttp2.git] / src / memchunk_test.cc
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2015 Tatsuhiro Tsujikawa
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include "memchunk_test.h"
26
27 #include <CUnit/CUnit.h>
28
29 #include <nghttp2/nghttp2.h>
30
31 #include "memchunk.h"
32 #include "util.h"
33
34 namespace nghttp2 {
35
36 void test_pool_recycle(void) {
37   MemchunkPool pool;
38
39   CU_ASSERT(!pool.pool);
40   CU_ASSERT(0 == pool.poolsize);
41   CU_ASSERT(nullptr == pool.freelist);
42
43   auto m1 = pool.get();
44
45   CU_ASSERT(m1 == pool.pool.get());
46   CU_ASSERT(MemchunkPool::value_type::size == pool.poolsize);
47   CU_ASSERT(nullptr == pool.freelist);
48
49   auto m2 = pool.get();
50
51   CU_ASSERT(m2 == pool.pool.get());
52   CU_ASSERT(2 * MemchunkPool::value_type::size == pool.poolsize);
53   CU_ASSERT(nullptr == pool.freelist);
54   CU_ASSERT(m1 == m2->knext.get());
55   CU_ASSERT(nullptr == m1->knext.get());
56
57   auto m3 = pool.get();
58
59   CU_ASSERT(m3 == pool.pool.get());
60   CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
61   CU_ASSERT(nullptr == pool.freelist);
62
63   pool.recycle(m3);
64
65   CU_ASSERT(m3 == pool.pool.get());
66   CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
67   CU_ASSERT(m3 == pool.freelist);
68
69   auto m4 = pool.get();
70
71   CU_ASSERT(m3 == m4);
72   CU_ASSERT(m4 == pool.pool.get());
73   CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize);
74   CU_ASSERT(nullptr == pool.freelist);
75
76   pool.recycle(m2);
77   pool.recycle(m1);
78
79   CU_ASSERT(m1 == pool.freelist);
80   CU_ASSERT(m2 == m1->next);
81   CU_ASSERT(nullptr == m2->next);
82 }
83
84 using Memchunk16 = Memchunk<16>;
85 using MemchunkPool16 = Pool<Memchunk16>;
86 using Memchunks16 = Memchunks<Memchunk16>;
87
88 void test_memchunks_append(void) {
89   MemchunkPool16 pool;
90   Memchunks16 chunks(&pool);
91
92   chunks.append("012");
93
94   auto m = chunks.tail;
95
96   CU_ASSERT(3 == m->len());
97   CU_ASSERT(13 == m->left());
98
99   chunks.append("3456789abcdef@");
100
101   CU_ASSERT(16 == m->len());
102   CU_ASSERT(0 == m->left());
103
104   m = chunks.tail;
105
106   CU_ASSERT(1 == m->len());
107   CU_ASSERT(15 == m->left());
108   CU_ASSERT(17 == chunks.rleft());
109
110   char buf[16];
111   size_t nread;
112
113   nread = chunks.remove(buf, 8);
114
115   CU_ASSERT(8 == nread);
116   CU_ASSERT(0 == memcmp("01234567", buf, nread));
117   CU_ASSERT(9 == chunks.rleft());
118
119   nread = chunks.remove(buf, sizeof(buf));
120
121   CU_ASSERT(9 == nread);
122   CU_ASSERT(0 == memcmp("89abcdef@", buf, nread));
123   CU_ASSERT(0 == chunks.rleft());
124   CU_ASSERT(nullptr == chunks.head);
125   CU_ASSERT(nullptr == chunks.tail);
126   CU_ASSERT(32 == pool.poolsize);
127 }
128
129 void test_memchunks_drain(void) {
130   MemchunkPool16 pool;
131   Memchunks16 chunks(&pool);
132
133   chunks.append("0123456789");
134
135   size_t nread;
136
137   nread = chunks.drain(3);
138
139   CU_ASSERT(3 == nread);
140
141   char buf[16];
142
143   nread = chunks.remove(buf, sizeof(buf));
144
145   CU_ASSERT(7 == nread);
146   CU_ASSERT(0 == memcmp("3456789", buf, nread));
147 }
148
149 void test_memchunks_riovec(void) {
150   MemchunkPool16 pool;
151   Memchunks16 chunks(&pool);
152
153   char buf[3 * 16];
154
155   chunks.append(buf, sizeof(buf));
156
157   std::array<struct iovec, 2> iov;
158   auto iovcnt = chunks.riovec(iov.data(), iov.size());
159
160   auto m = chunks.head;
161
162   CU_ASSERT(2 == iovcnt);
163   CU_ASSERT(m->buf.data() == iov[0].iov_base);
164   CU_ASSERT(m->len() == iov[0].iov_len);
165
166   m = m->next;
167
168   CU_ASSERT(m->buf.data() == iov[1].iov_base);
169   CU_ASSERT(m->len() == iov[1].iov_len);
170
171   chunks.drain(2 * 16);
172
173   iovcnt = chunks.riovec(iov.data(), iov.size());
174
175   CU_ASSERT(1 == iovcnt);
176
177   m = chunks.head;
178   CU_ASSERT(m->buf.data() == iov[0].iov_base);
179   CU_ASSERT(m->len() == iov[0].iov_len);
180 }
181
182 void test_memchunks_recycle(void) {
183   MemchunkPool16 pool;
184   {
185     Memchunks16 chunks(&pool);
186     char buf[32];
187     chunks.append(buf, sizeof(buf));
188   }
189   CU_ASSERT(32 == pool.poolsize);
190   CU_ASSERT(nullptr != pool.freelist);
191
192   auto m = pool.freelist;
193   m = m->next;
194
195   CU_ASSERT(nullptr != m);
196   CU_ASSERT(nullptr == m->next);
197 }
198
199 } // namespace nghttp2