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 37namespace impl = tools; 38 39// ------------------------------------------------------------------------- 40// Auxiliary functions. 41// ------------------------------------------------------------------------- 42 43namespace { 44 45typedef std::map< std::string, std::string > vars_map; 46 47const vars_map no_config; 48 49void 50do_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 65ATF_TEST_CASE(require_arch_one_ok); 66ATF_TEST_CASE_HEAD(require_arch_one_ok) {} 67ATF_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 73ATF_TEST_CASE(require_arch_one_fail); 74ATF_TEST_CASE_HEAD(require_arch_one_fail) {} 75ATF_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 81ATF_TEST_CASE(require_arch_many_ok); 82ATF_TEST_CASE_HEAD(require_arch_many_ok) {} 83ATF_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 90ATF_TEST_CASE(require_arch_many_fail); 91ATF_TEST_CASE_HEAD(require_arch_many_fail) {} 92ATF_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 103ATF_TEST_CASE(require_config_one_ok); 104ATF_TEST_CASE_HEAD(require_config_one_ok) {} 105ATF_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 112ATF_TEST_CASE(require_config_one_fail); 113ATF_TEST_CASE_HEAD(require_config_one_fail) {} 114ATF_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 121ATF_TEST_CASE(require_config_many_ok); 122ATF_TEST_CASE_HEAD(require_config_many_ok) {} 123ATF_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 132ATF_TEST_CASE(require_config_many_fail); 133ATF_TEST_CASE_HEAD(require_config_many_fail) {} 134ATF_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 147ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_ok); 148ATF_TEST_CASE_BODY(require_files_one_ok) { 149 vars_map metadata; 150 metadata["require.files"] = "/bin/ls"; 151 do_check("", metadata); 152} 153 154ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_missing); 155ATF_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 161ATF_TEST_CASE_WITHOUT_HEAD(require_files_one_fail); 162ATF_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 169ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_ok); 170ATF_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 176ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_missing); 177ATF_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 183ATF_TEST_CASE_WITHOUT_HEAD(require_files_many_fail); 184ATF_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 195ATF_TEST_CASE(require_machine_one_ok); 196ATF_TEST_CASE_HEAD(require_machine_one_ok) {} 197ATF_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 203ATF_TEST_CASE(require_machine_one_fail); 204ATF_TEST_CASE_HEAD(require_machine_one_fail) {} 205ATF_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 211ATF_TEST_CASE(require_machine_many_ok); 212ATF_TEST_CASE_HEAD(require_machine_many_ok) {} 213ATF_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 220ATF_TEST_CASE(require_machine_many_fail); 221ATF_TEST_CASE_HEAD(require_machine_many_fail) {} 222ATF_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 233ATF_TEST_CASE_WITHOUT_HEAD(require_memory_ok); 234ATF_TEST_CASE_BODY(require_memory_ok) { 235 vars_map metadata; 236 metadata["require.memory"] = "1m"; 237 do_check("", metadata); 238} 239 240ATF_TEST_CASE_WITHOUT_HEAD(require_memory_not_enough); 241ATF_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 248ATF_TEST_CASE_WITHOUT_HEAD(require_memory_fail); 249ATF_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 260ATF_TEST_CASE(require_progs_one_ok); 261ATF_TEST_CASE_HEAD(require_progs_one_ok) {} 262ATF_TEST_CASE_BODY(require_progs_one_ok) { 263 vars_map metadata; 264 metadata["require.progs"] = "cp"; 265 do_check("", metadata); 266} 267 268ATF_TEST_CASE(require_progs_one_missing); 269ATF_TEST_CASE_HEAD(require_progs_one_missing) {} 270ATF_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 277ATF_TEST_CASE(require_progs_one_fail); 278ATF_TEST_CASE_HEAD(require_progs_one_fail) {} 279ATF_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 286ATF_TEST_CASE(require_progs_many_ok); 287ATF_TEST_CASE_HEAD(require_progs_many_ok) {} 288ATF_TEST_CASE_BODY(require_progs_many_ok) { 289 vars_map metadata; 290 metadata["require.progs"] = "cp ls mv"; 291 do_check("", metadata); 292} 293 294ATF_TEST_CASE(require_progs_many_missing); 295ATF_TEST_CASE_HEAD(require_progs_many_missing) {} 296ATF_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 302ATF_TEST_CASE(require_progs_many_fail); 303ATF_TEST_CASE_HEAD(require_progs_many_fail) {} 304ATF_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 315ATF_TEST_CASE(require_user_root); 316ATF_TEST_CASE_HEAD(require_user_root) {} 317ATF_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 326ATF_TEST_CASE(require_user_unprivileged); 327ATF_TEST_CASE_HEAD(require_user_unprivileged) {} 328ATF_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 338ATF_TEST_CASE(require_user_fail); 339ATF_TEST_CASE_HEAD(require_user_fail) {} 340ATF_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 351ATF_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