1240116Smarcel// Copyright (c) 2008 The NetBSD Foundation, Inc.
2240116Smarcel// All rights reserved.
3240116Smarcel//
4240116Smarcel// Redistribution and use in source and binary forms, with or without
5240116Smarcel// modification, are permitted provided that the following conditions
6240116Smarcel// are met:
7240116Smarcel// 1. Redistributions of source code must retain the above copyright
8240116Smarcel//    notice, this list of conditions and the following disclaimer.
9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel//    notice, this list of conditions and the following disclaimer in the
11240116Smarcel//    documentation and/or other materials provided with the distribution.
12240116Smarcel//
13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25240116Smarcel
26275988Sngie#include "atf-c++/detail/process.hpp"
27275988Sngie
28240116Smarcel#include <cstdlib>
29240116Smarcel#include <cstring>
30240116Smarcel
31275988Sngie#include <atf-c++.hpp>
32240116Smarcel
33275988Sngie#include "atf-c++/detail/test_helpers.hpp"
34240116Smarcel
35240116Smarcel// TODO: Testing the fork function is a huge task and I'm afraid of
36240116Smarcel// copy/pasting tons of stuff from the C version.  I'd rather not do that
37240116Smarcel// until some code can be shared, which cannot happen until the C++ binding
38240116Smarcel// is cleaned by a fair amount.  Instead... just rely (at the moment) on
39240116Smarcel// the system tests for the tools using this module.
40240116Smarcel
41240116Smarcel// ------------------------------------------------------------------------
42240116Smarcel// Auxiliary functions.
43240116Smarcel// ------------------------------------------------------------------------
44240116Smarcel
45240116Smarcelstatic
46240116Smarcelstd::size_t
47240116Smarcelarray_size(const char* const* array)
48240116Smarcel{
49240116Smarcel    std::size_t size = 0;
50240116Smarcel
51240116Smarcel    for (const char* const* ptr = array; *ptr != NULL; ptr++)
52240116Smarcel        size++;
53240116Smarcel
54240116Smarcel    return size;
55240116Smarcel}
56240116Smarcel
57240116Smarcelstatic
58240116Smarcelatf::process::status
59240116Smarcelexec_process_helpers(const atf::tests::tc& tc, const char* helper_name)
60240116Smarcel{
61240116Smarcel    using atf::process::exec;
62240116Smarcel
63240116Smarcel    std::vector< std::string > argv;
64251108Smarcel    argv.push_back(get_process_helpers_path(tc, true).leaf_name());
65240116Smarcel    argv.push_back(helper_name);
66240116Smarcel
67251108Smarcel    return exec(get_process_helpers_path(tc, true),
68240116Smarcel                atf::process::argv_array(argv),
69240116Smarcel                atf::process::stream_inherit(),
70240116Smarcel                atf::process::stream_inherit());
71240116Smarcel}
72240116Smarcel
73240116Smarcel// ------------------------------------------------------------------------
74240116Smarcel// Tests for the "argv_array" type.
75240116Smarcel// ------------------------------------------------------------------------
76240116Smarcel
77240116SmarcelATF_TEST_CASE(argv_array_init_carray);
78240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_carray)
79240116Smarcel{
80240116Smarcel    set_md_var("descr", "Tests that argv_array is correctly constructed "
81240116Smarcel               "from a C-style array of strings");
82240116Smarcel}
83240116SmarcelATF_TEST_CASE_BODY(argv_array_init_carray)
84240116Smarcel{
85240116Smarcel    {
86240116Smarcel        const char* const carray[] = { NULL };
87240116Smarcel        atf::process::argv_array argv(carray);
88240116Smarcel
89240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 0);
90240116Smarcel    }
91240116Smarcel
92240116Smarcel    {
93240116Smarcel        const char* const carray[] = { "arg0", NULL };
94240116Smarcel        atf::process::argv_array argv(carray);
95240116Smarcel
96240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 1);
97240116Smarcel        ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
98240116Smarcel    }
99240116Smarcel
100240116Smarcel    {
101240116Smarcel        const char* const carray[] = { "arg0", "arg1", "arg2", NULL };
102240116Smarcel        atf::process::argv_array argv(carray);
103240116Smarcel
104240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 3);
105240116Smarcel        ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
106240116Smarcel        ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0);
107240116Smarcel        ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0);
108240116Smarcel    }
109240116Smarcel}
110240116Smarcel
111240116SmarcelATF_TEST_CASE(argv_array_init_col);
112240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_col)
113240116Smarcel{
114240116Smarcel    set_md_var("descr", "Tests that argv_array is correctly constructed "
115240116Smarcel               "from a string collection");
116240116Smarcel}
117240116SmarcelATF_TEST_CASE_BODY(argv_array_init_col)
118240116Smarcel{
119240116Smarcel    {
120240116Smarcel        std::vector< std::string > col;
121240116Smarcel        atf::process::argv_array argv(col);
122240116Smarcel
123240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 0);
124240116Smarcel    }
125240116Smarcel
126240116Smarcel    {
127240116Smarcel        std::vector< std::string > col;
128240116Smarcel        col.push_back("arg0");
129240116Smarcel        atf::process::argv_array argv(col);
130240116Smarcel
131240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 1);
132240116Smarcel        ATF_REQUIRE_EQ(argv[0], col[0]);
133240116Smarcel    }
134240116Smarcel
135240116Smarcel    {
136240116Smarcel        std::vector< std::string > col;
137240116Smarcel        col.push_back("arg0");
138240116Smarcel        col.push_back("arg1");
139240116Smarcel        col.push_back("arg2");
140240116Smarcel        atf::process::argv_array argv(col);
141240116Smarcel
142240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 3);
143240116Smarcel        ATF_REQUIRE_EQ(argv[0], col[0]);
144240116Smarcel        ATF_REQUIRE_EQ(argv[1], col[1]);
145240116Smarcel        ATF_REQUIRE_EQ(argv[2], col[2]);
146240116Smarcel    }
147240116Smarcel}
148240116Smarcel
149240116SmarcelATF_TEST_CASE(argv_array_init_empty);
150240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_empty)
151240116Smarcel{
152240116Smarcel    set_md_var("descr", "Tests that argv_array is correctly constructed "
153240116Smarcel               "by the default constructor");
154240116Smarcel}
155240116SmarcelATF_TEST_CASE_BODY(argv_array_init_empty)
156240116Smarcel{
157240116Smarcel    atf::process::argv_array argv;
158240116Smarcel
159240116Smarcel    ATF_REQUIRE_EQ(argv.size(), 0);
160240116Smarcel}
161240116Smarcel
162240116SmarcelATF_TEST_CASE(argv_array_init_varargs);
163240116SmarcelATF_TEST_CASE_HEAD(argv_array_init_varargs)
164240116Smarcel{
165240116Smarcel    set_md_var("descr", "Tests that argv_array is correctly constructed "
166240116Smarcel               "from a variable list of arguments");
167240116Smarcel}
168240116SmarcelATF_TEST_CASE_BODY(argv_array_init_varargs)
169240116Smarcel{
170240116Smarcel    {
171240116Smarcel        atf::process::argv_array argv("arg0", NULL);
172240116Smarcel
173240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 1);
174240116Smarcel        ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
175240116Smarcel    }
176240116Smarcel
177240116Smarcel    {
178240116Smarcel        atf::process::argv_array argv("arg0", "arg1", "arg2", NULL);
179240116Smarcel
180240116Smarcel        ATF_REQUIRE_EQ(argv.size(), 3);
181240116Smarcel        ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
182240116Smarcel        ATF_REQUIRE_EQ(argv[1], std::string("arg1"));
183240116Smarcel        ATF_REQUIRE_EQ(argv[2], std::string("arg2"));
184240116Smarcel    }
185240116Smarcel}
186240116Smarcel
187240116SmarcelATF_TEST_CASE(argv_array_assign);
188240116SmarcelATF_TEST_CASE_HEAD(argv_array_assign)
189240116Smarcel{
190240116Smarcel    set_md_var("descr", "Tests that assigning an argv_array works");
191240116Smarcel}
192240116SmarcelATF_TEST_CASE_BODY(argv_array_assign)
193240116Smarcel{
194240116Smarcel    using atf::process::argv_array;
195240116Smarcel
196240116Smarcel    const char* const carray1[] = { "arg1", NULL };
197240116Smarcel    const char* const carray2[] = { "arg1", "arg2", NULL };
198240116Smarcel
199240116Smarcel    std::auto_ptr< argv_array > argv1(new argv_array(carray1));
200240116Smarcel    std::auto_ptr< argv_array > argv2(new argv_array(carray2));
201240116Smarcel
202240116Smarcel    *argv2 = *argv1;
203240116Smarcel    ATF_REQUIRE_EQ(argv2->size(), argv1->size());
204240116Smarcel    ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
205240116Smarcel
206240116Smarcel    ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
207240116Smarcel    argv1.release();
208240116Smarcel    {
209240116Smarcel        const char* const* eargv2 = argv2->exec_argv();
210240116Smarcel        ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0);
211240116Smarcel        ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
212240116Smarcel    }
213240116Smarcel
214240116Smarcel    argv2.release();
215240116Smarcel}
216240116Smarcel
217240116SmarcelATF_TEST_CASE(argv_array_copy);
218240116SmarcelATF_TEST_CASE_HEAD(argv_array_copy)
219240116Smarcel{
220240116Smarcel    set_md_var("descr", "Tests that copying an argv_array constructed from "
221240116Smarcel               "a C-style array of strings works");
222240116Smarcel}
223240116SmarcelATF_TEST_CASE_BODY(argv_array_copy)
224240116Smarcel{
225240116Smarcel    using atf::process::argv_array;
226240116Smarcel
227240116Smarcel    const char* const carray[] = { "arg0", NULL };
228240116Smarcel
229240116Smarcel    std::auto_ptr< argv_array > argv1(new argv_array(carray));
230240116Smarcel    std::auto_ptr< argv_array > argv2(new argv_array(*argv1));
231240116Smarcel
232240116Smarcel    ATF_REQUIRE_EQ(argv2->size(), argv1->size());
233240116Smarcel    ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
234240116Smarcel
235240116Smarcel    ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
236240116Smarcel    argv1.release();
237240116Smarcel    {
238240116Smarcel        const char* const* eargv2 = argv2->exec_argv();
239240116Smarcel        ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0);
240240116Smarcel        ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
241240116Smarcel    }
242240116Smarcel
243240116Smarcel    argv2.release();
244240116Smarcel}
245240116Smarcel
246240116SmarcelATF_TEST_CASE(argv_array_exec_argv);
247240116SmarcelATF_TEST_CASE_HEAD(argv_array_exec_argv)
248240116Smarcel{
249240116Smarcel    set_md_var("descr", "Tests that the exec argv provided by an argv_array "
250240116Smarcel               "is correct");
251240116Smarcel}
252240116SmarcelATF_TEST_CASE_BODY(argv_array_exec_argv)
253240116Smarcel{
254240116Smarcel    using atf::process::argv_array;
255240116Smarcel
256240116Smarcel    {
257240116Smarcel        argv_array argv;
258240116Smarcel        const char* const* eargv = argv.exec_argv();
259240116Smarcel        ATF_REQUIRE_EQ(array_size(eargv), 0);
260240116Smarcel        ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL));
261240116Smarcel    }
262240116Smarcel
263240116Smarcel    {
264240116Smarcel        const char* const carray[] = { "arg0", NULL };
265240116Smarcel        argv_array argv(carray);
266240116Smarcel        const char* const* eargv = argv.exec_argv();
267240116Smarcel        ATF_REQUIRE_EQ(array_size(eargv), 1);
268240116Smarcel        ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
269240116Smarcel        ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
270240116Smarcel    }
271240116Smarcel
272240116Smarcel    {
273240116Smarcel        std::vector< std::string > col;
274240116Smarcel        col.push_back("arg0");
275240116Smarcel        argv_array argv(col);
276240116Smarcel        const char* const* eargv = argv.exec_argv();
277240116Smarcel        ATF_REQUIRE_EQ(array_size(eargv), 1);
278240116Smarcel        ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
279240116Smarcel        ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
280240116Smarcel    }
281240116Smarcel}
282240116Smarcel
283240116SmarcelATF_TEST_CASE(argv_array_iter);
284240116SmarcelATF_TEST_CASE_HEAD(argv_array_iter)
285240116Smarcel{
286240116Smarcel    set_md_var("descr", "Tests that an argv_array can be iterated");
287240116Smarcel}
288240116SmarcelATF_TEST_CASE_BODY(argv_array_iter)
289240116Smarcel{
290240116Smarcel    using atf::process::argv_array;
291240116Smarcel
292240116Smarcel    std::vector< std::string > vector;
293240116Smarcel    vector.push_back("arg0");
294240116Smarcel    vector.push_back("arg1");
295240116Smarcel    vector.push_back("arg2");
296240116Smarcel
297240116Smarcel    argv_array argv(vector);
298240116Smarcel    ATF_REQUIRE_EQ(argv.size(), 3);
299240116Smarcel    std::vector< std::string >::size_type pos = 0;
300240116Smarcel    for (argv_array::const_iterator iter = argv.begin(); iter != argv.end();
301240116Smarcel         iter++) {
302240116Smarcel        ATF_REQUIRE_EQ(*iter, vector[pos]);
303240116Smarcel        pos++;
304240116Smarcel    }
305240116Smarcel}
306240116Smarcel
307240116Smarcel// ------------------------------------------------------------------------
308240116Smarcel// Tests cases for the free functions.
309240116Smarcel// ------------------------------------------------------------------------
310240116Smarcel
311240116SmarcelATF_TEST_CASE(exec_failure);
312240116SmarcelATF_TEST_CASE_HEAD(exec_failure)
313240116Smarcel{
314240116Smarcel    set_md_var("descr", "Tests execing a command that reports failure");
315240116Smarcel}
316240116SmarcelATF_TEST_CASE_BODY(exec_failure)
317240116Smarcel{
318240116Smarcel    const atf::process::status s = exec_process_helpers(*this, "exit-failure");
319240116Smarcel    ATF_REQUIRE(s.exited());
320240116Smarcel    ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE);
321240116Smarcel}
322240116Smarcel
323240116SmarcelATF_TEST_CASE(exec_success);
324240116SmarcelATF_TEST_CASE_HEAD(exec_success)
325240116Smarcel{
326240116Smarcel    set_md_var("descr", "Tests execing a command that reports success");
327240116Smarcel}
328240116SmarcelATF_TEST_CASE_BODY(exec_success)
329240116Smarcel{
330240116Smarcel    const atf::process::status s = exec_process_helpers(*this, "exit-success");
331240116Smarcel    ATF_REQUIRE(s.exited());
332240116Smarcel    ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS);
333240116Smarcel}
334240116Smarcel
335240116Smarcel// ------------------------------------------------------------------------
336240116Smarcel// Main.
337240116Smarcel// ------------------------------------------------------------------------
338240116Smarcel
339240116SmarcelATF_INIT_TEST_CASES(tcs)
340240116Smarcel{
341240116Smarcel    // Add the test cases for the "argv_array" type.
342240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_assign);
343240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_copy);
344240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv);
345240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_init_carray);
346240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_init_col);
347240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_init_empty);
348240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs);
349240116Smarcel    ATF_ADD_TEST_CASE(tcs, argv_array_iter);
350240116Smarcel
351240116Smarcel    // Add the test cases for the free functions.
352240116Smarcel    ATF_ADD_TEST_CASE(tcs, exec_failure);
353240116Smarcel    ATF_ADD_TEST_CASE(tcs, exec_success);
354240116Smarcel}
355