1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include "src/core/lib/gpr/string.h" 20 21 #include <limits.h> 22 #include <stddef.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include <grpc/support/alloc.h> 27 #include <grpc/support/log.h> 28 #include <grpc/support/string_util.h> 29 30 #include "test/core/util/test_config.h" 31 32 #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) 33 34 static void test_strdup(void) { 35 static const char* src1 = "hello world"; 36 char* dst1; 37 38 LOG_TEST_NAME("test_strdup"); 39 40 dst1 = gpr_strdup(src1); 41 GPR_ASSERT(0 == strcmp(src1, dst1)); 42 gpr_free(dst1); 43 44 GPR_ASSERT(nullptr == gpr_strdup(nullptr)); 45 } 46 47 static void expect_dump(const char* buf, size_t len, uint32_t flags, 48 const char* result) { 49 char* got = gpr_dump(buf, len, flags); 50 GPR_ASSERT(0 == strcmp(got, result)); 51 gpr_free(got); 52 } 53 54 static void test_dump(void) { 55 LOG_TEST_NAME("test_dump"); 56 expect_dump("\x01", 1, GPR_DUMP_HEX, "01"); 57 expect_dump("\x01", 1, GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'"); 58 expect_dump("\x01\x02", 2, GPR_DUMP_HEX, "01 02"); 59 expect_dump("\x01\x23\x45\x67\x89\xab\xcd\xef", 8, GPR_DUMP_HEX, 60 "01 23 45 67 89 ab cd ef"); 61 expect_dump("ab", 2, GPR_DUMP_HEX | GPR_DUMP_ASCII, "61 62 'ab'"); 62 } 63 64 static void test_pu32_fail(const char* s) { 65 uint32_t out; 66 GPR_ASSERT(!gpr_parse_bytes_to_uint32(s, strlen(s), &out)); 67 } 68 69 static void test_pu32_succeed(const char* s, uint32_t want) { 70 uint32_t out; 71 GPR_ASSERT(gpr_parse_bytes_to_uint32(s, strlen(s), &out)); 72 GPR_ASSERT(out == want); 73 } 74 75 static void test_parse_uint32(void) { 76 LOG_TEST_NAME("test_parse_uint32"); 77 78 test_pu32_fail("-1"); 79 test_pu32_fail("a"); 80 test_pu32_fail(""); 81 test_pu32_succeed("0", 0); 82 test_pu32_succeed("1", 1); 83 test_pu32_succeed("2", 2); 84 test_pu32_succeed("3", 3); 85 test_pu32_succeed("4", 4); 86 test_pu32_succeed("5", 5); 87 test_pu32_succeed("6", 6); 88 test_pu32_succeed("7", 7); 89 test_pu32_succeed("8", 8); 90 test_pu32_succeed("9", 9); 91 test_pu32_succeed("10", 10); 92 test_pu32_succeed("11", 11); 93 test_pu32_succeed("12", 12); 94 test_pu32_succeed("13", 13); 95 test_pu32_succeed("14", 14); 96 test_pu32_succeed("15", 15); 97 test_pu32_succeed("16", 16); 98 test_pu32_succeed("17", 17); 99 test_pu32_succeed("18", 18); 100 test_pu32_succeed("19", 19); 101 test_pu32_succeed("1234567890", 1234567890); 102 test_pu32_succeed("4294967295", 4294967295u); 103 test_pu32_fail("4294967296"); 104 test_pu32_fail("4294967297"); 105 test_pu32_fail("4294967298"); 106 test_pu32_fail("4294967299"); 107 } 108 109 static void test_asprintf(void) { 110 char* buf; 111 int i, j; 112 113 LOG_TEST_NAME("test_asprintf"); 114 115 /* Print an empty string. */ 116 GPR_ASSERT(gpr_asprintf(&buf, "%s", "") == 0); 117 GPR_ASSERT(buf[0] == '\0'); 118 gpr_free(buf); 119 120 /* Print strings of various lengths. */ 121 for (i = 1; i < 100; i++) { 122 GPR_ASSERT(gpr_asprintf(&buf, "%0*d", i, 1) == i); 123 124 /* The buffer should resemble "000001\0". */ 125 for (j = 0; j < i - 2; j++) { 126 GPR_ASSERT(buf[j] == '0'); 127 } 128 GPR_ASSERT(buf[i - 1] == '1'); 129 GPR_ASSERT(buf[i] == '\0'); 130 gpr_free(buf); 131 } 132 } 133 134 static void test_strjoin(void) { 135 const char* parts[4] = {"one", "two", "three", "four"}; 136 size_t joined_len; 137 char* joined; 138 139 LOG_TEST_NAME("test_strjoin"); 140 141 joined = gpr_strjoin(parts, 4, &joined_len); 142 GPR_ASSERT(0 == strcmp("onetwothreefour", joined)); 143 gpr_free(joined); 144 145 joined = gpr_strjoin(parts, 0, &joined_len); 146 GPR_ASSERT(0 == strcmp("", joined)); 147 gpr_free(joined); 148 149 joined = gpr_strjoin(parts, 1, &joined_len); 150 GPR_ASSERT(0 == strcmp("one", joined)); 151 gpr_free(joined); 152 } 153 154 static void test_strjoin_sep(void) { 155 const char* parts[4] = {"one", "two", "three", "four"}; 156 size_t joined_len; 157 char* joined; 158 159 LOG_TEST_NAME("test_strjoin_sep"); 160 161 joined = gpr_strjoin_sep(parts, 4, ", ", &joined_len); 162 GPR_ASSERT(0 == strcmp("one, two, three, four", joined)); 163 gpr_free(joined); 164 165 /* empty separator */ 166 joined = gpr_strjoin_sep(parts, 4, "", &joined_len); 167 GPR_ASSERT(0 == strcmp("onetwothreefour", joined)); 168 gpr_free(joined); 169 170 /* degenerated case specifying zero input parts */ 171 joined = gpr_strjoin_sep(parts, 0, ", ", &joined_len); 172 GPR_ASSERT(0 == strcmp("", joined)); 173 gpr_free(joined); 174 175 /* single part should have no separator */ 176 joined = gpr_strjoin_sep(parts, 1, ", ", &joined_len); 177 GPR_ASSERT(0 == strcmp("one", joined)); 178 gpr_free(joined); 179 } 180 181 static void test_ltoa() { 182 char* str; 183 char buf[GPR_LTOA_MIN_BUFSIZE]; 184 185 LOG_TEST_NAME("test_ltoa"); 186 187 /* zero */ 188 GPR_ASSERT(1 == gpr_ltoa(0, buf)); 189 GPR_ASSERT(0 == strcmp("0", buf)); 190 191 /* positive number */ 192 GPR_ASSERT(3 == gpr_ltoa(123, buf)); 193 GPR_ASSERT(0 == strcmp("123", buf)); 194 195 /* negative number */ 196 GPR_ASSERT(6 == gpr_ltoa(-12345, buf)); 197 GPR_ASSERT(0 == strcmp("-12345", buf)); 198 199 /* large negative - we don't know the size of long in advance */ 200 GPR_ASSERT(gpr_asprintf(&str, "%lld", (long long)LONG_MIN)); 201 GPR_ASSERT(strlen(str) == (size_t)gpr_ltoa(LONG_MIN, buf)); 202 GPR_ASSERT(0 == strcmp(str, buf)); 203 gpr_free(str); 204 } 205 206 static void test_int64toa() { 207 char buf[GPR_INT64TOA_MIN_BUFSIZE]; 208 209 LOG_TEST_NAME("test_int64toa"); 210 211 /* zero */ 212 GPR_ASSERT(1 == int64_ttoa(0, buf)); 213 GPR_ASSERT(0 == strcmp("0", buf)); 214 215 /* positive */ 216 GPR_ASSERT(3 == int64_ttoa(123, buf)); 217 GPR_ASSERT(0 == strcmp("123", buf)); 218 219 /* large positive */ 220 GPR_ASSERT(19 == int64_ttoa(9223372036854775807LL, buf)); 221 GPR_ASSERT(0 == strcmp("9223372036854775807", buf)); 222 223 /* large negative */ 224 GPR_ASSERT(20 == int64_ttoa(-9223372036854775807LL - 1, buf)); 225 GPR_ASSERT(0 == strcmp("-9223372036854775808", buf)); 226 } 227 228 static void test_leftpad() { 229 char* padded; 230 231 LOG_TEST_NAME("test_leftpad"); 232 233 padded = gpr_leftpad("foo", ' ', 5); 234 GPR_ASSERT(0 == strcmp(" foo", padded)); 235 gpr_free(padded); 236 237 padded = gpr_leftpad("foo", ' ', 4); 238 GPR_ASSERT(0 == strcmp(" foo", padded)); 239 gpr_free(padded); 240 241 padded = gpr_leftpad("foo", ' ', 3); 242 GPR_ASSERT(0 == strcmp("foo", padded)); 243 gpr_free(padded); 244 245 padded = gpr_leftpad("foo", ' ', 2); 246 GPR_ASSERT(0 == strcmp("foo", padded)); 247 gpr_free(padded); 248 249 padded = gpr_leftpad("foo", ' ', 1); 250 GPR_ASSERT(0 == strcmp("foo", padded)); 251 gpr_free(padded); 252 253 padded = gpr_leftpad("foo", ' ', 0); 254 GPR_ASSERT(0 == strcmp("foo", padded)); 255 gpr_free(padded); 256 257 padded = gpr_leftpad("foo", '0', 5); 258 GPR_ASSERT(0 == strcmp("00foo", padded)); 259 gpr_free(padded); 260 } 261 262 static void test_stricmp(void) { 263 LOG_TEST_NAME("test_stricmp"); 264 265 GPR_ASSERT(0 == gpr_stricmp("hello", "hello")); 266 GPR_ASSERT(0 == gpr_stricmp("HELLO", "hello")); 267 GPR_ASSERT(gpr_stricmp("a", "b") < 0); 268 GPR_ASSERT(gpr_stricmp("b", "a") > 0); 269 } 270 271 static void test_memrchr(void) { 272 LOG_TEST_NAME("test_memrchr"); 273 274 GPR_ASSERT(nullptr == gpr_memrchr(nullptr, 'a', 0)); 275 GPR_ASSERT(nullptr == gpr_memrchr("", 'a', 0)); 276 GPR_ASSERT(nullptr == gpr_memrchr("hello", 'b', 5)); 277 GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'h', 5), "hello")); 278 GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'o', 5), "o")); 279 GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'l', 5), "lo")); 280 } 281 282 static void test_is_true(void) { 283 LOG_TEST_NAME("test_is_true"); 284 285 GPR_ASSERT(true == gpr_is_true("True")); 286 GPR_ASSERT(true == gpr_is_true("true")); 287 GPR_ASSERT(true == gpr_is_true("TRUE")); 288 GPR_ASSERT(true == gpr_is_true("Yes")); 289 GPR_ASSERT(true == gpr_is_true("yes")); 290 GPR_ASSERT(true == gpr_is_true("YES")); 291 GPR_ASSERT(true == gpr_is_true("1")); 292 GPR_ASSERT(false == gpr_is_true(nullptr)); 293 GPR_ASSERT(false == gpr_is_true("")); 294 GPR_ASSERT(false == gpr_is_true("0")); 295 } 296 297 int main(int argc, char** argv) { 298 grpc_test_init(argc, argv); 299 test_strdup(); 300 test_dump(); 301 test_parse_uint32(); 302 test_asprintf(); 303 test_strjoin(); 304 test_strjoin_sep(); 305 test_ltoa(); 306 test_int64toa(); 307 test_leftpad(); 308 test_stricmp(); 309 test_memrchr(); 310 test_is_true(); 311 return 0; 312 } 313