tizen 2.4 release
[external/nghttp2.git] / src / util_test.cc
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2013 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 "util_test.h"
26
27 #include <cstring>
28 #include <iostream>
29
30 #include <CUnit/CUnit.h>
31
32 #include <nghttp2/nghttp2.h>
33
34 #include "util.h"
35
36 using namespace nghttp2;
37
38 namespace shrpx {
39
40 void test_util_streq(void) {
41   CU_ASSERT(util::streq("alpha", (const uint8_t *)"alpha", 5));
42   CU_ASSERT(util::streq("alpha", (const uint8_t *)"alphabravo", 5));
43   CU_ASSERT(!util::streq("alpha", (const uint8_t *)"alphabravo", 6));
44   CU_ASSERT(!util::streq("alphabravo", (const uint8_t *)"alpha", 5));
45   CU_ASSERT(!util::streq("alpha", (const uint8_t *)"alphA", 5));
46   CU_ASSERT(!util::streq("", (const uint8_t *)"a", 1));
47   CU_ASSERT(util::streq("", (const uint8_t *)"", 0));
48   CU_ASSERT(!util::streq("alpha", (const uint8_t *)"", 0));
49
50   CU_ASSERT(
51       util::streq((const uint8_t *)"alpha", 5, (const uint8_t *)"alpha", 5));
52   CU_ASSERT(
53       !util::streq((const uint8_t *)"alpha", 4, (const uint8_t *)"alpha", 5));
54   CU_ASSERT(
55       !util::streq((const uint8_t *)"alpha", 5, (const uint8_t *)"alpha", 4));
56   CU_ASSERT(
57       !util::streq((const uint8_t *)"alpha", 5, (const uint8_t *)"alphA", 5));
58   char *a = nullptr;
59   char *b = nullptr;
60   CU_ASSERT(util::streq(a, 0, b, 0));
61 }
62
63 void test_util_strieq(void) {
64   CU_ASSERT(util::strieq(std::string("alpha"), std::string("alpha")));
65   CU_ASSERT(util::strieq(std::string("alpha"), std::string("AlPhA")));
66   CU_ASSERT(util::strieq(std::string(), std::string()));
67   CU_ASSERT(!util::strieq(std::string("alpha"), std::string("AlPhA ")));
68   CU_ASSERT(!util::strieq(std::string(), std::string("AlPhA ")));
69 }
70
71 void test_util_inp_strlower(void) {
72   std::string a("alPha");
73   util::inp_strlower(a);
74   CU_ASSERT("alpha" == a);
75
76   a = "ALPHA123BRAVO";
77   util::inp_strlower(a);
78   CU_ASSERT("alpha123bravo" == a);
79
80   a = "";
81   util::inp_strlower(a);
82   CU_ASSERT("" == a);
83 }
84
85 void test_util_to_base64(void) {
86   std::string x = "AAA--B_";
87   util::to_base64(x);
88   CU_ASSERT("AAA++B/=" == x);
89
90   x = "AAA--B_B";
91   util::to_base64(x);
92   CU_ASSERT("AAA++B/B" == x);
93 }
94
95 void test_util_percent_encode_token(void) {
96   CU_ASSERT("h2" == util::percent_encode_token("h2"));
97   CU_ASSERT("h3~" == util::percent_encode_token("h3~"));
98   CU_ASSERT("100%25" == util::percent_encode_token("100%"));
99   CU_ASSERT("http%202" == util::percent_encode_token("http 2"));
100 }
101
102 void test_util_quote_string(void) {
103   CU_ASSERT("alpha" == util::quote_string("alpha"));
104   CU_ASSERT("" == util::quote_string(""));
105   CU_ASSERT("\\\"alpha\\\"" == util::quote_string("\"alpha\""));
106 }
107
108 void test_util_utox(void) {
109   CU_ASSERT("0" == util::utox(0));
110   CU_ASSERT("1" == util::utox(1));
111   CU_ASSERT("F" == util::utox(15));
112   CU_ASSERT("10" == util::utox(16));
113   CU_ASSERT("3B9ACA07" == util::utox(1000000007));
114   CU_ASSERT("100000000" == util::utox(1LL << 32));
115 }
116
117 void test_util_http_date(void) {
118   CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" == util::http_date(0));
119   CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" == util::http_date(1330506916));
120 }
121
122 void test_util_select_h2(void) {
123   const unsigned char *out = NULL;
124   unsigned char outlen = 0;
125
126   // Check single entry and select it.
127   const unsigned char t1[] = "\x5h2-14";
128   CU_ASSERT(util::select_h2(&out, &outlen, t1, sizeof(t1) - 1));
129   CU_ASSERT(
130       memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
131   CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
132
133   out = NULL;
134   outlen = 0;
135
136   // Check the case where id is correct but length is invalid and too
137   // long.
138   const unsigned char t2[] = "\x6h2-14";
139   CU_ASSERT(!util::select_h2(&out, &outlen, t2, sizeof(t2) - 1));
140
141   // Check the case where h2-14 is located after bogus ID.
142   const unsigned char t3[] = "\x2h3\x5h2-14";
143   CU_ASSERT(util::select_h2(&out, &outlen, t3, sizeof(t3) - 1));
144   CU_ASSERT(
145       memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
146   CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
147
148   out = NULL;
149   outlen = 0;
150
151   // Check the case that last entry's length is invalid and too long.
152   const unsigned char t4[] = "\x2h3\x6h2-14";
153   CU_ASSERT(!util::select_h2(&out, &outlen, t4, sizeof(t4) - 1));
154
155   // Check the case that all entries are not supported.
156   const unsigned char t5[] = "\x2h3\x2h4";
157   CU_ASSERT(!util::select_h2(&out, &outlen, t5, sizeof(t5) - 1));
158
159   // Check the case where 2 values are eligible, but last one is
160   // picked up because it has precedence over the other.
161   const unsigned char t6[] = "\x5h2-14\x5h2-16";
162   CU_ASSERT(util::select_h2(&out, &outlen, t6, sizeof(t6) - 1));
163   CU_ASSERT(memcmp(NGHTTP2_H2_16_ID, out, NGHTTP2_H2_16_ID_LEN) == 0);
164   CU_ASSERT(NGHTTP2_H2_16_ID_LEN == outlen);
165 }
166
167 void test_util_ipv6_numeric_addr(void) {
168   CU_ASSERT(util::ipv6_numeric_addr("::1"));
169   CU_ASSERT(util::ipv6_numeric_addr("2001:0db8:85a3:0042:1000:8a2e:0370:7334"));
170   // IPv4
171   CU_ASSERT(!util::ipv6_numeric_addr("127.0.0.1"));
172   // not numeric address
173   CU_ASSERT(!util::ipv6_numeric_addr("localhost"));
174 }
175
176 void test_util_utos_with_unit(void) {
177   CU_ASSERT("0" == util::utos_with_unit(0));
178   CU_ASSERT("1023" == util::utos_with_unit(1023));
179   CU_ASSERT("1K" == util::utos_with_unit(1024));
180   CU_ASSERT("1K" == util::utos_with_unit(1025));
181   CU_ASSERT("1M" == util::utos_with_unit(1 << 20));
182   CU_ASSERT("1G" == util::utos_with_unit(1 << 30));
183   CU_ASSERT("1024G" == util::utos_with_unit(1LL << 40));
184 }
185
186 void test_util_utos_with_funit(void) {
187   CU_ASSERT("0" == util::utos_with_funit(0));
188   CU_ASSERT("1023" == util::utos_with_funit(1023));
189   CU_ASSERT("1.00K" == util::utos_with_funit(1024));
190   CU_ASSERT("1.00K" == util::utos_with_funit(1025));
191   CU_ASSERT("1.09K" == util::utos_with_funit(1119));
192   CU_ASSERT("1.27K" == util::utos_with_funit(1300));
193   CU_ASSERT("1.00M" == util::utos_with_funit(1 << 20));
194   CU_ASSERT("1.18M" == util::utos_with_funit(1234567));
195   CU_ASSERT("1.00G" == util::utos_with_funit(1 << 30));
196   CU_ASSERT("4492450797.23G" == util::utos_with_funit(4823732313248234343LL));
197   CU_ASSERT("1024.00G" == util::utos_with_funit(1LL << 40));
198 }
199
200 void test_util_parse_uint_with_unit(void) {
201   CU_ASSERT(0 == util::parse_uint_with_unit("0"));
202   CU_ASSERT(1023 == util::parse_uint_with_unit("1023"));
203   CU_ASSERT(1024 == util::parse_uint_with_unit("1k"));
204   CU_ASSERT(2048 == util::parse_uint_with_unit("2K"));
205   CU_ASSERT(1 << 20 == util::parse_uint_with_unit("1m"));
206   CU_ASSERT(1 << 21 == util::parse_uint_with_unit("2M"));
207   CU_ASSERT(1 << 30 == util::parse_uint_with_unit("1g"));
208   CU_ASSERT(1LL << 31 == util::parse_uint_with_unit("2G"));
209   CU_ASSERT(9223372036854775807LL ==
210             util::parse_uint_with_unit("9223372036854775807"));
211   // check overflow case
212   CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775808"));
213   CU_ASSERT(-1 == util::parse_uint_with_unit("10000000000000000000"));
214   CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775807G"));
215   // bad characters
216   CU_ASSERT(-1 == util::parse_uint_with_unit("1.1"));
217   CU_ASSERT(-1 == util::parse_uint_with_unit("1a"));
218   CU_ASSERT(-1 == util::parse_uint_with_unit("a1"));
219   CU_ASSERT(-1 == util::parse_uint_with_unit("1T"));
220   CU_ASSERT(-1 == util::parse_uint_with_unit(""));
221 }
222
223 void test_util_parse_uint(void) {
224   CU_ASSERT(0 == util::parse_uint("0"));
225   CU_ASSERT(1023 == util::parse_uint("1023"));
226   CU_ASSERT(-1 == util::parse_uint("1k"));
227   CU_ASSERT(9223372036854775807LL == util::parse_uint("9223372036854775807"));
228   // check overflow case
229   CU_ASSERT(-1 == util::parse_uint("9223372036854775808"));
230   CU_ASSERT(-1 == util::parse_uint("10000000000000000000"));
231   // bad characters
232   CU_ASSERT(-1 == util::parse_uint("1.1"));
233   CU_ASSERT(-1 == util::parse_uint("1a"));
234   CU_ASSERT(-1 == util::parse_uint("a1"));
235   CU_ASSERT(-1 == util::parse_uint("1T"));
236   CU_ASSERT(-1 == util::parse_uint(""));
237 }
238
239 void test_util_parse_duration_with_unit(void) {
240   CU_ASSERT(0. == util::parse_duration_with_unit("0"));
241   CU_ASSERT(123. == util::parse_duration_with_unit("123"));
242   CU_ASSERT(123. == util::parse_duration_with_unit("123s"));
243   CU_ASSERT(0.500 == util::parse_duration_with_unit("500ms"));
244   CU_ASSERT(123. == util::parse_duration_with_unit("123S"));
245   CU_ASSERT(0.500 == util::parse_duration_with_unit("500MS"));
246
247   auto err = std::numeric_limits<double>::infinity();
248   // check overflow case
249   CU_ASSERT(err == util::parse_duration_with_unit("9223372036854775808"));
250   // bad characters
251   CU_ASSERT(err == util::parse_duration_with_unit("0u"));
252   CU_ASSERT(err == util::parse_duration_with_unit("0xs"));
253   CU_ASSERT(err == util::parse_duration_with_unit("0mt"));
254   CU_ASSERT(err == util::parse_duration_with_unit("0mss"));
255   CU_ASSERT(err == util::parse_duration_with_unit("s"));
256   CU_ASSERT(err == util::parse_duration_with_unit("ms"));
257 }
258
259 void test_util_duration_str(void) {
260   CU_ASSERT("0" == util::duration_str(0.));
261   CU_ASSERT("1s" == util::duration_str(1.));
262   CU_ASSERT("500ms" == util::duration_str(0.5));
263   CU_ASSERT("1500ms" == util::duration_str(1.5));
264 }
265
266 void test_util_format_duration(void) {
267   CU_ASSERT("0us" == util::format_duration(std::chrono::microseconds(0)));
268   CU_ASSERT("999us" == util::format_duration(std::chrono::microseconds(999)));
269   CU_ASSERT("1.00ms" == util::format_duration(std::chrono::microseconds(1000)));
270   CU_ASSERT("1.09ms" == util::format_duration(std::chrono::microseconds(1090)));
271   CU_ASSERT("1.01ms" == util::format_duration(std::chrono::microseconds(1009)));
272   CU_ASSERT("999.99ms" ==
273             util::format_duration(std::chrono::microseconds(999990)));
274   CU_ASSERT("1.00s" ==
275             util::format_duration(std::chrono::microseconds(1000000)));
276   CU_ASSERT("1.05s" ==
277             util::format_duration(std::chrono::microseconds(1050000)));
278 }
279
280 } // namespace shrpx