xref: /minix3/external/bsd/atf/dist/tools/requirements_test.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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++.hpp>
31 
32 #include "config.hpp"
33 #include "requirements.hpp"
34 #include "text.hpp"
35 #include "user.hpp"
36 
37 namespace impl = tools;
38 
39 // -------------------------------------------------------------------------
40 // Auxiliary functions.
41 // -------------------------------------------------------------------------
42 
43 namespace {
44 
45 typedef std::map< std::string, std::string > vars_map;
46 
47 const vars_map no_config;
48 
49 void
do_check(const std::string & expected,const vars_map & metadata,const vars_map & config=no_config)50 do_check(const std::string& expected, const vars_map& metadata,
51          const vars_map& config = no_config)
52 {
53     const std::string actual = impl::check_requirements(metadata, config);
54     if (!tools::text::match(actual, expected))
55         ATF_FAIL("Requirements failure reason \"" + actual + "\" does not "
56                  "match \"" + expected + "\"");
57 }
58 
59 } // anonymous namespace
60 
61 // -------------------------------------------------------------------------
62 // Tests for the require.arch metadata property.
63 // -------------------------------------------------------------------------
64 
65 ATF_TEST_CASE(require_arch_one_ok);
ATF_TEST_CASE_HEAD(require_arch_one_ok)66 ATF_TEST_CASE_HEAD(require_arch_one_ok) {}
ATF_TEST_CASE_BODY(require_arch_one_ok)67 ATF_TEST_CASE_BODY(require_arch_one_ok) {
68     vars_map metadata;
69     metadata["require.arch"] = tools::config::get("atf_arch");
70     do_check("", metadata);
71 }
72 
73 ATF_TEST_CASE(require_arch_one_fail);
ATF_TEST_CASE_HEAD(require_arch_one_fail)74 ATF_TEST_CASE_HEAD(require_arch_one_fail) {}
ATF_TEST_CASE_BODY(require_arch_one_fail)75 ATF_TEST_CASE_BODY(require_arch_one_fail) {
76     vars_map metadata;
77     metadata["require.arch"] = "__fake_arch__";
78     do_check("Requires the '__fake_arch__' architecture", metadata);
79 }
80 
81 ATF_TEST_CASE(require_arch_many_ok);
ATF_TEST_CASE_HEAD(require_arch_many_ok)82 ATF_TEST_CASE_HEAD(require_arch_many_ok) {}
ATF_TEST_CASE_BODY(require_arch_many_ok)83 ATF_TEST_CASE_BODY(require_arch_many_ok) {
84     vars_map metadata;
85     metadata["require.arch"] = "__foo__ " + tools::config::get("atf_arch") +
86         " __bar__";
87     do_check("", metadata);
88 }
89 
90 ATF_TEST_CASE(require_arch_many_fail);
ATF_TEST_CASE_HEAD(require_arch_many_fail)91 ATF_TEST_CASE_HEAD(require_arch_many_fail) {}
ATF_TEST_CASE_BODY(require_arch_many_fail)92 ATF_TEST_CASE_BODY(require_arch_many_fail) {
93     vars_map metadata;
94     metadata["require.arch"] = "__foo__ __bar__ __baz__";
95     do_check("Requires one of the '__foo__ __bar__ __baz__' architectures",
96              metadata);
97 }
98 
99 // -------------------------------------------------------------------------
100 // Tests for the require.config metadata property.
101 // -------------------------------------------------------------------------
102 
103 ATF_TEST_CASE(require_config_one_ok);
ATF_TEST_CASE_HEAD(require_config_one_ok)104 ATF_TEST_CASE_HEAD(require_config_one_ok) {}
ATF_TEST_CASE_BODY(require_config_one_ok)105 ATF_TEST_CASE_BODY(require_config_one_ok) {
106     vars_map metadata, config;
107     metadata["require.config"] = "var1";
108     config["var1"] = "some-value";
109     do_check("", metadata, config);
110 }
111 
112 ATF_TEST_CASE(require_config_one_fail);
ATF_TEST_CASE_HEAD(require_config_one_fail)113 ATF_TEST_CASE_HEAD(require_config_one_fail) {}
ATF_TEST_CASE_BODY(require_config_one_fail)114 ATF_TEST_CASE_BODY(require_config_one_fail) {
115     vars_map metadata, config;
116     metadata["require.config"] = "var1";
117     do_check("Required configuration variable 'var1' not defined", metadata,
118              config);
119 }
120 
121 ATF_TEST_CASE(require_config_many_ok);
ATF_TEST_CASE_HEAD(require_config_many_ok)122 ATF_TEST_CASE_HEAD(require_config_many_ok) {}
ATF_TEST_CASE_BODY(require_config_many_ok)123 ATF_TEST_CASE_BODY(require_config_many_ok) {
124     vars_map metadata, config;
125     metadata["require.config"] = "var1 var2 var3";
126     config["var1"] = "first-value";
127     config["var2"] = "second-value";
128     config["var3"] = "third-value";
129     do_check("", metadata, config);
130 }
131 
132 ATF_TEST_CASE(require_config_many_fail);
ATF_TEST_CASE_HEAD(require_config_many_fail)133 ATF_TEST_CASE_HEAD(require_config_many_fail) {}
ATF_TEST_CASE_BODY(require_config_many_fail)134 ATF_TEST_CASE_BODY(require_config_many_fail) {
135     vars_map metadata, config;
136     metadata["require.config"] = "var1 var2 var3";
137     config["var1"] = "first-value";
138     config["var3"] = "third-value";
139     do_check("Required configuration variable 'var2' not defined", metadata,
140              config);
141 }
142 
143 // -------------------------------------------------------------------------
144 // Tests for the require.files metadata property.
145 // -------------------------------------------------------------------------
146 
147 ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_ok);
ATF_TEST_CASE_BODY(require_files_one_ok)148 ATF_TEST_CASE_BODY(require_files_one_ok) {
149     vars_map metadata;
150     metadata["require.files"] = "/bin/ls";
151     do_check("", metadata);
152 }
153 
154 ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_missing);
ATF_TEST_CASE_BODY(require_files_one_missing)155 ATF_TEST_CASE_BODY(require_files_one_missing) {
156     vars_map metadata;
157     metadata["require.files"] = "/non-existent/foo";
158     do_check("Required file '/non-existent/foo' not found", metadata);
159 }
160 
161 ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_fail);
ATF_TEST_CASE_BODY(require_files_one_fail)162 ATF_TEST_CASE_BODY(require_files_one_fail) {
163     vars_map metadata;
164     metadata["require.files"] = "/bin/cp this-is-relative";
165     ATF_REQUIRE_THROW_RE(std::runtime_error, "Relative.*(this-is-relative)",
166                          impl::check_requirements(metadata, no_config));
167 }
168 
169 ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_ok);
ATF_TEST_CASE_BODY(require_files_many_ok)170 ATF_TEST_CASE_BODY(require_files_many_ok) {
171     vars_map metadata;
172     metadata["require.files"] = "/bin/ls /bin/cp";
173     do_check("", metadata);
174 }
175 
176 ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_missing);
ATF_TEST_CASE_BODY(require_files_many_missing)177 ATF_TEST_CASE_BODY(require_files_many_missing) {
178     vars_map metadata;
179     metadata["require.files"] = "/bin/ls /non-existent/bar /bin/cp";
180     do_check("Required file '/non-existent/bar' not found", metadata);
181 }
182 
183 ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_fail);
ATF_TEST_CASE_BODY(require_files_many_fail)184 ATF_TEST_CASE_BODY(require_files_many_fail) {
185     vars_map metadata;
186     metadata["require.files"] = "/bin/cp also-relative";
187     ATF_REQUIRE_THROW_RE(std::runtime_error, "Relative.*(also-relative)",
188                          impl::check_requirements(metadata, no_config));
189 }
190 
191 // -------------------------------------------------------------------------
192 // Tests for the require.machine metadata property.
193 // -------------------------------------------------------------------------
194 
195 ATF_TEST_CASE(require_machine_one_ok);
ATF_TEST_CASE_HEAD(require_machine_one_ok)196 ATF_TEST_CASE_HEAD(require_machine_one_ok) {}
ATF_TEST_CASE_BODY(require_machine_one_ok)197 ATF_TEST_CASE_BODY(require_machine_one_ok) {
198     vars_map metadata;
199     metadata["require.machine"] = tools::config::get("atf_machine");
200     do_check("", metadata);
201 }
202 
203 ATF_TEST_CASE(require_machine_one_fail);
ATF_TEST_CASE_HEAD(require_machine_one_fail)204 ATF_TEST_CASE_HEAD(require_machine_one_fail) {}
ATF_TEST_CASE_BODY(require_machine_one_fail)205 ATF_TEST_CASE_BODY(require_machine_one_fail) {
206     vars_map metadata;
207     metadata["require.machine"] = "__fake_machine__";
208     do_check("Requires the '__fake_machine__' machine type", metadata);
209 }
210 
211 ATF_TEST_CASE(require_machine_many_ok);
ATF_TEST_CASE_HEAD(require_machine_many_ok)212 ATF_TEST_CASE_HEAD(require_machine_many_ok) {}
ATF_TEST_CASE_BODY(require_machine_many_ok)213 ATF_TEST_CASE_BODY(require_machine_many_ok) {
214     vars_map metadata;
215     metadata["require.machine"] = "__foo__ " +
216         tools::config::get("atf_machine") + " __bar__";
217     do_check("", metadata);
218 }
219 
220 ATF_TEST_CASE(require_machine_many_fail);
ATF_TEST_CASE_HEAD(require_machine_many_fail)221 ATF_TEST_CASE_HEAD(require_machine_many_fail) {}
ATF_TEST_CASE_BODY(require_machine_many_fail)222 ATF_TEST_CASE_BODY(require_machine_many_fail) {
223     vars_map metadata;
224     metadata["require.machine"] = "__foo__ __bar__ __baz__";
225     do_check("Requires one of the '__foo__ __bar__ __baz__' machine types",
226              metadata);
227 }
228 
229 // -------------------------------------------------------------------------
230 // Tests for the require.memory metadata property.
231 // -------------------------------------------------------------------------
232 
233 ATF_TEST_CASE_WITHOUT_HEAD(require_memory_ok);
ATF_TEST_CASE_BODY(require_memory_ok)234 ATF_TEST_CASE_BODY(require_memory_ok) {
235     vars_map metadata;
236     metadata["require.memory"] = "1m";
237     do_check("", metadata);
238 }
239 
240 ATF_TEST_CASE_WITHOUT_HEAD(require_memory_not_enough);
ATF_TEST_CASE_BODY(require_memory_not_enough)241 ATF_TEST_CASE_BODY(require_memory_not_enough) {
242     vars_map metadata;
243     metadata["require.memory"] = "128t";
244     do_check("Not enough memory; needed 140737488355328, available [0-9]*",
245              metadata);
246 }
247 
248 ATF_TEST_CASE_WITHOUT_HEAD(require_memory_fail);
ATF_TEST_CASE_BODY(require_memory_fail)249 ATF_TEST_CASE_BODY(require_memory_fail) {
250     vars_map metadata;
251     metadata["require.memory"] = "foo";
252     ATF_REQUIRE_THROW(std::runtime_error,
253                       impl::check_requirements(metadata, no_config));
254 }
255 
256 // -------------------------------------------------------------------------
257 // Tests for the require.progs metadata property.
258 // -------------------------------------------------------------------------
259 
260 ATF_TEST_CASE(require_progs_one_ok);
ATF_TEST_CASE_HEAD(require_progs_one_ok)261 ATF_TEST_CASE_HEAD(require_progs_one_ok) {}
ATF_TEST_CASE_BODY(require_progs_one_ok)262 ATF_TEST_CASE_BODY(require_progs_one_ok) {
263     vars_map metadata;
264     metadata["require.progs"] = "cp";
265     do_check("", metadata);
266 }
267 
268 ATF_TEST_CASE(require_progs_one_missing);
ATF_TEST_CASE_HEAD(require_progs_one_missing)269 ATF_TEST_CASE_HEAD(require_progs_one_missing) {}
ATF_TEST_CASE_BODY(require_progs_one_missing)270 ATF_TEST_CASE_BODY(require_progs_one_missing) {
271     vars_map metadata;
272     metadata["require.progs"] = "cp __non-existent__";
273     do_check("Required program '__non-existent__' not found in the PATH",
274              metadata);
275 }
276 
277 ATF_TEST_CASE(require_progs_one_fail);
ATF_TEST_CASE_HEAD(require_progs_one_fail)278 ATF_TEST_CASE_HEAD(require_progs_one_fail) {}
ATF_TEST_CASE_BODY(require_progs_one_fail)279 ATF_TEST_CASE_BODY(require_progs_one_fail) {
280     vars_map metadata;
281     metadata["require.progs"] = "bin/cp";
282     ATF_REQUIRE_THROW(std::runtime_error,
283                     impl::check_requirements(metadata, no_config));
284 }
285 
286 ATF_TEST_CASE(require_progs_many_ok);
ATF_TEST_CASE_HEAD(require_progs_many_ok)287 ATF_TEST_CASE_HEAD(require_progs_many_ok) {}
ATF_TEST_CASE_BODY(require_progs_many_ok)288 ATF_TEST_CASE_BODY(require_progs_many_ok) {
289     vars_map metadata;
290     metadata["require.progs"] = "cp ls mv";
291     do_check("", metadata);
292 }
293 
294 ATF_TEST_CASE(require_progs_many_missing);
ATF_TEST_CASE_HEAD(require_progs_many_missing)295 ATF_TEST_CASE_HEAD(require_progs_many_missing) {}
ATF_TEST_CASE_BODY(require_progs_many_missing)296 ATF_TEST_CASE_BODY(require_progs_many_missing) {
297     vars_map metadata;
298     metadata["require.progs"] = "mv ls __foo__ cp";
299     do_check("Required program '__foo__' not found in the PATH", metadata);
300 }
301 
302 ATF_TEST_CASE(require_progs_many_fail);
ATF_TEST_CASE_HEAD(require_progs_many_fail)303 ATF_TEST_CASE_HEAD(require_progs_many_fail) {}
ATF_TEST_CASE_BODY(require_progs_many_fail)304 ATF_TEST_CASE_BODY(require_progs_many_fail) {
305     vars_map metadata;
306     metadata["require.progs"] = "ls cp ../bin/cp";
307     ATF_REQUIRE_THROW(std::runtime_error,
308                     impl::check_requirements(metadata, no_config));
309 }
310 
311 // -------------------------------------------------------------------------
312 // Tests for the require.user metadata property.
313 // -------------------------------------------------------------------------
314 
315 ATF_TEST_CASE(require_user_root);
ATF_TEST_CASE_HEAD(require_user_root)316 ATF_TEST_CASE_HEAD(require_user_root) {}
ATF_TEST_CASE_BODY(require_user_root)317 ATF_TEST_CASE_BODY(require_user_root) {
318     vars_map metadata;
319     metadata["require.user"] = "root";
320     if (tools::user::is_root())
321         do_check("", metadata);
322     else
323         do_check("Requires root privileges", metadata);
324 }
325 
326 ATF_TEST_CASE(require_user_unprivileged);
ATF_TEST_CASE_HEAD(require_user_unprivileged)327 ATF_TEST_CASE_HEAD(require_user_unprivileged) {}
ATF_TEST_CASE_BODY(require_user_unprivileged)328 ATF_TEST_CASE_BODY(require_user_unprivileged) {
329     vars_map metadata;
330     metadata["require.user"] = "unprivileged";
331     if (tools::user::is_root())
332         do_check("Requires an unprivileged user and the 'unprivileged-user' "
333                  "configuration variable is not set", metadata);
334     else
335         do_check("", metadata);
336 }
337 
338 ATF_TEST_CASE(require_user_fail);
ATF_TEST_CASE_HEAD(require_user_fail)339 ATF_TEST_CASE_HEAD(require_user_fail) {}
ATF_TEST_CASE_BODY(require_user_fail)340 ATF_TEST_CASE_BODY(require_user_fail) {
341     vars_map metadata;
342     metadata["require.user"] = "nobody";
343     ATF_REQUIRE_THROW(std::runtime_error,
344                     impl::check_requirements(metadata, no_config));
345 }
346 
347 // -------------------------------------------------------------------------
348 // Main.
349 // -------------------------------------------------------------------------
350 
ATF_INIT_TEST_CASES(tcs)351 ATF_INIT_TEST_CASES(tcs)
352 {
353     // Add test cases for require.arch.
354     ATF_ADD_TEST_CASE(tcs, require_arch_one_ok);
355     ATF_ADD_TEST_CASE(tcs, require_arch_one_fail);
356     ATF_ADD_TEST_CASE(tcs, require_arch_many_ok);
357     ATF_ADD_TEST_CASE(tcs, require_arch_many_fail);
358 
359     // Add test cases for require.config.
360     ATF_ADD_TEST_CASE(tcs, require_config_one_ok);
361     ATF_ADD_TEST_CASE(tcs, require_config_one_fail);
362     ATF_ADD_TEST_CASE(tcs, require_config_many_ok);
363     ATF_ADD_TEST_CASE(tcs, require_config_many_fail);
364 
365     // Add test cases for require.files.
366     ATF_ADD_TEST_CASE(tcs, require_files_one_ok);
367     ATF_ADD_TEST_CASE(tcs, require_files_one_missing);
368     ATF_ADD_TEST_CASE(tcs, require_files_one_fail);
369     ATF_ADD_TEST_CASE(tcs, require_files_many_ok);
370     ATF_ADD_TEST_CASE(tcs, require_files_many_missing);
371     ATF_ADD_TEST_CASE(tcs, require_files_many_fail);
372 
373     // Add test cases for require.machine.
374     ATF_ADD_TEST_CASE(tcs, require_machine_one_ok);
375     ATF_ADD_TEST_CASE(tcs, require_machine_one_fail);
376     ATF_ADD_TEST_CASE(tcs, require_machine_many_ok);
377     ATF_ADD_TEST_CASE(tcs, require_machine_many_fail);
378 
379     // Add test cases for require.memory.
380     ATF_ADD_TEST_CASE(tcs, require_memory_ok);
381     ATF_ADD_TEST_CASE(tcs, require_memory_not_enough);
382     ATF_ADD_TEST_CASE(tcs, require_memory_fail);
383 
384     // Add test cases for require.progs.
385     ATF_ADD_TEST_CASE(tcs, require_progs_one_ok);
386     ATF_ADD_TEST_CASE(tcs, require_progs_one_missing);
387     ATF_ADD_TEST_CASE(tcs, require_progs_one_fail);
388     ATF_ADD_TEST_CASE(tcs, require_progs_many_ok);
389     ATF_ADD_TEST_CASE(tcs, require_progs_many_missing);
390     ATF_ADD_TEST_CASE(tcs, require_progs_many_fail);
391 
392     // Add test cases for require.user.
393     ATF_ADD_TEST_CASE(tcs, require_user_root);
394     ATF_ADD_TEST_CASE(tcs, require_user_unprivileged);
395     ATF_ADD_TEST_CASE(tcs, require_user_fail);
396 }
397