Example #1
0
/// Converts a test program name into a class-like name.
///
/// \param test_program Test program from which to extract the name.
///
/// \return A class-like representation of the test program's identifier.
std::string
drivers::junit_classname(const model::test_program& test_program)
{
    std::string classname = test_program.relative_path().str();
    std::replace(classname.begin(), classname.end(), '/', '.');
    return classname;
}
Example #2
0
/// Executes a test program's list operation.
///
/// This method is intended to be called within a subprocess and is expected
/// to terminate execution either by exec(2)ing the test program or by
/// exiting with a failure.
///
/// \param test_program The test program to execute.
/// \param vars User-provided variables to pass to the test program.
void
engine::atf_interface::exec_list(const model::test_program& test_program,
                                 const config::properties_map& vars) const
{
    utils::setenv("__RUNNING_INSIDE_ATF_RUN", "internal-yes-value");

    process::args_vector args;
    for (config::properties_map::const_iterator iter = vars.begin();
         iter != vars.end(); ++iter) {
        args.push_back(F("-v%s=%s") % (*iter).first % (*iter).second);
    }

    args.push_back("-l");
    try {
        process::exec_unsafe(test_program.absolute_path(), args);
    } catch (const process::system_error& e) {
        if (e.original_errno() == EACCES)
            ::_exit(exit_eacces);
        else if (e.original_errno() == ENOENT)
            ::_exit(exit_enoent);
        else if (e.original_errno() == ENOEXEC)
            ::_exit(exit_enoexec);
        throw;
    }
}
Example #3
0
/// Puts a test program into the database.
///
/// \pre The test program has not been put yet.
/// \post The test program is stored into the database with a new identifier.
///
/// \param test_program The test program to put.
///
/// \return The identifier of the inserted test program.
///
/// \throw error If there is any problem when talking to the database.
int64_t
store::write_transaction::put_test_program(
    const model::test_program& test_program)
{
    try {
        const int64_t metadata_id = put_metadata(
            _pimpl->_db, test_program.get_metadata());

        sqlite::statement stmt = _pimpl->_db.create_statement(
            "INSERT INTO test_programs (absolute_path, "
            "                           root, relative_path, test_suite_name, "
            "                           metadata_id, interface) "
            "VALUES (:absolute_path, :root, :relative_path, "
            "        :test_suite_name, :metadata_id, :interface)");
        stmt.bind(":absolute_path", test_program.absolute_path().str());
        // TODO(jmmv): The root is not necessarily absolute.  We need to ensure
        // that we can recover the absolute path of the test program.  Maybe we
        // need to change the test_program to always ensure root is absolute?
        stmt.bind(":root", test_program.root().str());
        stmt.bind(":relative_path", test_program.relative_path().str());
        stmt.bind(":test_suite_name", test_program.test_suite_name());
        stmt.bind(":metadata_id", metadata_id);
        stmt.bind(":interface", test_program.interface_name());
        stmt.step_without_results();
        return _pimpl->_db.last_insert_rowid();
    } catch (const sqlite::error& e) {
        throw error(e.what());
    }
}
Example #4
0
/// Executes a test cleanup routine of the test program.
///
/// This method is intended to be called within a subprocess and is expected
/// to terminate execution either by exec(2)ing the test program or by
/// exiting with a failure.
///
/// \param test_program The test program to execute.
/// \param test_case_name Name of the test case to invoke.
/// \param vars User-provided variables to pass to the test program.
/// \param unused_control_directory Directory where the interface may place
///     control files.
void
engine::atf_interface::exec_cleanup(
    const model::test_program& test_program,
    const std::string& test_case_name,
    const config::properties_map& vars,
    const fs::path& UTILS_UNUSED_PARAM(control_directory)) const
{
    utils::setenv("__RUNNING_INSIDE_ATF_RUN", "internal-yes-value");

    process::args_vector args;
    for (config::properties_map::const_iterator iter = vars.begin();
         iter != vars.end(); ++iter) {
        args.push_back(F("-v%s=%s") % (*iter).first % (*iter).second);
    }

    args.push_back(F("%s:cleanup") % test_case_name);
    process::exec(test_program.absolute_path(), args);
}
Example #5
0
/// Puts a test case into the database.
///
/// \pre The test case has not been put yet.
/// \post The test case is stored into the database with a new identifier.
///
/// \param test_program The program containing the test case to be stored.
/// \param test_case_name The name of the test case to put.
/// \param test_program_id The test program this test case belongs to.
///
/// \return The identifier of the inserted test case.
///
/// \throw error If there is any problem when talking to the database.
int64_t
store::write_transaction::put_test_case(const model::test_program& test_program,
                                        const std::string& test_case_name,
                                        const int64_t test_program_id)
{
    const model::test_case& test_case = test_program.find(test_case_name);

    try {
        const int64_t metadata_id = put_metadata(
            _pimpl->_db, test_case.get_raw_metadata());

        sqlite::statement stmt = _pimpl->_db.create_statement(
            "INSERT INTO test_cases (test_program_id, name, metadata_id) "
            "VALUES (:test_program_id, :name, :metadata_id)");
        stmt.bind(":test_program_id", test_program_id);
        stmt.bind(":name", test_case.name());
        stmt.bind(":metadata_id", metadata_id);
        stmt.step_without_results();
        return _pimpl->_db.last_insert_rowid();
    } catch (const sqlite::error& e) {
        throw error(e.what());
    }
}