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 <string.h>
20
21 #include <grpc/support/alloc.h>
22 #include <grpc/support/log.h>
23
24 #include "src/core/lib/gpr/useful.h"
25 #include "test/core/util/cmdline.h"
26 #include "test/core/util/test_config.h"
27
28 #define LOG_TEST() gpr_log(GPR_INFO, "test at %s:%d", __FILE__, __LINE__)
29
test_simple_int(void)30 static void test_simple_int(void) {
31 int x = 1;
32 gpr_cmdline* cl;
33 char* args[] = {(char*)__FILE__, const_cast<char*>("-foo"),
34 const_cast<char*>("3")};
35
36 LOG_TEST();
37
38 cl = gpr_cmdline_create(nullptr);
39 gpr_cmdline_add_int(cl, "foo", nullptr, &x);
40 GPR_ASSERT(x == 1);
41 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
42 GPR_ASSERT(x == 3);
43 gpr_cmdline_destroy(cl);
44 }
45
test_eq_int(void)46 static void test_eq_int(void) {
47 int x = 1;
48 gpr_cmdline* cl;
49 char* args[] = {(char*)__FILE__, const_cast<char*>("-foo=3")};
50
51 LOG_TEST();
52
53 cl = gpr_cmdline_create(nullptr);
54 gpr_cmdline_add_int(cl, "foo", nullptr, &x);
55 GPR_ASSERT(x == 1);
56 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
57 GPR_ASSERT(x == 3);
58 gpr_cmdline_destroy(cl);
59 }
60
test_2dash_int(void)61 static void test_2dash_int(void) {
62 int x = 1;
63 gpr_cmdline* cl;
64 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo"),
65 const_cast<char*>("3")};
66
67 LOG_TEST();
68
69 cl = gpr_cmdline_create(nullptr);
70 gpr_cmdline_add_int(cl, "foo", nullptr, &x);
71 GPR_ASSERT(x == 1);
72 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
73 GPR_ASSERT(x == 3);
74 gpr_cmdline_destroy(cl);
75 }
76
test_2dash_eq_int(void)77 static void test_2dash_eq_int(void) {
78 int x = 1;
79 gpr_cmdline* cl;
80 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=3")};
81
82 LOG_TEST();
83
84 cl = gpr_cmdline_create(nullptr);
85 gpr_cmdline_add_int(cl, "foo", nullptr, &x);
86 GPR_ASSERT(x == 1);
87 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
88 GPR_ASSERT(x == 3);
89 gpr_cmdline_destroy(cl);
90 }
91
test_simple_string(void)92 static void test_simple_string(void) {
93 const char* x = nullptr;
94 gpr_cmdline* cl;
95 char* args[] = {(char*)__FILE__, const_cast<char*>("-foo"),
96 const_cast<char*>("3")};
97
98 LOG_TEST();
99
100 cl = gpr_cmdline_create(nullptr);
101 gpr_cmdline_add_string(cl, "foo", nullptr, &x);
102 GPR_ASSERT(x == nullptr);
103 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
104 GPR_ASSERT(0 == strcmp(x, "3"));
105 gpr_cmdline_destroy(cl);
106 }
107
test_eq_string(void)108 static void test_eq_string(void) {
109 const char* x = nullptr;
110 gpr_cmdline* cl;
111 char* args[] = {(char*)__FILE__, const_cast<char*>("-foo=3")};
112
113 LOG_TEST();
114
115 cl = gpr_cmdline_create(nullptr);
116 gpr_cmdline_add_string(cl, "foo", nullptr, &x);
117 GPR_ASSERT(x == nullptr);
118 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
119 GPR_ASSERT(0 == strcmp(x, "3"));
120 gpr_cmdline_destroy(cl);
121 }
122
test_2dash_string(void)123 static void test_2dash_string(void) {
124 const char* x = nullptr;
125 gpr_cmdline* cl;
126 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo"),
127 const_cast<char*>("3")};
128
129 LOG_TEST();
130
131 cl = gpr_cmdline_create(nullptr);
132 gpr_cmdline_add_string(cl, "foo", nullptr, &x);
133 GPR_ASSERT(x == nullptr);
134 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
135 GPR_ASSERT(0 == strcmp(x, "3"));
136 gpr_cmdline_destroy(cl);
137 }
138
test_2dash_eq_string(void)139 static void test_2dash_eq_string(void) {
140 const char* x = nullptr;
141 gpr_cmdline* cl;
142 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=3")};
143
144 LOG_TEST();
145
146 cl = gpr_cmdline_create(nullptr);
147 gpr_cmdline_add_string(cl, "foo", nullptr, &x);
148 GPR_ASSERT(x == nullptr);
149 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
150 GPR_ASSERT(0 == strcmp(x, "3"));
151 gpr_cmdline_destroy(cl);
152 }
153
test_flag_on(void)154 static void test_flag_on(void) {
155 int x = 2;
156 gpr_cmdline* cl;
157 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo")};
158
159 LOG_TEST();
160
161 cl = gpr_cmdline_create(nullptr);
162 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
163 GPR_ASSERT(x == 2);
164 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
165 GPR_ASSERT(x == 1);
166 gpr_cmdline_destroy(cl);
167 }
168
test_flag_no(void)169 static void test_flag_no(void) {
170 int x = 2;
171 gpr_cmdline* cl;
172 char* args[] = {(char*)__FILE__, const_cast<char*>("--no-foo")};
173
174 LOG_TEST();
175
176 cl = gpr_cmdline_create(nullptr);
177 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
178 GPR_ASSERT(x == 2);
179 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
180 GPR_ASSERT(x == 0);
181 gpr_cmdline_destroy(cl);
182 }
183
test_flag_val_1(void)184 static void test_flag_val_1(void) {
185 int x = 2;
186 gpr_cmdline* cl;
187 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=1")};
188
189 LOG_TEST();
190
191 cl = gpr_cmdline_create(nullptr);
192 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
193 GPR_ASSERT(x == 2);
194 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
195 GPR_ASSERT(x == 1);
196 gpr_cmdline_destroy(cl);
197 }
198
test_flag_val_0(void)199 static void test_flag_val_0(void) {
200 int x = 2;
201 gpr_cmdline* cl;
202 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=0")};
203
204 LOG_TEST();
205
206 cl = gpr_cmdline_create(nullptr);
207 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
208 GPR_ASSERT(x == 2);
209 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
210 GPR_ASSERT(x == 0);
211 gpr_cmdline_destroy(cl);
212 }
213
test_flag_val_true(void)214 static void test_flag_val_true(void) {
215 int x = 2;
216 gpr_cmdline* cl;
217 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=true")};
218
219 LOG_TEST();
220
221 cl = gpr_cmdline_create(nullptr);
222 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
223 GPR_ASSERT(x == 2);
224 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
225 GPR_ASSERT(x == 1);
226 gpr_cmdline_destroy(cl);
227 }
228
test_flag_val_false(void)229 static void test_flag_val_false(void) {
230 int x = 2;
231 gpr_cmdline* cl;
232 char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=false")};
233
234 LOG_TEST();
235
236 cl = gpr_cmdline_create(nullptr);
237 gpr_cmdline_add_flag(cl, "foo", nullptr, &x);
238 GPR_ASSERT(x == 2);
239 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
240 GPR_ASSERT(x == 0);
241 gpr_cmdline_destroy(cl);
242 }
243
test_many(void)244 static void test_many(void) {
245 const char* str = nullptr;
246 int x = 0;
247 int flag = 2;
248 gpr_cmdline* cl;
249
250 char* args[] = {(char*)__FILE__, const_cast<char*>("--str"),
251 const_cast<char*>("hello"), const_cast<char*>("-x=4"),
252 const_cast<char*>("-no-flag")};
253
254 LOG_TEST();
255
256 cl = gpr_cmdline_create(nullptr);
257 gpr_cmdline_add_string(cl, "str", nullptr, &str);
258 gpr_cmdline_add_int(cl, "x", nullptr, &x);
259 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
260 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
261 GPR_ASSERT(x == 4);
262 GPR_ASSERT(0 == strcmp(str, "hello"));
263 GPR_ASSERT(flag == 0);
264 gpr_cmdline_destroy(cl);
265 }
266
extra_arg_cb(void * user_data,const char * arg)267 static void extra_arg_cb(void* user_data, const char* arg) {
268 int* count = static_cast<int*>(user_data);
269 GPR_ASSERT(arg != nullptr);
270 GPR_ASSERT(strlen(arg) == 1);
271 GPR_ASSERT(arg[0] == 'a' + *count);
272 ++*count;
273 }
274
test_extra(void)275 static void test_extra(void) {
276 gpr_cmdline* cl;
277 int count = 0;
278 char* args[] = {(char*)__FILE__, const_cast<char*>("a"),
279 const_cast<char*>("b"), const_cast<char*>("c")};
280
281 LOG_TEST();
282
283 cl = gpr_cmdline_create(nullptr);
284 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
285 &count);
286 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
287 GPR_ASSERT(count == 3);
288 gpr_cmdline_destroy(cl);
289 }
290
test_extra_dashdash(void)291 static void test_extra_dashdash(void) {
292 gpr_cmdline* cl;
293 int count = 0;
294 char* args[] = {(char*)__FILE__, const_cast<char*>("--"),
295 const_cast<char*>("a"), const_cast<char*>("b"),
296 const_cast<char*>("c")};
297
298 LOG_TEST();
299
300 cl = gpr_cmdline_create(nullptr);
301 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
302 &count);
303 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args);
304 GPR_ASSERT(count == 3);
305 gpr_cmdline_destroy(cl);
306 }
307
test_usage(void)308 static void test_usage(void) {
309 gpr_cmdline* cl;
310
311 const char* str = nullptr;
312 int x = 0;
313 int flag = 2;
314
315 LOG_TEST();
316
317 cl = gpr_cmdline_create(nullptr);
318 gpr_cmdline_add_string(cl, "str", nullptr, &str);
319 gpr_cmdline_add_int(cl, "x", nullptr, &x);
320 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
321 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
322 nullptr);
323
324 std::string usage = gpr_cmdline_usage_string(cl, "test");
325 GPR_ASSERT(usage ==
326 "Usage: test [--str=string] [--x=int] "
327 "[--flag|--no-flag] [file...]\n");
328
329 usage = gpr_cmdline_usage_string(cl, "/foo/test");
330 GPR_ASSERT(usage ==
331 "Usage: test [--str=string] [--x=int] "
332 "[--flag|--no-flag] [file...]\n");
333
334 gpr_cmdline_destroy(cl);
335 }
336
test_help(void)337 static void test_help(void) {
338 gpr_cmdline* cl;
339
340 const char* str = nullptr;
341 int x = 0;
342 int flag = 2;
343
344 char* help[] = {(char*)__FILE__, const_cast<char*>("-h")};
345
346 LOG_TEST();
347
348 cl = gpr_cmdline_create(nullptr);
349 gpr_cmdline_set_survive_failure(cl);
350 gpr_cmdline_add_string(cl, "str", nullptr, &str);
351 gpr_cmdline_add_int(cl, "x", nullptr, &x);
352 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
353 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
354 nullptr);
355
356 GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(help), help));
357
358 gpr_cmdline_destroy(cl);
359 }
360
test_badargs1(void)361 static void test_badargs1(void) {
362 gpr_cmdline* cl;
363
364 const char* str = nullptr;
365 int x = 0;
366 int flag = 2;
367
368 char* bad_arg_name[] = {(char*)__FILE__, const_cast<char*>("--y")};
369
370 LOG_TEST();
371
372 cl = gpr_cmdline_create(nullptr);
373 gpr_cmdline_set_survive_failure(cl);
374 gpr_cmdline_add_string(cl, "str", nullptr, &str);
375 gpr_cmdline_add_int(cl, "x", nullptr, &x);
376 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
377 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
378 nullptr);
379
380 GPR_ASSERT(0 ==
381 gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_arg_name), bad_arg_name));
382
383 gpr_cmdline_destroy(cl);
384 }
385
test_badargs2(void)386 static void test_badargs2(void) {
387 gpr_cmdline* cl;
388
389 const char* str = nullptr;
390 int x = 0;
391 int flag = 2;
392
393 char* bad_int_value[] = {(char*)__FILE__, const_cast<char*>("--x"),
394 const_cast<char*>("henry")};
395
396 LOG_TEST();
397
398 cl = gpr_cmdline_create(nullptr);
399 gpr_cmdline_set_survive_failure(cl);
400 gpr_cmdline_add_string(cl, "str", nullptr, &str);
401 gpr_cmdline_add_int(cl, "x", nullptr, &x);
402 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
403 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
404 nullptr);
405
406 GPR_ASSERT(
407 0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_int_value), bad_int_value));
408
409 gpr_cmdline_destroy(cl);
410 }
411
test_badargs3(void)412 static void test_badargs3(void) {
413 gpr_cmdline* cl;
414
415 const char* str = nullptr;
416 int x = 0;
417 int flag = 2;
418
419 char* bad_bool_value[] = {(char*)__FILE__, const_cast<char*>("--flag=henry")};
420
421 LOG_TEST();
422
423 cl = gpr_cmdline_create(nullptr);
424 gpr_cmdline_set_survive_failure(cl);
425 gpr_cmdline_add_string(cl, "str", nullptr, &str);
426 gpr_cmdline_add_int(cl, "x", nullptr, &x);
427 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
428 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
429 nullptr);
430
431 GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value),
432 bad_bool_value));
433
434 gpr_cmdline_destroy(cl);
435 }
436
test_badargs4(void)437 static void test_badargs4(void) {
438 gpr_cmdline* cl;
439
440 const char* str = nullptr;
441 int x = 0;
442 int flag = 2;
443
444 char* bad_bool_value[] = {(char*)__FILE__, const_cast<char*>("--no-str")};
445
446 LOG_TEST();
447
448 cl = gpr_cmdline_create(nullptr);
449 gpr_cmdline_set_survive_failure(cl);
450 gpr_cmdline_add_string(cl, "str", nullptr, &str);
451 gpr_cmdline_add_int(cl, "x", nullptr, &x);
452 gpr_cmdline_add_flag(cl, "flag", nullptr, &flag);
453 gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb,
454 nullptr);
455
456 GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value),
457 bad_bool_value));
458
459 gpr_cmdline_destroy(cl);
460 }
461
main(int argc,char ** argv)462 int main(int argc, char** argv) {
463 grpc::testing::TestEnvironment env(argc, argv);
464 test_simple_int();
465 test_eq_int();
466 test_2dash_int();
467 test_2dash_eq_int();
468 test_simple_string();
469 test_eq_string();
470 test_2dash_string();
471 test_2dash_eq_string();
472 test_flag_on();
473 test_flag_no();
474 test_flag_val_1();
475 test_flag_val_0();
476 test_flag_val_true();
477 test_flag_val_false();
478 test_many();
479 test_extra();
480 test_extra_dashdash();
481 test_usage();
482 test_help();
483 test_badargs1();
484 test_badargs2();
485 test_badargs3();
486 test_badargs4();
487 return 0;
488 }
489