]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/ceph_argparse.cc
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"
19 #include "include/stringify.h"
23 /* Holds a std::vector with C-strings.
24 * Will free() them properly in the destructor.
26 * Note: the ceph_argparse functions modify the vector, removing elements as
27 * they find them. So we keep a parallel vector, orig, to make sure that we
28 * never forget to delete a string.
33 explicit VectorContainer(const char** arr_
) {
34 for (const char **a
= arr_
; *a
; ++a
) {
35 const char *str
= (const char*)strdup(*a
);
41 for (std::vector
<const char*>::iterator i
= orig
.begin();
48 arr
.assign(orig
.begin(), orig
.end());
50 std::vector
< const char* > arr
;
53 std::vector
< const char* > orig
;
56 TEST(CephArgParse
, SimpleArgParse
) {
57 const char *BAR5
[] = { "./myprog", "--bar", "5", NULL
};
58 const char *FOO
[] = { "./myprog", "--foo", "--baz", NULL
};
59 const char *NONE
[] = { "./myprog", NULL
};
61 bool found_foo
= false;
62 std::string found_bar
;
63 VectorContainer
bar5(BAR5
);
64 for (std::vector
<const char*>::iterator i
= bar5
.arr
.begin();
65 i
!= bar5
.arr
.end(); )
67 if (ceph_argparse_flag(bar5
.arr
, i
, "--foo", (char*)NULL
)) {
70 else if (ceph_argparse_witharg(bar5
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
75 ASSERT_EQ(found_foo
, false);
76 ASSERT_EQ(found_bar
, "5");
80 bool baz_found
= false;
81 std::string found_baz
= "";
82 VectorContainer
foo(FOO
);
84 for (std::vector
<const char*>::iterator i
= foo
.arr
.begin();
87 if (ceph_argparse_flag(foo
.arr
, i
, "--foo", (char*)NULL
)) {
90 else if (ceph_argparse_witharg(foo
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
92 else if (ceph_argparse_witharg(foo
.arr
, i
, &found_baz
, err
, "--baz", (char*)NULL
)) {
93 ASSERT_NE(string(""), err
.str());
99 ASSERT_EQ(found_foo
, true);
100 ASSERT_EQ(found_bar
, "");
101 ASSERT_EQ(baz_found
, true);
102 ASSERT_EQ(found_baz
, "");
106 VectorContainer
none(NONE
);
107 for (std::vector
<const char*>::iterator i
= none
.arr
.begin();
108 i
!= none
.arr
.end(); )
110 if (ceph_argparse_flag(none
.arr
, i
, "--foo", (char*)NULL
)) {
113 else if (ceph_argparse_witharg(none
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
118 ASSERT_EQ(found_foo
, false);
119 ASSERT_EQ(found_bar
, "");
122 TEST(CephArgParse
, DoubleDash
) {
123 const char *ARGS
[] = { "./myprog", "--foo", "5", "--", "--bar", "6", NULL
};
125 int foo
= -1, bar
= -1;
126 VectorContainer
args(ARGS
);
127 for (std::vector
<const char*>::iterator i
= args
.arr
.begin();
128 i
!= args
.arr
.end(); )
131 if (ceph_argparse_double_dash(args
.arr
, i
)) {
134 else if (ceph_argparse_witharg(args
.arr
, i
, &myarg
, "--foo", (char*)NULL
)) {
135 foo
= atoi(myarg
.c_str());
137 else if (ceph_argparse_witharg(args
.arr
, i
, &myarg
, "--bar", (char*)NULL
)) {
138 bar
= atoi(myarg
.c_str());
148 TEST(CephArgParse
, WithDashesAndUnderscores
) {
149 const char *BAZSTUFF1
[] = { "./myprog", "--goo", "--baz-stuff", "50", "--end", NULL
};
150 const char *BAZSTUFF2
[] = { "./myprog", "--goo2", "--baz_stuff", "50", NULL
};
151 const char *BAZSTUFF3
[] = { "./myprog", "--goo2", "--baz-stuff=50", "50", NULL
};
152 const char *BAZSTUFF4
[] = { "./myprog", "--goo2", "--baz_stuff=50", "50", NULL
};
153 const char *NONE1
[] = { "./myprog", NULL
};
154 const char *NONE2
[] = { "./myprog", "--goo2", "--baz_stuff2", "50", NULL
};
155 const char *NONE3
[] = { "./myprog", "--goo2", "__baz_stuff", "50", NULL
};
158 std::string found_baz
;
159 VectorContainer
bazstuff1(BAZSTUFF1
);
160 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
161 i
!= bazstuff1
.arr
.end(); )
163 if (ceph_argparse_flag(bazstuff1
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
169 ASSERT_EQ(found_baz
, "true");
173 VectorContainer
bazstuff2(BAZSTUFF2
);
174 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
175 i
!= bazstuff2
.arr
.end(); )
177 if (ceph_argparse_flag(bazstuff2
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
183 ASSERT_EQ(found_baz
, "true");
188 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
189 i
!= bazstuff1
.arr
.end(); )
191 if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
196 ASSERT_EQ(found_baz
, "50");
201 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
202 i
!= bazstuff2
.arr
.end(); )
204 if (ceph_argparse_witharg(bazstuff2
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
209 ASSERT_EQ(found_baz
, "50");
213 VectorContainer
bazstuff3(BAZSTUFF3
);
214 for (std::vector
<const char*>::iterator i
= bazstuff3
.arr
.begin();
215 i
!= bazstuff3
.arr
.end(); )
217 if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
222 ASSERT_EQ(found_baz
, "50");
226 VectorContainer
bazstuff4(BAZSTUFF4
);
227 for (std::vector
<const char*>::iterator i
= bazstuff4
.arr
.begin();
228 i
!= bazstuff4
.arr
.end(); )
230 if (ceph_argparse_witharg(bazstuff4
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
235 ASSERT_EQ(found_baz
, "50");
239 VectorContainer
none1(NONE1
);
240 for (std::vector
<const char*>::iterator i
= none1
.arr
.begin();
241 i
!= none1
.arr
.end(); )
243 if (ceph_argparse_flag(none1
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
246 else if (ceph_argparse_witharg(none1
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
251 ASSERT_EQ(found_baz
, "");
255 VectorContainer
none2(NONE2
);
256 for (std::vector
<const char*>::iterator i
= none2
.arr
.begin();
257 i
!= none2
.arr
.end(); )
259 if (ceph_argparse_flag(none2
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
262 else if (ceph_argparse_witharg(none2
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
267 ASSERT_EQ(found_baz
, "");
271 VectorContainer
none3(NONE3
);
272 for (std::vector
<const char*>::iterator i
= none3
.arr
.begin();
273 i
!= none3
.arr
.end(); )
275 if (ceph_argparse_flag(none3
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
278 else if (ceph_argparse_witharg(none3
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
283 ASSERT_EQ(found_baz
, "");
286 TEST(CephArgParse
, WithFloat
) {
287 const char *BAZSTUFF1
[] = { "./myprog", "--foo", "50.5", "--bar", "52", NULL
};
289 VectorContainer
bazstuff1(BAZSTUFF1
);
293 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
294 i
!= bazstuff1
.arr
.end(); )
296 if (ceph_argparse_double_dash(bazstuff1
.arr
, i
)) {
298 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
299 ASSERT_EQ(string(""), err
.str());
300 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
301 ASSERT_EQ(string(""), err
.str());
307 ASSERT_EQ(foo
, 50.5);
311 TEST(CephArgParse
, WithInt
) {
312 const char *BAZSTUFF1
[] = { "./myprog", "--foo", "50", "--bar", "52", NULL
};
313 const char *BAZSTUFF2
[] = { "./myprog", "--foo", "--bar", "52", NULL
};
314 const char *BAZSTUFF3
[] = { "./myprog", "--foo", "40", "--", "--bar", "42", NULL
};
317 VectorContainer
bazstuff1(BAZSTUFF1
);
319 int foo
= -1, bar
= -1;
320 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
321 i
!= bazstuff1
.arr
.end(); )
323 if (ceph_argparse_double_dash(bazstuff1
.arr
, i
)) {
325 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
326 ASSERT_EQ(string(""), err
.str());
327 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
328 ASSERT_EQ(string(""), err
.str());
338 VectorContainer
bazstuff2(BAZSTUFF2
);
340 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
341 i
!= bazstuff2
.arr
.end(); )
343 if (ceph_argparse_double_dash(bazstuff2
.arr
, i
)) {
345 } else if (ceph_argparse_witharg(bazstuff2
.arr
, i
, &foo
, err2
, "--foo", (char*)NULL
)) {
346 ASSERT_NE(string(""), err2
.str());
354 VectorContainer
bazstuff3(BAZSTUFF3
);
356 for (std::vector
<const char*>::iterator i
= bazstuff3
.arr
.begin();
357 i
!= bazstuff3
.arr
.end(); )
359 if (ceph_argparse_double_dash(bazstuff3
.arr
, i
)) {
361 } else if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
362 ASSERT_EQ(string(""), err
.str());
363 } else if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
364 ASSERT_EQ(string(""), err
.str());
374 TEST(CephArgParse
, env_to_vec
) {
376 std::vector
<const char*> args
;
377 unsetenv("CEPH_ARGS");
378 unsetenv("WHATEVER");
381 EXPECT_EQ(0u, args
.size());
383 env_to_vec(args
, "WHATEVER");
384 EXPECT_EQ(0u, args
.size());
386 setenv("CEPH_ARGS", "b c", 0);
389 EXPECT_EQ(3u, args
.size());
390 EXPECT_EQ(string("b"), args
[0]);
391 EXPECT_EQ(string("c"), args
[1]);
392 EXPECT_EQ(string("a"), args
[2]);
393 setenv("WHATEVER", "d e", 0);
395 env_to_vec(args
, "WHATEVER");
396 EXPECT_EQ(5u, args
.size());
397 EXPECT_EQ(string("d"), args
[0]);
398 EXPECT_EQ(string("e"), args
[1]);
401 std::vector
<const char*> args
;
402 unsetenv("CEPH_ARGS");
404 args
.push_back("--");
406 setenv("CEPH_ARGS", "b -- d", 0);
409 EXPECT_EQ(5u, args
.size());
410 EXPECT_EQ(string("b"), args
[0]);
411 EXPECT_EQ(string("a"), args
[1]);
412 EXPECT_EQ(string("--"), args
[2]);
413 EXPECT_EQ(string("d"), args
[3]);
414 EXPECT_EQ(string("c"), args
[4]);
417 std::vector
<const char*> args
;
418 unsetenv("CEPH_ARGS");
420 args
.push_back("--");
421 setenv("CEPH_ARGS", "b -- c", 0);
424 EXPECT_EQ(4u, args
.size());
425 EXPECT_EQ(string("b"), args
[0]);
426 EXPECT_EQ(string("a"), args
[1]);
427 EXPECT_EQ(string("--"), args
[2]);
428 EXPECT_EQ(string("c"), args
[3]);
431 std::vector
<const char*> args
;
432 unsetenv("CEPH_ARGS");
433 args
.push_back("--");
435 setenv("CEPH_ARGS", "b -- d", 0);
438 EXPECT_EQ(4u, args
.size());
439 EXPECT_EQ(string("b"), args
[0]);
440 EXPECT_EQ(string("--"), args
[1]);
441 EXPECT_EQ(string("d"), args
[2]);
442 EXPECT_EQ(string("c"), args
[3]);
445 std::vector
<const char*> args
;
446 unsetenv("CEPH_ARGS");
448 setenv("CEPH_ARGS", "c -- d", 0);
451 EXPECT_EQ(4u, args
.size());
452 EXPECT_EQ(string("c"), args
[0]);
453 EXPECT_EQ(string("b"), args
[1]);
454 EXPECT_EQ(string("--"), args
[2]);
455 EXPECT_EQ(string("d"), args
[3]);
458 std::vector
<const char*> args
;
459 unsetenv("CEPH_ARGS");
461 args
.push_back("--");
463 setenv("CEPH_ARGS", "-- d", 0);
466 EXPECT_EQ(4u, args
.size());
467 EXPECT_EQ(string("a"), args
[0]);
468 EXPECT_EQ(string("--"), args
[1]);
469 EXPECT_EQ(string("d"), args
[2]);
470 EXPECT_EQ(string("c"), args
[3]);
473 std::vector
<const char*> args
;
474 unsetenv("CEPH_ARGS");
476 args
.push_back("--");
478 setenv("CEPH_ARGS", "d", 0);
481 EXPECT_EQ(4u, args
.size());
482 EXPECT_EQ(string("d"), args
[0]);
483 EXPECT_EQ(string("a"), args
[1]);
484 EXPECT_EQ(string("--"), args
[2]);
485 EXPECT_EQ(string("c"), args
[3]);
489 TEST(CephArgParse
, parse_ip_port_vec
) {
495 { "1.2.3.4", entity_addr_t::TYPE_MSGR2
,
496 "v2:1.2.3.4:0/0\n" },
497 { "v1:1.2.3.4", entity_addr_t::TYPE_MSGR2
,
498 "v1:1.2.3.4:0/0\n" },
499 { "1.2.3.4", entity_addr_t::TYPE_LEGACY
,
500 "v1:1.2.3.4:0/0\n" },
501 { "[::],1.2.3.4", entity_addr_t::TYPE_LEGACY
,
502 "v1:[::]:0/0\nv1:1.2.3.4:0/0\n" },
503 { "v2:1.2.3.4:111,v1:5.6.7.8:222", entity_addr_t::TYPE_LEGACY
,
504 "v2:1.2.3.4:111/0\nv1:5.6.7.8:222/0\n" },
505 { "v2:1.2.3.4:111 v1:5.6.7.8:222", entity_addr_t::TYPE_LEGACY
,
506 "v2:1.2.3.4:111/0\nv1:5.6.7.8:222/0\n" },
507 { "[v2:1.2.3.4:111,v1:5.6.7.8:222] [v2:[::]:3300,v1:[::]:6789]",
508 entity_addr_t::TYPE_LEGACY
,
509 "[v2:1.2.3.4:111/0,v1:5.6.7.8:222/0]\n[v2:[::]:3300/0,v1:[::]:6789/0]\n" },
510 { "[v2:1.2.3.4:111,v1:5.6.7.8:222],[v2:[::]:3300,v1:[::]:6789]",
511 entity_addr_t::TYPE_LEGACY
,
512 "[v2:1.2.3.4:111/0,v1:5.6.7.8:222/0]\n[v2:[::]:3300/0,v1:[::]:6789/0]\n" },
516 for (unsigned i
= 0; tests
[i
].from
; ++i
) {
517 vector
<entity_addrvec_t
> v
;
518 cout
<< "-- " << tests
[i
].from
<< " type " << tests
[i
].type
519 << " ->\n" << tests
[i
].to
;
520 ASSERT_TRUE(parse_ip_port_vec(tests
[i
].from
, v
, tests
[i
].type
));
523 actual
+= stringify(s
) + "\n";
525 ASSERT_EQ(actual
, tests
[i
].to
);
528 const char *bad
[] = {
532 for (unsigned i
= 0; bad
[i
]; ++i
) {
533 vector
<entity_addrvec_t
> v
;
534 cout
<< "bad " << bad
[i
] << std::endl
;
535 ASSERT_FALSE(parse_ip_port_vec(bad
[i
], v
));
542 * compile-command: "cd .. ; make unittest_ceph_argparse && ./unittest_ceph_argparse"