1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2007 The NetBSD Foundation, Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 // 1. Redistributions of source code must retain the above copyright
11 //    notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 //    notice, this list of conditions and the following disclaimer in the
14 //    documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 
30 #include <cstring>
31 #include <iostream>
32 
33 #include <atf-c++.hpp>
34 
35 #include "config.hpp"
36 #include "env.hpp"
37 #include "exceptions.hpp"
38 
39 static const char *test_value = "env-value";
40 
41 static struct varnames {
42     const char *lc;
43     const char *uc;
44     bool can_be_empty;
45 } all_vars[] = {
46     { "atf_arch",           "ATF_ARCH",           false },
47     { "atf_build_cc",       "ATF_BUILD_CC",       false },
48     { "atf_build_cflags",   "ATF_BUILD_CFLAGS",   true  },
49     { "atf_build_cpp",      "ATF_BUILD_CPP",      false },
50     { "atf_build_cppflags", "ATF_BUILD_CPPFLAGS", true  },
51     { "atf_build_cxx",      "ATF_BUILD_CXX",      false },
52     { "atf_build_cxxflags", "ATF_BUILD_CXXFLAGS", true  },
53     { "atf_confdir",        "ATF_CONFDIR",        false },
54     { "atf_includedir",     "ATF_INCLUDEDIR",     false },
55     { "atf_libdir",         "ATF_LIBDIR",         false },
56     { "atf_libexecdir",     "ATF_LIBEXECDIR",     false },
57     { "atf_machine",        "ATF_MACHINE",        false },
58     { "atf_pkgdatadir",     "ATF_PKGDATADIR",     false },
59     { "atf_shell",          "ATF_SHELL",          false },
60     { "atf_workdir",        "ATF_WORKDIR",        false },
61     { NULL,                 NULL,                 false }
62 };
63 
64 // ------------------------------------------------------------------------
65 // Auxiliary functions.
66 // ------------------------------------------------------------------------
67 
68 namespace tools {
69     namespace config {
70         void __reinit(void);
71     }
72 }
73 
74 static
75 void
set_env_var(const char * name,const char * val)76 set_env_var(const char* name, const char* val)
77 {
78     try {
79         tools::env::set(name, val);
80     } catch (const tools::system_error&) {
81         ATF_FAIL(std::string("set_env_var(") + name + ", " + val +
82                  ") failed");
83     }
84 }
85 
86 static
87 void
unset_env_var(const char * name)88 unset_env_var(const char* name)
89 {
90     try {
91         tools::env::unset(name);
92     } catch (const tools::system_error&) {
93         ATF_FAIL(std::string("unset_env_var(") + name + ") failed");
94     }
95 }
96 
97 static
98 size_t
all_vars_count(void)99 all_vars_count(void)
100 {
101     size_t count = 0;
102     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
103         count++;
104     return count;
105 }
106 
107 static
108 void
unset_all(void)109 unset_all(void)
110 {
111     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
112         unset_env_var(v->uc);
113 }
114 
115 static
116 void
compare_one(const char * var,const char * expvalue)117 compare_one(const char* var, const char* expvalue)
118 {
119     std::cout << "Checking that " << var << " is set to " << expvalue << "\n";
120 
121     for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
122         if (std::strcmp(v->lc, var) == 0)
123             ATF_REQUIRE_EQ(tools::config::get(v->lc), test_value);
124         else
125             ATF_REQUIRE(tools::config::get(v->lc) != test_value);
126     }
127 }
128 
129 // ------------------------------------------------------------------------
130 // Test cases for the free functions.
131 // ------------------------------------------------------------------------
132 
133 ATF_TEST_CASE(get);
ATF_TEST_CASE_HEAD(get)134 ATF_TEST_CASE_HEAD(get)
135 {
136     set_md_var("descr", "Tests the config::get function");
137 }
ATF_TEST_CASE_BODY(get)138 ATF_TEST_CASE_BODY(get)
139 {
140     // Unset all known environment variables and make sure the built-in
141     // values do not match the bogus value we will use for testing.
142     unset_all();
143     tools::config::__reinit();
144     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
145         ATF_REQUIRE(tools::config::get(v->lc) != test_value);
146 
147     // Test the behavior of empty values.
148     for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
149         unset_all();
150         if (!tools::config::get(v->lc).empty()) {
151             set_env_var(v->uc, "");
152             tools::config::__reinit();
153             if (v->can_be_empty)
154                 ATF_REQUIRE(tools::config::get(v->lc).empty());
155             else
156                 ATF_REQUIRE(!tools::config::get(v->lc).empty());
157         }
158     }
159 
160     // Check if the ATF_ARCH variable is recognized.
161     for (const struct varnames* v = all_vars; v->lc != NULL; v++) {
162         unset_all();
163         set_env_var(v->uc, test_value);
164         tools::config::__reinit();
165         compare_one(v->lc, test_value);
166     }
167 }
168 
169 ATF_TEST_CASE(get_all);
ATF_TEST_CASE_HEAD(get_all)170 ATF_TEST_CASE_HEAD(get_all)
171 {
172     set_md_var("descr", "Tests the config::get_all function");
173 }
ATF_TEST_CASE_BODY(get_all)174 ATF_TEST_CASE_BODY(get_all)
175 {
176     tools::config::__reinit();
177 
178     // Check that the valid variables, and only those, are returned.
179     std::map< std::string, std::string > vars = tools::config::get_all();
180     ATF_REQUIRE_EQ(vars.size(), all_vars_count());
181     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
182         ATF_REQUIRE(vars.find(v->lc) != vars.end());
183 }
184 
185 ATF_TEST_CASE(has);
ATF_TEST_CASE_HEAD(has)186 ATF_TEST_CASE_HEAD(has)
187 {
188     set_md_var("descr", "Tests the config::has function");
189 }
ATF_TEST_CASE_BODY(has)190 ATF_TEST_CASE_BODY(has)
191 {
192     tools::config::__reinit();
193 
194     // Check for all the variables that must exist.
195     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
196         ATF_REQUIRE(tools::config::has(v->lc));
197 
198     // Same as above, but using uppercase (which is incorrect).
199     for (const struct varnames* v = all_vars; v->lc != NULL; v++)
200         ATF_REQUIRE(!tools::config::has(v->uc));
201 
202     // Check for some other variables that cannot exist.
203     ATF_REQUIRE(!tools::config::has("foo"));
204     ATF_REQUIRE(!tools::config::has("BAR"));
205     ATF_REQUIRE(!tools::config::has("atf_foo"));
206     ATF_REQUIRE(!tools::config::has("ATF_BAR"));
207     ATF_REQUIRE(!tools::config::has("atf_shel"));
208     ATF_REQUIRE(!tools::config::has("atf_shells"));
209 }
210 
211 // ------------------------------------------------------------------------
212 // Main.
213 // ------------------------------------------------------------------------
214 
ATF_INIT_TEST_CASES(tcs)215 ATF_INIT_TEST_CASES(tcs)
216 {
217     // Add the test cases for the free functions.
218     ATF_ADD_TEST_CASE(tcs, has);
219     ATF_ADD_TEST_CASE(tcs, get);
220     ATF_ADD_TEST_CASE(tcs, get_all);
221 }
222