libmoost
|
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()