Blame engine/scanner_test.cpp

Packit 209faa
// Copyright 2014 The Kyua Authors.
Packit 209faa
// All rights reserved.
Packit 209faa
//
Packit 209faa
// Redistribution and use in source and binary forms, with or without
Packit 209faa
// modification, are permitted provided that the following conditions are
Packit 209faa
// met:
Packit 209faa
//
Packit 209faa
// * Redistributions of source code must retain the above copyright
Packit 209faa
//   notice, this list of conditions and the following disclaimer.
Packit 209faa
// * Redistributions in binary form must reproduce the above copyright
Packit 209faa
//   notice, this list of conditions and the following disclaimer in the
Packit 209faa
//   documentation and/or other materials provided with the distribution.
Packit 209faa
// * Neither the name of Google Inc. nor the names of its contributors
Packit 209faa
//   may be used to endorse or promote products derived from this software
Packit 209faa
//   without specific prior written permission.
Packit 209faa
//
Packit 209faa
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 209faa
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 209faa
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 209faa
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 209faa
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 209faa
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 209faa
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 209faa
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 209faa
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 209faa
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 209faa
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 209faa
Packit 209faa
#include "engine/scanner.hpp"
Packit 209faa
Packit 209faa
#include <cstdarg>
Packit 209faa
#include <cstddef>
Packit 209faa
#include <typeinfo>
Packit 209faa
Packit 209faa
#include <atf-c++.hpp>
Packit 209faa
Packit 209faa
#include "engine/filters.hpp"
Packit 209faa
#include "model/metadata.hpp"
Packit 209faa
#include "model/test_case.hpp"
Packit 209faa
#include "model/test_program.hpp"
Packit 209faa
#include "utils/format/containers.ipp"
Packit 209faa
#include "utils/fs/path.hpp"
Packit 209faa
#include "utils/optional.ipp"
Packit 209faa
Packit 209faa
namespace fs = utils::fs;
Packit 209faa
Packit 209faa
using utils::optional;
Packit 209faa
Packit 209faa
Packit 209faa
namespace {
Packit 209faa
Packit 209faa
Packit 209faa
/// Test program that implements a mock test_cases() lazy call.
Packit 209faa
class mock_test_program : public model::test_program {
Packit 209faa
    /// Number of times test_cases has been called.
Packit 209faa
    mutable std::size_t _num_calls;
Packit 209faa
Packit 209faa
    /// Collection of test cases; lazily initialized.
Packit 209faa
    mutable model::test_cases_map _test_cases;
Packit 209faa
Packit 209faa
public:
Packit 209faa
    /// Constructs a new test program.
Packit 209faa
    ///
Packit 209faa
    /// \param binary_ The name of the test program binary relative to root_.
Packit 209faa
    mock_test_program(const fs::path& binary_) :
Packit 209faa
        test_program("unused-interface", binary_, fs::path("unused-root"),
Packit 209faa
                     "unused-suite", model::metadata_builder().build(),
Packit 209faa
                     model::test_cases_map()),
Packit 209faa
        _num_calls(0)
Packit 209faa
    {
Packit 209faa
    }
Packit 209faa
Packit 209faa
    /// Gets or loads the list of test cases from the test program.
Packit 209faa
    ///
Packit 209faa
    /// \return The list of test cases provided by the test program.
Packit 209faa
    const model::test_cases_map&
Packit 209faa
    test_cases(void) const
Packit 209faa
    {
Packit 209faa
        if (_num_calls == 0) {
Packit 209faa
            const model::metadata metadata = model::metadata_builder().build();
Packit 209faa
            const model::test_case tc1("one", metadata);
Packit 209faa
            const model::test_case tc2("two", metadata);
Packit 209faa
            _test_cases.insert(model::test_cases_map::value_type("one", tc1));
Packit 209faa
            _test_cases.insert(model::test_cases_map::value_type("two", tc2));
Packit 209faa
        }
Packit 209faa
        _num_calls++;
Packit 209faa
        return _test_cases;
Packit 209faa
    }
Packit 209faa
Packit 209faa
    /// Returns the number of times test_cases() has been called.
Packit 209faa
    ///
Packit 209faa
    /// \return A counter.
Packit 209faa
    std::size_t
Packit 209faa
    num_calls(void) const
Packit 209faa
    {
Packit 209faa
        return _num_calls;
Packit 209faa
    }
Packit 209faa
};
Packit 209faa
Packit 209faa
Packit 209faa
/// Syntactic sugar to instantiate a test program with various test cases.
Packit 209faa
///
Packit 209faa
/// The scanner only cares about the relative path of the test program object
Packit 209faa
/// and the names of the test cases.  This function helps in instantiating a
Packit 209faa
/// test program that has the minimum set of details only.
Packit 209faa
///
Packit 209faa
/// \param relative_path Relative path to the test program.
Packit 209faa
/// \param ... List of test case names to add to the test program.  Must be
Packit 209faa
///     NULL-terminated.
Packit 209faa
///
Packit 209faa
/// \return A constructed test program.
Packit 209faa
static model::test_program_ptr
Packit 209faa
new_test_program(const char* relative_path, ...)
Packit 209faa
{
Packit 209faa
    model::test_program_builder builder(
Packit 209faa
        "unused-interface", fs::path(relative_path), fs::path("unused-root"),
Packit 209faa
        "unused-suite");
Packit 209faa
Packit 209faa
    va_list ap;
Packit 209faa
    va_start(ap, relative_path);
Packit 209faa
    const char* test_case_name;
Packit 209faa
    while ((test_case_name = va_arg(ap, const char*)) != NULL) {
Packit 209faa
        builder.add_test_case(test_case_name);
Packit 209faa
    }
Packit 209faa
    va_end(ap);
Packit 209faa
Packit 209faa
    return builder.build_ptr();
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
/// Yields all test cases in the scanner for simplicity of testing.
Packit 209faa
///
Packit 209faa
/// In most of the tests below, we just care about the scanner returning the
Packit 209faa
/// full set of matching test cases, not the specific behavior of every single
Packit 209faa
/// yield() call.  This function just returns the whole set, which helps in
Packit 209faa
/// writing functional tests.
Packit 209faa
///
Packit 209faa
/// \param scanner The scanner on which to iterate.
Packit 209faa
///
Packit 209faa
/// \return The full collection of results yielded by the scanner.
Packit 209faa
static std::set< engine::scan_result >
Packit 209faa
yield_all(engine::scanner& scanner)
Packit 209faa
{
Packit 209faa
    std::set< engine::scan_result > results;
Packit 209faa
    while (!scanner.done()) {
Packit 209faa
        const optional< engine::scan_result > result = scanner.yield();
Packit 209faa
        ATF_REQUIRE(result);
Packit 209faa
        results.insert(result.get());
Packit 209faa
    }
Packit 209faa
    ATF_REQUIRE(!scanner.yield());
Packit 209faa
    ATF_REQUIRE(scanner.done());
Packit 209faa
    return results;
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
}  // anonymous namespace
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__no_tests);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__no_tests)
Packit 209faa
{
Packit 209faa
    const model::test_programs_vector test_programs;
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    ATF_REQUIRE(scanner.done());
Packit 209faa
    ATF_REQUIRE(!scanner.yield());
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__one_test_in_one_program);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__one_test_in_one_program)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program = new_test_program(
Packit 209faa
        "dir/program", "lone_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program);
Packit 209faa
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program, "lone_test"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__one_test_per_many_programs);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__one_test_per_many_programs)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1 = new_test_program(
Packit 209faa
        "dir/program1", "foo_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program2 = new_test_program(
Packit 209faa
        "program2", "bar_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program3 = new_test_program(
Packit 209faa
        "a/b/c/d/e/program3", "baz_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
    test_programs.push_back(test_program3);
Packit 209faa
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "foo_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program2, "bar_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program3, "baz_test"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__many_tests_in_one_program);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__many_tests_in_one_program)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program = new_test_program(
Packit 209faa
        "dir/program", "first_test", "second_test", "third_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program);
Packit 209faa
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program, "first_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program, "second_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program, "third_test"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__many_tests_per_many_programs);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__many_tests_per_many_programs)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1 = new_test_program(
Packit 209faa
        "dir/program1", "foo_test", "bar_test", "baz_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program2 = new_test_program(
Packit 209faa
        "program2", "lone_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program3 = new_test_program(
Packit 209faa
        "a/b/c/d/e/program3", "another_test", "last_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
    test_programs.push_back(test_program3);
Packit 209faa
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "foo_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "bar_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "baz_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program2, "lone_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program3, "another_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program3, "last_test"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__no_filters__verify_lazy_loads);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__no_filters__verify_lazy_loads)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1(new mock_test_program(
Packit 209faa
        fs::path("first")));
