1// Copyright 2010 The Kyua Authors.
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
31extern "C" {
32#include <unistd.h>
33}
34
35#include <stdexcept>
36#include <typeinfo>
37
38#include <atf-c++.hpp>
39#include <lutok/operations.hpp>
40#include <lutok/state.ipp>
41#include <lutok/test_utils.hpp>
42
43#include "engine/atf.hpp"
44#include "engine/exceptions.hpp"
45#include "engine/plain.hpp"
46#include "engine/scheduler.hpp"
47#include "engine/tap.hpp"
48#include "model/metadata.hpp"
49#include "model/test_program.hpp"
50#include "utils/config/tree.ipp"
51#include "utils/datetime.hpp"
52#include "utils/env.hpp"
53#include "utils/format/macros.hpp"
54#include "utils/fs/operations.hpp"
55#include "utils/optional.ipp"
56
57namespace config = utils::config;
58namespace datetime = utils::datetime;
59namespace fs = utils::fs;
60namespace scheduler = engine::scheduler;
61
62using utils::none;
63
64
65ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__empty);
66ATF_TEST_CASE_BODY(kyuafile__load__empty)
67{
68    scheduler::scheduler_handle handle = scheduler::setup();
69
70    atf::utils::create_file("config", "syntax(2)\n");
71
72    const engine::kyuafile suite = engine::kyuafile::load(
73        fs::path("config"), none, config::tree(), handle);
74    ATF_REQUIRE_EQ(fs::path("."), suite.source_root());
75    ATF_REQUIRE_EQ(fs::path("."), suite.build_root());
76    ATF_REQUIRE_EQ(0, suite.test_programs().size());
77
78    handle.cleanup();
79}
80
81
82ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__real_interfaces);
83ATF_TEST_CASE_BODY(kyuafile__load__real_interfaces)
84{
85    scheduler::scheduler_handle handle = scheduler::setup();
86
87    atf::utils::create_file(
88        "config",
89        "syntax(2)\n"
90        "test_suite('one-suite')\n"
91        "atf_test_program{name='1st'}\n"
92        "atf_test_program{name='2nd', test_suite='first'}\n"
93        "plain_test_program{name='3rd'}\n"
94        "tap_test_program{name='4th', test_suite='second'}\n"
95        "include('dir/config')\n");
96
97    fs::mkdir(fs::path("dir"), 0755);
98    atf::utils::create_file(
99        "dir/config",
100        "syntax(2)\n"
101        "atf_test_program{name='1st', test_suite='other-suite'}\n"
102        "include('subdir/config')\n");
103
104    fs::mkdir(fs::path("dir/subdir"), 0755);
105    atf::utils::create_file(
106        "dir/subdir/config",
107        "syntax(2)\n"
108        "atf_test_program{name='5th', test_suite='last-suite'}\n");
109
110    atf::utils::create_file("1st", "");
111    atf::utils::create_file("2nd", "");
112    atf::utils::create_file("3rd", "");
113    atf::utils::create_file("4th", "");
114    atf::utils::create_file("dir/1st", "");
115    atf::utils::create_file("dir/subdir/5th", "");
116
117    const engine::kyuafile suite = engine::kyuafile::load(
118        fs::path("config"), none, config::tree(), handle);
119    ATF_REQUIRE_EQ(fs::path("."), suite.source_root());
120    ATF_REQUIRE_EQ(fs::path("."), suite.build_root());
121    ATF_REQUIRE_EQ(6, suite.test_programs().size());
122
123    ATF_REQUIRE_EQ("atf", suite.test_programs()[0]->interface_name());
124    ATF_REQUIRE_EQ(fs::path("1st"), suite.test_programs()[0]->relative_path());
125    ATF_REQUIRE_EQ("one-suite", suite.test_programs()[0]->test_suite_name());
126
127    ATF_REQUIRE_EQ("atf", suite.test_programs()[1]->interface_name());
128    ATF_REQUIRE_EQ(fs::path("2nd"), suite.test_programs()[1]->relative_path());
129    ATF_REQUIRE_EQ("first", suite.test_programs()[1]->test_suite_name());
130
131    ATF_REQUIRE_EQ("plain", suite.test_programs()[2]->interface_name());
132    ATF_REQUIRE_EQ(fs::path("3rd"), suite.test_programs()[2]->relative_path());
133    ATF_REQUIRE_EQ("one-suite", suite.test_programs()[2]->test_suite_name());
134
135    ATF_REQUIRE_EQ("tap", suite.test_programs()[3]->interface_name());
136    ATF_REQUIRE_EQ(fs::path("4th"), suite.test_programs()[3]->relative_path());
137    ATF_REQUIRE_EQ("second", suite.test_programs()[3]->test_suite_name());
138
139    ATF_REQUIRE_EQ("atf", suite.test_programs()[4]->interface_name());
140    ATF_REQUIRE_EQ(fs::path("dir/1st"),
141                   suite.test_programs()[4]->relative_path());
142    ATF_REQUIRE_EQ("other-suite", suite.test_programs()[4]->test_suite_name());
143
144    ATF_REQUIRE_EQ("atf", suite.test_programs()[5]->interface_name());
145    ATF_REQUIRE_EQ(fs::path("dir/subdir/5th"),
146                   suite.test_programs()[5]->relative_path());
147    ATF_REQUIRE_EQ("last-suite", suite.test_programs()[5]->test_suite_name());
148
149    handle.cleanup();
150}
151
152
153ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__mock_interfaces);
154ATF_TEST_CASE_BODY(kyuafile__load__mock_interfaces)
155{
156    scheduler::scheduler_handle handle = scheduler::setup();
157
158    std::shared_ptr< scheduler::interface > mock_interface(
159        new engine::plain_interface());
160
161    scheduler::register_interface("some", mock_interface);
162    scheduler::register_interface("random", mock_interface);
163    scheduler::register_interface("names", mock_interface);
164
165    atf::utils::create_file(
166        "config",
167        "syntax(2)\n"
168        "test_suite('one-suite')\n"
169        "some_test_program{name='1st'}\n"
170        "random_test_program{name='2nd'}\n"
171        "names_test_program{name='3rd'}\n");
172
173    atf::utils::create_file("1st", "");
174    atf::utils::create_file("2nd", "");
175    atf::utils::create_file("3rd", "");
176
177    const engine::kyuafile suite = engine::kyuafile::load(
178        fs::path("config"), none, config::tree(), handle);
179    ATF_REQUIRE_EQ(fs::path("."), suite.source_root());
180    ATF_REQUIRE_EQ(fs::path("."), suite.build_root());
181    ATF_REQUIRE_EQ(3, suite.test_programs().size());
182
183    ATF_REQUIRE_EQ("some", suite.test_programs()[0]->interface_name());
184    ATF_REQUIRE_EQ(fs::path("1st"), suite.test_programs()[0]->relative_path());
185
186    ATF_REQUIRE_EQ("random", suite.test_programs()[1]->interface_name());
187    ATF_REQUIRE_EQ(fs::path("2nd"), suite.test_programs()[1]->relative_path());
188
189    ATF_REQUIRE_EQ("names", suite.test_programs()[2]->interface_name());
190    ATF_REQUIRE_EQ(fs::path("3rd"), suite.test_programs()[2]->relative_path());
191
192    handle.cleanup();
193}
194
195
196ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__metadata);
197ATF_TEST_CASE_BODY(kyuafile__load__metadata)
198{
199    scheduler::scheduler_handle handle = scheduler::setup();
200
201    atf::utils::create_file(
202        "config",
203        "syntax(2)\n"
204        "atf_test_program{name='1st', test_suite='first',"
205        " allowed_architectures='amd64 i386', timeout=15}\n"
206        "plain_test_program{name='2nd', test_suite='second',"
207        " required_files='foo /bar//baz', required_user='root',"
208        " ['custom.a-number']=123, ['custom.a-bool']=true}\n");
209    atf::utils::create_file("1st", "");
210    atf::utils::create_file("2nd", "");
211
212    const engine::kyuafile suite = engine::kyuafile::load(
213        fs::path("config"), none, config::tree(), handle);
214    ATF_REQUIRE_EQ(2, suite.test_programs().size());
215
216    ATF_REQUIRE_EQ("atf", suite.test_programs()[0]->interface_name());
217    ATF_REQUIRE_EQ(fs::path("1st"), suite.test_programs()[0]->relative_path());
218    ATF_REQUIRE_EQ("first", suite.test_programs()[0]->test_suite_name());
219    const model::metadata md1 = model::metadata_builder()
220        .add_allowed_architecture("amd64")
221        .add_allowed_architecture("i386")
222        .set_timeout(datetime::delta(15, 0))
223        .build();
224    ATF_REQUIRE_EQ(md1, suite.test_programs()[0]->get_metadata());
225
226    ATF_REQUIRE_EQ("plain", suite.test_programs()[1]->interface_name());
227    ATF_REQUIRE_EQ(fs::path("2nd"), suite.test_programs()[1]->relative_path());
228    ATF_REQUIRE_EQ("second", suite.test_programs()[1]->test_suite_name());
229    const model::metadata md2 = model::metadata_builder()
230        .add_required_file(fs::path("foo"))
231        .add_required_file(fs::path("/bar/baz"))
232        .add_custom("a-bool", "true")
233        .add_custom("a-number", "123")
234        .set_required_user("root")
235        .build();
236    ATF_REQUIRE_EQ(md2, suite.test_programs()[1]->get_metadata());
237
238    handle.cleanup();
239}
240
241
242ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__current_directory);
243ATF_TEST_CASE_BODY(kyuafile__load__current_directory)
244{
245    scheduler::scheduler_handle handle = scheduler::setup();
246
247    atf::utils::create_file(
248        "config",
249        "syntax(2)\n"
250        "atf_test_program{name='one', test_suite='first'}\n"
251        "include('config2')\n");
252
253    atf::utils::create_file(
254        "config2",
255        "syntax(2)\n"
256        "test_suite('second')\n"
257        "atf_test_program{name='two'}\n");
258
259    atf::utils::create_file("one", "");
260    atf::utils::create_file("two", "");
261
262    const engine::kyuafile suite = engine::kyuafile::load(
263        fs::path("config"), none, config::tree(), handle);
264    ATF_REQUIRE_EQ(fs::path("."), suite.source_root());
265    ATF_REQUIRE_EQ(fs::path("."), suite.build_root());
266    ATF_REQUIRE_EQ(2, suite.test_programs().size());
267    ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path());
268    ATF_REQUIRE_EQ("first", suite.test_programs()[0]->test_suite_name());
269    ATF_REQUIRE_EQ(fs::path("two"),
270                   suite.test_programs()[1]->relative_path());
271    ATF_REQUIRE_EQ("second", suite.test_programs()[1]->test_suite_name());
272
273    handle.cleanup();
274}
275
276
277ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__other_directory);
278ATF_TEST_CASE_BODY(kyuafile__load__other_directory)
279{
280    scheduler::scheduler_handle handle = scheduler::setup();
281
282    fs::mkdir(fs::path("root"), 0755);
283    atf::utils::create_file(
284        "root/config",
285        "syntax(2)\n"
286        "test_suite('abc')\n"
287        "atf_test_program{name='one'}\n"
288        "include('dir/config')\n");
289
290    fs::mkdir(fs::path("root/dir"), 0755);
291    atf::utils::create_file(
292        "root/dir/config",
293        "syntax(2)\n"
294        "test_suite('foo')\n"
295        "atf_test_program{name='two', test_suite='def'}\n"
296        "atf_test_program{name='three'}\n");
297
298    atf::utils::create_file("root/one", "");
299    atf::utils::create_file("root/dir/two", "");
300    atf::utils::create_file("root/dir/three", "");
301
302    const engine::kyuafile suite = engine::kyuafile::load(
303        fs::path("root/config"), none, config::tree(), handle);
304    ATF_REQUIRE_EQ(fs::path("root"), suite.source_root());
305    ATF_REQUIRE_EQ(fs::path("root"), suite.build_root());
306    ATF_REQUIRE_EQ(3, suite.test_programs().size());
307    ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path());
308    ATF_REQUIRE_EQ("abc", suite.test_programs()[0]->test_suite_name());
309    ATF_REQUIRE_EQ(fs::path("dir/two"),
310                   suite.test_programs()[1]->relative_path());
311    ATF_REQUIRE_EQ("def", suite.test_programs()[1]->test_suite_name());
312    ATF_REQUIRE_EQ(fs::path("dir/three"),
313                   suite.test_programs()[2]->relative_path());
314    ATF_REQUIRE_EQ("foo", suite.test_programs()[2]->test_suite_name());
315
316    handle.cleanup();
317}
318
319
320ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__build_directory);
321ATF_TEST_CASE_BODY(kyuafile__load__build_directory)
322{
323    scheduler::scheduler_handle handle = scheduler::setup();
324
325    fs::mkdir(fs::path("srcdir"), 0755);
326    atf::utils::create_file(
327        "srcdir/config",
328        "syntax(2)\n"
329        "test_suite('abc')\n"
330        "atf_test_program{name='one'}\n"
331        "include('dir/config')\n");
332
333    fs::mkdir(fs::path("srcdir/dir"), 0755);
334    atf::utils::create_file(
335        "srcdir/dir/config",
336        "syntax(2)\n"
337        "test_suite('foo')\n"
338        "atf_test_program{name='two', test_suite='def'}\n"
339        "atf_test_program{name='three'}\n");
340
341    fs::mkdir(fs::path("builddir"), 0755);
342    atf::utils::create_file("builddir/one", "");
343    fs::mkdir(fs::path("builddir/dir"), 0755);
344    atf::utils::create_file("builddir/dir/two", "");
345    atf::utils::create_file("builddir/dir/three", "");
346
347    const engine::kyuafile suite = engine::kyuafile::load(
348        fs::path("srcdir/config"), utils::make_optional(fs::path("builddir")),
349        config::tree(), handle);
350    ATF_REQUIRE_EQ(fs::path("srcdir"), suite.source_root());
351    ATF_REQUIRE_EQ(fs::path("builddir"), suite.build_root());
352    ATF_REQUIRE_EQ(3, suite.test_programs().size());
353    ATF_REQUIRE_EQ(fs::path("builddir/one").to_absolute(),
354                   suite.test_programs()[0]->absolute_path());
355    ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path());
356    ATF_REQUIRE_EQ("abc", suite.test_programs()[0]->test_suite_name());
357    ATF_REQUIRE_EQ(fs::path("builddir/dir/two").to_absolute(),
358                   suite.test_programs()[1]->absolute_path());
359    ATF_REQUIRE_EQ(fs::path("dir/two"),
360                   suite.test_programs()[1]->relative_path());
361    ATF_REQUIRE_EQ("def", suite.test_programs()[1]->test_suite_name());
362    ATF_REQUIRE_EQ(fs::path("builddir/dir/three").to_absolute(),
363                   suite.test_programs()[2]->absolute_path());
364    ATF_REQUIRE_EQ(fs::path("dir/three"),
365                   suite.test_programs()[2]->relative_path());
366    ATF_REQUIRE_EQ("foo", suite.test_programs()[2]->test_suite_name());
367
368    handle.cleanup();
369}
370
371
372ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__absolute_paths_are_stable);
373ATF_TEST_CASE_BODY(kyuafile__load__absolute_paths_are_stable)
374{
375    scheduler::scheduler_handle handle = scheduler::setup();
376
377    atf::utils::create_file(
378        "config",
379        "syntax(2)\n"
380        "atf_test_program{name='one', test_suite='first'}\n");
381    atf::utils::create_file("one", "");
382
383    const engine::kyuafile suite = engine::kyuafile::load(
384        fs::path("config"), none, config::tree(), handle);
385
386    const fs::path previous_dir = fs::current_path();
387    fs::mkdir(fs::path("other"), 0755);
388    // Change the directory.  We want later calls to absolute_path() on the test
389    // programs to return references to previous_dir instead.
390    ATF_REQUIRE(::chdir("other") != -1);
391
392    ATF_REQUIRE_EQ(fs::path("."), suite.source_root());
393    ATF_REQUIRE_EQ(fs::path("."), suite.build_root());
394    ATF_REQUIRE_EQ(1, suite.test_programs().size());
395    ATF_REQUIRE_EQ(previous_dir / "one",
396                   suite.test_programs()[0]->absolute_path());
397    ATF_REQUIRE_EQ(fs::path("one"), suite.test_programs()[0]->relative_path());
398    ATF_REQUIRE_EQ("first", suite.test_programs()[0]->test_suite_name());
399
400    handle.cleanup();
401}
402
403
404ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__fs_calls_are_relative);
405ATF_TEST_CASE_BODY(kyuafile__load__fs_calls_are_relative)
406{
407    scheduler::scheduler_handle handle = scheduler::setup();
408
409    atf::utils::create_file(
410        "Kyuafile",
411        "syntax(2)\n"
412        "if fs.exists('one') then\n"
413        "    plain_test_program{name='one', test_suite='first'}\n"
414        "end\n"
415        "if fs.exists('two') then\n"
416        "    plain_test_program{name='two', test_suite='first'}\n"
417        "end\n"
418        "include('dir/Kyuafile')\n");
419    atf::utils::create_file("one", "");
420    fs::mkdir(fs::path("dir"), 0755);
421    atf::utils::create_file(
422        "dir/Kyuafile",
423        "syntax(2)\n"
424        "if fs.exists('one') then\n"
425        "    plain_test_program{name='one', test_suite='first'}\n"
426        "end\n"
427        "if fs.exists('two') then\n"
428        "    plain_test_program{name='two', test_suite='first'}\n"
429        "end\n");
430    atf::utils::create_file("dir/two", "");
431
432    const engine::kyuafile suite = engine::kyuafile::load(
433        fs::path("Kyuafile"), none, config::tree(), handle);
434
435    ATF_REQUIRE_EQ(2, suite.test_programs().size());
436    ATF_REQUIRE_EQ(fs::current_path() / "one",
437                   suite.test_programs()[0]->absolute_path());
438    ATF_REQUIRE_EQ(fs::current_path() / "dir/two",
439                   suite.test_programs()[1]->absolute_path());
440
441    handle.cleanup();
442}
443
444
445/// Verifies that load raises a load_error on a given input.
446///
447/// \param file Name of the file to load.
448/// \param regex Expression to match on load_error's contents.
449static void
450do_load_error_test(const char* file, const char* regex)
451{
452    scheduler::scheduler_handle handle = scheduler::setup();
453    ATF_REQUIRE_THROW_RE(engine::load_error, regex,
454                         engine::kyuafile::load(fs::path(file), none,
455                                                config::tree(), handle));
456    handle.cleanup();
457}
458
459
460ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__test_program_not_basename);
461ATF_TEST_CASE_BODY(kyuafile__load__test_program_not_basename)
462{
463    atf::utils::create_file(
464        "config",
465        "syntax(2)\n"
466        "test_suite('abc')\n"
467        "atf_test_program{name='one'}\n"
468        "atf_test_program{name='./ls'}\n");
469
470    atf::utils::create_file("one", "");
471    do_load_error_test("config", "./ls.*path components");
472}
473
474
475ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__lua_error);
476ATF_TEST_CASE_BODY(kyuafile__load__lua_error)
477{
478    atf::utils::create_file("config", "this syntax is invalid\n");
479
480    do_load_error_test("config", ".*");
481}
482
483
484ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__not_called);
485ATF_TEST_CASE_BODY(kyuafile__load__syntax__not_called)
486{
487    atf::utils::create_file("config", "");
488
489    do_load_error_test("config", "syntax.* never called");
490}
491
492
493
494ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__deprecated_format);
495ATF_TEST_CASE_BODY(kyuafile__load__syntax__deprecated_format)
496{
497    atf::utils::create_file("config", "syntax('foo', 1)\n");
498    do_load_error_test("config", "must be 'kyuafile'");
499
500    atf::utils::create_file("config", "syntax('config', 2)\n");
501    do_load_error_test("config", "only takes one argument");
502}
503
504
505ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__twice);
506ATF_TEST_CASE_BODY(kyuafile__load__syntax__twice)
507{
508    atf::utils::create_file(
509        "config",
510        "syntax(2)\n"
511        "syntax(2)\n");
512
513    do_load_error_test("config", "Can only call syntax.* once");
514}
515
516
517ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__syntax__bad_version);
518ATF_TEST_CASE_BODY(kyuafile__load__syntax__bad_version)
519{
520    atf::utils::create_file("config", "syntax(12)\n");
521
522    do_load_error_test("config", "Unsupported file version 12");
523}
524
525
526ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__test_suite__missing);
527ATF_TEST_CASE_BODY(kyuafile__load__test_suite__missing)
528{
529    atf::utils::create_file(
530        "config",
531        "syntax(2)\n"
532        "plain_test_program{name='one'}");
533
534    atf::utils::create_file("one", "");
535
536    do_load_error_test("config", "No test suite defined");
537}
538
539
540ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__test_suite__twice);
541ATF_TEST_CASE_BODY(kyuafile__load__test_suite__twice)
542{
543    atf::utils::create_file(
544        "config",
545        "syntax(2)\n"
546        "test_suite('foo')\n"
547        "test_suite('bar')\n");
548
549    do_load_error_test("config", "Can only call test_suite.* once");
550}
551
552
553ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__missing_file);
554ATF_TEST_CASE_BODY(kyuafile__load__missing_file)
555{
556    do_load_error_test("missing", "Load of 'missing' failed");
557}
558
559
560ATF_TEST_CASE_WITHOUT_HEAD(kyuafile__load__missing_test_program);
561ATF_TEST_CASE_BODY(kyuafile__load__missing_test_program)
562{
563    atf::utils::create_file(
564        "config",
565        "syntax(2)\n"
566        "atf_test_program{name='one', test_suite='first'}\n"
567        "atf_test_program{name='two', test_suite='first'}\n");
568
569    atf::utils::create_file("one", "");
570
571    do_load_error_test("config", "Non-existent.*'two'");
572}
573
574
575ATF_INIT_TEST_CASES(tcs)
576{
577    scheduler::register_interface(
578        "atf", std::shared_ptr< scheduler::interface >(
579            new engine::atf_interface()));
580    scheduler::register_interface(
581        "plain", std::shared_ptr< scheduler::interface >(
582            new engine::plain_interface()));
583    scheduler::register_interface(
584        "tap", std::shared_ptr< scheduler::interface >(
585            new engine::tap_interface()));
586
587    ATF_ADD_TEST_CASE(tcs, kyuafile__load__empty);
588    ATF_ADD_TEST_CASE(tcs, kyuafile__load__real_interfaces);
589    ATF_ADD_TEST_CASE(tcs, kyuafile__load__mock_interfaces);
590    ATF_ADD_TEST_CASE(tcs, kyuafile__load__metadata);
591    ATF_ADD_TEST_CASE(tcs, kyuafile__load__current_directory);
592    ATF_ADD_TEST_CASE(tcs, kyuafile__load__other_directory);
593    ATF_ADD_TEST_CASE(tcs, kyuafile__load__build_directory);
594    ATF_ADD_TEST_CASE(tcs, kyuafile__load__absolute_paths_are_stable);
595    ATF_ADD_TEST_CASE(tcs, kyuafile__load__fs_calls_are_relative);
596    ATF_ADD_TEST_CASE(tcs, kyuafile__load__test_program_not_basename);
597    ATF_ADD_TEST_CASE(tcs, kyuafile__load__lua_error);
598    ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__not_called);
599    ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__deprecated_format);
600    ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__twice);
601    ATF_ADD_TEST_CASE(tcs, kyuafile__load__syntax__bad_version);
602    ATF_ADD_TEST_CASE(tcs, kyuafile__load__test_suite__missing);
603    ATF_ADD_TEST_CASE(tcs, kyuafile__load__test_suite__twice);
604    ATF_ADD_TEST_CASE(tcs, kyuafile__load__missing_file);
605    ATF_ADD_TEST_CASE(tcs, kyuafile__load__missing_test_program);
606}
607