string_test.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. #include "src/core/support/string.h"
  34. #include <stddef.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <grpc/support/alloc.h>
  38. #include <grpc/support/log.h>
  39. #include <grpc/support/string_util.h>
  40. #include <grpc/support/useful.h>
  41. #include "test/core/util/test_config.h"
  42. #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x)
  43. static void
  44. test_strdup (void)
  45. {
  46. static const char *src1 = "hello world";
  47. char *dst1;
  48. LOG_TEST_NAME ("test_strdup");
  49. dst1 = gpr_strdup (src1);
  50. GPR_ASSERT (0 == strcmp (src1, dst1));
  51. gpr_free (dst1);
  52. GPR_ASSERT (NULL == gpr_strdup (NULL));
  53. }
  54. static void
  55. expect_dump (const char *buf, size_t len, gpr_uint32 flags, const char *result)
  56. {
  57. char *got = gpr_dump (buf, len, flags);
  58. GPR_ASSERT (0 == strcmp (got, result));
  59. gpr_free (got);
  60. }
  61. static void
  62. test_dump (void)
  63. {
  64. LOG_TEST_NAME ("test_dump");
  65. expect_dump ("\x01", 1, GPR_DUMP_HEX, "01");
  66. expect_dump ("\x01", 1, GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
  67. expect_dump ("\x01\x02", 2, GPR_DUMP_HEX, "01 02");
  68. expect_dump ("\x01\x23\x45\x67\x89\xab\xcd\xef", 8, GPR_DUMP_HEX, "01 23 45 67 89 ab cd ef");
  69. expect_dump ("ab", 2, GPR_DUMP_HEX | GPR_DUMP_ASCII, "61 62 'ab'");
  70. }
  71. static void
  72. expect_slice_dump (gpr_slice slice, gpr_uint32 flags, const char *result)
  73. {
  74. char *got = gpr_dump_slice (slice, flags);
  75. GPR_ASSERT (0 == strcmp (got, result));
  76. gpr_free (got);
  77. gpr_slice_unref (slice);
  78. }
  79. static void
  80. test_dump_slice (void)
  81. {
  82. static const char *text = "HELLO WORLD!";
  83. static const char *long_text = "It was a bright cold day in April, and the clocks were striking " "thirteen. Winston Smith, his chin nuzzled into his breast in an effort " "to escape the vile wind, slipped quickly through the glass doors of " "Victory Mansions, though not quickly enough to prevent a swirl of " "gritty dust from entering along with him.";
  84. LOG_TEST_NAME ("test_dump_slice");
  85. expect_slice_dump (gpr_slice_from_copied_string (text), GPR_DUMP_ASCII, text);
  86. expect_slice_dump (gpr_slice_from_copied_string (long_text), GPR_DUMP_ASCII, long_text);
  87. expect_slice_dump (gpr_slice_from_copied_buffer ("\x01", 1), GPR_DUMP_HEX, "01");
  88. expect_slice_dump (gpr_slice_from_copied_buffer ("\x01", 1), GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
  89. }
  90. static void
  91. test_pu32_fail (const char *s)
  92. {
  93. gpr_uint32 out;
  94. GPR_ASSERT (!gpr_parse_bytes_to_uint32 (s, strlen (s), &out));
  95. }
  96. static void
  97. test_pu32_succeed (const char *s, gpr_uint32 want)
  98. {
  99. gpr_uint32 out;
  100. GPR_ASSERT (gpr_parse_bytes_to_uint32 (s, strlen (s), &out));
  101. GPR_ASSERT (out == want);
  102. }
  103. static void
  104. test_parse_uint32 (void)
  105. {
  106. LOG_TEST_NAME ("test_parse_uint32");
  107. test_pu32_fail ("-1");
  108. test_pu32_fail ("a");
  109. test_pu32_fail ("");
  110. test_pu32_succeed ("0", 0);
  111. test_pu32_succeed ("1", 1);
  112. test_pu32_succeed ("2", 2);
  113. test_pu32_succeed ("3", 3);
  114. test_pu32_succeed ("4", 4);
  115. test_pu32_succeed ("5", 5);
  116. test_pu32_succeed ("6", 6);
  117. test_pu32_succeed ("7", 7);
  118. test_pu32_succeed ("8", 8);
  119. test_pu32_succeed ("9", 9);
  120. test_pu32_succeed ("10", 10);
  121. test_pu32_succeed ("11", 11);
  122. test_pu32_succeed ("12", 12);
  123. test_pu32_succeed ("13", 13);
  124. test_pu32_succeed ("14", 14);
  125. test_pu32_succeed ("15", 15);
  126. test_pu32_succeed ("16", 16);
  127. test_pu32_succeed ("17", 17);
  128. test_pu32_succeed ("18", 18);
  129. test_pu32_succeed ("19", 19);
  130. test_pu32_succeed ("1234567890", 1234567890);
  131. test_pu32_succeed ("4294967295", 4294967295u);
  132. test_pu32_fail ("4294967296");
  133. test_pu32_fail ("4294967297");
  134. test_pu32_fail ("4294967298");
  135. test_pu32_fail ("4294967299");
  136. }
  137. static void
  138. test_asprintf (void)
  139. {
  140. char *buf;
  141. int i, j;
  142. LOG_TEST_NAME ("test_asprintf");
  143. /* Print an empty string. */
  144. GPR_ASSERT (gpr_asprintf (&buf, "") == 0);
  145. GPR_ASSERT (buf[0] == '\0');
  146. gpr_free (buf);
  147. /* Print strings of various lengths. */
  148. for (i = 1; i < 100; i++)
  149. {
  150. GPR_ASSERT (gpr_asprintf (&buf, "%0*d", i, 1) == i);
  151. /* The buffer should resemble "000001\0". */
  152. for (j = 0; j < i - 2; j++)
  153. {
  154. GPR_ASSERT (buf[j] == '0');
  155. }
  156. GPR_ASSERT (buf[i - 1] == '1');
  157. GPR_ASSERT (buf[i] == '\0');
  158. gpr_free (buf);
  159. }
  160. }
  161. static void
  162. test_strjoin (void)
  163. {
  164. const char *parts[4] = { "one", "two", "three", "four" };
  165. size_t joined_len;
  166. char *joined;
  167. LOG_TEST_NAME ("test_strjoin");
  168. joined = gpr_strjoin (parts, 4, &joined_len);
  169. GPR_ASSERT (0 == strcmp ("onetwothreefour", joined));
  170. gpr_free (joined);
  171. joined = gpr_strjoin (parts, 0, &joined_len);
  172. GPR_ASSERT (0 == strcmp ("", joined));
  173. gpr_free (joined);
  174. joined = gpr_strjoin (parts, 1, &joined_len);
  175. GPR_ASSERT (0 == strcmp ("one", joined));
  176. gpr_free (joined);
  177. }
  178. static void
  179. test_strjoin_sep (void)
  180. {
  181. const char *parts[4] = { "one", "two", "three", "four" };
  182. size_t joined_len;
  183. char *joined;
  184. LOG_TEST_NAME ("test_strjoin_sep");
  185. joined = gpr_strjoin_sep (parts, 4, ", ", &joined_len);
  186. GPR_ASSERT (0 == strcmp ("one, two, three, four", joined));
  187. gpr_free (joined);
  188. /* empty separator */
  189. joined = gpr_strjoin_sep (parts, 4, "", &joined_len);
  190. GPR_ASSERT (0 == strcmp ("onetwothreefour", joined));
  191. gpr_free (joined);
  192. /* degenerated case specifying zero input parts */
  193. joined = gpr_strjoin_sep (parts, 0, ", ", &joined_len);
  194. GPR_ASSERT (0 == strcmp ("", joined));
  195. gpr_free (joined);
  196. /* single part should have no separator */
  197. joined = gpr_strjoin_sep (parts, 1, ", ", &joined_len);
  198. GPR_ASSERT (0 == strcmp ("one", joined));
  199. gpr_free (joined);
  200. }
  201. static void
  202. test_strsplit (void)
  203. {
  204. gpr_slice_buffer *parts;
  205. gpr_slice str;
  206. LOG_TEST_NAME ("test_strsplit");
  207. parts = gpr_malloc (sizeof (gpr_slice_buffer));
  208. gpr_slice_buffer_init (parts);
  209. str = gpr_slice_from_copied_string ("one, two, three, four");
  210. gpr_slice_split (str, ", ", parts);
  211. GPR_ASSERT (4 == parts->count);
  212. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], "one"));
  213. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[1], "two"));
  214. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[2], "three"));
  215. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[3], "four"));
  216. gpr_slice_buffer_reset_and_unref (parts);
  217. gpr_slice_unref (str);
  218. /* separator not present in string */
  219. str = gpr_slice_from_copied_string ("one two three four");
  220. gpr_slice_split (str, ", ", parts);
  221. GPR_ASSERT (1 == parts->count);
  222. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], "one two three four"));
  223. gpr_slice_buffer_reset_and_unref (parts);
  224. gpr_slice_unref (str);
  225. /* separator at the end */
  226. str = gpr_slice_from_copied_string ("foo,");
  227. gpr_slice_split (str, ",", parts);
  228. GPR_ASSERT (2 == parts->count);
  229. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], "foo"));
  230. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[1], ""));
  231. gpr_slice_buffer_reset_and_unref (parts);
  232. gpr_slice_unref (str);
  233. /* separator at the beginning */
  234. str = gpr_slice_from_copied_string (",foo");
  235. gpr_slice_split (str, ",", parts);
  236. GPR_ASSERT (2 == parts->count);
  237. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], ""));
  238. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[1], "foo"));
  239. gpr_slice_buffer_reset_and_unref (parts);
  240. gpr_slice_unref (str);
  241. /* standalone separator */
  242. str = gpr_slice_from_copied_string (",");
  243. gpr_slice_split (str, ",", parts);
  244. GPR_ASSERT (2 == parts->count);
  245. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], ""));
  246. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[1], ""));
  247. gpr_slice_buffer_reset_and_unref (parts);
  248. gpr_slice_unref (str);
  249. /* empty input */
  250. str = gpr_slice_from_copied_string ("");
  251. gpr_slice_split (str, ", ", parts);
  252. GPR_ASSERT (1 == parts->count);
  253. GPR_ASSERT (0 == gpr_slice_str_cmp (parts->slices[0], ""));
  254. gpr_slice_buffer_reset_and_unref (parts);
  255. gpr_slice_unref (str);
  256. gpr_slice_buffer_destroy (parts);
  257. gpr_free (parts);
  258. }
  259. int
  260. main (int argc, char **argv)
  261. {
  262. grpc_test_init (argc, argv);
  263. test_strdup ();
  264. test_dump ();
  265. test_dump_slice ();
  266. test_parse_uint32 ();
  267. test_asprintf ();
  268. test_strjoin ();
  269. test_strjoin_sep ();
  270. test_strsplit ();
  271. return 0;
  272. }