// Copyright (c) 2005-2007 Hartmut.kaiser@gmail.com) // Copyright (c) 2005-2006 Andre Merzky (andre@merzky.net) // Copyright (c) 2005-2006 Chris Miceli (cmicel1@cct.lsu.edu) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #if !defined(SAGA_TEST_JOB_API_HPP) #define SAGA_TEST_JOB_API_HPP #include #include #include #include #include #include "../test_saga.hpp" #include "../macros.hpp" /////////////////////////////////////////////////////////////////////////////// namespace test_job { namespace api { struct equipment { saga::url test_helper; std::string host; std::string contact; std::vector arguments; std::string get_command_line() const { std::string result(test_helper.get_path()); typedef std::vector::const_iterator iterator; iterator end = arguments.end(); for (iterator it = arguments.begin(); it != arguments.end(); ++it) { result += " " + *it; } return result; } }; /////////////////////////////////////////////////////////////////////////// struct PlainSync {}; typedef boost::mpl::vector< // saga::task_base::Sync, // saga::task_base::Async, // saga::task_base::Task, PlainSync > apitypes; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// inline void wait_on_futures(boost::futures::future current) { current(); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// template struct call_test_exception { call_test_exception(equipment equipment) : equipment_(equipment) {} typedef int result_type; template int operator()(Tag) { saga::error err = (saga::error)E::value; SAGA_REQUIRE_THROW(TestFunctor::test(Tag(), E(), equipment_), err); if(err != (saga::error)E::value) { std::string message; message += "Test " + TestFunctor::name + " failed with exception " + saga::error_names[err] + " expecting " + saga::error_names[E::value] + " with threading "; if(boost::is_same::value) message += "enabled"; else message += "disabled"; message += " with api_type "; if(boost::is_same::value) message += "Sync"; else if(boost::is_same::value) message += "Async"; else if(boost::is_same::value) message += "Task"; else if(boost::is_same::value) message += "Normal"; BOOST_ERROR(message.c_str()); } return 0; } equipment equipment_; }; /////////////////////////////////////////////////////////////////////////// // call_test that is instantiated with the test to be run and // a generic error code including success template struct call_test; template struct call_test { call_test(equipment equipment, std::vector > &futures) : equipment_(equipment), futures_(futures){} template void operator()(Tag) { boost::futures::simple_future f( boost::bind(call_test_exception(equipment_), Tag())); futures_.push_back(f); } equipment equipment_; std::vector > &futures_; }; template struct call_test { call_test(equipment equipment) : equipment_(equipment) {} template void operator()(Tag) { boost::bind(call_test_exception(equipment_), Tag())(); } equipment equipment_; }; /////////////////////////////////////////////////////////////////////////// template struct api_test; template struct api_test { api_test(equipment equipment) : equipment_(equipment) {} // The error is from the list of error_codes defined in the test // structure the api_test is instantiated with template void operator()(Error) { std::vector > futures; boost::mpl::for_each( call_test( equipment_, futures)); std::for_each(futures.begin(), futures.end(), wait_on_futures); } equipment equipment_; }; template struct api_test { api_test(equipment equipment) : equipment_(equipment) {} // The error is from the list of error_codes defined in the test // structure the api_test is instantiated with template void operator()(Error) { boost::mpl::for_each( call_test( equipment_)); } equipment equipment_; }; // run_test gets instantiated with test to be run from test packages // passed from the package a utils for testing template struct run_test { static void execute(equipment equipment_) { // run tests in a non-futurized manner boost::mpl::for_each( api_test(equipment_)); // run tests in a futurized manner (highly parallel) boost::mpl::for_each( api_test(equipment_)); } }; } // api } // test_job #endif // !SAGA_TEST_JOB_API_HPP