1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/ceph_argparse.h"
17 #include "gtest/gtest.h"
20 /* Holds a std::vector with C-strings.
21 * Will free() them properly in the destructor.
23 * Note: the ceph_argparse functions modify the vector, removing elements as
24 * they find them. So we keep a parallel vector, orig, to make sure that we
25 * never forget to delete a string.
30 explicit VectorContainer(const char** arr_) {
31 for (const char **a = arr_; *a; ++a) {
32 const char *str = (const char*)strdup(*a);
38 for (std::vector<const char*>::iterator i = orig.begin();
45 arr.assign(orig.begin(), orig.end());
47 std::vector < const char* > arr;
50 std::vector < const char* > orig;
53 TEST(CephArgParse, SimpleArgParse) {
54 const char *BAR5[] = { "./myprog", "--bar", "5", NULL };
55 const char *FOO[] = { "./myprog", "--foo", "--baz", NULL };
56 const char *NONE[] = { "./myprog", NULL };
58 bool found_foo = false;
59 std::string found_bar;
60 VectorContainer bar5(BAR5);
61 for (std::vector<const char*>::iterator i = bar5.arr.begin();
62 i != bar5.arr.end(); )
64 if (ceph_argparse_flag(bar5.arr, i, "--foo", (char*)NULL)) {
67 else if (ceph_argparse_witharg(bar5.arr, i, &found_bar, "--bar", (char*)NULL)) {
72 ASSERT_EQ(found_foo, false);
73 ASSERT_EQ(found_bar, "5");
77 bool baz_found = false;
78 std::string found_baz = "";
79 VectorContainer foo(FOO);
81 for (std::vector<const char*>::iterator i = foo.arr.begin();
84 if (ceph_argparse_flag(foo.arr, i, "--foo", (char*)NULL)) {
87 else if (ceph_argparse_witharg(foo.arr, i, &found_bar, "--bar", (char*)NULL)) {
89 else if (ceph_argparse_witharg(foo.arr, i, &found_baz, err, "--baz", (char*)NULL)) {
90 ASSERT_NE(string(""), err.str());
96 ASSERT_EQ(found_foo, true);
97 ASSERT_EQ(found_bar, "");
98 ASSERT_EQ(baz_found, true);
99 ASSERT_EQ(found_baz, "");
103 VectorContainer none(NONE);
104 for (std::vector<const char*>::iterator i = none.arr.begin();
105 i != none.arr.end(); )
107 if (ceph_argparse_flag(none.arr, i, "--foo", (char*)NULL)) {
110 else if (ceph_argparse_witharg(none.arr, i, &found_bar, "--bar", (char*)NULL)) {
115 ASSERT_EQ(found_foo, false);
116 ASSERT_EQ(found_bar, "");
119 TEST(CephArgParse, DoubleDash) {
120 const char *ARGS[] = { "./myprog", "--foo", "5", "--", "--bar", "6", NULL };
122 int foo = -1, bar = -1;
123 VectorContainer args(ARGS);
124 for (std::vector<const char*>::iterator i = args.arr.begin();
125 i != args.arr.end(); )
128 if (ceph_argparse_double_dash(args.arr, i)) {
131 else if (ceph_argparse_witharg(args.arr, i, &myarg, "--foo", (char*)NULL)) {
132 foo = atoi(myarg.c_str());
134 else if (ceph_argparse_witharg(args.arr, i, &myarg, "--bar", (char*)NULL)) {
135 bar = atoi(myarg.c_str());
145 TEST(CephArgParse, WithDashesAndUnderscores) {
146 const char *BAZSTUFF1[] = { "./myprog", "--goo", "--baz-stuff", "50", "--end", NULL };
147 const char *BAZSTUFF2[] = { "./myprog", "--goo2", "--baz_stuff", "50", NULL };
148 const char *BAZSTUFF3[] = { "./myprog", "--goo2", "--baz-stuff=50", "50", NULL };
149 const char *BAZSTUFF4[] = { "./myprog", "--goo2", "--baz_stuff=50", "50", NULL };
150 const char *NONE1[] = { "./myprog", NULL };
151 const char *NONE2[] = { "./myprog", "--goo2", "--baz_stuff2", "50", NULL };
152 const char *NONE3[] = { "./myprog", "--goo2", "__baz_stuff", "50", NULL };
155 std::string found_baz;
156 VectorContainer bazstuff1(BAZSTUFF1);
157 for (std::vector<const char*>::iterator i = bazstuff1.arr.begin();
158 i != bazstuff1.arr.end(); )
160 if (ceph_argparse_flag(bazstuff1.arr, i, "--baz-stuff", (char*)NULL)) {
166 ASSERT_EQ(found_baz, "true");
170 VectorContainer bazstuff2(BAZSTUFF2);
171 for (std::vector<const char*>::iterator i = bazstuff2.arr.begin();
172 i != bazstuff2.arr.end(); )
174 if (ceph_argparse_flag(bazstuff2.arr, i, "--baz-stuff", (char*)NULL)) {
180 ASSERT_EQ(found_baz, "true");
185 for (std::vector<const char*>::iterator i = bazstuff1.arr.begin();
186 i != bazstuff1.arr.end(); )
188 if (ceph_argparse_witharg(bazstuff1.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
193 ASSERT_EQ(found_baz, "50");
198 for (std::vector<const char*>::iterator i = bazstuff2.arr.begin();
199 i != bazstuff2.arr.end(); )
201 if (ceph_argparse_witharg(bazstuff2.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
206 ASSERT_EQ(found_baz, "50");
210 VectorContainer bazstuff3(BAZSTUFF3);
211 for (std::vector<const char*>::iterator i = bazstuff3.arr.begin();
212 i != bazstuff3.arr.end(); )
214 if (ceph_argparse_witharg(bazstuff3.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
219 ASSERT_EQ(found_baz, "50");
223 VectorContainer bazstuff4(BAZSTUFF4);
224 for (std::vector<const char*>::iterator i = bazstuff4.arr.begin();
225 i != bazstuff4.arr.end(); )
227 if (ceph_argparse_witharg(bazstuff4.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
232 ASSERT_EQ(found_baz, "50");
236 VectorContainer none1(NONE1);
237 for (std::vector<const char*>::iterator i = none1.arr.begin();
238 i != none1.arr.end(); )
240 if (ceph_argparse_flag(none1.arr, i, "--baz-stuff", (char*)NULL)) {
243 else if (ceph_argparse_witharg(none1.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
248 ASSERT_EQ(found_baz, "");
252 VectorContainer none2(NONE2);
253 for (std::vector<const char*>::iterator i = none2.arr.begin();
254 i != none2.arr.end(); )
256 if (ceph_argparse_flag(none2.arr, i, "--baz-stuff", (char*)NULL)) {
259 else if (ceph_argparse_witharg(none2.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
264 ASSERT_EQ(found_baz, "");
268 VectorContainer none3(NONE3);
269 for (std::vector<const char*>::iterator i = none3.arr.begin();
270 i != none3.arr.end(); )
272 if (ceph_argparse_flag(none3.arr, i, "--baz-stuff", (char*)NULL)) {
275 else if (ceph_argparse_witharg(none3.arr, i, &found_baz, "--baz-stuff", (char*)NULL)) {
280 ASSERT_EQ(found_baz, "");
283 TEST(CephArgParse, WithFloat) {
284 const char *BAZSTUFF1[] = { "./myprog", "--foo", "50.5", "--bar", "52", NULL };
286 VectorContainer bazstuff1(BAZSTUFF1);
290 for (std::vector<const char*>::iterator i = bazstuff1.arr.begin();
291 i != bazstuff1.arr.end(); )
293 if (ceph_argparse_double_dash(bazstuff1.arr, i)) {
295 } else if (ceph_argparse_witharg(bazstuff1.arr, i, &foo, err, "--foo", (char*)NULL)) {
296 ASSERT_EQ(string(""), err.str());
297 } else if (ceph_argparse_witharg(bazstuff1.arr, i, &bar, err, "--bar", (char*)NULL)) {
298 ASSERT_EQ(string(""), err.str());
304 ASSERT_EQ(foo, 50.5);
308 TEST(CephArgParse, WithInt) {
309 const char *BAZSTUFF1[] = { "./myprog", "--foo", "50", "--bar", "52", NULL };
310 const char *BAZSTUFF2[] = { "./myprog", "--foo", "--bar", "52", NULL };
311 const char *BAZSTUFF3[] = { "./myprog", "--foo", "40", "--", "--bar", "42", NULL };
314 VectorContainer bazstuff1(BAZSTUFF1);
316 int foo = -1, bar = -1;
317 for (std::vector<const char*>::iterator i = bazstuff1.arr.begin();
318 i != bazstuff1.arr.end(); )
320 if (ceph_argparse_double_dash(bazstuff1.arr, i)) {
322 } else if (ceph_argparse_witharg(bazstuff1.arr, i, &foo, err, "--foo", (char*)NULL)) {
323 ASSERT_EQ(string(""), err.str());
324 } else if (ceph_argparse_witharg(bazstuff1.arr, i, &bar, err, "--bar", (char*)NULL)) {
325 ASSERT_EQ(string(""), err.str());
335 VectorContainer bazstuff2(BAZSTUFF2);
337 for (std::vector<const char*>::iterator i = bazstuff2.arr.begin();
338 i != bazstuff2.arr.end(); )
340 if (ceph_argparse_double_dash(bazstuff2.arr, i)) {
342 } else if (ceph_argparse_witharg(bazstuff2.arr, i, &foo, err2, "--foo", (char*)NULL)) {
343 ASSERT_NE(string(""), err2.str());
351 VectorContainer bazstuff3(BAZSTUFF3);
353 for (std::vector<const char*>::iterator i = bazstuff3.arr.begin();
354 i != bazstuff3.arr.end(); )
356 if (ceph_argparse_double_dash(bazstuff3.arr, i)) {
358 } else if (ceph_argparse_witharg(bazstuff3.arr, i, &foo, err, "--foo", (char*)NULL)) {
359 ASSERT_EQ(string(""), err.str());
360 } else if (ceph_argparse_witharg(bazstuff3.arr, i, &bar, err, "--bar", (char*)NULL)) {
361 ASSERT_EQ(string(""), err.str());
371 TEST(CephArgParse, env_to_vec) {
373 std::vector<const char*> args;
374 unsetenv("CEPH_ARGS");
375 unsetenv("WHATEVER");
377 EXPECT_EQ(0u, args.size());
378 env_to_vec(args, "WHATEVER");
379 EXPECT_EQ(0u, args.size());
381 setenv("CEPH_ARGS", "b c", 0);
383 EXPECT_EQ(3u, args.size());
384 EXPECT_EQ(string("b"), args[1]);
385 EXPECT_EQ(string("c"), args[2]);
386 setenv("WHATEVER", "d e", 0);
387 env_to_vec(args, "WHATEVER");
388 EXPECT_EQ(5u, args.size());
389 EXPECT_EQ(string("d"), args[3]);
390 EXPECT_EQ(string("e"), args[4]);
393 std::vector<const char*> args;
394 unsetenv("CEPH_ARGS");
396 args.push_back("--");
398 setenv("CEPH_ARGS", "b -- d", 0);
400 EXPECT_EQ(5u, args.size());
401 EXPECT_EQ(string("a"), args[0]);
402 EXPECT_EQ(string("b"), args[1]);
403 EXPECT_EQ(string("--"), args[2]);
404 EXPECT_EQ(string("c"), args[3]);
405 EXPECT_EQ(string("d"), args[4]);
408 std::vector<const char*> args;
409 unsetenv("CEPH_ARGS");
411 args.push_back("--");
412 setenv("CEPH_ARGS", "b -- c", 0);
414 EXPECT_EQ(4u, args.size());
415 EXPECT_EQ(string("a"), args[0]);
416 EXPECT_EQ(string("b"), args[1]);
417 EXPECT_EQ(string("--"), args[2]);
418 EXPECT_EQ(string("c"), args[3]);
421 std::vector<const char*> args;
422 unsetenv("CEPH_ARGS");
423 args.push_back("--");
425 setenv("CEPH_ARGS", "b -- d", 0);
427 EXPECT_EQ(4u, args.size());
428 EXPECT_EQ(string("b"), args[0]);
429 EXPECT_EQ(string("--"), args[1]);
430 EXPECT_EQ(string("c"), args[2]);
431 EXPECT_EQ(string("d"), args[3]);
434 std::vector<const char*> args;
435 unsetenv("CEPH_ARGS");
437 setenv("CEPH_ARGS", "c -- d", 0);
439 EXPECT_EQ(4u, args.size());
440 EXPECT_EQ(string("b"), args[0]);
441 EXPECT_EQ(string("c"), args[1]);
442 EXPECT_EQ(string("--"), args[2]);
443 EXPECT_EQ(string("d"), args[3]);
446 std::vector<const char*> args;
447 unsetenv("CEPH_ARGS");
449 args.push_back("--");
451 setenv("CEPH_ARGS", "-- d", 0);
453 EXPECT_EQ(4u, args.size());
454 EXPECT_EQ(string("a"), args[0]);
455 EXPECT_EQ(string("--"), args[1]);
456 EXPECT_EQ(string("c"), args[2]);
457 EXPECT_EQ(string("d"), args[3]);
460 std::vector<const char*> args;
461 unsetenv("CEPH_ARGS");
463 args.push_back("--");
465 setenv("CEPH_ARGS", "d", 0);
467 EXPECT_EQ(4u, args.size());
468 EXPECT_EQ(string("a"), args[0]);
469 EXPECT_EQ(string("d"), args[1]);
470 EXPECT_EQ(string("--"), args[2]);
471 EXPECT_EQ(string("c"), args[3]);
476 * compile-command: "cd .. ; make unittest_ceph_argparse && ./unittest_ceph_argparse"