1240116Smarcel//
2240116Smarcel// Automated Testing Framework (atf)
3240116Smarcel//
4240116Smarcel// Copyright (c) 2007 The NetBSD Foundation, Inc.
5240116Smarcel// All rights reserved.
6240116Smarcel//
7240116Smarcel// Redistribution and use in source and binary forms, with or without
8240116Smarcel// modification, are permitted provided that the following conditions
9240116Smarcel// are met:
10240116Smarcel// 1. Redistributions of source code must retain the above copyright
11240116Smarcel//    notice, this list of conditions and the following disclaimer.
12240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright
13240116Smarcel//    notice, this list of conditions and the following disclaimer in the
14240116Smarcel//    documentation and/or other materials provided with the distribution.
15240116Smarcel//
16240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28240116Smarcel//
29240116Smarcel
30240116Smarcel#include <cstring>
31240116Smarcel#include <iostream>
32240116Smarcel
33240116Smarcel#include "config.hpp"
34240116Smarcel#include "macros.hpp"
35240116Smarcel
36240116Smarcel#include "detail/env.hpp"
37240116Smarcel#include "detail/exceptions.hpp"
38240116Smarcel#include "detail/test_helpers.hpp"
39240116Smarcel
40240116Smarcelstatic const char *test_value = "env-value";
41240116Smarcel
42240116Smarcelstatic struct varnames {
43240116Smarcel    const char *lc;
44240116Smarcel    const char *uc;
45240116Smarcel    bool can_be_empty;
46240116Smarcel} all_vars[] = {
47240116Smarcel    { "atf_build_cc",       "ATF_BUILD_CC",       false },
48240116Smarcel    { "atf_build_cflags",   "ATF_BUILD_CFLAGS",   true  },
49240116Smarcel    { "atf_build_cpp",      "ATF_BUILD_CPP",      false },
50240116Smarcel    { "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true  },
51240116Smarcel    { "atf_build_cxx",      "ATF_BUILD_CXX",      false },
52240116Smarcel    { "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true  },
53240116Smarcel    { "atf_includedir",     "ATF_INCLUDEDIR",     false },
54240116Smarcel    { "atf_libexecdir",     "ATF_LIBEXECDIR",     false },
55240116Smarcel    { "atf_pkgdatadir",     "ATF_PKGDATADIR",     false },
56240116Smarcel    { "atf_shell",          "ATF_SHELL",          false },
57240116Smarcel    { "atf_workdir",        "ATF_WORKDIR",        false },
58240116Smarcel    { NULL,                 NULL,                 false }
59240116Smarcel};
60240116Smarcel
61240116Smarcel// ------------------------------------------------------------------------
62240116Smarcel// Auxiliary functions.
63240116Smarcel// ------------------------------------------------------------------------
64240116Smarcel
65240116Smarcelnamespace atf {
66240116Smarcel    namespace config {
67240116Smarcel        void __reinit(void);
68240116Smarcel    }
69240116Smarcel}
70240116Smarcel
71240116Smarcelstatic
72240116Smarcelvoid
73240116Smarcelset_env_var(const char* name, const char* val)
74240116Smarcel{
75240116Smarcel    try {
76240116Smarcel        atf::env::set(name, val);
77240116Smarcel    } catch (const atf::system_error&) {
78240116Smarcel        ATF_FAIL(std::string("set_env_var(") + name + ", " + val +
79240116Smarcel                 ") failed");
80240116Smarcel    }
81240116Smarcel}
82240116Smarcel
83240116Smarcelstatic
84240116Smarcelvoid
85240116Smarcelunset_env_var(const char* name)
86240116Smarcel{
87240116Smarcel    try {
88240116Smarcel        atf::env::unset(name);
89240116Smarcel    } catch (const atf::system_error&) {
90240116Smarcel        ATF_FAIL(std::string("unset_env_var(") + name + ") failed");
91240116Smarcel    }
92240116Smarcel}
93240116Smarcel
94240116Smarcelstatic
95240116Smarcelsize_t
96240116Smarcelall_vars_count(void)
97240116Smarcel{
98240116Smarcel    size_t count = 0;
99240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
100240116Smarcel        count++;
101240116Smarcel    return count;
102240116Smarcel}
103240116Smarcel
104240116Smarcelstatic
105240116Smarcelvoid
106240116Smarcelunset_all(void)
107240116Smarcel{
108240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
109240116Smarcel        unset_env_var(v->uc);
110240116Smarcel}
111240116Smarcel
112240116Smarcelstatic
113240116Smarcelvoid
114240116Smarcelcompare_one(const char* var, const char* expvalue)
115240116Smarcel{
116240116Smarcel    std::cout << "Checking that " << var << " is set to " << expvalue << "\n";
117240116Smarcel
118240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
119240116Smarcel        if (std::strcmp(v->lc, var) == 0)
120240116Smarcel            ATF_REQUIRE_EQ(atf::config::get(v->lc), test_value);
121240116Smarcel        else
122240116Smarcel            ATF_REQUIRE(atf::config::get(v->lc) != test_value);
123240116Smarcel    }
124240116Smarcel}
125240116Smarcel
126240116Smarcel// ------------------------------------------------------------------------
127240116Smarcel// Test cases for the free functions.
128240116Smarcel// ------------------------------------------------------------------------
129240116Smarcel
130240116SmarcelATF_TEST_CASE(get);
131240116SmarcelATF_TEST_CASE_HEAD(get)
132240116Smarcel{
133240116Smarcel    set_md_var("descr", "Tests the config::get function");
134240116Smarcel}
135240116SmarcelATF_TEST_CASE_BODY(get)
136240116Smarcel{
137240116Smarcel    // Unset all known environment variables and make sure the built-in
138240116Smarcel    // values do not match the bogus value we will use for testing.
139240116Smarcel    unset_all();
140240116Smarcel    atf::config::__reinit();
141240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
142240116Smarcel        ATF_REQUIRE(atf::config::get(v->lc) != test_value);
143240116Smarcel
144240116Smarcel    // Test the behavior of empty values.
145240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
146240116Smarcel        unset_all();
147240116Smarcel        if (!atf::config::get(v->lc).empty()) {
148240116Smarcel            set_env_var(v->uc, "");
149240116Smarcel            atf::config::__reinit();
150240116Smarcel            if (v->can_be_empty)
151240116Smarcel                ATF_REQUIRE(atf::config::get(v->lc).empty());
152240116Smarcel            else
153240116Smarcel                ATF_REQUIRE(!atf::config::get(v->lc).empty());
154240116Smarcel        }
155240116Smarcel    }
156240116Smarcel
157240116Smarcel    // Check if the ATF_ARCH variable is recognized.
158240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
159240116Smarcel        unset_all();
160240116Smarcel        set_env_var(v->uc, test_value);
161240116Smarcel        atf::config::__reinit();
162240116Smarcel        compare_one(v->lc, test_value);
163240116Smarcel    }
164240116Smarcel}
165240116Smarcel
166240116SmarcelATF_TEST_CASE(get_all);
167240116SmarcelATF_TEST_CASE_HEAD(get_all)
168240116Smarcel{
169240116Smarcel    set_md_var("descr", "Tests the config::get_all function");
170240116Smarcel}
171240116SmarcelATF_TEST_CASE_BODY(get_all)
172240116Smarcel{
173240116Smarcel    atf::config::__reinit();
174240116Smarcel
175240116Smarcel    // Check that the valid variables, and only those, are returned.
176240116Smarcel    std::map< std::string, std::string > vars = atf::config::get_all();
177240116Smarcel    ATF_REQUIRE_EQ(vars.size(), all_vars_count());
178240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
179240116Smarcel        ATF_REQUIRE(vars.find(v->lc) != vars.end());
180240116Smarcel}
181240116Smarcel
182240116SmarcelATF_TEST_CASE(has);
183240116SmarcelATF_TEST_CASE_HEAD(has)
184240116Smarcel{
185240116Smarcel    set_md_var("descr", "Tests the config::has function");
186240116Smarcel}
187240116SmarcelATF_TEST_CASE_BODY(has)
188240116Smarcel{
189240116Smarcel    atf::config::__reinit();
190240116Smarcel
191240116Smarcel    // Check for all the variables that must exist.
192240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
193240116Smarcel        ATF_REQUIRE(atf::config::has(v->lc));
194240116Smarcel
195240116Smarcel    // Same as above, but using uppercase (which is incorrect).
196240116Smarcel    for (const struct varnames* v = all_vars; v->lc != NULL; v++)
197240116Smarcel        ATF_REQUIRE(!atf::config::has(v->uc));
198240116Smarcel
199240116Smarcel    // Check for some other variables that cannot exist.
200240116Smarcel    ATF_REQUIRE(!atf::config::has("foo"));
201240116Smarcel    ATF_REQUIRE(!atf::config::has("BAR"));
202240116Smarcel    ATF_REQUIRE(!atf::config::has("atf_foo"));
203240116Smarcel    ATF_REQUIRE(!atf::config::has("ATF_BAR"));
204240116Smarcel    ATF_REQUIRE(!atf::config::has("atf_shel"));
205240116Smarcel    ATF_REQUIRE(!atf::config::has("atf_shells"));
206240116Smarcel}
207240116Smarcel
208240116Smarcel// ------------------------------------------------------------------------
209240116Smarcel// Tests cases for the header file.
210240116Smarcel// ------------------------------------------------------------------------
211240116Smarcel
212240116SmarcelHEADER_TC(include, "atf-c++/config.hpp");
213240116Smarcel
214240116Smarcel// ------------------------------------------------------------------------
215240116Smarcel// Main.
216240116Smarcel// ------------------------------------------------------------------------
217240116Smarcel
218240116SmarcelATF_INIT_TEST_CASES(tcs)
219240116Smarcel{
220240116Smarcel    // Add the test cases for the free functions.
221240116Smarcel    ATF_ADD_TEST_CASE(tcs, has);
222240116Smarcel    ATF_ADD_TEST_CASE(tcs, get);
223240116Smarcel    ATF_ADD_TEST_CASE(tcs, get_all);
224240116Smarcel
225240116Smarcel    // Add the test cases for the header file.
226240116Smarcel    ATF_ADD_TEST_CASE(tcs, include);
227240116Smarcel}
228