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
24int
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
34static 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
45static 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
57static 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
69static 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
80static 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
97static 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
120static 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
142static void
144{
145 struct argv a = argv_new();
146
148 assert_int_equal(a.argc, 3);
149
150 argv_free(&a);
151}
152
153static 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
165static 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
178static 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
192static 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
213static 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
227static 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
253int
254main(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),
272 };
273
274 return cmocka_run_group_tests_name("argv", tests, NULL, NULL);
275}
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
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
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:102
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:440
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:464
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:88
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
#define PA_BRACKET
Definition buffer.h:144
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static struct gc_arena gc_new(void)
Definition buffer.h:1025
Definition argv.h:35
char ** argv
Definition argv.h:39
size_t argc
Definition argv.h:38
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
static void argv_parse_cmd__command_and_extra_options__argc_correct(void **state)
Definition test_argv.c:154
static void argv_printf_cat__used_twice__argc_correct(void **state)
Definition test_argv.c:166
static void argv_str__multiple_argv__correct_output(void **state)
Definition test_argv.c:193
#define PATH1
Definition test_argv.c:18
static void argv_printf__group_sep_in_arg__fail_no_ouput(void **state)
Definition test_argv.c:70
static void argv_printf_cat__multiple_spaces_in_format__parsed_as_one(void **state)
Definition test_argv.c:46
static void argv_str__empty_argv__empty_output(void **state)
Definition test_argv.c:179
static void argv_insert_head__empty_argv__head_only(void **state)
Definition test_argv.c:214
static void argv_printf__embedded_format_directive__replaced_in_output(void **state)
Definition test_argv.c:58
static void argv_printf__empty_parameter__argc_correct(void **state)
Definition test_argv.c:98
#define SCRIPT_CMD
Definition test_argv.c:22
#define PARAM1
Definition test_argv.c:20
static void argv_printf__multiple_spaces_in_format__parsed_as_one(void **state)
Definition test_argv.c:35
int main(void)
Definition test_argv.c:254
#define PATH2
Definition test_argv.c:19
static void argv_parse_cmd__command_string__argc_correct(void **state)
Definition test_argv.c:143
static void argv_printf__combined_path_with_spaces__argc_correct(void **state)
Definition test_argv.c:81
#define PARAM2
Definition test_argv.c:21
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
static void argv_printf__long_args__data_correct(void **state)
Definition test_argv.c:121
static void argv_insert_head__non_empty_argv__head_added(void **state)
Definition test_argv.c:228
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
struct gc_arena gc
Definition test_ssl.c:155