Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/atf/atf-c++/detail/process_test.cpp
39563 views
1
// Copyright (c) 2008 The NetBSD Foundation, Inc.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions
6
// are met:
7
// 1. Redistributions of source code must retain the above copyright
8
// notice, this list of conditions and the following disclaimer.
9
// 2. Redistributions in binary form must reproduce the above copyright
10
// notice, this list of conditions and the following disclaimer in the
11
// documentation and/or other materials provided with the distribution.
12
//
13
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26
#include "atf-c++/detail/process.hpp"
27
28
#include <cstdlib>
29
#include <cstring>
30
31
#include <atf-c++.hpp>
32
33
#include "atf-c++/detail/test_helpers.hpp"
34
35
// TODO: Testing the fork function is a huge task and I'm afraid of
36
// copy/pasting tons of stuff from the C version. I'd rather not do that
37
// until some code can be shared, which cannot happen until the C++ binding
38
// is cleaned by a fair amount. Instead... just rely (at the moment) on
39
// the system tests for the tools using this module.
40
41
// ------------------------------------------------------------------------
42
// Auxiliary functions.
43
// ------------------------------------------------------------------------
44
45
static
46
std::size_t
47
array_size(const char* const* array)
48
{
49
std::size_t size = 0;
50
51
for (const char* const* ptr = array; *ptr != NULL; ptr++)
52
size++;
53
54
return size;
55
}
56
57
static
58
atf::process::status
59
exec_process_helpers(const atf::tests::tc& tc, const char* helper_name)
60
{
61
using atf::process::exec;
62
63
std::vector< std::string > argv;
64
argv.push_back(get_process_helpers_path(tc, true).leaf_name());
65
argv.push_back(helper_name);
66
67
return exec(get_process_helpers_path(tc, true),
68
atf::process::argv_array(argv),
69
atf::process::stream_inherit(),
70
atf::process::stream_inherit());
71
}
72
73
// ------------------------------------------------------------------------
74
// Tests for the "argv_array" type.
75
// ------------------------------------------------------------------------
76
77
ATF_TEST_CASE(argv_array_init_carray);
78
ATF_TEST_CASE_HEAD(argv_array_init_carray)
79
{
80
set_md_var("descr", "Tests that argv_array is correctly constructed "
81
"from a C-style array of strings");
82
}
83
ATF_TEST_CASE_BODY(argv_array_init_carray)
84
{
85
{
86
const char* const carray[] = { NULL };
87
atf::process::argv_array argv(carray);
88
89
ATF_REQUIRE_EQ(argv.size(), 0);
90
}
91
92
{
93
const char* const carray[] = { "arg0", NULL };
94
atf::process::argv_array argv(carray);
95
96
ATF_REQUIRE_EQ(argv.size(), 1);
97
ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
98
}
99
100
{
101
const char* const carray[] = { "arg0", "arg1", "arg2", NULL };
102
atf::process::argv_array argv(carray);
103
104
ATF_REQUIRE_EQ(argv.size(), 3);
105
ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
106
ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0);
107
ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0);
108
}
109
}
110
111
ATF_TEST_CASE(argv_array_init_col);
112
ATF_TEST_CASE_HEAD(argv_array_init_col)
113
{
114
set_md_var("descr", "Tests that argv_array is correctly constructed "
115
"from a string collection");
116
}
117
ATF_TEST_CASE_BODY(argv_array_init_col)
118
{
119
{
120
std::vector< std::string > col;
121
atf::process::argv_array argv(col);
122
123
ATF_REQUIRE_EQ(argv.size(), 0);
124
}
125
126
{
127
std::vector< std::string > col;
128
col.push_back("arg0");
129
atf::process::argv_array argv(col);
130
131
ATF_REQUIRE_EQ(argv.size(), 1);
132
ATF_REQUIRE_EQ(argv[0], col[0]);
133
}
134
135
{
136
std::vector< std::string > col;
137
col.push_back("arg0");
138
col.push_back("arg1");
139
col.push_back("arg2");
140
atf::process::argv_array argv(col);
141
142
ATF_REQUIRE_EQ(argv.size(), 3);
143
ATF_REQUIRE_EQ(argv[0], col[0]);
144
ATF_REQUIRE_EQ(argv[1], col[1]);
145
ATF_REQUIRE_EQ(argv[2], col[2]);
146
}
147
}
148
149
ATF_TEST_CASE(argv_array_init_empty);
150
ATF_TEST_CASE_HEAD(argv_array_init_empty)
151
{
152
set_md_var("descr", "Tests that argv_array is correctly constructed "
153
"by the default constructor");
154
}
155
ATF_TEST_CASE_BODY(argv_array_init_empty)
156
{
157
atf::process::argv_array argv;
158
159
ATF_REQUIRE_EQ(argv.size(), 0);
160
}
161
162
ATF_TEST_CASE(argv_array_init_varargs);
163
ATF_TEST_CASE_HEAD(argv_array_init_varargs)
164
{
165
set_md_var("descr", "Tests that argv_array is correctly constructed "
166
"from a variable list of arguments");
167
}
168
ATF_TEST_CASE_BODY(argv_array_init_varargs)
169
{
170
{
171
atf::process::argv_array argv("arg0", NULL);
172
173
ATF_REQUIRE_EQ(argv.size(), 1);
174
ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
175
}
176
177
{
178
atf::process::argv_array argv("arg0", "arg1", "arg2", NULL);
179
180
ATF_REQUIRE_EQ(argv.size(), 3);
181
ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
182
ATF_REQUIRE_EQ(argv[1], std::string("arg1"));
183
ATF_REQUIRE_EQ(argv[2], std::string("arg2"));
184
}
185
}
186
187
ATF_TEST_CASE(argv_array_assign);
188
ATF_TEST_CASE_HEAD(argv_array_assign)
189
{
190
set_md_var("descr", "Tests that assigning an argv_array works");
191
}
192
ATF_TEST_CASE_BODY(argv_array_assign)
193
{
194
using atf::process::argv_array;
195
196
const char* const carray1[] = { "arg1", NULL };
197
const char* const carray2[] = { "arg1", "arg2", NULL };
198
199
std::unique_ptr< argv_array > argv1(new argv_array(carray1));
200
std::unique_ptr< argv_array > argv2(new argv_array(carray2));
201
202
*argv2 = *argv1;
203
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
204
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
205
206
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
207
argv1.release();
208
{
209
const char* const* eargv2 = argv2->exec_argv();
210
ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0);
211
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
212
}
213
214
argv2.release();
215
}
216
217
ATF_TEST_CASE(argv_array_copy);
218
ATF_TEST_CASE_HEAD(argv_array_copy)
219
{
220
set_md_var("descr", "Tests that copying an argv_array constructed from "
221
"a C-style array of strings works");
222
}
223
ATF_TEST_CASE_BODY(argv_array_copy)
224
{
225
using atf::process::argv_array;
226
227
const char* const carray[] = { "arg0", NULL };
228
229
std::unique_ptr< argv_array > argv1(new argv_array(carray));
230
std::unique_ptr< argv_array > argv2(new argv_array(*argv1));
231
232
ATF_REQUIRE_EQ(argv2->size(), argv1->size());
233
ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
234
235
ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
236
argv1.release();
237
{
238
const char* const* eargv2 = argv2->exec_argv();
239
ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0);
240
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
241
}
242
243
argv2.release();
244
}
245
246
ATF_TEST_CASE(argv_array_exec_argv);
247
ATF_TEST_CASE_HEAD(argv_array_exec_argv)
248
{
249
set_md_var("descr", "Tests that the exec argv provided by an argv_array "
250
"is correct");
251
}
252
ATF_TEST_CASE_BODY(argv_array_exec_argv)
253
{
254
using atf::process::argv_array;
255
256
{
257
argv_array argv;
258
const char* const* eargv = argv.exec_argv();
259
ATF_REQUIRE_EQ(array_size(eargv), 0);
260
ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL));
261
}
262
263
{
264
const char* const carray[] = { "arg0", NULL };
265
argv_array argv(carray);
266
const char* const* eargv = argv.exec_argv();
267
ATF_REQUIRE_EQ(array_size(eargv), 1);
268
ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
269
ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
270
}
271
272
{
273
std::vector< std::string > col;
274
col.push_back("arg0");
275
argv_array argv(col);
276
const char* const* eargv = argv.exec_argv();
277
ATF_REQUIRE_EQ(array_size(eargv), 1);
278
ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
279
ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
280
}
281
}
282
283
ATF_TEST_CASE(argv_array_iter);
284
ATF_TEST_CASE_HEAD(argv_array_iter)
285
{
286
set_md_var("descr", "Tests that an argv_array can be iterated");
287
}
288
ATF_TEST_CASE_BODY(argv_array_iter)
289
{
290
using atf::process::argv_array;
291
292
std::vector< std::string > vector;
293
vector.push_back("arg0");
294
vector.push_back("arg1");
295
vector.push_back("arg2");
296
297
argv_array argv(vector);
298
ATF_REQUIRE_EQ(argv.size(), 3);
299
std::vector< std::string >::size_type pos = 0;
300
for (argv_array::const_iterator iter = argv.begin(); iter != argv.end();
301
iter++) {
302
ATF_REQUIRE_EQ(*iter, vector[pos]);
303
pos++;
304
}
305
}
306
307
// ------------------------------------------------------------------------
308
// Tests cases for the free functions.
309
// ------------------------------------------------------------------------
310
311
ATF_TEST_CASE(exec_failure);
312
ATF_TEST_CASE_HEAD(exec_failure)
313
{
314
set_md_var("descr", "Tests execing a command that reports failure");
315
}
316
ATF_TEST_CASE_BODY(exec_failure)
317
{
318
const atf::process::status s = exec_process_helpers(*this, "exit-failure");
319
ATF_REQUIRE(s.exited());
320
ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE);
321
}
322
323
ATF_TEST_CASE(exec_success);
324
ATF_TEST_CASE_HEAD(exec_success)
325
{
326
set_md_var("descr", "Tests execing a command that reports success");
327
}
328
ATF_TEST_CASE_BODY(exec_success)
329
{
330
const atf::process::status s = exec_process_helpers(*this, "exit-success");
331
ATF_REQUIRE(s.exited());
332
ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS);
333
}
334
335
// ------------------------------------------------------------------------
336
// Main.
337
// ------------------------------------------------------------------------
338
339
ATF_INIT_TEST_CASES(tcs)
340
{
341
// Add the test cases for the "argv_array" type.
342
ATF_ADD_TEST_CASE(tcs, argv_array_assign);
343
ATF_ADD_TEST_CASE(tcs, argv_array_copy);
344
ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv);
345
ATF_ADD_TEST_CASE(tcs, argv_array_init_carray);
346
ATF_ADD_TEST_CASE(tcs, argv_array_init_col);
347
ATF_ADD_TEST_CASE(tcs, argv_array_init_empty);
348
ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs);
349
ATF_ADD_TEST_CASE(tcs, argv_array_iter);
350
351
// Add the test cases for the free functions.
352
ATF_ADD_TEST_CASE(tcs, exec_failure);
353
ATF_ADD_TEST_CASE(tcs, exec_success);
354
}
355
356