libmoost
/home/mhx/git/github/libmoost/test/thread/threaded_job_scheduler.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00031 #include <set>
00032 #include <sstream>
00033 
00034 #include <boost/test/unit_test.hpp>
00035 
00036 #include "../../include/moost/testing/error_matcher.hpp"
00037 
00038 #include "../../include/moost/thread/threaded_job_scheduler.hpp"
00039 
00040 using namespace moost;
00041 
00042 typedef moost::testing::error_matcher matches;
00043 
00044 namespace {
00045 
00046 void add_to_set(boost::shared_ptr<thread::job_batch> jobs, boost::mutex& mx, std::set<int>& s, int x)
00047 {
00048    {
00049       boost::mutex::scoped_lock lock(mx);
00050       if (!s.insert(x).second)
00051       {
00052          std::ostringstream oss;
00053          oss << "duplicate element " << x;
00054          throw std::runtime_error(oss.str());
00055       }
00056    }
00057 
00058    if (x < 512)
00059    {
00060       for (int i = 0; i < 2; ++i)
00061       {
00062          jobs->add(boost::bind(&add_to_set, jobs, boost::ref(mx), boost::ref(s), 2*x + i));
00063       }
00064    }
00065 }
00066 
00067 void run_scheduler_tests(thread::threaded_job_scheduler& scheduler)
00068 {
00069    boost::shared_ptr<thread::threaded_job_batch> jobs(new thread::threaded_job_batch());
00070    boost::mutex mx;
00071    std::set<int> s, ref;
00072 
00073    for (int i = 1; i < 1024; ++i)
00074    {
00075       ref.insert(i);
00076    }
00077 
00078    // we need to check errors for elements that don't trigger
00079    // new jobs (i.e. >= 512)
00080    s.insert(631);
00081    s.insert(632);
00082 
00083    jobs->add(boost::bind(&add_to_set, jobs, boost::ref(mx), boost::ref(s), 1));
00084 
00085    scheduler.dispatch(jobs);
00086 
00087    BOOST_CHECK_EQUAL(jobs->count(), 1023);
00088    BOOST_CHECK_EQUAL_COLLECTIONS(s.begin(), s.end(), ref.begin(), ref.end());
00089 
00090    BOOST_CHECK_EQUAL(jobs->errors().size(), 2);
00091 
00092    std::set<std::string> err, ref_err;
00093    ref_err.insert("duplicate element 631");
00094    ref_err.insert("duplicate element 632");
00095    std::copy(jobs->errors().begin(), jobs->errors().end(), std::inserter(err, err.begin()));
00096    BOOST_CHECK_EQUAL_COLLECTIONS(err.begin(), err.end(), ref_err.begin(), ref_err.end());
00097 }
00098 
00099 }
00100 
00101 BOOST_AUTO_TEST_SUITE(threaded_job_scheduler_test)
00102 
00103 BOOST_AUTO_TEST_CASE(threaded_job_scheduler_test)
00104 {
00105    boost::shared_ptr<thread::threaded_job_scheduler> scheduler;
00106 
00107    BOOST_CHECK_EXCEPTION(scheduler.reset(new thread::threaded_job_scheduler(0)), std::runtime_error, matches("invalid number of worker threads"));
00108 
00109    for (size_t num_threads = 1; num_threads <= 8; ++num_threads)
00110    {
00111       scheduler.reset(new thread::threaded_job_scheduler(num_threads));
00112       run_scheduler_tests(*scheduler);
00113    }
00114 }
00115 
00116 BOOST_AUTO_TEST_SUITE_END()