Packit 209faa
    const mock_test_program* mock_program1 =
Packit 209faa
        dynamic_cast< const mock_test_program* >(test_program1.get());
Packit 209faa
    const model::test_program_ptr test_program2(new mock_test_program(
Packit 209faa
        fs::path("second")));
Packit 209faa
    const mock_test_program* mock_program2 =
Packit 209faa
        dynamic_cast< const mock_test_program* >(test_program2.get());
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
Packit 209faa
    const std::set< engine::test_filter > filters;
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "one"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "two"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program2, "one"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program2, "two"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    std::set< engine::scan_result > results;
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
Packit 209faa
    // This abuses the internal implementation of the scanner by making
Packit 209faa
    // assumptions on the order of the results.
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program2->num_calls());
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program2->num_calls());
Packit 209faa
    ATF_REQUIRE(scanner.done());
Packit 209faa
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
Packit 209faa
    // Make sure we are still talking to the original objects.
Packit 209faa
    for (std::set< engine::scan_result >::const_iterator iter = results.begin();
Packit 209faa
         iter != results.end(); ++iter) {
Packit 209faa
        const mock_test_program* mock_program =
Packit 209faa
            dynamic_cast< const mock_test_program* >((*iter).first.get());
Packit 209faa
        ATF_REQUIRE_EQ(1, mock_program->num_calls());
Packit 209faa
    }
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__with_filters__no_tests);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__with_filters__no_tests)
Packit 209faa
{
Packit 209faa
    const model::test_programs_vector test_programs;
Packit 209faa
Packit 209faa
    std::set< engine::test_filter > filters;
Packit 209faa
    filters.insert(engine::test_filter(fs::path("foo"), "bar"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    ATF_REQUIRE(scanner.done());
Packit 209faa
    ATF_REQUIRE(!scanner.yield());
Packit 209faa
    ATF_REQUIRE_EQ(filters, scanner.unused_filters());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__with_filters__no_matches);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__with_filters__no_matches)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1 = new_test_program(
Packit 209faa
        "dir/program1", "foo_test", "bar_test", "baz_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program2 = new_test_program(
Packit 209faa
        "dir/program2", "bar_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program3 = new_test_program(
Packit 209faa
        "program3", "another_test", "last_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
    test_programs.push_back(test_program3);
Packit 209faa
Packit 209faa
    std::set< engine::test_filter > filters;
Packit 209faa
    filters.insert(engine::test_filter(fs::path("dir/program2"), "baz_test"));
Packit 209faa
    filters.insert(engine::test_filter(fs::path("program4"), "another_test"));
Packit 209faa
    filters.insert(engine::test_filter(fs::path("dir/program3"), ""));
Packit 209faa
Packit 209faa
    const std::set< engine::scan_result > exp_results;
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE_EQ(filters, scanner.unused_filters());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__with_filters__some_matches);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__with_filters__some_matches)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1 = new_test_program(
Packit 209faa
        "dir/program1", "foo_test", "bar_test", "baz_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program2 = new_test_program(
Packit 209faa
        "dir/program2", "bar_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program3 = new_test_program(
Packit 209faa
        "program3", "another_test", "last_test", NULL);
