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