1 // Copyright 2011 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 extern "C" { 30 #include <unistd.h> 31 } 32 33 #include <atf-c++.hpp> 34 35 #include "engine/config.hpp" 36 #include "engine/kyuafile.hpp" 37 #include "utils/config/tree.ipp" 38 #include "utils/fs/operations.hpp" 39 #include "utils/fs/path.hpp" 40 #include "utils/optional.ipp" 41 #include "utils/passwd.hpp" 42 43 namespace config = utils::config; 44 namespace fs = utils::fs; 45 namespace passwd = utils::passwd; 46 47 using utils::none; 48 49 50 namespace { 51 52 53 /// Gets the path to an example file. 54 /// 55 /// \param tc The caller test case. Needed to obtain its 'examplesdir' 56 /// property, if any. 57 /// \param name The name of the example file. 58 /// 59 /// \return A path to the desired example file. This can either be inside the 60 /// source tree before installing Kyua or in the target installation directory 61 /// after installation. 62 static fs::path 63 example_file(const atf::tests::tc* tc, const char* name) 64 { 65 const fs::path examplesdir = 66 tc->has_config_var("examplesdir") ? 67 fs::path(tc->get_config_var("examplesdir")) : 68 fs::path(KYUA_EXAMPLESDIR); 69 return examplesdir / name; 70 } 71 72 73 } // anonymous namespace 74 75 76 ATF_TEST_CASE(kyua_conf); 77 ATF_TEST_CASE_HEAD(kyua_conf) 78 { 79 set_md_var("require.files", example_file(this, "kyua.conf").str()); 80 } 81 ATF_TEST_CASE_BODY(kyua_conf) 82 { 83 std::vector< passwd::user > users; 84 users.push_back(passwd::user("nobody", 1, 2)); 85 passwd::set_mock_users_for_testing(users); 86 87 const config::tree user_config = engine::load_config( 88 example_file(this, "kyua.conf")); 89 90 ATF_REQUIRE_EQ( 91 "x86_64", 92 user_config.lookup< config::string_node >("architecture")); 93 ATF_REQUIRE_EQ( 94 "amd64", 95 user_config.lookup< config::string_node >("platform")); 96 97 ATF_REQUIRE_EQ( 98 "nobody", 99 user_config.lookup< engine::user_node >("unprivileged_user").name); 100 101 config::properties_map exp_test_suites; 102 exp_test_suites["test_suites.FreeBSD.iterations"] = "1000"; 103 exp_test_suites["test_suites.FreeBSD.run_old_tests"] = "false"; 104 exp_test_suites["test_suites.NetBSD.file_systems"] = "ffs lfs ext2fs"; 105 exp_test_suites["test_suites.NetBSD.iterations"] = "100"; 106 exp_test_suites["test_suites.NetBSD.run_broken_tests"] = "true"; 107 ATF_REQUIRE(exp_test_suites == user_config.all_properties("test_suites")); 108 } 109 110 111 ATF_TEST_CASE(kyuafile_top__no_matches); 112 ATF_TEST_CASE_HEAD(kyuafile_top__no_matches) 113 { 114 set_md_var("require.files", example_file(this, "Kyuafile.top").str()); 115 } 116 ATF_TEST_CASE_BODY(kyuafile_top__no_matches) 117 { 118 fs::mkdir(fs::path("root"), 0755); 119 const fs::path source_path = example_file(this, "Kyuafile.top"); 120 ATF_REQUIRE(::symlink(source_path.c_str(), "root/Kyuafile") != -1); 121 122 atf::utils::create_file("root/file", ""); 123 fs::mkdir(fs::path("root/subdir"), 0755); 124 125 const engine::kyuafile kyuafile = engine::kyuafile::load( 126 fs::path("root/Kyuafile"), none); 127 ATF_REQUIRE_EQ(fs::path("root"), kyuafile.source_root()); 128 ATF_REQUIRE_EQ(fs::path("root"), kyuafile.build_root()); 129 ATF_REQUIRE(kyuafile.test_programs().empty()); 130 } 131 132 133 ATF_TEST_CASE(kyuafile_top__some_matches); 134 ATF_TEST_CASE_HEAD(kyuafile_top__some_matches) 135 { 136 set_md_var("require.files", example_file(this, "Kyuafile.top").str()); 137 } 138 ATF_TEST_CASE_BODY(kyuafile_top__some_matches) 139 { 140 fs::mkdir(fs::path("root"), 0755); 141 const fs::path source_path = example_file(this, "Kyuafile.top"); 142 ATF_REQUIRE(::symlink(source_path.c_str(), "root/Kyuafile") != -1); 143 144 atf::utils::create_file("root/file", ""); 145 146 fs::mkdir(fs::path("root/subdir1"), 0755); 147 atf::utils::create_file("root/subdir1/Kyuafile", 148 "syntax(2)\n" 149 "atf_test_program{name='a', test_suite='b'}\n"); 150 atf::utils::create_file("root/subdir1/a", ""); 151 152 fs::mkdir(fs::path("root/subdir2"), 0755); 153 atf::utils::create_file("root/subdir2/Kyuafile", 154 "syntax(2)\n" 155 "atf_test_program{name='c', test_suite='d'}\n"); 156 atf::utils::create_file("root/subdir2/c", ""); 157 atf::utils::create_file("root/subdir2/Kyuafile.etc", "invalid"); 158 159 const engine::kyuafile kyuafile = engine::kyuafile::load( 160 fs::path("root/Kyuafile"), none); 161 ATF_REQUIRE_EQ(fs::path("root"), kyuafile.source_root()); 162 ATF_REQUIRE_EQ(fs::path("root"), kyuafile.build_root()); 163 164 engine::test_program exp_test_program_a( 165 "atf", fs::path("subdir1/a"), fs::path("root"), "b", 166 engine::metadata_builder().build()); 167 engine::test_program exp_test_program_c( 168 "atf", fs::path("subdir2/c"), fs::path("root"), "d", 169 engine::metadata_builder().build()); 170 171 ATF_REQUIRE_EQ(2, kyuafile.test_programs().size()); 172 ATF_REQUIRE((exp_test_program_a == *kyuafile.test_programs()[0] && 173 exp_test_program_c == *kyuafile.test_programs()[1]) 174 || 175 (exp_test_program_a == *kyuafile.test_programs()[1] && 176 exp_test_program_c == *kyuafile.test_programs()[0])); 177 } 178 179 180 ATF_INIT_TEST_CASES(tcs) 181 { 182 ATF_ADD_TEST_CASE(tcs, kyua_conf); 183 184 ATF_ADD_TEST_CASE(tcs, kyuafile_top__no_matches); 185 ATF_ADD_TEST_CASE(tcs, kyuafile_top__some_matches); 186 } 187