Home | History | Annotate | Line # | Download | only in atf-c++
      1  1.1  jmmv //
      2  1.1  jmmv // Automated Testing Framework (atf)
      3  1.1  jmmv //
      4  1.2  gson // 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 extern "C" {
     31  1.1  jmmv #include <fcntl.h>
     32  1.1  jmmv #include <unistd.h>
     33  1.1  jmmv }
     34  1.1  jmmv 
     35  1.1  jmmv #include <cerrno>
     36  1.1  jmmv #include <cstdlib>
     37  1.1  jmmv #include <iostream>
     38  1.1  jmmv #include <stdexcept>
     39  1.1  jmmv 
     40  1.2  gson #include "macros.hpp"
     41  1.2  gson #include "utils.hpp"
     42  1.1  jmmv 
     43  1.2  gson #include "detail/fs.hpp"
     44  1.2  gson #include "detail/process.hpp"
     45  1.2  gson #include "detail/sanity.hpp"
     46  1.2  gson #include "detail/test_helpers.hpp"
     47  1.2  gson #include "detail/text.hpp"
     48  1.1  jmmv 
     49  1.1  jmmv // ------------------------------------------------------------------------
     50  1.1  jmmv // Auxiliary functions.
     51  1.1  jmmv // ------------------------------------------------------------------------
     52  1.1  jmmv 
     53  1.1  jmmv static
     54  1.1  jmmv void
     55  1.2  gson create_ctl_file(const char *name)
     56  1.1  jmmv {
     57  1.2  gson     ATF_REQUIRE(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
     58  1.1  jmmv }
     59  1.1  jmmv 
     60  1.1  jmmv // ------------------------------------------------------------------------
     61  1.1  jmmv // Auxiliary test cases.
     62  1.1  jmmv // ------------------------------------------------------------------------
     63  1.1  jmmv 
     64  1.1  jmmv ATF_TEST_CASE(h_pass);
     65  1.1  jmmv ATF_TEST_CASE_HEAD(h_pass)
     66  1.1  jmmv {
     67  1.1  jmmv     set_md_var("descr", "Helper test case");
     68  1.1  jmmv }
     69  1.1  jmmv ATF_TEST_CASE_BODY(h_pass)
     70  1.1  jmmv {
     71  1.2  gson     create_ctl_file("before");
     72  1.1  jmmv     ATF_PASS();
     73  1.2  gson     create_ctl_file("after");
     74  1.1  jmmv }
     75  1.1  jmmv 
     76  1.1  jmmv ATF_TEST_CASE(h_fail);
     77  1.1  jmmv ATF_TEST_CASE_HEAD(h_fail)
     78  1.1  jmmv {
     79  1.1  jmmv     set_md_var("descr", "Helper test case");
     80  1.1  jmmv }
     81  1.1  jmmv ATF_TEST_CASE_BODY(h_fail)
     82  1.1  jmmv {
     83  1.2  gson     create_ctl_file("before");
     84  1.1  jmmv     ATF_FAIL("Failed on purpose");
     85  1.2  gson     create_ctl_file("after");
     86  1.1  jmmv }
     87  1.1  jmmv 
     88  1.1  jmmv ATF_TEST_CASE(h_skip);
     89  1.1  jmmv ATF_TEST_CASE_HEAD(h_skip)
     90  1.1  jmmv {
     91  1.1  jmmv     set_md_var("descr", "Helper test case");
     92  1.1  jmmv }
     93  1.1  jmmv ATF_TEST_CASE_BODY(h_skip)
     94  1.1  jmmv {
     95  1.2  gson     create_ctl_file("before");
     96  1.1  jmmv     ATF_SKIP("Skipped on purpose");
     97  1.2  gson     create_ctl_file("after");
     98  1.1  jmmv }
     99  1.1  jmmv 
    100  1.2  gson ATF_TEST_CASE(h_require);
    101  1.2  gson ATF_TEST_CASE_HEAD(h_require)
    102  1.1  jmmv {
    103  1.1  jmmv     set_md_var("descr", "Helper test case");
    104  1.1  jmmv }
    105  1.2  gson ATF_TEST_CASE_BODY(h_require)
    106  1.1  jmmv {
    107  1.1  jmmv     bool condition = atf::text::to_bool(get_config_var("condition"));
    108  1.1  jmmv 
    109  1.2  gson     create_ctl_file("before");
    110  1.2  gson     ATF_REQUIRE(condition);
    111  1.2  gson     create_ctl_file("after");
    112  1.1  jmmv }
    113  1.1  jmmv 
    114  1.2  gson ATF_TEST_CASE(h_require_eq);
    115  1.2  gson ATF_TEST_CASE_HEAD(h_require_eq)
    116  1.1  jmmv {
    117  1.1  jmmv     set_md_var("descr", "Helper test case");
    118  1.1  jmmv }
    119  1.2  gson ATF_TEST_CASE_BODY(h_require_eq)
    120  1.1  jmmv {
    121  1.1  jmmv     long v1 = atf::text::to_type< long >(get_config_var("v1"));
    122  1.1  jmmv     long v2 = atf::text::to_type< long >(get_config_var("v2"));
    123  1.1  jmmv 
    124  1.2  gson     create_ctl_file("before");
    125  1.2  gson     ATF_REQUIRE_EQ(v1, v2);
    126  1.2  gson     create_ctl_file("after");
    127  1.1  jmmv }
    128  1.1  jmmv 
    129  1.2  gson ATF_TEST_CASE(h_require_in);
    130  1.2  gson ATF_TEST_CASE_HEAD(h_require_in)
    131  1.1  jmmv {
    132  1.1  jmmv     set_md_var("descr", "Helper test case");
    133  1.1  jmmv }
    134  1.2  gson ATF_TEST_CASE_BODY(h_require_in)
    135  1.1  jmmv {
    136  1.2  gson     const std::string element = get_config_var("value");
    137  1.2  gson 
    138  1.2  gson     std::set< std::string > collection;
    139  1.2  gson     collection.insert("foo");
    140  1.2  gson     collection.insert("bar");
    141  1.2  gson     collection.insert("baz");
    142  1.2  gson 
    143  1.2  gson     create_ctl_file("before");
    144  1.2  gson     ATF_REQUIRE_IN(element, collection);
    145  1.2  gson     create_ctl_file("after");
    146  1.2  gson }
    147  1.2  gson 
    148  1.2  gson ATF_TEST_CASE(h_require_match);
    149  1.2  gson ATF_TEST_CASE_HEAD(h_require_match)
    150  1.2  gson {
    151  1.2  gson     set_md_var("descr", "Helper test case");
    152  1.2  gson }
    153  1.2  gson ATF_TEST_CASE_BODY(h_require_match)
    154  1.2  gson {
    155  1.2  gson     const std::string regexp = get_config_var("regexp");
    156  1.2  gson     const std::string string = get_config_var("string");
    157  1.2  gson 
    158  1.2  gson     create_ctl_file("before");
    159  1.2  gson     ATF_REQUIRE_MATCH(regexp, string);
    160  1.2  gson     create_ctl_file("after");
    161  1.2  gson }
    162  1.2  gson 
    163  1.2  gson ATF_TEST_CASE(h_require_not_in);
    164  1.2  gson ATF_TEST_CASE_HEAD(h_require_not_in)
    165  1.2  gson {
    166  1.2  gson     set_md_var("descr", "Helper test case");
    167  1.2  gson }
    168  1.2  gson ATF_TEST_CASE_BODY(h_require_not_in)
    169  1.2  gson {
    170  1.2  gson     const std::string element = get_config_var("value");
    171  1.2  gson 
    172  1.2  gson     std::set< std::string > collection;
    173  1.2  gson     collection.insert("foo");
    174  1.2  gson     collection.insert("bar");
    175  1.2  gson     collection.insert("baz");
    176  1.2  gson 
    177  1.2  gson     create_ctl_file("before");
    178  1.2  gson     ATF_REQUIRE_NOT_IN(element, collection);
    179  1.2  gson     create_ctl_file("after");
    180  1.2  gson }
    181  1.2  gson 
    182  1.2  gson ATF_TEST_CASE(h_require_throw);
    183  1.2  gson ATF_TEST_CASE_HEAD(h_require_throw)
    184  1.2  gson {
    185  1.2  gson     set_md_var("descr", "Helper test case");
    186  1.2  gson }
    187  1.2  gson ATF_TEST_CASE_BODY(h_require_throw)
    188  1.2  gson {
    189  1.2  gson     create_ctl_file("before");
    190  1.1  jmmv 
    191  1.1  jmmv     if (get_config_var("what") == "throw_int")
    192  1.2  gson         ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
    193  1.1  jmmv     else if (get_config_var("what") == "throw_rt")
    194  1.2  gson         ATF_REQUIRE_THROW(std::runtime_error,
    195  1.1  jmmv                         if (1) throw std::runtime_error("e"));
    196  1.1  jmmv     else if (get_config_var("what") == "no_throw_rt")
    197  1.2  gson         ATF_REQUIRE_THROW(std::runtime_error,
    198  1.1  jmmv                         if (0) throw std::runtime_error("e"));
    199  1.1  jmmv 
    200  1.2  gson     create_ctl_file("after");
    201  1.2  gson }
    202  1.2  gson 
    203  1.2  gson ATF_TEST_CASE(h_require_throw_re);
    204  1.2  gson ATF_TEST_CASE_HEAD(h_require_throw_re)
    205  1.2  gson {
    206  1.2  gson     set_md_var("descr", "Helper test case");
    207  1.2  gson }
    208  1.2  gson ATF_TEST_CASE_BODY(h_require_throw_re)
    209  1.2  gson {
    210  1.2  gson     create_ctl_file("before");
    211  1.2  gson 
    212  1.2  gson     if (get_config_var("what") == "throw_int")
    213  1.2  gson         ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
    214  1.2  gson     else if (get_config_var("what") == "throw_rt_match")
    215  1.2  gson         ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
    216  1.2  gson                              if (1) throw std::runtime_error("a foo bar baz"));
    217  1.2  gson     else if (get_config_var("what") == "throw_rt_no_match")
    218  1.2  gson         ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
    219  1.2  gson                              if (1) throw std::runtime_error("baz foo bar a"));
    220  1.2  gson     else if (get_config_var("what") == "no_throw_rt")
    221  1.2  gson         ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
    222  1.2  gson                              if (0) throw std::runtime_error("e"));
    223  1.2  gson 
    224  1.2  gson     create_ctl_file("after");
    225  1.1  jmmv }
    226  1.1  jmmv 
    227  1.1  jmmv static int
    228  1.1  jmmv errno_fail_stub(const int raised_errno)
    229  1.1  jmmv {
    230  1.1  jmmv     errno = raised_errno;
    231  1.1  jmmv     return -1;
    232  1.1  jmmv }
    233  1.1  jmmv 
    234  1.1  jmmv static int
    235  1.1  jmmv errno_ok_stub(void)
    236  1.1  jmmv {
    237  1.1  jmmv     return 0;
    238  1.1  jmmv }
    239  1.1  jmmv 
    240  1.1  jmmv ATF_TEST_CASE(h_check_errno);
    241  1.1  jmmv ATF_TEST_CASE_HEAD(h_check_errno)
    242  1.1  jmmv {
    243  1.1  jmmv     set_md_var("descr", "Helper test case");
    244  1.1  jmmv }
    245  1.1  jmmv ATF_TEST_CASE_BODY(h_check_errno)
    246  1.1  jmmv {
    247  1.2  gson     create_ctl_file("before");
    248  1.1  jmmv 
    249  1.1  jmmv     if (get_config_var("what") == "no_error")
    250  1.1  jmmv         ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
    251  1.1  jmmv     else if (get_config_var("what") == "errno_ok")
    252  1.1  jmmv         ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
    253  1.1  jmmv     else if (get_config_var("what") == "errno_fail")
    254  1.1  jmmv         ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
    255  1.1  jmmv     else
    256  1.1  jmmv         UNREACHABLE;
    257  1.1  jmmv 
    258  1.2  gson     create_ctl_file("after");
    259  1.1  jmmv }
    260  1.1  jmmv 
    261  1.1  jmmv ATF_TEST_CASE(h_require_errno);
    262  1.1  jmmv ATF_TEST_CASE_HEAD(h_require_errno)
    263  1.1  jmmv {
    264  1.1  jmmv     set_md_var("descr", "Helper test case");
    265  1.1  jmmv }
    266  1.1  jmmv ATF_TEST_CASE_BODY(h_require_errno)
    267  1.1  jmmv {
    268  1.2  gson     create_ctl_file("before");
    269  1.1  jmmv 
    270  1.1  jmmv     if (get_config_var("what") == "no_error")
    271  1.1  jmmv         ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
    272  1.1  jmmv     else if (get_config_var("what") == "errno_ok")
    273  1.1  jmmv         ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
    274  1.1  jmmv     else if (get_config_var("what") == "errno_fail")
    275  1.1  jmmv         ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
    276  1.1  jmmv     else
    277  1.1  jmmv         UNREACHABLE;
    278  1.1  jmmv 
    279  1.2  gson     create_ctl_file("after");
    280  1.1  jmmv }
    281  1.1  jmmv 
    282  1.1  jmmv // ------------------------------------------------------------------------
    283  1.1  jmmv // Test cases for the macros.
    284  1.1  jmmv // ------------------------------------------------------------------------
    285  1.1  jmmv 
    286  1.1  jmmv ATF_TEST_CASE(pass);
    287  1.1  jmmv ATF_TEST_CASE_HEAD(pass)
    288  1.1  jmmv {
    289  1.1  jmmv     set_md_var("descr", "Tests the ATF_PASS macro");
    290  1.1  jmmv }
    291  1.1  jmmv ATF_TEST_CASE_BODY(pass)
    292  1.1  jmmv {
    293  1.2  gson     ATF_TEST_CASE_USE(h_pass);
    294  1.1  jmmv     run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
    295  1.2  gson     ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    296  1.2  gson     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
    297  1.2  gson     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
    298  1.1  jmmv }
    299  1.1  jmmv 
    300  1.1  jmmv ATF_TEST_CASE(fail);
    301  1.1  jmmv ATF_TEST_CASE_HEAD(fail)
    302  1.1  jmmv {
    303  1.1  jmmv     set_md_var("descr", "Tests the ATF_FAIL macro");
    304  1.1  jmmv }
    305  1.1  jmmv ATF_TEST_CASE_BODY(fail)
    306  1.1  jmmv {
    307  1.2  gson     ATF_TEST_CASE_USE(h_fail);
    308  1.1  jmmv     run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
    309  1.2  gson     ATF_REQUIRE(atf::utils::grep_file("^failed: Failed on purpose", "result"));
    310  1.2  gson     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
    311  1.2  gson     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
    312  1.1  jmmv }
    313  1.1  jmmv 
    314  1.1  jmmv ATF_TEST_CASE(skip);
    315  1.1  jmmv ATF_TEST_CASE_HEAD(skip)
    316  1.1  jmmv {
    317  1.1  jmmv     set_md_var("descr", "Tests the ATF_SKIP macro");
    318  1.1  jmmv }
    319  1.1  jmmv ATF_TEST_CASE_BODY(skip)
    320  1.1  jmmv {
    321  1.2  gson     ATF_TEST_CASE_USE(h_skip);
    322  1.1  jmmv     run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
    323  1.2  gson     ATF_REQUIRE(atf::utils::grep_file("^skipped: Skipped on purpose",
    324  1.2  gson         "result"));
    325  1.2  gson     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
    326  1.2  gson     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
    327  1.1  jmmv }
    328  1.1  jmmv 
    329  1.2  gson ATF_TEST_CASE(require);
    330  1.2  gson ATF_TEST_CASE_HEAD(require)
    331  1.1  jmmv {
    332  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE macro");
    333  1.1  jmmv }
    334  1.2  gson ATF_TEST_CASE_BODY(require)
    335  1.1  jmmv {
    336  1.1  jmmv     struct test {
    337  1.1  jmmv         const char *cond;
    338  1.1  jmmv         bool ok;
    339  1.1  jmmv     } *t, tests[] = {
    340  1.1  jmmv         { "false", false },
    341  1.1  jmmv         { "true", true },
    342  1.1  jmmv         { NULL, false }
    343  1.1  jmmv     };
    344  1.1  jmmv 
    345  1.1  jmmv     const atf::fs::path before("before");
    346  1.1  jmmv     const atf::fs::path after("after");
    347  1.1  jmmv 
    348  1.1  jmmv     for (t = &tests[0]; t->cond != NULL; t++) {
    349  1.1  jmmv         atf::tests::vars_map config;
    350  1.1  jmmv         config["condition"] = t->cond;
    351  1.1  jmmv 
    352  1.2  gson         std::cout << "Checking with a " << t->cond << " value\n";
    353  1.1  jmmv 
    354  1.2  gson         ATF_TEST_CASE_USE(h_require);
    355  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
    356  1.1  jmmv 
    357  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    358  1.1  jmmv         if (t->ok) {
    359  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    360  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    361  1.1  jmmv         } else {
    362  1.2  gson             ATF_REQUIRE(atf::utils::grep_file(
    363  1.2  gson                 "^failed: .*condition not met", "result"));
    364  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    365  1.1  jmmv         }
    366  1.1  jmmv 
    367  1.1  jmmv         atf::fs::remove(before);
    368  1.1  jmmv         if (t->ok)
    369  1.1  jmmv             atf::fs::remove(after);
    370  1.1  jmmv     }
    371  1.1  jmmv }
    372  1.1  jmmv 
    373  1.2  gson ATF_TEST_CASE(require_eq);
    374  1.2  gson ATF_TEST_CASE_HEAD(require_eq)
    375  1.1  jmmv {
    376  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
    377  1.1  jmmv }
    378  1.2  gson ATF_TEST_CASE_BODY(require_eq)
    379  1.1  jmmv {
    380  1.1  jmmv     struct test {
    381  1.1  jmmv         const char *v1;
    382  1.1  jmmv         const char *v2;
    383  1.1  jmmv         bool ok;
    384  1.1  jmmv     } *t, tests[] = {
    385  1.1  jmmv         { "1", "1", true },
    386  1.1  jmmv         { "1", "2", false },
    387  1.1  jmmv         { "2", "1", false },
    388  1.1  jmmv         { "2", "2", true },
    389  1.1  jmmv         { NULL, NULL, false }
    390  1.1  jmmv     };
    391  1.1  jmmv 
    392  1.1  jmmv     const atf::fs::path before("before");
    393  1.1  jmmv     const atf::fs::path after("after");
    394  1.1  jmmv 
    395  1.1  jmmv     for (t = &tests[0]; t->v1 != NULL; t++) {
    396  1.1  jmmv         atf::tests::vars_map config;
    397  1.1  jmmv         config["v1"] = t->v1;
    398  1.1  jmmv         config["v2"] = t->v2;
    399  1.1  jmmv 
    400  1.1  jmmv         std::cout << "Checking with " << t->v1 << ", " << t->v2
    401  1.1  jmmv                   << " and expecting " << (t->ok ? "true" : "false")
    402  1.2  gson                   << "\n";
    403  1.2  gson 
    404  1.2  gson         ATF_TEST_CASE_USE(h_require_eq);
    405  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
    406  1.2  gson 
    407  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    408  1.2  gson         if (t->ok) {
    409  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    410  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    411  1.2  gson         } else {
    412  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^failed: .*v1 != v2", "result"));
    413  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    414  1.2  gson         }
    415  1.2  gson 
    416  1.2  gson         atf::fs::remove(before);
    417  1.2  gson         if (t->ok)
    418  1.2  gson             atf::fs::remove(after);
    419  1.2  gson     }
    420  1.2  gson }
    421  1.2  gson 
    422  1.2  gson ATF_TEST_CASE(require_in);
    423  1.2  gson ATF_TEST_CASE_HEAD(require_in)
    424  1.2  gson {
    425  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
    426  1.2  gson }
    427  1.2  gson ATF_TEST_CASE_BODY(require_in)
    428  1.2  gson {
    429  1.2  gson     struct test {
    430  1.2  gson         const char *value;
    431  1.2  gson         bool ok;
    432  1.2  gson     } *t, tests[] = {
    433  1.2  gson         { "foo", true },
    434  1.2  gson         { "bar", true },
    435  1.2  gson         { "baz", true },
    436  1.2  gson         { "xxx", false },
    437  1.2  gson         { "fooa", false },
    438  1.2  gson         { "foo ", false },
    439  1.2  gson         { NULL, false }
    440  1.2  gson     };
    441  1.2  gson 
    442  1.2  gson     const atf::fs::path before("before");
    443  1.2  gson     const atf::fs::path after("after");
    444  1.2  gson 
    445  1.2  gson     for (t = &tests[0]; t->value != NULL; t++) {
    446  1.2  gson         atf::tests::vars_map config;
    447  1.2  gson         config["value"] = t->value;
    448  1.2  gson 
    449  1.2  gson         ATF_TEST_CASE_USE(h_require_in);
    450  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
    451  1.2  gson 
    452  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    453  1.2  gson         if (t->ok) {
    454  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    455  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    456  1.2  gson         } else {
    457  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
    458  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    459  1.2  gson         }
    460  1.2  gson 
    461  1.2  gson         atf::fs::remove(before);
    462  1.2  gson         if (t->ok)
    463  1.2  gson             atf::fs::remove(after);
    464  1.2  gson     }
    465  1.2  gson }
    466  1.2  gson 
    467  1.2  gson ATF_TEST_CASE(require_match);
    468  1.2  gson ATF_TEST_CASE_HEAD(require_match)
    469  1.2  gson {
    470  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
    471  1.2  gson }
    472  1.2  gson ATF_TEST_CASE_BODY(require_match)
    473  1.2  gson {
    474  1.2  gson     struct test {
    475  1.2  gson         const char *regexp;
    476  1.2  gson         const char *string;
    477  1.2  gson         bool ok;
    478  1.2  gson     } *t, tests[] = {
    479  1.2  gson         { "foo.*bar", "this is a foo, bar, baz", true },
    480  1.2  gson         { "bar.*baz", "this is a baz, bar, foo", false },
    481  1.2  gson         { NULL, NULL, false }
    482  1.2  gson     };
    483  1.2  gson 
    484  1.2  gson     const atf::fs::path before("before");
    485  1.2  gson     const atf::fs::path after("after");
    486  1.2  gson 
    487  1.2  gson     for (t = &tests[0]; t->regexp != NULL; t++) {
    488  1.2  gson         atf::tests::vars_map config;
    489  1.2  gson         config["regexp"] = t->regexp;
    490  1.2  gson         config["string"] = t->string;
    491  1.2  gson 
    492  1.2  gson         std::cout << "Checking with " << t->regexp << ", " << t->string
    493  1.2  gson                   << " and expecting " << (t->ok ? "true" : "false")
    494  1.2  gson                   << "\n";
    495  1.1  jmmv 
    496  1.2  gson         ATF_TEST_CASE_USE(h_require_match);
    497  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
    498  1.1  jmmv 
    499  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    500  1.1  jmmv         if (t->ok) {
    501  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    502  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    503  1.1  jmmv         } else {
    504  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
    505  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    506  1.1  jmmv         }
    507  1.1  jmmv 
    508  1.1  jmmv         atf::fs::remove(before);
    509  1.1  jmmv         if (t->ok)
    510  1.1  jmmv             atf::fs::remove(after);
    511  1.1  jmmv     }
    512  1.1  jmmv }
    513  1.1  jmmv 
    514  1.2  gson ATF_TEST_CASE(require_not_in);
    515  1.2  gson ATF_TEST_CASE_HEAD(require_not_in)
    516  1.1  jmmv {
    517  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
    518  1.1  jmmv }
    519  1.2  gson ATF_TEST_CASE_BODY(require_not_in)
    520  1.2  gson {
    521  1.2  gson     struct test {
    522  1.2  gson         const char *value;
    523  1.2  gson         bool ok;
    524  1.2  gson     } *t, tests[] = {
    525  1.2  gson         { "foo", false },
    526  1.2  gson         { "bar", false },
    527  1.2  gson         { "baz", false },
    528  1.2  gson         { "xxx", true },
    529  1.2  gson         { "fooa", true },
    530  1.2  gson         { "foo ", true },
    531  1.2  gson         { NULL, false }
    532  1.2  gson     };
    533  1.2  gson 
    534  1.2  gson     const atf::fs::path before("before");
    535  1.2  gson     const atf::fs::path after("after");
    536  1.2  gson 
    537  1.2  gson     for (t = &tests[0]; t->value != NULL; t++) {
    538  1.2  gson         atf::tests::vars_map config;
    539  1.2  gson         config["value"] = t->value;
    540  1.2  gson 
    541  1.2  gson         ATF_TEST_CASE_USE(h_require_not_in);
    542  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
    543  1.2  gson 
    544  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    545  1.2  gson         if (t->ok) {
    546  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    547  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    548  1.2  gson         } else {
    549  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
    550  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    551  1.2  gson         }
    552  1.2  gson 
    553  1.2  gson         atf::fs::remove(before);
    554  1.2  gson         if (t->ok)
    555  1.2  gson             atf::fs::remove(after);
    556  1.2  gson     }
    557  1.2  gson }
    558  1.2  gson 
    559  1.2  gson ATF_TEST_CASE(require_throw);
    560  1.2  gson ATF_TEST_CASE_HEAD(require_throw)
    561  1.2  gson {
    562  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
    563  1.2  gson }
    564  1.2  gson ATF_TEST_CASE_BODY(require_throw)
    565  1.1  jmmv {
    566  1.1  jmmv     struct test {
    567  1.1  jmmv         const char *what;
    568  1.1  jmmv         bool ok;
    569  1.1  jmmv         const char *msg;
    570  1.1  jmmv     } *t, tests[] = {
    571  1.1  jmmv         { "throw_int", false, "unexpected error" },
    572  1.1  jmmv         { "throw_rt", true, NULL },
    573  1.1  jmmv         { "no_throw_rt", false, "did not throw" },
    574  1.1  jmmv         { NULL, false, NULL }
    575  1.1  jmmv     };
    576  1.1  jmmv 
    577  1.1  jmmv     const atf::fs::path before("before");
    578  1.1  jmmv     const atf::fs::path after("after");
    579  1.1  jmmv 
    580  1.1  jmmv     for (t = &tests[0]; t->what != NULL; t++) {
    581  1.1  jmmv         atf::tests::vars_map config;
    582  1.1  jmmv         config["what"] = t->what;
    583  1.1  jmmv 
    584  1.1  jmmv         std::cout << "Checking with " << t->what << " and expecting "
    585  1.2  gson                   << (t->ok ? "true" : "false") << "\n";
    586  1.2  gson 
    587  1.2  gson         ATF_TEST_CASE_USE(h_require_throw);
    588  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
    589  1.2  gson 
    590  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    591  1.2  gson         if (t->ok) {
    592  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    593  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    594  1.2  gson         } else {
    595  1.2  gson             std::cout << "Checking that message contains '" << t->msg
    596  1.2  gson                       << "'\n";
    597  1.2  gson             std::string exp_result = std::string("^failed: .*") + t->msg;
    598  1.2  gson             ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
    599  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    600  1.2  gson         }
    601  1.2  gson 
    602  1.2  gson         atf::fs::remove(before);
    603  1.2  gson         if (t->ok)
    604  1.2  gson             atf::fs::remove(after);
    605  1.2  gson     }
    606  1.2  gson }
    607  1.2  gson 
    608  1.2  gson ATF_TEST_CASE(require_throw_re);
    609  1.2  gson ATF_TEST_CASE_HEAD(require_throw_re)
    610  1.2  gson {
    611  1.2  gson     set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
    612  1.2  gson }
    613  1.2  gson ATF_TEST_CASE_BODY(require_throw_re)
    614  1.2  gson {
    615  1.2  gson     struct test {
    616  1.2  gson         const char *what;
    617  1.2  gson         bool ok;
    618  1.2  gson         const char *msg;
    619  1.2  gson     } *t, tests[] = {
    620  1.2  gson         { "throw_int", false, "unexpected error" },
    621  1.2  gson         { "throw_rt_match", true, NULL },
    622  1.2  gson         { "throw_rt_no_match", false,
    623  1.2  gson           "threw.*runtime_error\\(baz foo bar a\\).*"
    624  1.2  gson           "does not match 'foo\\.\\*baz'" },
    625  1.2  gson         { "no_throw_rt", false, "did not throw" },
    626  1.2  gson         { NULL, false, NULL }
    627  1.2  gson     };
    628  1.2  gson 
    629  1.2  gson     const atf::fs::path before("before");
    630  1.2  gson     const atf::fs::path after("after");
    631  1.2  gson 
    632  1.2  gson     for (t = &tests[0]; t->what != NULL; t++) {
    633  1.2  gson         atf::tests::vars_map config;
    634  1.2  gson         config["what"] = t->what;
    635  1.2  gson 
    636  1.2  gson         std::cout << "Checking with " << t->what << " and expecting "
    637  1.2  gson                   << (t->ok ? "true" : "false") << "\n";
    638  1.1  jmmv 
    639  1.2  gson         ATF_TEST_CASE_USE(h_require_throw_re);
    640  1.2  gson         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
    641  1.1  jmmv 
    642  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    643  1.1  jmmv         if (t->ok) {
    644  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    645  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    646  1.1  jmmv         } else {
    647  1.1  jmmv             std::cout << "Checking that message contains '" << t->msg
    648  1.2  gson                       << "'\n";
    649  1.1  jmmv             std::string exp_result = std::string("^failed: .*") + t->msg;
    650  1.2  gson             ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
    651  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    652  1.1  jmmv         }
    653  1.1  jmmv 
    654  1.1  jmmv         atf::fs::remove(before);
    655  1.1  jmmv         if (t->ok)
    656  1.1  jmmv             atf::fs::remove(after);
    657  1.1  jmmv     }
    658  1.1  jmmv }
    659  1.1  jmmv 
    660  1.1  jmmv ATF_TEST_CASE(check_errno);
    661  1.1  jmmv ATF_TEST_CASE_HEAD(check_errno)
    662  1.1  jmmv {
    663  1.1  jmmv     set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
    664  1.1  jmmv }
    665  1.1  jmmv ATF_TEST_CASE_BODY(check_errno)
    666  1.1  jmmv {
    667  1.1  jmmv     struct test {
    668  1.1  jmmv         const char *what;
    669  1.1  jmmv         bool ok;
    670  1.1  jmmv         const char *msg;
    671  1.1  jmmv     } *t, tests[] = {
    672  1.1  jmmv         { "no_error", false,
    673  1.1  jmmv           "Expected true value in errno_ok_stub\\(\\) == -1" },
    674  1.1  jmmv         { "errno_ok", true, NULL },
    675  1.1  jmmv         { "errno_fail", false,
    676  1.1  jmmv           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
    677  1.1  jmmv         { NULL, false, NULL }
    678  1.1  jmmv     };
    679  1.1  jmmv 
    680  1.1  jmmv     const atf::fs::path before("before");
    681  1.1  jmmv     const atf::fs::path after("after");
    682  1.1  jmmv 
    683  1.1  jmmv     for (t = &tests[0]; t->what != NULL; t++) {
    684  1.1  jmmv         atf::tests::vars_map config;
    685  1.1  jmmv         config["what"] = t->what;
    686  1.1  jmmv 
    687  1.2  gson         ATF_TEST_CASE_USE(h_check_errno);
    688  1.1  jmmv         run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
    689  1.1  jmmv 
    690  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    691  1.2  gson         ATF_REQUIRE(atf::fs::exists(after));
    692  1.1  jmmv 
    693  1.1  jmmv         if (t->ok) {
    694  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    695  1.1  jmmv         } else {
    696  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^failed", "result"));
    697  1.1  jmmv 
    698  1.1  jmmv             std::string exp_result = "macros_test.cpp:[0-9]+: " +
    699  1.1  jmmv                 std::string(t->msg) + "$";
    700  1.2  gson             ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "stderr"));
    701  1.1  jmmv         }
    702  1.1  jmmv 
    703  1.1  jmmv         atf::fs::remove(before);
    704  1.1  jmmv         atf::fs::remove(after);
    705  1.1  jmmv     }
    706  1.1  jmmv }
    707  1.1  jmmv 
    708  1.1  jmmv ATF_TEST_CASE(require_errno);
    709  1.1  jmmv ATF_TEST_CASE_HEAD(require_errno)
    710  1.1  jmmv {
    711  1.1  jmmv     set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
    712  1.1  jmmv }
    713  1.1  jmmv ATF_TEST_CASE_BODY(require_errno)
    714  1.1  jmmv {
    715  1.1  jmmv     struct test {
    716  1.1  jmmv         const char *what;
    717  1.1  jmmv         bool ok;
    718  1.1  jmmv         const char *msg;
    719  1.1  jmmv     } *t, tests[] = {
    720  1.1  jmmv         { "no_error", false,
    721  1.1  jmmv           "Expected true value in errno_ok_stub\\(\\) == -1" },
    722  1.1  jmmv         { "errno_ok", true, NULL },
    723  1.1  jmmv         { "errno_fail", false,
    724  1.1  jmmv           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
    725  1.1  jmmv         { NULL, false, NULL }
    726  1.1  jmmv     };
    727  1.1  jmmv 
    728  1.1  jmmv     const atf::fs::path before("before");
    729  1.1  jmmv     const atf::fs::path after("after");
    730  1.1  jmmv 
    731  1.1  jmmv     for (t = &tests[0]; t->what != NULL; t++) {
    732  1.1  jmmv         atf::tests::vars_map config;
    733  1.1  jmmv         config["what"] = t->what;
    734  1.1  jmmv 
    735  1.2  gson         ATF_TEST_CASE_USE(h_require_errno);
    736  1.1  jmmv         run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
    737  1.1  jmmv 
    738  1.2  gson         ATF_REQUIRE(atf::fs::exists(before));
    739  1.1  jmmv         if (t->ok) {
    740  1.2  gson             ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
    741  1.2  gson             ATF_REQUIRE(atf::fs::exists(after));
    742  1.1  jmmv         } else {
    743  1.1  jmmv             std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
    744  1.1  jmmv                 std::string(t->msg) + "$";
    745  1.2  gson             ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
    746  1.1  jmmv 
    747  1.2  gson             ATF_REQUIRE(!atf::fs::exists(after));
    748  1.1  jmmv         }
    749  1.1  jmmv 
    750  1.1  jmmv         atf::fs::remove(before);
    751  1.1  jmmv         if (t->ok)
    752  1.1  jmmv             atf::fs::remove(after);
    753  1.1  jmmv     }
    754  1.1  jmmv }
    755  1.1  jmmv 
    756  1.1  jmmv // ------------------------------------------------------------------------
    757  1.1  jmmv // Tests cases for the header file.
    758  1.1  jmmv // ------------------------------------------------------------------------
    759  1.1  jmmv 
    760  1.1  jmmv HEADER_TC(include, "atf-c++/macros.hpp");
    761  1.1  jmmv BUILD_TC(use, "macros_hpp_test.cpp",
    762  1.1  jmmv          "Tests that the macros provided by the atf-c++/macros.hpp file "
    763  1.1  jmmv          "do not cause syntax errors when used",
    764  1.1  jmmv          "Build of macros_hpp_test.cpp failed; some macros in "
    765  1.1  jmmv          "atf-c++/macros.hpp are broken");
    766  1.1  jmmv 
    767  1.2  gson ATF_TEST_CASE(detect_unused_tests);
    768  1.2  gson ATF_TEST_CASE_HEAD(detect_unused_tests)
    769  1.2  gson {
    770  1.2  gson     set_md_var("descr",
    771  1.2  gson                "Tests that defining an unused test case raises a warning (and "
    772  1.2  gson                "thus an error)");
    773  1.2  gson }
    774  1.2  gson ATF_TEST_CASE_BODY(detect_unused_tests)
    775  1.2  gson {
    776  1.2  gson     const char* validate_compiler =
    777  1.2  gson         "class test_class { public: int dummy; };\n"
    778  1.2  gson         "#define define_unused static test_class unused\n"
    779  1.2  gson         "define_unused;\n";
    780  1.2  gson 
    781  1.2  gson     atf::utils::create_file("compiler_test.cpp", validate_compiler);
    782  1.2  gson     if (build_check_cxx_o("compiler_test.cpp"))
    783  1.2  gson         expect_fail("Compiler does not raise a warning on an unused "
    784  1.2  gson                     "static global variable declared by a macro");
    785  1.2  gson 
    786  1.2  gson #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
    787  1.2  gson         expect_fail("PR 49187");
    788  1.2  gson #endif
    789  1.2  gson 
    790  1.2  gson     if (build_check_cxx_o_srcdir(*this, "unused_test.cpp"))
    791  1.2  gson         ATF_FAIL("Build of unused_test.cpp passed; unused test cases are "
    792  1.2  gson                  "not properly detected");
    793  1.2  gson }
    794  1.2  gson 
    795  1.1  jmmv // ------------------------------------------------------------------------
    796  1.1  jmmv // Main.
    797  1.1  jmmv // ------------------------------------------------------------------------
    798  1.1  jmmv 
    799  1.1  jmmv ATF_INIT_TEST_CASES(tcs)
    800  1.1  jmmv {
    801  1.1  jmmv     // Add the test cases for the macros.
    802  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, pass);
    803  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, fail);
    804  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, skip);
    805  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, check_errno);
    806  1.2  gson     ATF_ADD_TEST_CASE(tcs, require);
    807  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_eq);
    808  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_in);
    809  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_match);
    810  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_not_in);
    811  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_throw);
    812  1.2  gson     ATF_ADD_TEST_CASE(tcs, require_throw_re);
    813  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, require_errno);
    814  1.1  jmmv 
    815  1.1  jmmv     // Add the test cases for the header file.
    816  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, include);
    817  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, use);
    818  1.2  gson     ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
    819  1.1  jmmv }
    820