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 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); 66 ATF_TEST_CASE_HEAD(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); 74 ATF_TEST_CASE_HEAD(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); 82 ATF_TEST_CASE_HEAD(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); 91 ATF_TEST_CASE_HEAD(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); 104 ATF_TEST_CASE_HEAD(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); 113 ATF_TEST_CASE_HEAD(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); 122 ATF_TEST_CASE_HEAD(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); 133 ATF_TEST_CASE_HEAD(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); 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); 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); 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); 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); 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); 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); 196 ATF_TEST_CASE_HEAD(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); 204 ATF_TEST_CASE_HEAD(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); 212 ATF_TEST_CASE_HEAD(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); 221 ATF_TEST_CASE_HEAD(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); 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); 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); 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); 261 ATF_TEST_CASE_HEAD(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); 269 ATF_TEST_CASE_HEAD(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); 278 ATF_TEST_CASE_HEAD(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); 287 ATF_TEST_CASE_HEAD(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); 295 ATF_TEST_CASE_HEAD(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); 303 ATF_TEST_CASE_HEAD(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); 316 ATF_TEST_CASE_HEAD(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); 327 ATF_TEST_CASE_HEAD(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); 339 ATF_TEST_CASE_HEAD(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 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