OpenVPN
test_argv.c
Go to the documentation of this file.
1 #include "config.h"
2 #include "syshead.h"
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8 #include <setjmp.h>
9 #include <cmocka.h>
10 #include <assert.h>
11 #include <stdbool.h>
12 
13 #include "argv.h"
14 #include "buffer.h"
15 #include "test_common.h"
16 
17 /* Defines for use in the tests and the mock parse_line() */
18 #define PATH1 "/s p a c e"
19 #define PATH2 "/foo bar/baz"
20 #define PARAM1 "param1"
21 #define PARAM2 "param two"
22 #define SCRIPT_CMD "\"" PATH1 PATH2 "\"" PARAM1 "\"" PARAM2 "\""
23 
24 int
25 __wrap_parse_line(const char *line, char **p, const int n, const char *file,
26  const int line_num, int msglevel, struct gc_arena *gc)
27 {
28  p[0] = PATH1 PATH2;
29  p[1] = PARAM1;
30  p[2] = PARAM2;
31  return 3;
32 }
33 
34 static void
36 {
37  struct argv a = argv_new();
38 
39  argv_printf(&a, " %s %s %d ", PATH1, PATH2, 42);
40  assert_int_equal(a.argc, 3);
41 
42  argv_free(&a);
43 }
44 
45 static void
47 {
48  struct argv a = argv_new();
49 
50  argv_printf(&a, "%s ", PATH1);
51  argv_printf_cat(&a, " %s %s", PATH2, PARAM1);
52  assert_int_equal(a.argc, 3);
53 
54  argv_free(&a);
55 }
56 
57 static void
59 {
60  struct argv a = argv_new();
61 
62  argv_printf(&a, "<p1:%s>", PATH1);
63  assert_int_equal(a.argc, 1);
64  assert_string_equal(a.argv[0], "<p1:" PATH1 ">");
65 
66  argv_free(&a);
67 }
68 
69 static void
71 {
72  struct argv a = argv_new();
73 
74  assert_false(argv_printf(&a, "tool --do %s", "this\035--harmful"));
75  assert_int_equal(a.argc, 0);
76 
77  argv_free(&a);
78 }
79 
80 static void
82 {
83  struct argv a = argv_new();
84 
85  argv_printf(&a, "%s%s", PATH1, PATH2);
86  assert_int_equal(a.argc, 1);
87 
88  argv_printf(&a, "%s%s %d", PATH1, PATH2, 42);
89  assert_int_equal(a.argc, 2);
90 
91  argv_printf(&a, "foo %s%s %s x y", PATH2, PATH1, "foo");
92  assert_int_equal(a.argc, 5);
93 
94  argv_free(&a);
95 }
96 
97 static void
99 {
100  struct argv a = argv_new();
101 
102  argv_printf(&a, "%s", "");
103  assert_int_equal(a.argc, 1);
104 
105  argv_printf(&a, "%s %s", PATH1, "");
106  assert_int_equal(a.argc, 2);
107 
108  argv_printf(&a, "%s %s %s", PATH1, "", PARAM1);
109  assert_int_equal(a.argc, 3);
110 
111  argv_printf(&a, "%s %s %s %s", PATH1, "", "", PARAM1);
112  assert_int_equal(a.argc, 4);
113 
114  argv_printf(&a, "%s %s", "", PARAM1);
115  assert_int_equal(a.argc, 2);
116 
117  argv_free(&a);
118 }
119 
120 static void
122 {
123  int i;
124  struct argv a = argv_new();
125  const char *args[] = {
126  "good_tools_have_good_names_even_though_it_might_impair_typing",
127  "--long-opt=looooooooooooooooooooooooooooooooooooooooooooooooong",
128  "--long-cat=loooooooooooooooooooooooooooooooooooooooooooooooooooonger",
129  "file_with_very_descriptive_filename_that_leaves_no_questions_open.jpg.exe"
130  };
131 
132  argv_printf(&a, "%s %s %s %s", args[0], args[1], args[2], args[3]);
133  assert_int_equal(a.argc, 4);
134  for (i = 0; i < a.argc; i++)
135  {
136  assert_string_equal(a.argv[i], args[i]);
137  }
138 
139  argv_free(&a);
140 }
141 
142 static void
144 {
145  struct argv a = argv_new();
146 
148  assert_int_equal(a.argc, 3);
149 
150  argv_free(&a);
151 }
152 
153 static void
155 {
156  struct argv a = argv_new();
157 
159  argv_printf_cat(&a, "bar baz %d %s", 42, PATH1);
160  assert_int_equal(a.argc, 7);
161 
162  argv_free(&a);
163 }
164 
165 static void
167 {
168  struct argv a = argv_new();
169 
170  argv_printf(&a, "%s %s %s", PATH1, PATH2, PARAM1);
171  argv_printf_cat(&a, "%s", PARAM2);
172  argv_printf_cat(&a, "foo");
173  assert_int_equal(a.argc, 5);
174 
175  argv_free(&a);
176 }
177 
178 static void
180 {
181  struct argv a = argv_new();
182  struct gc_arena gc = gc_new();
183  const char *output;
184 
185  output = argv_str(&a, &gc, PA_BRACKET);
186  assert_string_equal(output, "");
187 
188  argv_free(&a);
189  gc_free(&gc);
190 }
191 
192 static void
194 {
195  struct argv a = argv_new();
196  struct gc_arena gc = gc_new();
197  const char *output;
198 
199  argv_printf(&a, "%s%s", PATH1, PATH2);
200  argv_printf_cat(&a, "%s", PARAM1);
201  argv_printf_cat(&a, "%s", PARAM2);
202  argv_printf_cat(&a, "%d", -1);
203  argv_printf_cat(&a, "%u", -1);
204  argv_printf_cat(&a, "%lu", 1L );
205  output = argv_str(&a, &gc, PA_BRACKET);
206  assert_string_equal(output, "[" PATH1 PATH2 "] [" PARAM1 "] [" PARAM2 "]"
207  " [-1] [4294967295] [1]");
208 
209  argv_free(&a);
210  gc_free(&gc);
211 }
212 
213 static void
215 {
216  struct argv a = argv_new();
217  struct argv b;
218 
219  b = argv_insert_head(&a, PATH1);
220  assert_int_equal(b.argc, 1);
221  assert_string_equal(b.argv[0], PATH1);
222  argv_free(&b);
223 
224  argv_free(&a);
225 }
226 
227 static void
229 {
230  struct argv a = argv_new();
231  struct argv b;
232  int i;
233 
234  argv_printf(&a, "%s", PATH2);
235  b = argv_insert_head(&a, PATH1);
236  assert_int_equal(b.argc, a.argc + 1);
237  for (i = 0; i < b.argc; i++)
238  {
239  if (i == 0)
240  {
241  assert_string_equal(b.argv[i], PATH1);
242  }
243  else
244  {
245  assert_string_equal(b.argv[i], a.argv[i - 1]);
246  }
247  }
248  argv_free(&b);
249 
250  argv_free(&a);
251 }
252 
253 int
254 main(void)
255 {
257  const struct CMUnitTest tests[] = {
264  cmocka_unit_test(argv_printf__long_args__data_correct),
268  cmocka_unit_test(argv_str__empty_argv__empty_output),
269  cmocka_unit_test(argv_str__multiple_argv__correct_output),
271  cmocka_unit_test(argv_insert_head__empty_argv__head_only),
272  };
273 
274  return cmocka_run_group_tests_name("argv", tests, NULL, NULL);
275 }
PA_BRACKET
#define PA_BRACKET
Definition: buffer.h:144
argv_parse_cmd__command_string__argc_correct
static void argv_parse_cmd__command_string__argc_correct(void **state)
Definition: test_argv.c:143
argv_printf__empty_parameter__argc_correct
static void argv_printf__empty_parameter__argc_correct(void **state)
Definition: test_argv.c:98
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1030
argv_parse_cmd__command_and_extra_options__argc_correct
static void argv_parse_cmd__command_and_extra_options__argc_correct(void **state)
Definition: test_argv.c:154
argv_printf__long_args__data_correct
static void argv_printf__long_args__data_correct(void **state)
Definition: test_argv.c:121
argv
Definition: argv.h:35
test_common.h
argv_printf_cat
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition: argv.c:464
argv_free
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition: argv.c:102
argv_parse_cmd
void argv_parse_cmd(struct argv *argres, const char *cmdstr)
Parses a command string, tokenizes it and puts each element into a separate struct argv argument slot...
Definition: argv.c:483
PATH1
#define PATH1
Definition: test_argv.c:18
argv_printf_cat__used_twice__argc_correct
static void argv_printf_cat__used_twice__argc_correct(void **state)
Definition: test_argv.c:166
argv_printf__combined_path_with_spaces__argc_correct
static void argv_printf__combined_path_with_spaces__argc_correct(void **state)
Definition: test_argv.c:81
argv.h
argv::argv
char ** argv
Definition: argv.h:39
__wrap_parse_line
int __wrap_parse_line(const char *line, char **p, const int n, const char *file, const int line_num, int msglevel, struct gc_arena *gc)
Definition: test_argv.c:25
argv_insert_head
struct argv argv_insert_head(const struct argv *a, const char *head)
Inserts an argument string in front of all other argument slots.
Definition: argv.c:208
argv_insert_head__non_empty_argv__head_added
static void argv_insert_head__non_empty_argv__head_added(void **state)
Definition: test_argv.c:228
main
int main(void)
Definition: test_argv.c:254
argv::argc
size_t argc
Definition: argv.h:38
argv_printf__group_sep_in_arg__fail_no_ouput
static void argv_printf__group_sep_in_arg__fail_no_ouput(void **state)
Definition: test_argv.c:70
buffer.h
syshead.h
argv_str
const char * argv_str(const struct argv *a, struct gc_arena *gc, const unsigned int flags)
Generate a single string with all the arguments in a struct argv concatenated.
Definition: argv.c:231
argv_str__multiple_argv__correct_output
static void argv_str__multiple_argv__correct_output(void **state)
Definition: test_argv.c:193
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
argv_printf__embedded_format_directive__replaced_in_output
static void argv_printf__embedded_format_directive__replaced_in_output(void **state)
Definition: test_argv.c:58
argv_printf_cat__multiple_spaces_in_format__parsed_as_one
static void argv_printf_cat__multiple_spaces_in_format__parsed_as_one(void **state)
Definition: test_argv.c:46
openvpn_unit_test_setup
static void openvpn_unit_test_setup(void)
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition: test_common.h:36
argv_new
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition: argv.c:88
argv_printf
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition: argv.c:440
PARAM1
#define PARAM1
Definition: test_argv.c:20
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1038
PARAM2
#define PARAM2
Definition: test_argv.c:21
config.h
argv_printf__multiple_spaces_in_format__parsed_as_one
static void argv_printf__multiple_spaces_in_format__parsed_as_one(void **state)
Definition: test_argv.c:35
PATH2
#define PATH2
Definition: test_argv.c:19
argv_insert_head__empty_argv__head_only
static void argv_insert_head__empty_argv__head_only(void **state)
Definition: test_argv.c:214
SCRIPT_CMD
#define SCRIPT_CMD
Definition: test_argv.c:22
argv_str__empty_argv__empty_output
static void argv_str__empty_argv__empty_output(void **state)
Definition: test_argv.c:179