1//
2// Automated Testing Framework (atf)
3//
4// Copyright (c) 2010 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 "atf-c++/config.hpp"
31#include "atf-c++/macros.hpp"
32
33#include "requirements.hpp"
34#include "user.hpp"
35
36namespace impl = atf::atf_run;
37
38// -------------------------------------------------------------------------
39// Auxiliary functions.
40// -------------------------------------------------------------------------
41
42namespace {
43
44const atf::tests::vars_map no_config;
45
46void
47do_check(const std::string& expected, const atf::tests::vars_map& metadata,
48         const atf::tests::vars_map& config = no_config)
49{
50    const std::string actual = impl::check_requirements(metadata, config);
51    if (actual != expected)
52        ATF_FAIL("Requirements failure reason \"" + actual + "\" does not "
53                 "match \"" + expected + "\"");
54}
55
56} // anonymous namespace
57
58// -------------------------------------------------------------------------
59// Tests for the require.arch metadata property.
60// -------------------------------------------------------------------------
61
62ATF_TEST_CASE(require_arch_one_ok);
63ATF_TEST_CASE_HEAD(require_arch_one_ok) {}
64ATF_TEST_CASE_BODY(require_arch_one_ok) {
65    atf::tests::vars_map metadata;
66    metadata["require.arch"] = atf::config::get("atf_arch");
67    do_check("", metadata);
68}
69
70ATF_TEST_CASE(require_arch_one_fail);
71ATF_TEST_CASE_HEAD(require_arch_one_fail) {}
72ATF_TEST_CASE_BODY(require_arch_one_fail) {
73    atf::tests::vars_map metadata;
74    metadata["require.arch"] = "__fake_arch__";
75    do_check("Requires the '__fake_arch__' architecture", metadata);
76}
77
78ATF_TEST_CASE(require_arch_many_ok);
79ATF_TEST_CASE_HEAD(require_arch_many_ok) {}
80ATF_TEST_CASE_BODY(require_arch_many_ok) {
81    atf::tests::vars_map metadata;
82    metadata["require.arch"] = "__foo__ " + atf::config::get("atf_arch") +
83        " __bar__";
84    do_check("", metadata);
85}
86
87ATF_TEST_CASE(require_arch_many_fail);
88ATF_TEST_CASE_HEAD(require_arch_many_fail) {}
89ATF_TEST_CASE_BODY(require_arch_many_fail) {
90    atf::tests::vars_map metadata;
91    metadata["require.arch"] = "__foo__ __bar__ __baz__";
92    do_check("Requires one of the '__foo__ __bar__ __baz__' architectures",
93             metadata);
94}
95
96// -------------------------------------------------------------------------
97// Tests for the require.config metadata property.
98// -------------------------------------------------------------------------
99
100ATF_TEST_CASE(require_config_one_ok);
101ATF_TEST_CASE_HEAD(require_config_one_ok) {}
102ATF_TEST_CASE_BODY(require_config_one_ok) {
103    atf::tests::vars_map metadata, config;
104    metadata["require.config"] = "var1";
105    config["var1"] = "some-value";
106    do_check("", metadata, config);
107}
108
109ATF_TEST_CASE(require_config_one_fail);
110ATF_TEST_CASE_HEAD(require_config_one_fail) {}
111ATF_TEST_CASE_BODY(require_config_one_fail) {
112    atf::tests::vars_map metadata, config;
113    metadata["require.config"] = "var1";
114    do_check("Required configuration variable 'var1' not defined", metadata,
115             config);
116}
117
118ATF_TEST_CASE(require_config_many_ok);
119ATF_TEST_CASE_HEAD(require_config_many_ok) {}
120ATF_TEST_CASE_BODY(require_config_many_ok) {
121    atf::tests::vars_map metadata, config;
122    metadata["require.config"] = "var1 var2 var3";
123    config["var1"] = "first-value";
124    config["var2"] = "second-value";
125    config["var3"] = "third-value";
126    do_check("", metadata, config);
127}
128
129ATF_TEST_CASE(require_config_many_fail);
130ATF_TEST_CASE_HEAD(require_config_many_fail) {}
131ATF_TEST_CASE_BODY(require_config_many_fail) {
132    atf::tests::vars_map metadata, config;
133    metadata["require.config"] = "var1 var2 var3";
134    config["var1"] = "first-value";
135    config["var3"] = "third-value";
136    do_check("Required configuration variable 'var2' not defined", metadata,
137             config);
138}
139
140// -------------------------------------------------------------------------
141// Tests for the require.machine metadata property.
142// -------------------------------------------------------------------------
143
144ATF_TEST_CASE(require_machine_one_ok);
145ATF_TEST_CASE_HEAD(require_machine_one_ok) {}
146ATF_TEST_CASE_BODY(require_machine_one_ok) {
147    atf::tests::vars_map metadata;
148    metadata["require.machine"] = atf::config::get("atf_machine");
149    do_check("", metadata);
150}
151
152ATF_TEST_CASE(require_machine_one_fail);
153ATF_TEST_CASE_HEAD(require_machine_one_fail) {}
154ATF_TEST_CASE_BODY(require_machine_one_fail) {
155    atf::tests::vars_map metadata;
156    metadata["require.machine"] = "__fake_machine__";
157    do_check("Requires the '__fake_machine__' machine type", metadata);
158}
159
160ATF_TEST_CASE(require_machine_many_ok);
161ATF_TEST_CASE_HEAD(require_machine_many_ok) {}
162ATF_TEST_CASE_BODY(require_machine_many_ok) {
163    atf::tests::vars_map metadata;
164    metadata["require.machine"] = "__foo__ " + atf::config::get("atf_machine") +
165        " __bar__";
166    do_check("", metadata);
167}
168
169ATF_TEST_CASE(require_machine_many_fail);
170ATF_TEST_CASE_HEAD(require_machine_many_fail) {}
171ATF_TEST_CASE_BODY(require_machine_many_fail) {
172    atf::tests::vars_map metadata;
173    metadata["require.machine"] = "__foo__ __bar__ __baz__";
174    do_check("Requires one of the '__foo__ __bar__ __baz__' machine types",
175             metadata);
176}
177
178// -------------------------------------------------------------------------
179// Tests for the require.progs metadata property.
180// -------------------------------------------------------------------------
181
182ATF_TEST_CASE(require_progs_one_ok);
183ATF_TEST_CASE_HEAD(require_progs_one_ok) {}
184ATF_TEST_CASE_BODY(require_progs_one_ok) {
185    atf::tests::vars_map metadata;
186    metadata["require.progs"] = "cp";
187    do_check("", metadata);
188}
189
190ATF_TEST_CASE(require_progs_one_missing);
191ATF_TEST_CASE_HEAD(require_progs_one_missing) {}
192ATF_TEST_CASE_BODY(require_progs_one_missing) {
193    atf::tests::vars_map metadata;
194    metadata["require.progs"] = "cp __non-existent__";
195    do_check("Required program '__non-existent__' not found in the PATH",
196             metadata);
197}
198
199ATF_TEST_CASE(require_progs_one_fail);
200ATF_TEST_CASE_HEAD(require_progs_one_fail) {}
201ATF_TEST_CASE_BODY(require_progs_one_fail) {
202    atf::tests::vars_map metadata;
203    metadata["require.progs"] = "bin/cp";
204    ATF_REQUIRE_THROW(std::runtime_error,
205                    impl::check_requirements(metadata, no_config));
206}
207
208ATF_TEST_CASE(require_progs_many_ok);
209ATF_TEST_CASE_HEAD(require_progs_many_ok) {}
210ATF_TEST_CASE_BODY(require_progs_many_ok) {
211    atf::tests::vars_map metadata;
212    metadata["require.progs"] = "cp ls mv";
213    do_check("", metadata);
214}
215
216ATF_TEST_CASE(require_progs_many_missing);
217ATF_TEST_CASE_HEAD(require_progs_many_missing) {}
218ATF_TEST_CASE_BODY(require_progs_many_missing) {
219    atf::tests::vars_map metadata;
220    metadata["require.progs"] = "mv ls __foo__ cp";
221    do_check("Required program '__foo__' not found in the PATH", metadata);
222}
223
224ATF_TEST_CASE(require_progs_many_fail);
225ATF_TEST_CASE_HEAD(require_progs_many_fail) {}
226ATF_TEST_CASE_BODY(require_progs_many_fail) {
227    atf::tests::vars_map metadata;
228    metadata["require.progs"] = "ls cp ../bin/cp";
229    ATF_REQUIRE_THROW(std::runtime_error,
230                    impl::check_requirements(metadata, no_config));
231}
232
233// -------------------------------------------------------------------------
234// Tests for the require.user metadata property.
235// -------------------------------------------------------------------------
236
237ATF_TEST_CASE(require_user_root);
238ATF_TEST_CASE_HEAD(require_user_root) {}
239ATF_TEST_CASE_BODY(require_user_root) {
240    atf::tests::vars_map metadata;
241    metadata["require.user"] = "root";
242    if (atf::atf_run::is_root())
243        do_check("", metadata);
244    else
245        do_check("Requires root privileges", metadata);
246}
247
248ATF_TEST_CASE(require_user_unprivileged);
249ATF_TEST_CASE_HEAD(require_user_unprivileged) {}
250ATF_TEST_CASE_BODY(require_user_unprivileged) {
251    atf::tests::vars_map metadata;
252    metadata["require.user"] = "unprivileged";
253    if (atf::atf_run::is_root())
254        do_check("Requires an unprivileged user and the 'unprivileged-user' "
255                 "configuration variable is not set", metadata);
256    else
257        do_check("", metadata);
258}
259
260ATF_TEST_CASE(require_user_fail);
261ATF_TEST_CASE_HEAD(require_user_fail) {}
262ATF_TEST_CASE_BODY(require_user_fail) {
263    atf::tests::vars_map metadata;
264    metadata["require.user"] = "nobody";
265    ATF_REQUIRE_THROW(std::runtime_error,
266                    impl::check_requirements(metadata, no_config));
267}
268
269// -------------------------------------------------------------------------
270// Main.
271// -------------------------------------------------------------------------
272
273ATF_INIT_TEST_CASES(tcs)
274{
275    // Add test cases for require.arch.
276    ATF_ADD_TEST_CASE(tcs, require_arch_one_ok);
277    ATF_ADD_TEST_CASE(tcs, require_arch_one_fail);
278    ATF_ADD_TEST_CASE(tcs, require_arch_many_ok);
279    ATF_ADD_TEST_CASE(tcs, require_arch_many_fail);
280
281    // Add test cases for require.config.
282    ATF_ADD_TEST_CASE(tcs, require_config_one_ok);
283    ATF_ADD_TEST_CASE(tcs, require_config_one_fail);
284    ATF_ADD_TEST_CASE(tcs, require_config_many_ok);
285    ATF_ADD_TEST_CASE(tcs, require_config_many_fail);
286
287    // Add test cases for require.machine.
288    ATF_ADD_TEST_CASE(tcs, require_machine_one_ok);
289    ATF_ADD_TEST_CASE(tcs, require_machine_one_fail);
290    ATF_ADD_TEST_CASE(tcs, require_machine_many_ok);
291    ATF_ADD_TEST_CASE(tcs, require_machine_many_fail);
292
293    // Add test cases for require.progs.
294    ATF_ADD_TEST_CASE(tcs, require_progs_one_ok);
295    ATF_ADD_TEST_CASE(tcs, require_progs_one_missing);
296    ATF_ADD_TEST_CASE(tcs, require_progs_one_fail);
297    ATF_ADD_TEST_CASE(tcs, require_progs_many_ok);
298    ATF_ADD_TEST_CASE(tcs, require_progs_many_missing);
299    ATF_ADD_TEST_CASE(tcs, require_progs_many_fail);
300
301    // Add test cases for require.user.
302    ATF_ADD_TEST_CASE(tcs, require_user_root);
303    ATF_ADD_TEST_CASE(tcs, require_user_unprivileged);
304    ATF_ADD_TEST_CASE(tcs, require_user_fail);
305}
306