serial_listener_tests.cc
Go to the documentation of this file.
00001 /* To run these tests you need to change the define below to the serial port 
00002  * with a loop back device attached.
00003  * 
00004  * Alternatively you could use an Arduino:
00005  * 
00006  *     void setup()
00007  *     {
00008  *       Serial.begin(115200);
00009  *     }
00010  *     
00011  *     void loop()
00012  *     {
00013  *       while (Serial.available() > 0) {
00014  *         Serial.write(Serial.read());
00015  *       }
00016  *     }
00017  * 
00018  */
00019 
00020 // #define SERIAL_PORT_NAME "/dev/tty.usbserial-A900cfJA"
00021 #define SERIAL_PORT_NAME "p0"
00022 
00023 #include "gtest/gtest.h"
00024 
00025 #include <boost/bind.hpp>
00026 
00027 // OMG this is so nasty...
00028 #define private public
00029 #define protected public
00030 
00031 #include "serial/utils/serial_listener.h"
00032 using namespace serial;
00033 using namespace serial::utils;
00034 
00035 static size_t global_count, global_listen_count;
00036 static bool matched;
00037 
00038 void filter_handler(std::string token) {
00039   global_listen_count++;
00040   std::cout << "filter_handler got: " << token << std::endl;
00041 }
00042 
00043 void default_handler(std::string line) {
00044   global_count++;
00045   std::cout << "default_handler got: " << line << std::endl;
00046 }
00047 
00048 namespace {
00049 
00050 void my_sleep(long milliseconds) {
00051   boost::this_thread::sleep(boost::posix_time::milliseconds(milliseconds));
00052 }
00053 
00054 class SerialListenerTests : public ::testing::Test {
00055 protected:
00056   virtual void SetUp() {
00057     port1 = new Serial("/dev/pty"SERIAL_PORT_NAME, 115200, 10);
00058     port2 = new Serial("/dev/tty"SERIAL_PORT_NAME, 115200, 250);
00059 
00060     listener.setDefaultHandler(default_handler);
00061     listener.startListening((*port1));
00062   }
00063 
00064   virtual void TearDown() {
00065     listener.stopListening();
00066     delete port1;
00067     delete port2;
00068   }
00069 
00070   SerialListener listener;
00071   Serial * port1;
00072   Serial * port2;
00073 
00074 };
00075 
00076 TEST_F(SerialListenerTests, handlesPartialMessage) {
00077   global_count = 0;
00078   std::string input_str = "?$1E\r$1E=Robo";
00079 
00080   std::cout << "writing: ?$1E<cr>$1E=Robo" << std::endl;
00081   port2->write(input_str);
00082   // Allow time for processing
00083   my_sleep(50);
00084 
00085   ASSERT_EQ(1, global_count);
00086 
00087   input_str = "?$1E\r$1E=Roboteq\r";
00088   std::cout << "writing: ?$1E<cr>$1E=Roboteq<cr>" << std::endl;
00089   port2->write(input_str);
00090   // Allow time for processing
00091   my_sleep(50);
00092 
00093   ASSERT_EQ(3, global_count);
00094 }
00095 
00096 TEST_F(SerialListenerTests, normalFilterWorks) {
00097   global_count = 0;
00098   global_listen_count = 0;
00099   std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
00100 
00101   // Setup filter
00102   FilterPtr filt_1 =
00103     listener.createFilter(SerialListener::startsWith("V="), filter_handler);
00104 
00105   std::cout << "writing: ?$1E<cr>$1E=Robo<cr>V=1334:1337<cr>T=123";
00106   std::cout << std::endl;
00107   port2->write(input_str);
00108   // Allow time for processing
00109   my_sleep(50);
00110 
00111   ASSERT_EQ(2, global_count);
00112   ASSERT_EQ(1, global_listen_count);
00113 }
00114 
00115 void run_blocking_filter(BlockingFilterPtr filt_1) {
00116   // Wait 100 ms for a match
00117   std::string temp = filt_1->wait(100);
00118   if (temp.empty()) {
00119     return;
00120   }
00121   std::cout << "blocking filter matched: " << temp << std::endl;
00122   global_listen_count++;
00123   matched = true;
00124 }
00125 
00126 TEST_F(SerialListenerTests, blockingFilterWorks) {
00127   global_count = 0;
00128   global_listen_count = 0;
00129   matched = false;
00130   std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
00131 
00132   // Setup blocking filter
00133   BlockingFilterPtr filt_1 =
00134     listener.createBlockingFilter(SerialListener::startsWith("$1E="));
00135 
00136   boost::thread t(boost::bind(run_blocking_filter, filt_1));
00137 
00138   std::cout << "writing: ?$1E<cr>$1E=Robo<cr>V=1334:1337<cr>T=123";
00139   std::cout << std::endl;
00140   port2->write(input_str);
00141   // Allow time for processing
00142   my_sleep(50);
00143 
00144   using boost::posix_time::milliseconds;
00145   ASSERT_TRUE(t.timed_join(milliseconds(10)));
00146   ASSERT_EQ(2, global_count);
00147   ASSERT_EQ(1, global_listen_count);
00148   ASSERT_TRUE(matched);
00149 }
00150 
00151 TEST_F(SerialListenerTests, blockingFilterTimesOut) {
00152   global_count = 0;
00153   global_listen_count = 0;
00154   matched = false;
00155   std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
00156 
00157   // Setup blocking filter
00158   BlockingFilterPtr filt_1 =
00159     listener.createBlockingFilter(SerialListener::startsWith("T="));
00160 
00161   boost::thread t(boost::bind(run_blocking_filter, filt_1));
00162 
00163   std::cout << "writing: ?$1E<cr>$1E=Robo<cr>V=1334:1337<cr>T=123";
00164   std::cout << std::endl;
00165   port2->write(input_str);
00166   // Allow time for processing
00167   my_sleep(50);
00168 
00169   using boost::posix_time::milliseconds;
00170   // First one should not be within timeout, should be false
00171   ASSERT_FALSE(t.timed_join(milliseconds(10)));
00172   // Second one should capture timeout and return true to join
00173   ASSERT_TRUE(t.timed_join(milliseconds(60)));
00174   ASSERT_EQ(3, global_count);
00175   ASSERT_EQ(0, global_listen_count);
00176   ASSERT_FALSE(matched);
00177 }
00178 
00179 void write_later(Serial *port, std::string input_str, long wait_for) {
00180   my_sleep(wait_for);
00181   port->write(input_str);
00182 }
00183 
00184 TEST_F(SerialListenerTests, bufferedFilterWorks) {
00185   global_count = 0;
00186   std::string input_str = "?$1E\r+\r$1E=Robo\rV=1334:1337\rT=123";
00187 
00188   // Setup buffered filter, buffer size 3
00189   BufferedFilterPtr filt_1 =
00190     listener.createBufferedFilter(SerialListener::exactly("+"), 3);
00191 
00192   // Write the string to the port 10 ms in the future
00193   boost::thread t(boost::bind(write_later, port2, input_str, 10));
00194 
00195   // This should be empty because of a timeout
00196   ASSERT_TRUE(filt_1->wait(2).empty());
00197   // Make sure wait works properly
00198   ASSERT_EQ("+", filt_1->wait(20));
00199   // This should be empty cause there was only one
00200   ASSERT_TRUE(filt_1->wait(2).empty());
00201   // The queue in the filter should be empty
00202   ASSERT_EQ(0, filt_1->queue.size());
00203   ASSERT_EQ(3, global_count);
00204   t.join();
00205 }
00206 
00207 TEST_F(SerialListenerTests, bufferedFilterQueueWorks) {
00208   global_count = 0;
00209   std::string input_str = "?$1E$\r+\r$1E=Robo$\rV=1334:1337$\rT=123$\r";
00210 
00211   // Setup buffered filter, buffer size 3
00212   BufferedFilterPtr filt_1 =
00213     listener.createBufferedFilter(SerialListener::endsWith("$"), 3);
00214 
00215   // write the string
00216   port2->write(input_str);
00217 
00218   my_sleep(20); // Let things process
00219   // There should have been four matches
00220   //   therefore the first one should the second match.
00221   ASSERT_EQ("$1E=Robo$", filt_1->wait(1));
00222   ASSERT_EQ("V=1334:1337$", filt_1->wait(1));
00223   ASSERT_EQ("T=123$", filt_1->wait(1));
00224   ASSERT_EQ(0, filt_1->queue.size());
00225 
00226   ASSERT_EQ(1, global_count);
00227 }
00228 
00229 }  // namespace
00230 
00231 int main(int argc, char **argv) {
00232   try {
00233     ::testing::InitGoogleTest(&argc, argv);
00234     return RUN_ALL_TESTS();
00235   } catch (std::exception &e) {
00236     std::cerr << "Unhandled Exception: " << e.what() << std::endl;
00237   }
00238   return 1;
00239 }


serial_utils
Author(s): William Woodall , John Harrison
autogenerated on Thu Jun 6 2019 19:02:26