Packit 209faa
    const model::test_program_ptr test_program4 = new_test_program(
Packit 209faa
        "program4", "more_test", NULL);
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
    test_programs.push_back(test_program3);
Packit 209faa
    test_programs.push_back(test_program4);
Packit 209faa
Packit 209faa
    std::set< engine::test_filter > filters;
Packit 209faa
    filters.insert(engine::test_filter(fs::path("dir/program1"), "baz_test"));
Packit 209faa
    filters.insert(engine::test_filter(fs::path("dir/program2"), "foo_test"));
Packit 209faa
    filters.insert(engine::test_filter(fs::path("program3"), ""));
Packit 209faa
Packit 209faa
    std::set< engine::test_filter > exp_filters;
Packit 209faa
    exp_filters.insert(engine::test_filter(fs::path("dir/program2"),
Packit 209faa
                                           "foo_test"));
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "baz_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program3, "another_test"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program3, "last_test"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    const std::set< engine::scan_result > results = yield_all(scanner);
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
Packit 209faa
    ATF_REQUIRE_EQ(exp_filters, scanner.unused_filters());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_TEST_CASE_WITHOUT_HEAD(scanner__with_filters__verify_lazy_loads);
Packit 209faa
ATF_TEST_CASE_BODY(scanner__with_filters__verify_lazy_loads)
Packit 209faa
{
Packit 209faa
    const model::test_program_ptr test_program1(new mock_test_program(
Packit 209faa
        fs::path("first")));
Packit 209faa
    const mock_test_program* mock_program1 =
Packit 209faa
        dynamic_cast< const mock_test_program* >(test_program1.get());
Packit 209faa
    const model::test_program_ptr test_program2(new mock_test_program(
Packit 209faa
        fs::path("second")));
Packit 209faa
    const mock_test_program* mock_program2 =
Packit 209faa
        dynamic_cast< const mock_test_program* >(test_program2.get());
Packit 209faa
Packit 209faa
    model::test_programs_vector test_programs;
Packit 209faa
    test_programs.push_back(test_program1);
Packit 209faa
    test_programs.push_back(test_program2);
Packit 209faa
Packit 209faa
    std::set< engine::test_filter > filters;
Packit 209faa
    filters.insert(engine::test_filter(fs::path("first"), ""));
Packit 209faa
Packit 209faa
    std::set< engine::scan_result > exp_results;
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "one"));
Packit 209faa
    exp_results.insert(engine::scan_result(test_program1, "two"));
Packit 209faa
Packit 209faa
    engine::scanner scanner(test_programs, filters);
Packit 209faa
    std::set< engine::scan_result > results;
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
    results.insert(scanner.yield().get());
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
    ATF_REQUIRE(scanner.done());
Packit 209faa
Packit 209faa
    ATF_REQUIRE_EQ(exp_results, results);
Packit 209faa
    ATF_REQUIRE(scanner.unused_filters().empty());
Packit 209faa
Packit 209faa
    ATF_REQUIRE_EQ(1, mock_program1->num_calls());
Packit 209faa
    ATF_REQUIRE_EQ(0, mock_program2->num_calls());
Packit 209faa
}
Packit 209faa
Packit 209faa
Packit 209faa
ATF_INIT_TEST_CASES(tcs)
Packit 209faa
{
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__no_tests);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__one_test_in_one_program);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__one_test_per_many_programs);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__many_tests_in_one_program);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__many_tests_per_many_programs);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__no_filters__verify_lazy_loads);
Packit 209faa
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__with_filters__no_tests);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__with_filters__no_matches);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__with_filters__some_matches);
Packit 209faa
    ATF_ADD_TEST_CASE(tcs, scanner__with_filters__verify_lazy_loads);
Packit 209faa
}