]>
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"
21 /* Holds a std::vector with C-strings.
22 * Will free() them properly in the destructor.
24 * Note: the ceph_argparse functions modify the vector, removing elements as
25 * they find them. So we keep a parallel vector, orig, to make sure that we
26 * never forget to delete a string.
31 explicit VectorContainer(const char** arr_
) {
32 for (const char **a
= arr_
; *a
; ++a
) {
33 const char *str
= (const char*)strdup(*a
);
39 for (std::vector
<const char*>::iterator i
= orig
.begin();
46 arr
.assign(orig
.begin(), orig
.end());
48 std::vector
< const char* > arr
;
51 std::vector
< const char* > orig
;
54 TEST(CephArgParse
, SimpleArgParse
) {
55 const char *BAR5
[] = { "./myprog", "--bar", "5", NULL
};
56 const char *FOO
[] = { "./myprog", "--foo", "--baz", NULL
};
57 const char *NONE
[] = { "./myprog", NULL
};
59 bool found_foo
= false;
60 std::string found_bar
;
61 VectorContainer
bar5(BAR5
);
62 for (std::vector
<const char*>::iterator i
= bar5
.arr
.begin();
63 i
!= bar5
.arr
.end(); )
65 if (ceph_argparse_flag(bar5
.arr
, i
, "--foo", (char*)NULL
)) {
68 else if (ceph_argparse_witharg(bar5
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
73 ASSERT_EQ(found_foo
, false);
74 ASSERT_EQ(found_bar
, "5");
78 bool baz_found
= false;
79 std::string found_baz
= "";
80 VectorContainer
foo(FOO
);
82 for (std::vector
<const char*>::iterator i
= foo
.arr
.begin();
85 if (ceph_argparse_flag(foo
.arr
, i
, "--foo", (char*)NULL
)) {
88 else if (ceph_argparse_witharg(foo
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
90 else if (ceph_argparse_witharg(foo
.arr
, i
, &found_baz
, err
, "--baz", (char*)NULL
)) {
91 ASSERT_NE(string(""), err
.str());
97 ASSERT_EQ(found_foo
, true);
98 ASSERT_EQ(found_bar
, "");
99 ASSERT_EQ(baz_found
, true);
100 ASSERT_EQ(found_baz
, "");
104 VectorContainer
none(NONE
);
105 for (std::vector
<const char*>::iterator i
= none
.arr
.begin();
106 i
!= none
.arr
.end(); )
108 if (ceph_argparse_flag(none
.arr
, i
, "--foo", (char*)NULL
)) {
111 else if (ceph_argparse_witharg(none
.arr
, i
, &found_bar
, "--bar", (char*)NULL
)) {
116 ASSERT_EQ(found_foo
, false);
117 ASSERT_EQ(found_bar
, "");
120 TEST(CephArgParse
, DoubleDash
) {
121 const char *ARGS
[] = { "./myprog", "--foo", "5", "--", "--bar", "6", NULL
};
123 int foo
= -1, bar
= -1;
124 VectorContainer
args(ARGS
);
125 for (std::vector
<const char*>::iterator i
= args
.arr
.begin();
126 i
!= args
.arr
.end(); )
129 if (ceph_argparse_double_dash(args
.arr
, i
)) {
132 else if (ceph_argparse_witharg(args
.arr
, i
, &myarg
, "--foo", (char*)NULL
)) {
133 foo
= atoi(myarg
.c_str());
135 else if (ceph_argparse_witharg(args
.arr
, i
, &myarg
, "--bar", (char*)NULL
)) {
136 bar
= atoi(myarg
.c_str());
146 TEST(CephArgParse
, WithDashesAndUnderscores
) {
147 const char *BAZSTUFF1
[] = { "./myprog", "--goo", "--baz-stuff", "50", "--end", NULL
};
148 const char *BAZSTUFF2
[] = { "./myprog", "--goo2", "--baz_stuff", "50", NULL
};
149 const char *BAZSTUFF3
[] = { "./myprog", "--goo2", "--baz-stuff=50", "50", NULL
};
150 const char *BAZSTUFF4
[] = { "./myprog", "--goo2", "--baz_stuff=50", "50", NULL
};
151 const char *NONE1
[] = { "./myprog", NULL
};
152 const char *NONE2
[] = { "./myprog", "--goo2", "--baz_stuff2", "50", NULL
};
153 const char *NONE3
[] = { "./myprog", "--goo2", "__baz_stuff", "50", NULL
};
156 std::string found_baz
;
157 VectorContainer
bazstuff1(BAZSTUFF1
);
158 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
159 i
!= bazstuff1
.arr
.end(); )
161 if (ceph_argparse_flag(bazstuff1
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
167 ASSERT_EQ(found_baz
, "true");
171 VectorContainer
bazstuff2(BAZSTUFF2
);
172 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
173 i
!= bazstuff2
.arr
.end(); )
175 if (ceph_argparse_flag(bazstuff2
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
181 ASSERT_EQ(found_baz
, "true");
186 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
187 i
!= bazstuff1
.arr
.end(); )
189 if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
194 ASSERT_EQ(found_baz
, "50");
199 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
200 i
!= bazstuff2
.arr
.end(); )
202 if (ceph_argparse_witharg(bazstuff2
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
207 ASSERT_EQ(found_baz
, "50");
211 VectorContainer
bazstuff3(BAZSTUFF3
);
212 for (std::vector
<const char*>::iterator i
= bazstuff3
.arr
.begin();
213 i
!= bazstuff3
.arr
.end(); )
215 if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
220 ASSERT_EQ(found_baz
, "50");
224 VectorContainer
bazstuff4(BAZSTUFF4
);
225 for (std::vector
<const char*>::iterator i
= bazstuff4
.arr
.begin();
226 i
!= bazstuff4
.arr
.end(); )
228 if (ceph_argparse_witharg(bazstuff4
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
233 ASSERT_EQ(found_baz
, "50");
237 VectorContainer
none1(NONE1
);
238 for (std::vector
<const char*>::iterator i
= none1
.arr
.begin();
239 i
!= none1
.arr
.end(); )
241 if (ceph_argparse_flag(none1
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
244 else if (ceph_argparse_witharg(none1
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
249 ASSERT_EQ(found_baz
, "");
253 VectorContainer
none2(NONE2
);
254 for (std::vector
<const char*>::iterator i
= none2
.arr
.begin();
255 i
!= none2
.arr
.end(); )
257 if (ceph_argparse_flag(none2
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
260 else if (ceph_argparse_witharg(none2
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
265 ASSERT_EQ(found_baz
, "");
269 VectorContainer
none3(NONE3
);
270 for (std::vector
<const char*>::iterator i
= none3
.arr
.begin();
271 i
!= none3
.arr
.end(); )
273 if (ceph_argparse_flag(none3
.arr
, i
, "--baz-stuff", (char*)NULL
)) {
276 else if (ceph_argparse_witharg(none3
.arr
, i
, &found_baz
, "--baz-stuff", (char*)NULL
)) {
281 ASSERT_EQ(found_baz
, "");
284 TEST(CephArgParse
, WithFloat
) {
285 const char *BAZSTUFF1
[] = { "./myprog", "--foo", "50.5", "--bar", "52", NULL
};
287 VectorContainer
bazstuff1(BAZSTUFF1
);
291 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
292 i
!= bazstuff1
.arr
.end(); )
294 if (ceph_argparse_double_dash(bazstuff1
.arr
, i
)) {
296 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
297 ASSERT_EQ(string(""), err
.str());
298 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
299 ASSERT_EQ(string(""), err
.str());
305 ASSERT_EQ(foo
, 50.5);
309 TEST(CephArgParse
, WithInt
) {
310 const char *BAZSTUFF1
[] = { "./myprog", "--foo", "50", "--bar", "52", NULL
};
311 const char *BAZSTUFF2
[] = { "./myprog", "--foo", "--bar", "52", NULL
};
312 const char *BAZSTUFF3
[] = { "./myprog", "--foo", "40", "--", "--bar", "42", NULL
};
315 VectorContainer
bazstuff1(BAZSTUFF1
);
317 int foo
= -1, bar
= -1;
318 for (std::vector
<const char*>::iterator i
= bazstuff1
.arr
.begin();
319 i
!= bazstuff1
.arr
.end(); )
321 if (ceph_argparse_double_dash(bazstuff1
.arr
, i
)) {
323 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
324 ASSERT_EQ(string(""), err
.str());
325 } else if (ceph_argparse_witharg(bazstuff1
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
326 ASSERT_EQ(string(""), err
.str());
336 VectorContainer
bazstuff2(BAZSTUFF2
);
338 for (std::vector
<const char*>::iterator i
= bazstuff2
.arr
.begin();
339 i
!= bazstuff2
.arr
.end(); )
341 if (ceph_argparse_double_dash(bazstuff2
.arr
, i
)) {
343 } else if (ceph_argparse_witharg(bazstuff2
.arr
, i
, &foo
, err2
, "--foo", (char*)NULL
)) {
344 ASSERT_NE(string(""), err2
.str());
352 VectorContainer
bazstuff3(BAZSTUFF3
);
354 for (std::vector
<const char*>::iterator i
= bazstuff3
.arr
.begin();
355 i
!= bazstuff3
.arr
.end(); )
357 if (ceph_argparse_double_dash(bazstuff3
.arr
, i
)) {
359 } else if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &foo
, err
, "--foo", (char*)NULL
)) {
360 ASSERT_EQ(string(""), err
.str());
361 } else if (ceph_argparse_witharg(bazstuff3
.arr
, i
, &bar
, err
, "--bar", (char*)NULL
)) {
362 ASSERT_EQ(string(""), err
.str());
372 TEST(CephArgParse
, env_to_vec
) {
374 std::vector
<const char*> args
;
375 unsetenv("CEPH_ARGS");
376 unsetenv("WHATEVER");
379 EXPECT_EQ(0u, args
.size());
381 env_to_vec(args
, "WHATEVER");
382 EXPECT_EQ(0u, args
.size());
384 setenv("CEPH_ARGS", "b c", 0);
387 EXPECT_EQ(3u, args
.size());
388 EXPECT_EQ(string("b"), args
[0]);
389 EXPECT_EQ(string("c"), args
[1]);
390 EXPECT_EQ(string("a"), args
[2]);
391 setenv("WHATEVER", "d e", 0);
393 env_to_vec(args
, "WHATEVER");
394 EXPECT_EQ(5u, args
.size());
395 EXPECT_EQ(string("d"), args
[0]);
396 EXPECT_EQ(string("e"), args
[1]);
399 std::vector
<const char*> args
;
400 unsetenv("CEPH_ARGS");
402 args
.push_back("--");
404 setenv("CEPH_ARGS", "b -- d", 0);
407 EXPECT_EQ(5u, args
.size());
408 EXPECT_EQ(string("b"), args
[0]);
409 EXPECT_EQ(string("a"), args
[1]);
410 EXPECT_EQ(string("--"), args
[2]);
411 EXPECT_EQ(string("d"), args
[3]);
412 EXPECT_EQ(string("c"), args
[4]);
415 std::vector
<const char*> args
;
416 unsetenv("CEPH_ARGS");
418 args
.push_back("--");
419 setenv("CEPH_ARGS", "b -- c", 0);
422 EXPECT_EQ(4u, args
.size());
423 EXPECT_EQ(string("b"), args
[0]);
424 EXPECT_EQ(string("a"), args
[1]);
425 EXPECT_EQ(string("--"), args
[2]);
426 EXPECT_EQ(string("c"), args
[3]);
429 std::vector
<const char*> args
;
430 unsetenv("CEPH_ARGS");
431 args
.push_back("--");
433 setenv("CEPH_ARGS", "b -- d", 0);
436 EXPECT_EQ(4u, args
.size());
437 EXPECT_EQ(string("b"), args
[0]);
438 EXPECT_EQ(string("--"), args
[1]);
439 EXPECT_EQ(string("d"), args
[2]);
440 EXPECT_EQ(string("c"), args
[3]);
443 std::vector
<const char*> args
;
444 unsetenv("CEPH_ARGS");
446 setenv("CEPH_ARGS", "c -- d", 0);
449 EXPECT_EQ(4u, args
.size());
450 EXPECT_EQ(string("c"), args
[0]);
451 EXPECT_EQ(string("b"), args
[1]);
452 EXPECT_EQ(string("--"), args
[2]);
453 EXPECT_EQ(string("d"), args
[3]);
456 std::vector
<const char*> args
;
457 unsetenv("CEPH_ARGS");
459 args
.push_back("--");
461 setenv("CEPH_ARGS", "-- d", 0);
464 EXPECT_EQ(4u, args
.size());
465 EXPECT_EQ(string("a"), args
[0]);
466 EXPECT_EQ(string("--"), args
[1]);
467 EXPECT_EQ(string("d"), args
[2]);
468 EXPECT_EQ(string("c"), args
[3]);
471 std::vector
<const char*> args
;
472 unsetenv("CEPH_ARGS");
474 args
.push_back("--");
476 setenv("CEPH_ARGS", "d", 0);
479 EXPECT_EQ(4u, args
.size());
480 EXPECT_EQ(string("d"), args
[0]);
481 EXPECT_EQ(string("a"), args
[1]);
482 EXPECT_EQ(string("--"), args
[2]);
483 EXPECT_EQ(string("c"), args
[3]);
487 TEST(CephArgParse
, parse_ip_port_vec
) {
493 { "1.2.3.4", entity_addr_t::TYPE_MSGR2
,
494 "v2:1.2.3.4:0/0\n" },
495 { "v1:1.2.3.4", entity_addr_t::TYPE_MSGR2
,
496 "v1:1.2.3.4:0/0\n" },
497 { "1.2.3.4", entity_addr_t::TYPE_LEGACY
,
498 "v1:1.2.3.4:0/0\n" },
499 { "[::],1.2.3.4", entity_addr_t::TYPE_LEGACY
,
500 "v1:[::]:0/0\nv1:1.2.3.4:0/0\n" },
501 { "v2:1.2.3.4:111,v1:5.6.7.8:222", entity_addr_t::TYPE_LEGACY
,
502 "v2:1.2.3.4:111/0\nv1:5.6.7.8:222/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] [v2:[::]:3300,v1:[::]:6789]",
506 entity_addr_t::TYPE_LEGACY
,
507 "[v2:1.2.3.4:111/0,v1:5.6.7.8:222/0]\n[v2:[::]:3300/0,v1:[::]:6789/0]\n" },
508 { "[v2:1.2.3.4:111,v1:5.6.7.8:222],[v2:[::]:3300,v1:[::]:6789]",
509 entity_addr_t::TYPE_LEGACY
,
510 "[v2:1.2.3.4:111/0,v1:5.6.7.8:222/0]\n[v2:[::]:3300/0,v1:[::]:6789/0]\n" },
514 for (unsigned i
= 0; tests
[i
].from
; ++i
) {
515 vector
<entity_addrvec_t
> v
;
516 cout
<< "-- " << tests
[i
].from
<< " type " << tests
[i
].type
517 << " ->\n" << tests
[i
].to
;
518 ASSERT_TRUE(parse_ip_port_vec(tests
[i
].from
, v
, tests
[i
].type
));
521 actual
+= stringify(s
) + "\n";
523 ASSERT_EQ(actual
, tests
[i
].to
);
526 const char *bad
[] = {
530 for (unsigned i
= 0; bad
[i
]; ++i
) {
531 vector
<entity_addrvec_t
> v
;
532 cout
<< "bad " << bad
[i
] << std::endl
;
533 ASSERT_FALSE(parse_ip_port_vec(bad
[i
], v
));
540 * compile-command: "cd .. ; make unittest_ceph_argparse && ./unittest_ceph_argparse"