11590Srgrimes// Copyright 2013 The Kyua Authors.
21590Srgrimes// All rights reserved.
31590Srgrimes//
41590Srgrimes// Redistribution and use in source and binary forms, with or without
51590Srgrimes// modification, are permitted provided that the following conditions are
61590Srgrimes// met:
71590Srgrimes//
81590Srgrimes// * Redistributions of source code must retain the above copyright
91590Srgrimes//   notice, this list of conditions and the following disclaimer.
101590Srgrimes// * Redistributions in binary form must reproduce the above copyright
111590Srgrimes//   notice, this list of conditions and the following disclaimer in the
121590Srgrimes//   documentation and/or other materials provided with the distribution.
131590Srgrimes// * Neither the name of Google Inc. nor the names of its contributors
141590Srgrimes//   may be used to endorse or promote products derived from this software
151590Srgrimes//   without specific prior written permission.
161590Srgrimes//
171590Srgrimes// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181590Srgrimes// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191590Srgrimes// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201590Srgrimes// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211590Srgrimes// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221590Srgrimes// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231590Srgrimes// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241590Srgrimes// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251590Srgrimes// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261590Srgrimes// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
271590Srgrimes// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281590Srgrimes
291590Srgrimes#include <map>
3087687Smarkm
3187687Smarkm#include <atf-c++.hpp>
3287687Smarkm
3387687Smarkm#include "model/context.hpp"
341590Srgrimes#include "model/metadata.hpp"
3528855Scharnier#include "model/test_program.hpp"
361590Srgrimes#include "model/test_result.hpp"
371590Srgrimes#include "store/migrate.hpp"
3887687Smarkm#include "store/read_backend.hpp"
391590Srgrimes#include "store/read_transaction.hpp"
401590Srgrimes#include "store/write_backend.hpp"
4187687Smarkm#include "utils/datetime.hpp"
4228855Scharnier#include "utils/env.hpp"
431590Srgrimes#include "utils/format/macros.hpp"
441590Srgrimes#include "utils/fs/path.hpp"
4587687Smarkm#include "utils/logging/operations.hpp"
4628855Scharnier#include "utils/sqlite/database.hpp"
4728855Scharnier#include "utils/stream.hpp"
4828855Scharnier#include "utils/units.hpp"
4928855Scharnier
501590Srgrimesnamespace datetime = utils::datetime;
5128855Scharniernamespace fs = utils::fs;
521590Srgrimesnamespace logging = utils::logging;
5387687Smarkmnamespace sqlite = utils::sqlite;
541590Srgrimesnamespace units = utils::units;
551590Srgrimes
561590Srgrimes
571590Srgrimesnamespace {
581590Srgrimes
591590Srgrimes
601590Srgrimes/// Gets a data file from the tests directory.
611590Srgrimes///
621590Srgrimes/// We cannot use the srcdir property because the required files are not there
631590Srgrimes/// when building with an object directory.  In those cases, the data files
641590Srgrimes/// remainin the source directory while the resulting test program is in the
65227247Sed/// object directory, thus having the wrong value for its srcdir property.
661590Srgrimes///
67227247Sed/// \param name Basename of the test data file to query.
68227247Sed///
69227247Sed/// \return The actual path to the requested data file.
701590Srgrimesstatic fs::path
71227247Sedtestdata_file(const std::string& name)
72227247Sed{
73227247Sed    const fs::path testdatadir(utils::getenv_with_default(
741590Srgrimes        "KYUA_STORETESTDATADIR", KYUA_STORETESTDATADIR));
75227247Sed    return testdatadir / name;
7687687Smarkm}
77227247Sed
78227247Sed
79227247Sed/// Validates the contents of the action with identifier 1.
80227247Sed///
8128855Scharnier/// \param dbpath Path to the database in which to check the action contents.
82227247Sedstatic void
83227247Sedcheck_action_1(const fs::path& dbpath)
8487687Smarkm{
8592922Simp    store::read_backend backend = store::read_backend::open_ro(dbpath);
8687687Smarkm    store::read_transaction transaction = backend.start_read();
87227247Sed
88227247Sed    const fs::path root("/some/root");
89227247Sed    std::map< std::string, std::string > environment;
90227247Sed    const model::context context(root, environment);
91227247Sed
92227247Sed    ATF_REQUIRE_EQ(context, transaction.get_context());
93227247Sed
9487687Smarkm    store::results_iterator iter = transaction.get_results();
9528855Scharnier    ATF_REQUIRE(!iter);
96102944Sdwmalone}
971590Srgrimes
9828855Scharnier
99178973Skevlo/// Validates the contents of the action with identifier 2.
1001590Srgrimes///
10128855Scharnier/// \param dbpath Path to the database in which to check the action contents.
10228855Scharnierstatic void
10328855Scharniercheck_action_2(const fs::path& dbpath)
1041590Srgrimes{
10528855Scharnier    store::read_backend backend = store::read_backend::open_ro(dbpath);
1061590Srgrimes    store::read_transaction transaction = backend.start_read();
1071590Srgrimes
10828855Scharnier    const fs::path root("/test/suite/root");
1091590Srgrimes    std::map< std::string, std::string > environment;
1101590Srgrimes    environment["HOME"] = "/home/test";
11128855Scharnier    environment["PATH"] = "/bin:/usr/bin";
1121590Srgrimes    const model::context context(root, environment);
11328855Scharnier
11428855Scharnier    ATF_REQUIRE_EQ(context, transaction.get_context());
11528855Scharnier
11628855Scharnier    const model::test_program test_program_1 = model::test_program_builder(
11728855Scharnier        "plain", fs::path("foo_test"), fs::path("/test/suite/root"),
1181590Srgrimes        "suite-name")
1191590Srgrimes        .add_test_case("main")
12028855Scharnier        .build();
1211590Srgrimes    const model::test_result result_1(model::test_result_passed);
122178973Skevlo
123178973Skevlo    const model::test_program test_program_2 = model::test_program_builder(
124178973Skevlo        "plain", fs::path("subdir/another_test"), fs::path("/test/suite/root"),
125178973Skevlo        "subsuite-name")
126178973Skevlo        .add_test_case("main",
127178973Skevlo                       model::metadata_builder()
128178973Skevlo                       .set_timeout(datetime::delta(10, 0))
129178973Skevlo                       .build())
130178973Skevlo        .set_metadata(model::metadata_builder()
131178973Skevlo                      .set_timeout(datetime::delta(10, 0))
1321590Srgrimes                      .build())
1331590Srgrimes        .build();
13428855Scharnier    const model::test_result result_2(model::test_result_failed,
1351590Srgrimes                                      "Exited with code 1");
13628855Scharnier
1371590Srgrimes    const model::test_program test_program_3 = model::test_program_builder(
1381590Srgrimes        "plain", fs::path("subdir/bar_test"), fs::path("/test/suite/root"),
1391590Srgrimes        "subsuite-name")
1401590Srgrimes        .add_test_case("main")
1411590Srgrimes        .build();
1421590Srgrimes    const model::test_result result_3(model::test_result_broken,
1431590Srgrimes                                      "Received signal 1");
1441590Srgrimes
1451590Srgrimes    const model::test_program test_program_4 = model::test_program_builder(
1461590Srgrimes        "plain", fs::path("top_test"), fs::path("/test/suite/root"),
1471590Srgrimes        "suite-name")
1481590Srgrimes        .add_test_case("main")
1491590Srgrimes        .build();
1501590Srgrimes    const model::test_result result_4(model::test_result_expected_failure,
15128855Scharnier                                      "Known bug");
152102944Sdwmalone
15328855Scharnier    const model::test_program test_program_5 = model::test_program_builder(
154146467Sru        "plain", fs::path("last_test"), fs::path("/test/suite/root"),
15528855Scharnier        "suite-name")
15628855Scharnier        .add_test_case("main")
15728855Scharnier        .build();
158227247Sed    const model::test_result result_5(model::test_result_skipped,
1591590Srgrimes                                      "Does not apply");
160227247Sed
161102944Sdwmalone    store::results_iterator iter = transaction.get_results();
1621590Srgrimes    ATF_REQUIRE(iter);
1631590Srgrimes    ATF_REQUIRE_EQ(test_program_1, *iter.test_program());
16487687Smarkm    ATF_REQUIRE_EQ("main", iter.test_case_name());
16587687Smarkm    ATF_REQUIRE_EQ(result_1, iter.result());
1661590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
1671590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
1681590Srgrimes    ATF_REQUIRE_EQ(1357643611000000LL, iter.start_time().to_microseconds());
1691590Srgrimes    ATF_REQUIRE_EQ(1357643621000500LL, iter.end_time().to_microseconds());
1701590Srgrimes
17128855Scharnier    ++iter;
17228855Scharnier    ATF_REQUIRE(iter);
1731590Srgrimes    ATF_REQUIRE_EQ(test_program_5, *iter.test_program());
1741590Srgrimes    ATF_REQUIRE_EQ("main", iter.test_case_name());
1751590Srgrimes    ATF_REQUIRE_EQ(result_5, iter.result());
1761590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
1771590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
1781590Srgrimes    ATF_REQUIRE_EQ(1357643632000000LL, iter.start_time().to_microseconds());
1791590Srgrimes    ATF_REQUIRE_EQ(1357643638000000LL, iter.end_time().to_microseconds());
1801590Srgrimes
1811590Srgrimes    ++iter;
18228855Scharnier    ATF_REQUIRE(iter);
1838874Srgrimes    ATF_REQUIRE_EQ(test_program_2, *iter.test_program());
1841590Srgrimes    ATF_REQUIRE_EQ("main", iter.test_case_name());
1851590Srgrimes    ATF_REQUIRE_EQ(result_2, iter.result());
1861590Srgrimes    ATF_REQUIRE_EQ("Test stdout", iter.stdout_contents());
1871590Srgrimes    ATF_REQUIRE_EQ("Test stderr", iter.stderr_contents());
1881590Srgrimes    ATF_REQUIRE_EQ(1357643622001200LL, iter.start_time().to_microseconds());
1891590Srgrimes    ATF_REQUIRE_EQ(1357643622900021LL, iter.end_time().to_microseconds());
1901590Srgrimes
1911590Srgrimes    ++iter;
1921590Srgrimes    ATF_REQUIRE(iter);
1931590Srgrimes    ATF_REQUIRE_EQ(test_program_3, *iter.test_program());
1941590Srgrimes    ATF_REQUIRE_EQ("main", iter.test_case_name());
1951590Srgrimes    ATF_REQUIRE_EQ(result_3, iter.result());
1961590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
1971590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
1981590Srgrimes    ATF_REQUIRE_EQ(1357643623500000LL, iter.start_time().to_microseconds());
1991590Srgrimes    ATF_REQUIRE_EQ(1357643630981932LL, iter.end_time().to_microseconds());
2001590Srgrimes
2011590Srgrimes    ++iter;
2021590Srgrimes    ATF_REQUIRE(iter);
2031590Srgrimes    ATF_REQUIRE_EQ(test_program_4, *iter.test_program());
2041590Srgrimes    ATF_REQUIRE_EQ("main", iter.test_case_name());
2051590Srgrimes    ATF_REQUIRE_EQ(result_4, iter.result());
2061590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
2071590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
2081590Srgrimes    ATF_REQUIRE_EQ(1357643631000000LL, iter.start_time().to_microseconds());
2091590Srgrimes    ATF_REQUIRE_EQ(1357643631020000LL, iter.end_time().to_microseconds());
2101590Srgrimes
2111590Srgrimes    ++iter;
2121590Srgrimes    ATF_REQUIRE(!iter);
2131590Srgrimes}
2141590Srgrimes
2151590Srgrimes
2168874Srgrimes/// Validates the contents of the action with identifier 3.
2171590Srgrimes///
2181590Srgrimes/// \param dbpath Path to the database in which to check the action contents.
2191590Srgrimesstatic void
2201590Srgrimescheck_action_3(const fs::path& dbpath)
2211590Srgrimes{
2221590Srgrimes    store::read_backend backend = store::read_backend::open_ro(dbpath);
2231590Srgrimes    store::read_transaction transaction = backend.start_read();
2241590Srgrimes
22587687Smarkm    const fs::path root("/usr/tests");
2261590Srgrimes    std::map< std::string, std::string > environment;
2271590Srgrimes    environment["PATH"] = "/bin:/usr/bin";
228227247Sed    const model::context context(root, environment);
229102944Sdwmalone
2301590Srgrimes    ATF_REQUIRE_EQ(context, transaction.get_context());
23187687Smarkm
23287687Smarkm    const model::test_program test_program_6 = model::test_program_builder(
2331590Srgrimes        "atf", fs::path("complex_test"), fs::path("/usr/tests"),
23487687Smarkm        "suite-name")
23587687Smarkm        .add_test_case("this_passes")
23687687Smarkm        .add_test_case("this_fails",
2371590Srgrimes                       model::metadata_builder()
23828855Scharnier                       .set_description("Test description")
239106296Stjr                       .set_has_cleanup(true)
240106296Stjr                       .set_required_memory(units::bytes(128))
2411590Srgrimes                       .set_required_user("root")
2421590Srgrimes                       .build())
2431590Srgrimes        .add_test_case("this_skips",
2441590Srgrimes                       model::metadata_builder()
2451590Srgrimes                       .add_allowed_architecture("powerpc")
2461590Srgrimes                       .add_allowed_architecture("x86_64")
2471590Srgrimes                       .add_allowed_platform("amd64")
2481590Srgrimes                       .add_allowed_platform("macppc")
2491590Srgrimes                       .add_required_config("X-foo")
2501590Srgrimes                       .add_required_config("unprivileged_user")
2511590Srgrimes                       .add_required_file(fs::path("/the/data/file"))
2528874Srgrimes                       .add_required_program(fs::path("/bin/ls"))
2531590Srgrimes                       .add_required_program(fs::path("cp"))
25428855Scharnier                       .set_description("Test explanation")
25528855Scharnier                       .set_has_cleanup(true)
2561590Srgrimes                       .set_required_memory(units::bytes(512))
2571590Srgrimes                       .set_required_user("unprivileged")
2581590Srgrimes                       .set_timeout(datetime::delta(600, 0))
2591590Srgrimes                       .build())
2601590Srgrimes        .build();
26187687Smarkm    const model::test_result result_6(model::test_result_passed);
2621590Srgrimes    const model::test_result result_7(model::test_result_failed,
2631590Srgrimes                                      "Some reason");
2641590Srgrimes    const model::test_result result_8(model::test_result_skipped,
2651590Srgrimes                                      "Another reason");
2661590Srgrimes
2671590Srgrimes    const model::test_program test_program_7 = model::test_program_builder(
2681590Srgrimes        "atf", fs::path("simple_test"), fs::path("/usr/tests"),
2691590Srgrimes        "subsuite-name")
2701590Srgrimes        .add_test_case("main",
2711590Srgrimes                       model::metadata_builder()
2721590Srgrimes                       .set_description("More text")
2731590Srgrimes                       .set_has_cleanup(true)
2741590Srgrimes                       .set_required_memory(units::bytes(128))
2751590Srgrimes                       .set_required_user("unprivileged")
2761590Srgrimes                       .build())
2771590Srgrimes        .build();
2781590Srgrimes    const model::test_result result_9(model::test_result_failed,
2791590Srgrimes                                      "Exited with code 1");
2801590Srgrimes
2811590Srgrimes    store::results_iterator iter = transaction.get_results();
2821590Srgrimes    ATF_REQUIRE(iter);
2831590Srgrimes    ATF_REQUIRE_EQ(test_program_6, *iter.test_program());
2841590Srgrimes    ATF_REQUIRE_EQ("this_fails", iter.test_case_name());
2851590Srgrimes    ATF_REQUIRE_EQ(result_7, iter.result());
2861590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
2871590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
288227247Sed    ATF_REQUIRE_EQ(1357648719000000LL, iter.start_time().to_microseconds());
289102944Sdwmalone    ATF_REQUIRE_EQ(1357648720897182LL, iter.end_time().to_microseconds());
2901590Srgrimes
2911590Srgrimes    ++iter;
2921590Srgrimes    ATF_REQUIRE(iter);
2931590Srgrimes    ATF_REQUIRE_EQ(test_program_6, *iter.test_program());
294227247Sed    ATF_REQUIRE_EQ("this_passes", iter.test_case_name());
295102944Sdwmalone    ATF_REQUIRE_EQ(result_6, iter.result());
2961590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
2971590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
29887687Smarkm    ATF_REQUIRE_EQ(1357648712000000LL, iter.start_time().to_microseconds());
2991590Srgrimes    ATF_REQUIRE_EQ(1357648718000000LL, iter.end_time().to_microseconds());
3001590Srgrimes
3011590Srgrimes    ++iter;
3021590Srgrimes    ATF_REQUIRE(iter);
3031590Srgrimes    ATF_REQUIRE_EQ(test_program_6, *iter.test_program());
30428855Scharnier    ATF_REQUIRE_EQ("this_skips", iter.test_case_name());
3051590Srgrimes    ATF_REQUIRE_EQ(result_8, iter.result());
3061590Srgrimes    ATF_REQUIRE_EQ("Another stdout", iter.stdout_contents());
3071590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
3081590Srgrimes    ATF_REQUIRE_EQ(1357648729182013LL, iter.start_time().to_microseconds());
3091590Srgrimes    ATF_REQUIRE_EQ(1357648730000000LL, iter.end_time().to_microseconds());
3101590Srgrimes
311227247Sed    ++iter;
312102944Sdwmalone    ATF_REQUIRE(iter);
3131590Srgrimes    ATF_REQUIRE_EQ(test_program_7, *iter.test_program());
31487687Smarkm    ATF_REQUIRE_EQ("main", iter.test_case_name());
31587687Smarkm    ATF_REQUIRE_EQ(result_9, iter.result());
3161590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
3171590Srgrimes    ATF_REQUIRE_EQ("Another stderr", iter.stderr_contents());
3181590Srgrimes    ATF_REQUIRE_EQ(1357648740120000LL, iter.start_time().to_microseconds());
3191590Srgrimes    ATF_REQUIRE_EQ(1357648750081700LL, iter.end_time().to_microseconds());
32028855Scharnier
3211590Srgrimes    ++iter;
3221590Srgrimes    ATF_REQUIRE(!iter);
323227247Sed}
324102944Sdwmalone
3251590Srgrimes
3261590Srgrimes/// Validates the contents of the action with identifier 4.
3271590Srgrimes///
3281590Srgrimes/// \param dbpath Path to the database in which to check the action contents.
3291590Srgrimesstatic void
3301590Srgrimescheck_action_4(const fs::path& dbpath)
3311590Srgrimes{
3321590Srgrimes    store::read_backend backend = store::read_backend::open_ro(dbpath);
333227247Sed    store::read_transaction transaction = backend.start_read();
3341590Srgrimes
3351590Srgrimes    const fs::path root("/usr/tests");
3361590Srgrimes    std::map< std::string, std::string > environment;
3371590Srgrimes    environment["LANG"] = "C";
3381590Srgrimes    environment["PATH"] = "/bin:/usr/bin";
3391590Srgrimes    environment["TERM"] = "xterm";
340227247Sed    const model::context context(root, environment);
341102944Sdwmalone
3421590Srgrimes    ATF_REQUIRE_EQ(context, transaction.get_context());
3431590Srgrimes
34487687Smarkm    const model::test_program test_program_8 = model::test_program_builder(
3451590Srgrimes        "plain", fs::path("subdir/another_test"), fs::path("/usr/tests"),
3461590Srgrimes        "subsuite-name")
3471590Srgrimes        .add_test_case("main",
3481590Srgrimes                       model::metadata_builder()
3491590Srgrimes                       .set_timeout(datetime::delta(10, 0))
3501590Srgrimes                       .build())
3511590Srgrimes        .set_metadata(model::metadata_builder()
3521590Srgrimes                      .set_timeout(datetime::delta(10, 0))
35328855Scharnier                      .build())
35428855Scharnier        .build();
3551590Srgrimes    const model::test_result result_10(model::test_result_failed,
35628855Scharnier                                       "Exit failure");
35728855Scharnier
3581590Srgrimes    const model::test_program test_program_9 = model::test_program_builder(
3591590Srgrimes        "atf", fs::path("complex_test"), fs::path("/usr/tests"),
3601590Srgrimes        "suite-name")
3611590Srgrimes        .add_test_case("this_passes")
3621590Srgrimes        .add_test_case("this_fails",
3631590Srgrimes                       model::metadata_builder()
3641590Srgrimes                       .set_description("Test description")
365227247Sed                       .set_required_user("root")
366102944Sdwmalone                       .build())
3671590Srgrimes        .build();
36887687Smarkm    const model::test_result result_11(model::test_result_passed);
36987687Smarkm    const model::test_result result_12(model::test_result_failed,
37087687Smarkm                                       "Some reason");
37187687Smarkm
3721590Srgrimes    store::results_iterator iter = transaction.get_results();
3731590Srgrimes    ATF_REQUIRE(iter);
3741590Srgrimes    ATF_REQUIRE_EQ(test_program_9, *iter.test_program());
3751590Srgrimes    ATF_REQUIRE_EQ("this_fails", iter.test_case_name());
3761590Srgrimes    ATF_REQUIRE_EQ(result_12, iter.result());
3771590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
3781590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
3791590Srgrimes    ATF_REQUIRE_EQ(1357644397100000LL, iter.start_time().to_microseconds());
3801590Srgrimes    ATF_REQUIRE_EQ(1357644399005000LL, iter.end_time().to_microseconds());
3811590Srgrimes
3821590Srgrimes    ++iter;
383132182Stjr    ATF_REQUIRE(iter);
3841590Srgrimes    ATF_REQUIRE_EQ(test_program_9, *iter.test_program());
3851590Srgrimes    ATF_REQUIRE_EQ("this_passes", iter.test_case_name());
3861590Srgrimes    ATF_REQUIRE_EQ(result_11, iter.result());
3871590Srgrimes    ATF_REQUIRE(iter.stdout_contents().empty());
3881590Srgrimes    ATF_REQUIRE(iter.stderr_contents().empty());
3891590Srgrimes    ATF_REQUIRE_EQ(1357644396500000LL, iter.start_time().to_microseconds());
3901590Srgrimes    ATF_REQUIRE_EQ(1357644397000000LL, iter.end_time().to_microseconds());
39128855Scharnier
3921590Srgrimes    ++iter;
3931590Srgrimes    ATF_REQUIRE(iter);
3941590Srgrimes    ATF_REQUIRE_EQ(test_program_8, *iter.test_program());
39528855Scharnier    ATF_REQUIRE_EQ("main", iter.test_case_name());
3961590Srgrimes    ATF_REQUIRE_EQ(result_10, iter.result());
3971590Srgrimes    ATF_REQUIRE_EQ("Test stdout", iter.stdout_contents());
398227247Sed    ATF_REQUIRE_EQ("Test stderr", iter.stderr_contents());
399102944Sdwmalone    ATF_REQUIRE_EQ(1357644395000000LL, iter.start_time().to_microseconds());
4001590Srgrimes    ATF_REQUIRE_EQ(1357644396000000LL, iter.end_time().to_microseconds());
4011590Srgrimes
4021590Srgrimes    ++iter;
4031590Srgrimes    ATF_REQUIRE(!iter);
4041590Srgrimes}
4051590Srgrimes
4061590Srgrimes
4071590Srgrimes}  // anonymous namespace
4081590Srgrimes
4091590Srgrimes
4101590Srgrimes#define CURRENT_SCHEMA_TEST(dataset) \
411227247Sed    ATF_TEST_CASE(current_schema_ ##dataset); \
412102944Sdwmalone    ATF_TEST_CASE_HEAD(current_schema_ ##dataset) \
4131590Srgrimes    { \
41487687Smarkm        logging::set_inmemory(); \
4151590Srgrimes        const std::string required_files = \
41628855Scharnier            store::detail::schema_file().str() + " " + \
4171590Srgrimes            testdata_file("testdata_v3_" #dataset ".sql").str(); \
4181590Srgrimes        set_md_var("require.files", required_files); \
4191590Srgrimes    } \
4201590Srgrimes    ATF_TEST_CASE_BODY(current_schema_ ##dataset) \
4211590Srgrimes    { \
4221590Srgrimes        const fs::path testpath("test.db"); \
4231590Srgrimes        \
4241590Srgrimes        sqlite::database db = sqlite::database::open( \
4251590Srgrimes            testpath, sqlite::open_readwrite | sqlite::open_create); \
4261590Srgrimes        db.exec(utils::read_file(store::detail::schema_file())); \
427227247Sed        db.exec(utils::read_file(testdata_file(\
428102944Sdwmalone            "testdata_v3_" #dataset ".sql"))); \
4291590Srgrimes        db.close(); \
43087687Smarkm        \
43187687Smarkm        check_action_ ## dataset (testpath); \
4321590Srgrimes    }
4331590SrgrimesCURRENT_SCHEMA_TEST(1);
43428855ScharnierCURRENT_SCHEMA_TEST(2);
4351590SrgrimesCURRENT_SCHEMA_TEST(3);
4361590SrgrimesCURRENT_SCHEMA_TEST(4);
43728855Scharnier
4381590Srgrimes
4391590Srgrimes#define MIGRATE_SCHEMA_TEST(from_version) \
44087687Smarkm    ATF_TEST_CASE(migrate_schema__from_v ##from_version); \
4411590Srgrimes    ATF_TEST_CASE_HEAD(migrate_schema__from_v ##from_version) \
4421590Srgrimes    { \
4431590Srgrimes        logging::set_inmemory(); \
4441590Srgrimes        \
44528855Scharnier        const char* schema = "schema_v" #from_version ".sql"; \
44687687Smarkm        const char* testdata = "testdata_v" #from_version ".sql"; \
4471590Srgrimes        \
4481590Srgrimes        std::string required_files = \
4491590Srgrimes            testdata_file(schema).str() + " " + testdata_file(testdata).str(); \
4501590Srgrimes        for (int i = from_version; i < store::detail::current_schema_version; \
4511590Srgrimes             ++i) \
4521590Srgrimes            required_files += " " + store::detail::migration_file( \
4531590Srgrimes                i, i + 1).str(); \
4541590Srgrimes        \
4551590Srgrimes        set_md_var("require.files", required_files); \
4561590Srgrimes    } \
4571590Srgrimes    ATF_TEST_CASE_BODY(migrate_schema__from_v ##from_version) \
4581590Srgrimes    { \
4591590Srgrimes        const char* schema = "schema_v" #from_version ".sql"; \
4601590Srgrimes        const char* testdata = "testdata_v" #from_version ".sql"; \
4611590Srgrimes        \
462227247Sed        const fs::path testpath("test.db"); \
463102944Sdwmalone        \
4641590Srgrimes        sqlite::database db = sqlite::database::open( \
4651590Srgrimes            testpath, sqlite::open_readwrite | sqlite::open_create); \
4661590Srgrimes        db.exec(utils::read_file(testdata_file(schema))); \
4671590Srgrimes        db.exec(utils::read_file(testdata_file(testdata))); \
4681590Srgrimes        db.close(); \
4691590Srgrimes        \
4701590Srgrimes        store::migrate_schema(fs::path("test.db")); \
471227247Sed        \
472102944Sdwmalone        check_action_2(fs::path(".kyua/store/" \
4731590Srgrimes            "results.test_suite_root.20130108-111331-000000.db")); \
47487687Smarkm        check_action_3(fs::path(".kyua/store/" \
4751590Srgrimes            "results.usr_tests.20130108-123832-000000.db")); \
4761590Srgrimes        check_action_4(fs::path(".kyua/store/" \
4771590Srgrimes            "results.usr_tests.20130108-112635-000000.db")); \
4781590Srgrimes    }
4791590SrgrimesMIGRATE_SCHEMA_TEST(1);
4801590SrgrimesMIGRATE_SCHEMA_TEST(2);
481227247Sed
482102944Sdwmalone
4831590SrgrimesATF_INIT_TEST_CASES(tcs)
4841590Srgrimes{
4851590Srgrimes    ATF_ADD_TEST_CASE(tcs, current_schema_1);
4861590Srgrimes    ATF_ADD_TEST_CASE(tcs, current_schema_2);
4871590Srgrimes    ATF_ADD_TEST_CASE(tcs, current_schema_3);
4881590Srgrimes    ATF_ADD_TEST_CASE(tcs, current_schema_4);
4891590Srgrimes
4901590Srgrimes    ATF_ADD_TEST_CASE(tcs, migrate_schema__from_v1);
4911590Srgrimes    ATF_ADD_TEST_CASE(tcs, migrate_schema__from_v2);
492}
493