1 // Copyright 2010 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 #include "engine/test_program.hpp" 30 31 #include <sstream> 32 33 #include <atf-c++.hpp> 34 35 #include "engine/exceptions.hpp" 36 #include "utils/fs/operations.hpp" 37 #include "utils/fs/path.hpp" 38 39 namespace fs = utils::fs; 40 41 42 ATF_TEST_CASE_WITHOUT_HEAD(ctor_and_getters); 43 ATF_TEST_CASE_BODY(ctor_and_getters) 44 { 45 const engine::metadata md = engine::metadata_builder() 46 .add_custom("foo", "bar") 47 .build(); 48 const engine::test_program test_program( 49 "mock", fs::path("binary"), fs::path("root"), "suite-name", md); 50 ATF_REQUIRE_EQ("mock", test_program.interface_name()); 51 ATF_REQUIRE_EQ(fs::path("binary"), test_program.relative_path()); 52 ATF_REQUIRE_EQ(fs::current_path() / "root/binary", 53 test_program.absolute_path()); 54 ATF_REQUIRE_EQ(fs::path("root"), test_program.root()); 55 ATF_REQUIRE_EQ("suite-name", test_program.test_suite_name()); 56 ATF_REQUIRE_EQ(md, test_program.get_metadata()); 57 } 58 59 60 ATF_TEST_CASE_WITHOUT_HEAD(find__ok); 61 ATF_TEST_CASE_BODY(find__ok) 62 { 63 const engine::test_program test_program( 64 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 65 engine::metadata_builder().build()); 66 const engine::test_case_ptr test_case = test_program.find("main"); 67 ATF_REQUIRE_EQ(fs::path("non-existent"), 68 test_case->container_test_program().relative_path()); 69 ATF_REQUIRE_EQ("main", test_case->name()); 70 } 71 72 73 ATF_TEST_CASE_WITHOUT_HEAD(find__missing); 74 ATF_TEST_CASE_BODY(find__missing) 75 { 76 const engine::test_program test_program( 77 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 78 engine::metadata_builder().build()); 79 ATF_REQUIRE_THROW_RE(engine::not_found_error, 80 "case.*abc.*program.*non-existent", 81 test_program.find("abc")); 82 } 83 84 85 ATF_TEST_CASE_WITHOUT_HEAD(test_cases__get); 86 ATF_TEST_CASE_BODY(test_cases__get) 87 { 88 const engine::test_program test_program( 89 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 90 engine::metadata_builder().build()); 91 const engine::test_cases_vector& test_cases = test_program.test_cases(); 92 ATF_REQUIRE_EQ(1, test_cases.size()); 93 ATF_REQUIRE_EQ(fs::path("non-existent"), 94 test_cases[0]->container_test_program().relative_path()); 95 ATF_REQUIRE_EQ("main", test_cases[0]->name()); 96 } 97 98 99 ATF_TEST_CASE_WITHOUT_HEAD(test_cases__some); 100 ATF_TEST_CASE_BODY(test_cases__some) 101 { 102 engine::test_program test_program( 103 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 104 engine::metadata_builder().build()); 105 106 engine::test_cases_vector exp_test_cases; 107 const engine::test_case test_case("plain", test_program, "main", 108 engine::metadata_builder().build()); 109 exp_test_cases.push_back(engine::test_case_ptr( 110 new engine::test_case(test_case))); 111 test_program.set_test_cases(exp_test_cases); 112 113 ATF_REQUIRE_EQ(exp_test_cases, test_program.test_cases()); 114 } 115 116 117 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__copy); 118 ATF_TEST_CASE_BODY(operators_eq_and_ne__copy) 119 { 120 const engine::test_program tp1( 121 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 122 engine::metadata_builder().build()); 123 const engine::test_program tp2 = tp1; 124 ATF_REQUIRE( tp1 == tp2); 125 ATF_REQUIRE(!(tp1 != tp2)); 126 } 127 128 129 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__not_copy); 130 ATF_TEST_CASE_BODY(operators_eq_and_ne__not_copy) 131 { 132 const std::string base_interface("plain"); 133 const fs::path base_relative_path("the/test/program"); 134 const fs::path base_root("/the/root"); 135 const std::string base_test_suite("suite-name"); 136 const engine::metadata base_metadata = engine::metadata_builder() 137 .add_custom("X-foo", "bar") 138 .build(); 139 140 engine::test_program base_tp( 141 base_interface, base_relative_path, base_root, base_test_suite, 142 base_metadata); 143 144 engine::test_cases_vector base_tcs; 145 { 146 const engine::test_case tc1("plain", base_tp, "main", 147 engine::metadata_builder().build()); 148 base_tcs.push_back(engine::test_case_ptr(new engine::test_case(tc1))); 149 } 150 base_tp.set_test_cases(base_tcs); 151 152 // Construct with all same values. 153 { 154 engine::test_program other_tp( 155 base_interface, base_relative_path, base_root, base_test_suite, 156 base_metadata); 157 158 engine::test_cases_vector other_tcs; 159 { 160 const engine::test_case tc1("plain", other_tp, "main", 161 engine::metadata_builder().build()); 162 other_tcs.push_back(engine::test_case_ptr( 163 new engine::test_case(tc1))); 164 } 165 other_tp.set_test_cases(other_tcs); 166 167 ATF_REQUIRE( base_tp == other_tp); 168 ATF_REQUIRE(!(base_tp != other_tp)); 169 } 170 171 // Different interface. 172 { 173 engine::test_program other_tp( 174 "atf", base_relative_path, base_root, base_test_suite, 175 base_metadata); 176 other_tp.set_test_cases(base_tcs); 177 178 ATF_REQUIRE(!(base_tp == other_tp)); 179 ATF_REQUIRE( base_tp != other_tp); 180 } 181 182 // Different relative path. 183 { 184 engine::test_program other_tp( 185 base_interface, fs::path("a/b/c"), base_root, base_test_suite, 186 base_metadata); 187 other_tp.set_test_cases(base_tcs); 188 189 ATF_REQUIRE(!(base_tp == other_tp)); 190 ATF_REQUIRE( base_tp != other_tp); 191 } 192 193 // Different root. 194 { 195 engine::test_program other_tp( 196 base_interface, base_relative_path, fs::path("."), base_test_suite, 197 base_metadata); 198 other_tp.set_test_cases(base_tcs); 199 200 ATF_REQUIRE(!(base_tp == other_tp)); 201 ATF_REQUIRE( base_tp != other_tp); 202 } 203 204 // Different test suite. 205 { 206 engine::test_program other_tp( 207 base_interface, base_relative_path, base_root, "different-suite", 208 base_metadata); 209 other_tp.set_test_cases(base_tcs); 210 211 ATF_REQUIRE(!(base_tp == other_tp)); 212 ATF_REQUIRE( base_tp != other_tp); 213 } 214 215 // Different metadata. 216 { 217 engine::test_program other_tp( 218 base_interface, base_relative_path, base_root, base_test_suite, 219 engine::metadata_builder().build()); 220 other_tp.set_test_cases(base_tcs); 221 222 ATF_REQUIRE(!(base_tp == other_tp)); 223 ATF_REQUIRE( base_tp != other_tp); 224 } 225 226 // Different test cases. 227 { 228 engine::test_program other_tp( 229 base_interface, base_relative_path, base_root, base_test_suite, 230 base_metadata); 231 232 engine::test_cases_vector other_tcs; 233 { 234 const engine::test_case tc1("atf", base_tp, "foo", 235 engine::metadata_builder().build()); 236 other_tcs.push_back(engine::test_case_ptr( 237 new engine::test_case(tc1))); 238 } 239 other_tp.set_test_cases(other_tcs); 240 241 ATF_REQUIRE(!(base_tp == other_tp)); 242 ATF_REQUIRE( base_tp != other_tp); 243 } 244 } 245 246 247 ATF_TEST_CASE_WITHOUT_HEAD(output__no_test_cases); 248 ATF_TEST_CASE_BODY(output__no_test_cases) 249 { 250 engine::test_program tp( 251 "plain", fs::path("binary/path"), fs::path("/the/root"), "suite-name", 252 engine::metadata_builder().add_allowed_architecture("a").build()); 253 tp.set_test_cases(engine::test_cases_vector()); 254 255 std::ostringstream str; 256 str << tp; 257 ATF_REQUIRE_EQ( 258 "test_program{interface='plain', binary='binary/path', " 259 "root='/the/root', test_suite='suite-name', " 260 "metadata=metadata{allowed_architectures='a', allowed_platforms='', " 261 "description='', has_cleanup='false', " 262 "required_configs='', required_files='', required_memory='0', " 263 "required_programs='', required_user='', timeout='300'}, " 264 "test_cases=[]}", 265 str.str()); 266 } 267 268 269 ATF_TEST_CASE_WITHOUT_HEAD(output__some_test_cases); 270 ATF_TEST_CASE_BODY(output__some_test_cases) 271 { 272 engine::test_program tp( 273 "plain", fs::path("binary/path"), fs::path("/the/root"), "suite-name", 274 engine::metadata_builder().add_allowed_architecture("a").build()); 275 276 const engine::test_case_ptr tc1(new engine::test_case( 277 "plain", tp, "the-name", engine::metadata_builder() 278 .add_allowed_platform("foo").add_custom("X-bar", "baz").build())); 279 const engine::test_case_ptr tc2(new engine::test_case( 280 "plain", tp, "another-name", engine::metadata_builder().build())); 281 engine::test_cases_vector tcs; 282 tcs.push_back(tc1); 283 tcs.push_back(tc2); 284 tp.set_test_cases(tcs); 285 286 std::ostringstream str; 287 str << tp; 288 ATF_REQUIRE_EQ( 289 "test_program{interface='plain', binary='binary/path', " 290 "root='/the/root', test_suite='suite-name', " 291 "metadata=metadata{allowed_architectures='a', allowed_platforms='', " 292 "description='', has_cleanup='false', " 293 "required_configs='', required_files='', required_memory='0', " 294 "required_programs='', required_user='', timeout='300'}, " 295 "test_cases=[" 296 "test_case{interface='plain', name='the-name', " 297 "metadata=metadata{allowed_architectures='', allowed_platforms='foo', " 298 "custom.X-bar='baz', description='', has_cleanup='false', " 299 "required_configs='', required_files='', required_memory='0', " 300 "required_programs='', required_user='', timeout='300'}}, " 301 "test_case{interface='plain', name='another-name', " 302 "metadata=metadata{allowed_architectures='', allowed_platforms='', " 303 "description='', has_cleanup='false', " 304 "required_configs='', required_files='', required_memory='0', " 305 "required_programs='', required_user='', timeout='300'}}]}", 306 str.str()); 307 } 308 309 310 ATF_INIT_TEST_CASES(tcs) 311 { 312 // TODO(jmmv): These tests have ceased to be realistic with the move to 313 // TestersDesign. We probably should have some (few!) integration tests for 314 // the various known testers... or, alternatively, provide a mock tester to 315 // run our tests with. 316 ATF_ADD_TEST_CASE(tcs, ctor_and_getters); 317 ATF_ADD_TEST_CASE(tcs, find__ok); 318 ATF_ADD_TEST_CASE(tcs, find__missing); 319 ATF_ADD_TEST_CASE(tcs, test_cases__get); 320 ATF_ADD_TEST_CASE(tcs, test_cases__some); 321 322 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__copy); 323 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__not_copy); 324 325 ATF_ADD_TEST_CASE(tcs, output__no_test_cases); 326 ATF_ADD_TEST_CASE(tcs, output__some_test_cases); 327 } 328