xref: /freebsd/contrib/atf/atf-c++/detail/test_helpers.cpp (revision c243e4902be8df1e643c76b5f18b68bb77cc5268)
1*c243e490SMarcel Moolenaar //
2*c243e490SMarcel Moolenaar // Automated Testing Framework (atf)
3*c243e490SMarcel Moolenaar //
4*c243e490SMarcel Moolenaar // Copyright (c) 2009 The NetBSD Foundation, Inc.
5*c243e490SMarcel Moolenaar // All rights reserved.
6*c243e490SMarcel Moolenaar //
7*c243e490SMarcel Moolenaar // Redistribution and use in source and binary forms, with or without
8*c243e490SMarcel Moolenaar // modification, are permitted provided that the following conditions
9*c243e490SMarcel Moolenaar // are met:
10*c243e490SMarcel Moolenaar // 1. Redistributions of source code must retain the above copyright
11*c243e490SMarcel Moolenaar //    notice, this list of conditions and the following disclaimer.
12*c243e490SMarcel Moolenaar // 2. Redistributions in binary form must reproduce the above copyright
13*c243e490SMarcel Moolenaar //    notice, this list of conditions and the following disclaimer in the
14*c243e490SMarcel Moolenaar //    documentation and/or other materials provided with the distribution.
15*c243e490SMarcel Moolenaar //
16*c243e490SMarcel Moolenaar // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17*c243e490SMarcel Moolenaar // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18*c243e490SMarcel Moolenaar // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*c243e490SMarcel Moolenaar // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*c243e490SMarcel Moolenaar // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21*c243e490SMarcel Moolenaar // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*c243e490SMarcel Moolenaar // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23*c243e490SMarcel Moolenaar // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*c243e490SMarcel Moolenaar // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25*c243e490SMarcel Moolenaar // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26*c243e490SMarcel Moolenaar // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*c243e490SMarcel Moolenaar // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*c243e490SMarcel Moolenaar //
29*c243e490SMarcel Moolenaar 
30*c243e490SMarcel Moolenaar extern "C" {
31*c243e490SMarcel Moolenaar #include <regex.h>
32*c243e490SMarcel Moolenaar }
33*c243e490SMarcel Moolenaar 
34*c243e490SMarcel Moolenaar #include <fstream>
35*c243e490SMarcel Moolenaar #include <iostream>
36*c243e490SMarcel Moolenaar #include <string>
37*c243e490SMarcel Moolenaar #include <vector>
38*c243e490SMarcel Moolenaar 
39*c243e490SMarcel Moolenaar #include "../check.hpp"
40*c243e490SMarcel Moolenaar #include "../config.hpp"
41*c243e490SMarcel Moolenaar #include "../macros.hpp"
42*c243e490SMarcel Moolenaar 
43*c243e490SMarcel Moolenaar #include "fs.hpp"
44*c243e490SMarcel Moolenaar #include "process.hpp"
45*c243e490SMarcel Moolenaar #include "test_helpers.hpp"
46*c243e490SMarcel Moolenaar 
47*c243e490SMarcel Moolenaar void
48*c243e490SMarcel Moolenaar build_check_cxx_o_aux(const atf::fs::path& sfile, const char* failmsg,
49*c243e490SMarcel Moolenaar                       const bool expect_pass)
50*c243e490SMarcel Moolenaar {
51*c243e490SMarcel Moolenaar     std::vector< std::string > optargs;
52*c243e490SMarcel Moolenaar     optargs.push_back("-I" + atf::config::get("atf_includedir"));
53*c243e490SMarcel Moolenaar     optargs.push_back("-Wall");
54*c243e490SMarcel Moolenaar     optargs.push_back("-Werror");
55*c243e490SMarcel Moolenaar 
56*c243e490SMarcel Moolenaar     const bool result = atf::check::build_cxx_o(
57*c243e490SMarcel Moolenaar         sfile.str(), "test.o", atf::process::argv_array(optargs));
58*c243e490SMarcel Moolenaar     if ((expect_pass && !result) || (!expect_pass && result))
59*c243e490SMarcel Moolenaar         ATF_FAIL(failmsg);
60*c243e490SMarcel Moolenaar }
61*c243e490SMarcel Moolenaar 
62*c243e490SMarcel Moolenaar void
63*c243e490SMarcel Moolenaar build_check_cxx_o(const atf::tests::tc& tc, const char* sfile,
64*c243e490SMarcel Moolenaar                   const char* failmsg, const bool expect_pass)
65*c243e490SMarcel Moolenaar {
66*c243e490SMarcel Moolenaar     const atf::fs::path sfilepath =
67*c243e490SMarcel Moolenaar         atf::fs::path(tc.get_config_var("srcdir")) / sfile;
68*c243e490SMarcel Moolenaar     build_check_cxx_o_aux(sfilepath, failmsg, expect_pass);
69*c243e490SMarcel Moolenaar }
70*c243e490SMarcel Moolenaar 
71*c243e490SMarcel Moolenaar void
72*c243e490SMarcel Moolenaar header_check(const char *hdrname)
73*c243e490SMarcel Moolenaar {
74*c243e490SMarcel Moolenaar     std::ofstream srcfile("test.c");
75*c243e490SMarcel Moolenaar     ATF_REQUIRE(srcfile);
76*c243e490SMarcel Moolenaar     srcfile << "#include <" << hdrname << ">\n";
77*c243e490SMarcel Moolenaar     srcfile.close();
78*c243e490SMarcel Moolenaar 
79*c243e490SMarcel Moolenaar     const std::string failmsg = std::string("Header check failed; ") +
80*c243e490SMarcel Moolenaar         hdrname + " is not self-contained";
81*c243e490SMarcel Moolenaar     build_check_cxx_o_aux(atf::fs::path("test.c"), failmsg.c_str(), true);
82*c243e490SMarcel Moolenaar }
83*c243e490SMarcel Moolenaar 
84*c243e490SMarcel Moolenaar atf::fs::path
85*c243e490SMarcel Moolenaar get_process_helpers_path(const atf::tests::tc& tc)
86*c243e490SMarcel Moolenaar {
87*c243e490SMarcel Moolenaar     return atf::fs::path(tc.get_config_var("srcdir")) /
88*c243e490SMarcel Moolenaar            ".." / "atf-c" / "detail" / "process_helpers";
89*c243e490SMarcel Moolenaar }
90*c243e490SMarcel Moolenaar 
91*c243e490SMarcel Moolenaar bool
92*c243e490SMarcel Moolenaar grep_file(const char* name, const char* regex)
93*c243e490SMarcel Moolenaar {
94*c243e490SMarcel Moolenaar     std::ifstream is(name);
95*c243e490SMarcel Moolenaar     ATF_REQUIRE(is);
96*c243e490SMarcel Moolenaar 
97*c243e490SMarcel Moolenaar     bool found = false;
98*c243e490SMarcel Moolenaar 
99*c243e490SMarcel Moolenaar     std::string line;
100*c243e490SMarcel Moolenaar     std::getline(is, line);
101*c243e490SMarcel Moolenaar     while (!found && is.good()) {
102*c243e490SMarcel Moolenaar         if (grep_string(line, regex))
103*c243e490SMarcel Moolenaar             found = true;
104*c243e490SMarcel Moolenaar         else
105*c243e490SMarcel Moolenaar             std::getline(is, line);
106*c243e490SMarcel Moolenaar     }
107*c243e490SMarcel Moolenaar 
108*c243e490SMarcel Moolenaar     return found;
109*c243e490SMarcel Moolenaar }
110*c243e490SMarcel Moolenaar 
111*c243e490SMarcel Moolenaar bool
112*c243e490SMarcel Moolenaar grep_string(const std::string& str, const char* regex)
113*c243e490SMarcel Moolenaar {
114*c243e490SMarcel Moolenaar     int res;
115*c243e490SMarcel Moolenaar     regex_t preg;
116*c243e490SMarcel Moolenaar 
117*c243e490SMarcel Moolenaar     std::cout << "Looking for '" << regex << "' in '" << str << "'\n";
118*c243e490SMarcel Moolenaar     ATF_REQUIRE(::regcomp(&preg, regex, REG_EXTENDED) == 0);
119*c243e490SMarcel Moolenaar 
120*c243e490SMarcel Moolenaar     res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
121*c243e490SMarcel Moolenaar     ATF_REQUIRE(res == 0 || res == REG_NOMATCH);
122*c243e490SMarcel Moolenaar 
123*c243e490SMarcel Moolenaar     ::regfree(&preg);
124*c243e490SMarcel Moolenaar 
125*c243e490SMarcel Moolenaar     return res == 0;
126*c243e490SMarcel Moolenaar }
127*c243e490SMarcel Moolenaar 
128*c243e490SMarcel Moolenaar void
129*c243e490SMarcel Moolenaar test_helpers_detail::check_equal(const char* expected[],
130*c243e490SMarcel Moolenaar                                  const string_vector& actual)
131*c243e490SMarcel Moolenaar {
132*c243e490SMarcel Moolenaar     const char** expected_iter = expected;
133*c243e490SMarcel Moolenaar     string_vector::const_iterator actual_iter = actual.begin();
134*c243e490SMarcel Moolenaar 
135*c243e490SMarcel Moolenaar     bool equals = true;
136*c243e490SMarcel Moolenaar     while (equals && *expected_iter != NULL && actual_iter != actual.end()) {
137*c243e490SMarcel Moolenaar         if (*expected_iter != *actual_iter) {
138*c243e490SMarcel Moolenaar             equals = false;
139*c243e490SMarcel Moolenaar         } else {
140*c243e490SMarcel Moolenaar             expected_iter++;
141*c243e490SMarcel Moolenaar             actual_iter++;
142*c243e490SMarcel Moolenaar         }
143*c243e490SMarcel Moolenaar     }
144*c243e490SMarcel Moolenaar     if (equals && ((*expected_iter == NULL && actual_iter != actual.end()) ||
145*c243e490SMarcel Moolenaar                    (*expected_iter != NULL && actual_iter == actual.end())))
146*c243e490SMarcel Moolenaar         equals = false;
147*c243e490SMarcel Moolenaar 
148*c243e490SMarcel Moolenaar     if (!equals) {
149*c243e490SMarcel Moolenaar         std::cerr << "EXPECTED:\n";
150*c243e490SMarcel Moolenaar         for (expected_iter = expected; *expected_iter != NULL; expected_iter++)
151*c243e490SMarcel Moolenaar             std::cerr << *expected_iter << "\n";
152*c243e490SMarcel Moolenaar 
153*c243e490SMarcel Moolenaar         std::cerr << "ACTUAL:\n";
154*c243e490SMarcel Moolenaar         for (actual_iter = actual.begin(); actual_iter != actual.end();
155*c243e490SMarcel Moolenaar              actual_iter++)
156*c243e490SMarcel Moolenaar             std::cerr << *actual_iter << "\n";
157*c243e490SMarcel Moolenaar 
158*c243e490SMarcel Moolenaar         ATF_FAIL("Expected results differ to actual values");
159*c243e490SMarcel Moolenaar     }
160*c243e490SMarcel Moolenaar }
161