Go to the documentation of this file.00001 #include "gtest/gtest.h"
00002
00003 #include <string>
00004
00005 #include <boost/shared_ptr.hpp>
00006 #include <boost/thread.hpp>
00007 #include <boost/date_time/posix_time/posix_time.hpp>
00008
00009
00010 #define private public
00011 #define protected public
00012
00013 #include "serial/utils/concurrent_queue.h"
00014 using namespace serial::utils;
00015 using boost::posix_time::ptime;
00016 using boost::posix_time::time_duration;
00017 using boost::posix_time::microsec_clock;
00018 using boost::posix_time::milliseconds;
00019 using boost::thread;
00020 using boost::bind;
00021
00022 namespace {
00023
00024 void my_sleep(long milliseconds) {
00025 boost::this_thread::sleep(boost::posix_time::milliseconds(milliseconds));
00026 }
00027
00028 typedef boost::shared_ptr<std::string> TokenPtr;
00029
00030 class ConcurrentQueueTests : public ::testing::Test {
00031 protected:
00032 virtual void SetUp() {
00033
00034 }
00035
00036 virtual void TearDown() {
00037
00038 }
00039
00040 void push_later(TokenPtr &token, long delay) {
00041 my_sleep(delay);
00042 queue.push(token);
00043 }
00044
00045 ConcurrentQueue<TokenPtr> queue;
00046
00047 };
00048
00049 TEST_F(ConcurrentQueueTests, try_pop) {
00050 TokenPtr token_ptr;
00051 ASSERT_FALSE(queue.try_pop(token_ptr));
00052 ASSERT_TRUE(queue.empty());
00053 for(size_t i = 0; i < 10; ++i) {
00054 queue.push(TokenPtr(new std::string("Testing.")));
00055 }
00056 ASSERT_FALSE(queue.empty());
00057 ASSERT_TRUE(queue.try_pop(token_ptr));
00058 }
00059
00060 TEST_F(ConcurrentQueueTests, timed_wait_and_pop) {
00061 TokenPtr token_ptr;
00062 ptime start = microsec_clock::local_time();
00063 ASSERT_FALSE(queue.timed_wait_and_pop(token_ptr, 100));
00064 time_duration diff(microsec_clock::local_time() - start);
00065 ASSERT_GE(diff.total_milliseconds(), 100);
00066 ASSERT_TRUE(queue.empty());
00067
00068 queue.push(TokenPtr(new std::string("Testing.")));
00069 ASSERT_FALSE(queue.empty());
00070 start = microsec_clock::local_time();
00071 ASSERT_TRUE(queue.timed_wait_and_pop(token_ptr, 100));
00072 diff = microsec_clock::local_time() - start;
00073 ASSERT_LT(diff.total_milliseconds(), 100);
00074
00075 thread t(bind(&ConcurrentQueueTests::push_later, this,
00076 TokenPtr(new std::string("Testing.")), 30));
00077 start = microsec_clock::local_time();
00078 ASSERT_TRUE(queue.timed_wait_and_pop(token_ptr, 100));
00079 diff = microsec_clock::local_time() - start;
00080 ASSERT_LT(diff.total_milliseconds(), 100);
00081 ASSERT_GE(diff.total_milliseconds(), 30);
00082 ASSERT_TRUE(t.timed_join(milliseconds(100)));
00083 }
00084
00085 TEST_F(ConcurrentQueueTests, timed_pop_doesnt_block_push) {
00086 TokenPtr token_ptr;
00087 ptime start = microsec_clock::local_time();
00088 thread t(bind(&ConcurrentQueue<TokenPtr>::timed_wait_and_pop, &queue,
00089 token_ptr, 30));
00090 my_sleep(10);
00091 queue.push(TokenPtr(new std::string("Testing.")));
00092 time_duration diff(microsec_clock::local_time() - start);
00093 ASSERT_TRUE(t.timed_join(milliseconds(100)));
00094 ASSERT_LT(diff.total_milliseconds(), 30);
00095 ASSERT_TRUE(queue.empty());
00096 }
00097
00098 }
00099
00100 int main(int argc, char **argv) {
00101 try {
00102 ::testing::InitGoogleTest(&argc, argv);
00103 return RUN_ALL_TESTS();
00104 } catch (std::exception &e) {
00105 std::cerr << "Unhandled Exception: " << e.what() << std::endl;
00106 }
00107 return 1;
00108 }