Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include "src/core/support/string.h"
35 :
36 : #include <stddef.h>
37 : #include <stdlib.h>
38 : #include <string.h>
39 :
40 : #include <grpc/support/alloc.h>
41 : #include <grpc/support/log.h>
42 : #include <grpc/support/string_util.h>
43 : #include <grpc/support/useful.h>
44 : #include "test/core/util/test_config.h"
45 :
46 : #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
47 :
48 1 : static void test_strdup(void) {
49 : static const char *src1 = "hello world";
50 : char *dst1;
51 :
52 1 : LOG_TEST_NAME("test_strdup");
53 :
54 1 : dst1 = gpr_strdup(src1);
55 1 : GPR_ASSERT(0 == strcmp(src1, dst1));
56 1 : gpr_free(dst1);
57 :
58 1 : GPR_ASSERT(NULL == gpr_strdup(NULL));
59 1 : }
60 :
61 5 : static void expect_dump(const char *buf, size_t len, gpr_uint32 flags,
62 : const char *result) {
63 5 : char *got = gpr_dump(buf, len, flags);
64 5 : GPR_ASSERT(0 == strcmp(got, result));
65 5 : gpr_free(got);
66 5 : }
67 :
68 1 : static void test_dump(void) {
69 1 : LOG_TEST_NAME("test_dump");
70 1 : expect_dump("\x01", 1, GPR_DUMP_HEX, "01");
71 1 : expect_dump("\x01", 1, GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
72 1 : expect_dump("\x01\x02", 2, GPR_DUMP_HEX, "01 02");
73 1 : expect_dump("\x01\x23\x45\x67\x89\xab\xcd\xef", 8, GPR_DUMP_HEX,
74 : "01 23 45 67 89 ab cd ef");
75 1 : expect_dump("ab", 2, GPR_DUMP_HEX | GPR_DUMP_ASCII, "61 62 'ab'");
76 1 : }
77 :
78 4 : static void expect_slice_dump(gpr_slice slice, gpr_uint32 flags,
79 : const char *result) {
80 4 : char *got = gpr_dump_slice(slice, flags);
81 4 : GPR_ASSERT(0 == strcmp(got, result));
82 4 : gpr_free(got);
83 4 : gpr_slice_unref(slice);
84 4 : }
85 :
86 1 : static void test_dump_slice(void) {
87 : static const char *text = "HELLO WORLD!";
88 : static const char *long_text =
89 : "It was a bright cold day in April, and the clocks were striking "
90 : "thirteen. Winston Smith, his chin nuzzled into his breast in an effort "
91 : "to escape the vile wind, slipped quickly through the glass doors of "
92 : "Victory Mansions, though not quickly enough to prevent a swirl of "
93 : "gritty dust from entering along with him.";
94 :
95 1 : LOG_TEST_NAME("test_dump_slice");
96 :
97 1 : expect_slice_dump(gpr_slice_from_copied_string(text), GPR_DUMP_ASCII, text);
98 1 : expect_slice_dump(gpr_slice_from_copied_string(long_text), GPR_DUMP_ASCII,
99 : long_text);
100 1 : expect_slice_dump(gpr_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX,
101 : "01");
102 1 : expect_slice_dump(gpr_slice_from_copied_buffer("\x01", 1),
103 : GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
104 1 : }
105 :
106 7 : static void test_pu32_fail(const char *s) {
107 : gpr_uint32 out;
108 7 : GPR_ASSERT(!gpr_parse_bytes_to_uint32(s, strlen(s), &out));
109 7 : }
110 :
111 22 : static void test_pu32_succeed(const char *s, gpr_uint32 want) {
112 : gpr_uint32 out;
113 22 : GPR_ASSERT(gpr_parse_bytes_to_uint32(s, strlen(s), &out));
114 22 : GPR_ASSERT(out == want);
115 22 : }
116 :
117 1 : static void test_parse_uint32(void) {
118 1 : LOG_TEST_NAME("test_parse_uint32");
119 :
120 1 : test_pu32_fail("-1");
121 1 : test_pu32_fail("a");
122 1 : test_pu32_fail("");
123 1 : test_pu32_succeed("0", 0);
124 1 : test_pu32_succeed("1", 1);
125 1 : test_pu32_succeed("2", 2);
126 1 : test_pu32_succeed("3", 3);
127 1 : test_pu32_succeed("4", 4);
128 1 : test_pu32_succeed("5", 5);
129 1 : test_pu32_succeed("6", 6);
130 1 : test_pu32_succeed("7", 7);
131 1 : test_pu32_succeed("8", 8);
132 1 : test_pu32_succeed("9", 9);
133 1 : test_pu32_succeed("10", 10);
134 1 : test_pu32_succeed("11", 11);
135 1 : test_pu32_succeed("12", 12);
136 1 : test_pu32_succeed("13", 13);
137 1 : test_pu32_succeed("14", 14);
138 1 : test_pu32_succeed("15", 15);
139 1 : test_pu32_succeed("16", 16);
140 1 : test_pu32_succeed("17", 17);
141 1 : test_pu32_succeed("18", 18);
142 1 : test_pu32_succeed("19", 19);
143 1 : test_pu32_succeed("1234567890", 1234567890);
144 1 : test_pu32_succeed("4294967295", 4294967295u);
145 1 : test_pu32_fail("4294967296");
146 1 : test_pu32_fail("4294967297");
147 1 : test_pu32_fail("4294967298");
148 1 : test_pu32_fail("4294967299");
149 1 : }
150 :
151 1 : static void test_asprintf(void) {
152 : char *buf;
153 : int i, j;
154 :
155 1 : LOG_TEST_NAME("test_asprintf");
156 :
157 : /* Print an empty string. */
158 1 : GPR_ASSERT(gpr_asprintf(&buf, "") == 0);
159 1 : GPR_ASSERT(buf[0] == '\0');
160 1 : gpr_free(buf);
161 :
162 : /* Print strings of various lengths. */
163 100 : for (i = 1; i < 100; i++) {
164 99 : GPR_ASSERT(gpr_asprintf(&buf, "%0*d", i, 1) == i);
165 :
166 : /* The buffer should resemble "000001\0". */
167 4852 : for (j = 0; j < i - 2; j++) {
168 4753 : GPR_ASSERT(buf[j] == '0');
169 : }
170 99 : GPR_ASSERT(buf[i - 1] == '1');
171 99 : GPR_ASSERT(buf[i] == '\0');
172 99 : gpr_free(buf);
173 : }
174 1 : }
175 :
176 1 : static void test_strjoin(void) {
177 1 : const char *parts[4] = {"one", "two", "three", "four"};
178 : size_t joined_len;
179 : char *joined;
180 :
181 1 : LOG_TEST_NAME("test_strjoin");
182 :
183 1 : joined = gpr_strjoin(parts, 4, &joined_len);
184 1 : GPR_ASSERT(0 == strcmp("onetwothreefour", joined));
185 1 : gpr_free(joined);
186 :
187 1 : joined = gpr_strjoin(parts, 0, &joined_len);
188 1 : GPR_ASSERT(0 == strcmp("", joined));
189 1 : gpr_free(joined);
190 :
191 1 : joined = gpr_strjoin(parts, 1, &joined_len);
192 1 : GPR_ASSERT(0 == strcmp("one", joined));
193 1 : gpr_free(joined);
194 1 : }
195 :
196 1 : static void test_strjoin_sep(void) {
197 1 : const char *parts[4] = {"one", "two", "three", "four"};
198 : size_t joined_len;
199 : char *joined;
200 :
201 1 : LOG_TEST_NAME("test_strjoin_sep");
202 :
203 1 : joined = gpr_strjoin_sep(parts, 4, ", ", &joined_len);
204 1 : GPR_ASSERT(0 == strcmp("one, two, three, four", joined));
205 1 : gpr_free(joined);
206 :
207 : /* empty separator */
208 1 : joined = gpr_strjoin_sep(parts, 4, "", &joined_len);
209 1 : GPR_ASSERT(0 == strcmp("onetwothreefour", joined));
210 1 : gpr_free(joined);
211 :
212 : /* degenerated case specifying zero input parts */
213 1 : joined = gpr_strjoin_sep(parts, 0, ", ", &joined_len);
214 1 : GPR_ASSERT(0 == strcmp("", joined));
215 1 : gpr_free(joined);
216 :
217 : /* single part should have no separator */
218 1 : joined = gpr_strjoin_sep(parts, 1, ", ", &joined_len);
219 1 : GPR_ASSERT(0 == strcmp("one", joined));
220 1 : gpr_free(joined);
221 1 : }
222 :
223 1 : static void test_strsplit(void) {
224 : gpr_slice_buffer *parts;
225 : gpr_slice str;
226 :
227 1 : LOG_TEST_NAME("test_strsplit");
228 :
229 1 : parts = gpr_malloc(sizeof(gpr_slice_buffer));
230 1 : gpr_slice_buffer_init(parts);
231 :
232 1 : str = gpr_slice_from_copied_string("one, two, three, four");
233 1 : gpr_slice_split(str, ", ", parts);
234 1 : GPR_ASSERT(4 == parts->count);
235 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "one"));
236 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], "two"));
237 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[2], "three"));
238 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[3], "four"));
239 1 : gpr_slice_buffer_reset_and_unref(parts);
240 1 : gpr_slice_unref(str);
241 :
242 : /* separator not present in string */
243 1 : str = gpr_slice_from_copied_string("one two three four");
244 1 : gpr_slice_split(str, ", ", parts);
245 1 : GPR_ASSERT(1 == parts->count);
246 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "one two three four"));
247 1 : gpr_slice_buffer_reset_and_unref(parts);
248 1 : gpr_slice_unref(str);
249 :
250 : /* separator at the end */
251 1 : str = gpr_slice_from_copied_string("foo,");
252 1 : gpr_slice_split(str, ",", parts);
253 1 : GPR_ASSERT(2 == parts->count);
254 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], "foo"));
255 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], ""));
256 1 : gpr_slice_buffer_reset_and_unref(parts);
257 1 : gpr_slice_unref(str);
258 :
259 : /* separator at the beginning */
260 1 : str = gpr_slice_from_copied_string(",foo");
261 1 : gpr_slice_split(str, ",", parts);
262 1 : GPR_ASSERT(2 == parts->count);
263 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
264 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], "foo"));
265 1 : gpr_slice_buffer_reset_and_unref(parts);
266 1 : gpr_slice_unref(str);
267 :
268 : /* standalone separator */
269 1 : str = gpr_slice_from_copied_string(",");
270 1 : gpr_slice_split(str, ",", parts);
271 1 : GPR_ASSERT(2 == parts->count);
272 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
273 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[1], ""));
274 1 : gpr_slice_buffer_reset_and_unref(parts);
275 1 : gpr_slice_unref(str);
276 :
277 : /* empty input */
278 1 : str = gpr_slice_from_copied_string("");
279 1 : gpr_slice_split(str, ", ", parts);
280 1 : GPR_ASSERT(1 == parts->count);
281 1 : GPR_ASSERT(0 == gpr_slice_str_cmp(parts->slices[0], ""));
282 1 : gpr_slice_buffer_reset_and_unref(parts);
283 1 : gpr_slice_unref(str);
284 :
285 1 : gpr_slice_buffer_destroy(parts);
286 1 : gpr_free(parts);
287 1 : }
288 :
289 1 : int main(int argc, char **argv) {
290 1 : grpc_test_init(argc, argv);
291 1 : test_strdup();
292 1 : test_dump();
293 1 : test_dump_slice();
294 1 : test_parse_uint32();
295 1 : test_asprintf();
296 1 : test_strjoin();
297 1 : test_strjoin_sep();
298 1 : test_strsplit();
299 1 : return 0;
300 : }
|