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/kyuafile.hpp" 30 31#include <stdexcept> 32#include <typeinfo> 33 34#include <atf-c++.hpp> 35#include <lutok/operations.hpp> 36#include <lutok/state.ipp> 37#include <lutok/test_utils.hpp> 38 39#include "engine/exceptions.hpp" 40#include "engine/test_program.hpp" 41#include "utils/datetime.hpp" 42#include "utils/format/macros.hpp" 43#include "utils/fs/operations.hpp" 44#include "utils/optional.ipp" 45 46namespace datetime = utils::datetime; 47namespace fs = utils::fs; 48 49using utils::none; 50 51 52ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__empty); 53ATF_TEST_CASE_BODY(kyuafile__load__empty) 54{ 55 atf::utils::create_file("config", "syntax(2)\n"); 56 57 const engine::kyuafile suite = engine::kyuafile::load( 58 fs::path("config"), none); 59 ATF_REQUIRE_EQ(fs::path("."), suite.source_root()); 60 ATF_REQUIRE_EQ(fs::path("."), suite.build_root()); 61 ATF_REQUIRE_EQ(0, suite.test_programs().size()); 62} 63 64 65ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__some_programs); 66ATF_TEST_CASE_BODY(kyuafile__load__some_programs) 67{ 68 atf::utils::create_file( 69 "config", 70 "syntax(2)\n" 71 "test_suite('one-suite')\n" 72 "atf_test_program{name='1st'}\n" 73 "atf_test_program{name='2nd', test_suite='first'}\n" 74 "plain_test_program{name='3rd'}\n" 75 "plain_test_program{name='4th', test_suite='second'}\n" 76 "include('dir/config')\n"); 77 78 fs::mkdir(fs::path("dir"), 0755); 79 atf::utils::create_file( 80 "dir/config", 81 "syntax(2)\n" 82 "atf_test_program{name='1st', test_suite='other-suite'}\n" 83 "include('subdir/config')\n"); 84 85 fs::mkdir(fs::path("dir/subdir"), 0755); 86 atf::utils::create_file( 87 "dir/subdir/config", 88 "syntax(2)\n" 89 "atf_test_program{name='5th', test_suite='last-suite'}\n"); 90 91 atf::utils::create_file("1st", ""); 92 atf::utils::create_file("2nd", ""); 93 atf::utils::create_file("3rd", ""); 94 atf::utils::create_file("4th", ""); 95 atf::utils::create_file("dir/1st", ""); 96 atf::utils::create_file("dir/subdir/5th", ""); 97 98 const engine::kyuafile suite = engine::kyuafile::load( 99 fs::path("config"), none); 100 ATF_REQUIRE_EQ(fs::path("."), suite.source_root()); 101 ATF_REQUIRE_EQ(fs::path("."), suite.build_root()); 102 ATF_REQUIRE_EQ(6, suite.test_programs().size()); 103 104 ATF_REQUIRE_EQ("atf", suite.test_programs()[0]->interface_name()); 105 ATF_REQUIRE_EQ(fs::path("1st"), suite.test_programs()[0]->relative_path()); 106 ATF_REQUIRE_EQ("one-suite", suite.test_programs()[0]->test_suite_name()); 107 108 ATF_REQUIRE_EQ("atf", suite.test_programs()[1]->interface_name()); 109 ATF_REQUIRE_EQ(fs::path("2nd"), suite.test_programs()[1]->relative_path()); 110 ATF_REQUIRE_EQ("first", suite.test_programs()[1]->test_suite_name()); 111 112 ATF_REQUIRE_EQ("plain", suite.test_programs()[2]->interface_name()); 113 ATF_REQUIRE_EQ(fs::path("3rd"), suite.test_programs()[2]->relative_path()); 114 ATF_REQUIRE_EQ("one-suite", suite.test_programs()[2]->test_suite_name()); 115 116 ATF_REQUIRE_EQ("plain", suite.test_programs()[3]->interface_name()); 117 ATF_REQUIRE_EQ(fs::path("4th"), suite.test_programs()[3]->relative_path()); 118 ATF_REQUIRE_EQ("second", suite.test_programs()[3]->test_suite_name()); 119 120 ATF_REQUIRE_EQ("atf", suite.test_programs()[4]->interface_name()); 121 ATF_REQUIRE_EQ(fs::path("dir/1st"), 122 suite.test_programs()[4]->relative_path()); 123 ATF_REQUIRE_EQ("other-suite", suite.test_programs()[4]->test_suite_name()); 124 125 ATF_REQUIRE_EQ("atf", suite.test_programs()[5]->interface_name()); 126 ATF_REQUIRE_EQ(fs::path("dir/subdir/5th"), 127 suite.test_programs()[5]->relative_path()); 128 ATF_REQUIRE_EQ("last-suite", suite.test_programs()[5]->test_suite_name()); 129} 130 131 132ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__metadata); 133ATF_TEST_CASE_BODY(kyuafile__load__metadata) 134{ 135 atf::utils::create_file( 136 "config", 137 "syntax(2)\n" 138 "atf_test_program{name='1st', test_suite='first'," 139 " allowed_architectures='amd64 i386', timeout=15}\n" 140 "plain_test_program{name='2nd', test_suite='second'," 141 " required_files='foo /bar//baz', required_user='root'}\n"); 142 atf::utils::create_file("1st", ""); 143 atf::utils::create_file("2nd", ""); 144 145 const engine::kyuafile suite = engine::kyuafile::load( 146 fs::path("config"), none); 147 ATF_REQUIRE_EQ(2, suite.test_programs().size()); 148 149 ATF_REQUIRE_EQ("atf", suite.test_programs()[0]->interface_name()); 150 ATF_REQUIRE_EQ(fs::path("1st"), suite.test_programs()[0]->relative_path()); 151 ATF_REQUIRE_EQ("first", suite.test_programs()[0]->test_suite_name()); 152 const engine::metadata md1 = engine::metadata_builder() 153 .add_allowed_architecture("amd64") 154 .add_allowed_architecture("i386") 155 .set_timeout(datetime::delta(15, 0)) 156 .build(); 157 ATF_REQUIRE_EQ(md1, suite.test_programs()[0]->get_metadata()); 158 159 ATF_REQUIRE_EQ("plain", suite.test_programs()[1]->interface_name()); 160 ATF_REQUIRE_EQ(fs::path("2nd"), suite.test_programs()[1]->relative_path()); 161 ATF_REQUIRE_EQ("second", suite.test_programs()[1]->test_suite_name()); 162 const engine::metadata md2 = engine::metadata_builder() 163 .add_required_file(fs::path("foo")) 164 .add_required_file(fs::path("/bar/baz")) 165 .set_required_user("root") 166 .build(); 167 ATF_REQUIRE_EQ(md2, suite.test_programs()[1]->get_metadata()); 168} 169 170 171ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__current_directory); 172ATF_TEST_CASE_BODY(kyuafile__load__current_directory) 173{ 174 atf::utils::create_file( 175 "config", 176 "syntax(2)\n" 177 "atf_test_program{name='one', test_suite='first'}\n" 178 "include('config2')\n"); 179 180 atf::utils::create_file( 181 "config2", 182 "syntax(2)\n" 183 "test_suite('second')\n" 184 "atf_test_program{name='two'}\n"); 185 186 atf::utils::create_file("one", ""); 187 atf::utils::create_file("two", ""); 188 189 const engine::kyuafile suite = engine::kyuafile::load( 190 fs::path("config"), none); 191 ATF_REQUIRE_EQ(fs::path("."), suite.source_root()); 192 ATF_REQUIRE_EQ(fs::path("."), suite.build_root()); 193 ATF_REQUIRE_EQ(2, suite.test_programs().size()); 194 ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path()); 195 ATF_REQUIRE_EQ("first", suite.test_programs()[0]->test_suite_name()); 196 ATF_REQUIRE_EQ(fs::path("two"), 197 suite.test_programs()[1]->relative_path()); 198 ATF_REQUIRE_EQ("second", suite.test_programs()[1]->test_suite_name()); 199} 200 201 202ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__other_directory); 203ATF_TEST_CASE_BODY(kyuafile__load__other_directory) 204{ 205 fs::mkdir(fs::path("root"), 0755); 206 atf::utils::create_file( 207 "root/config", 208 "syntax(2)\n" 209 "test_suite('abc')\n" 210 "atf_test_program{name='one'}\n" 211 "include('dir/config')\n"); 212 213 fs::mkdir(fs::path("root/dir"), 0755); 214 atf::utils::create_file( 215 "root/dir/config", 216 "syntax(2)\n" 217 "test_suite('foo')\n" 218 "atf_test_program{name='two', test_suite='def'}\n" 219 "atf_test_program{name='three'}\n"); 220 221 atf::utils::create_file("root/one", ""); 222 atf::utils::create_file("root/dir/two", ""); 223 atf::utils::create_file("root/dir/three", ""); 224 225 const engine::kyuafile suite = engine::kyuafile::load( 226 fs::path("root/config"), none); 227 ATF_REQUIRE_EQ(fs::path("root"), suite.source_root()); 228 ATF_REQUIRE_EQ(fs::path("root"), suite.build_root()); 229 ATF_REQUIRE_EQ(3, suite.test_programs().size()); 230 ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path()); 231 ATF_REQUIRE_EQ("abc", suite.test_programs()[0]->test_suite_name()); 232 ATF_REQUIRE_EQ(fs::path("dir/two"), 233 suite.test_programs()[1]->relative_path()); 234 ATF_REQUIRE_EQ("def", suite.test_programs()[1]->test_suite_name()); 235 ATF_REQUIRE_EQ(fs::path("dir/three"), 236 suite.test_programs()[2]->relative_path()); 237 ATF_REQUIRE_EQ("foo", suite.test_programs()[2]->test_suite_name()); 238} 239 240 241ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__build_directory); 242ATF_TEST_CASE_BODY(kyuafile__load__build_directory) 243{ 244 fs::mkdir(fs::path("srcdir"), 0755); 245 atf::utils::create_file( 246 "srcdir/config", 247 "syntax(2)\n" 248 "test_suite('abc')\n" 249 "atf_test_program{name='one'}\n" 250 "include('dir/config')\n"); 251 252 fs::mkdir(fs::path("srcdir/dir"), 0755); 253 atf::utils::create_file( 254 "srcdir/dir/config", 255 "syntax(2)\n" 256 "test_suite('foo')\n" 257 "atf_test_program{name='two', test_suite='def'}\n" 258 "atf_test_program{name='three'}\n"); 259 260 fs::mkdir(fs::path("builddir"), 0755); 261 atf::utils::create_file("builddir/one", ""); 262 fs::mkdir(fs::path("builddir/dir"), 0755); 263 atf::utils::create_file("builddir/dir/two", ""); 264 atf::utils::create_file("builddir/dir/three", ""); 265 266 const engine::kyuafile suite = engine::kyuafile::load( 267 fs::path("srcdir/config"), utils::make_optional(fs::path("builddir"))); 268 ATF_REQUIRE_EQ(fs::path("srcdir"), suite.source_root()); 269 ATF_REQUIRE_EQ(fs::path("builddir"), suite.build_root()); 270 ATF_REQUIRE_EQ(3, suite.test_programs().size()); 271 ATF_REQUIRE_EQ(fs::path("builddir/one").to_absolute(), 272 suite.test_programs()[0]->absolute_path()); 273 ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path()); 274 ATF_REQUIRE_EQ("abc", suite.test_programs()[0]->test_suite_name()); 275 ATF_REQUIRE_EQ(fs::path("builddir/dir/two").to_absolute(), 276 suite.test_programs()[1]->absolute_path()); 277 ATF_REQUIRE_EQ(fs::path("dir/two"), 278 suite.test_programs()[1]->relative_path()); 279 ATF_REQUIRE_EQ("def", suite.test_programs()[1]->test_suite_name()); 280 ATF_REQUIRE_EQ(fs::path("builddir/dir/three").to_absolute(), 281 suite.test_programs()[2]->absolute_path()); 282 ATF_REQUIRE_EQ(fs::path("dir/three"), 283 suite.test_programs()[2]->relative_path()); 284 ATF_REQUIRE_EQ("foo", suite.test_programs()[2]->test_suite_name()); 285} 286 287 288ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__test_program_not_basename); 289ATF_TEST_CASE_BODY(kyuafile__load__test_program_not_basename) 290{ 291 atf::utils::create_file( 292 "config", 293 "syntax(2)\n" 294 "test_suite('abc')\n" 295 "atf_test_program{name='one'}\n" 296 "atf_test_program{name='./ls'}\n"); 297 298 atf::utils::create_file("one", ""); 299 ATF_REQUIRE_THROW_RE(engine::load_error, "./ls.*path components", 300 engine::kyuafile::load(fs::path("config"), none)); 301} 302 303 304ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__lua_error); 305ATF_TEST_CASE_BODY(kyuafile__load__lua_error) 306{ 307 atf::utils::create_file("config", "this syntax is invalid\n"); 308 309 ATF_REQUIRE_THROW(engine::load_error, engine::kyuafile::load( 310 fs::path("config"), none)); 311} 312 313 314ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__not_called); 315ATF_TEST_CASE_BODY(kyuafile__load__syntax__not_called) 316{ 317 atf::utils::create_file("config", ""); 318 319 ATF_REQUIRE_THROW_RE(engine::load_error, "syntax.* never called", 320 engine::kyuafile::load(fs::path("config"), none)); 321} 322 323 324ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__deprecated_format); 325ATF_TEST_CASE_BODY(kyuafile__load__syntax__deprecated_format) 326{ 327 atf::utils::create_file("config", "syntax('kyuafile', 1)\n"); 328 (void)engine::kyuafile::load(fs::path("config"), none); 329 330 atf::utils::create_file("config", "syntax('foo', 1)\n"); 331 ATF_REQUIRE_THROW_RE(engine::load_error, "must be 'kyuafile'", 332 engine::kyuafile::load(fs::path("config"), none)); 333 334 atf::utils::create_file("config", "syntax('config', 2)\n"); 335 ATF_REQUIRE_THROW_RE(engine::load_error, "only takes one argument", 336 engine::kyuafile::load(fs::path("config"), none)); 337} 338 339 340ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__twice); 341ATF_TEST_CASE_BODY(kyuafile__load__syntax__twice) 342{ 343 atf::utils::create_file( 344 "config", 345 "syntax(2)\n" 346 "syntax(2)\n"); 347 348 ATF_REQUIRE_THROW_RE(engine::load_error, "Can only call syntax.* once", 349 engine::kyuafile::load(fs::path("config"), none)); 350} 351 352 353ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__bad_version); 354ATF_TEST_CASE_BODY(kyuafile__load__syntax__bad_version) 355{ 356 atf::utils::create_file("config", "syntax(12)\n"); 357 358 ATF_REQUIRE_THROW_RE(engine::load_error, "Unsupported file version 12", 359 engine::kyuafile::load(fs::path("config"), none)); 360} 361 362 363ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__test_suite__twice); 364ATF_TEST_CASE_BODY(kyuafile__load__test_suite__twice) 365{ 366 atf::utils::create_file( 367 "config", 368 "syntax(2)\n" 369 "test_suite('foo')\n" 370 "test_suite('bar')\n"); 371 372 ATF_REQUIRE_THROW_RE(engine::load_error, "Can only call test_suite.* once", 373 engine::kyuafile::load(fs::path("config"), none)); 374} 375 376 377ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__missing_file); 378ATF_TEST_CASE_BODY(kyuafile__load__missing_file) 379{ 380 ATF_REQUIRE_THROW_RE(engine::load_error, "Load of 'missing' failed", 381 engine::kyuafile::load(fs::path("missing"), none)); 382} 383 384 385ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__missing_test_program); 386ATF_TEST_CASE_BODY(kyuafile__load__missing_test_program) 387{ 388 atf::utils::create_file( 389 "config", 390 "syntax(2)\n" 391 "atf_test_program{name='one', test_suite='first'}\n" 392 "atf_test_program{name='two', test_suite='first'}\n"); 393 394 atf::utils::create_file("one", ""); 395 396 ATF_REQUIRE_THROW_RE(engine::load_error, "Non-existent.*'two'", 397 engine::kyuafile::load(fs::path("config"), none)); 398} 399 400 401ATF_INIT_TEST_CASES(tcs) 402{ 403 ATF_ADD_TEST_CASE(tcs, kyuafile__load__empty); 404 ATF_ADD_TEST_CASE(tcs, kyuafile__load__some_programs); 405 ATF_ADD_TEST_CASE(tcs, kyuafile__load__metadata); 406 ATF_ADD_TEST_CASE(tcs, kyuafile__load__current_directory); 407 ATF_ADD_TEST_CASE(tcs, kyuafile__load__other_directory); 408 ATF_ADD_TEST_CASE(tcs, kyuafile__load__build_directory); 409 ATF_ADD_TEST_CASE(tcs, kyuafile__load__test_program_not_basename); 410 ATF_ADD_TEST_CASE(tcs, kyuafile__load__lua_error); 411 ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__not_called); 412 ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__deprecated_format); 413 ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__twice); 414 ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__bad_version); 415 ATF_ADD_TEST_CASE(tcs, kyuafile__load__test_suite__twice); 416 ATF_ADD_TEST_CASE(tcs, kyuafile__load__missing_file); 417 ATF_ADD_TEST_CASE(tcs, kyuafile__load__missing_test_program); 418} 419