taskthread_fd_test.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: S Roderick taskthread_fd_test.cpp
00003 
00004                         taskthread_fd_test.cpp -  description
00005                            -------------------
00006     copyright            : (C) 2012 S Roderick
00007     email                : kiwi.net@mac.com
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 
00019 #include "taskthread_test.hpp"
00020 
00021 #include <iostream>
00022 #include <errno.h>
00023 
00024 #include <TaskContext.hpp>
00025 #include <extras/FileDescriptorActivity.hpp>
00026 #include <os/MainThread.hpp>
00027 #include <Logger.hpp>
00028 #include <rtt-config.h>
00029 
00030 using namespace std;
00031 
00032 #include <boost/test/unit_test.hpp>
00033 #include <boost/test/floating_point_comparison.hpp>
00034 
00035 
00036 using namespace RTT;
00037 
00038 
00039 struct TestFileDescriptor
00040         : public TaskContext
00041 {
00042         TestFileDescriptor(std::string name) :
00043                         TaskContext(name, TaskContext::PreOperational),
00044                         countError(0),
00045                         countTimeout(0),
00046                         countRead(0),
00047                         countUpdate(0)
00048         {
00049                 fd[0] = fd[1] = -1;
00050         }
00051 
00052         virtual ~TestFileDescriptor()
00053         {
00054         }
00055 
00056         virtual bool configureHook()
00057         {
00058                 int rc = pipe(fd);
00059                 assert(0 == rc);
00060         (void)rc;       // avoid compiler warning
00061 
00062         extras::FileDescriptorActivity* fd_activity =
00063                         dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
00064         assert(0 != fd_activity);
00065 
00066                 fd_activity->watch(fd[0]);
00067         // set no timeout - leave that for test code
00068 
00069                 return true;
00070         }
00071 
00072         virtual bool startHook()
00073         {
00074                 countError              = 0;
00075                 countTimeout    = 0;
00076                 countRead               = 0;
00077                 countUpdate             = 0;
00078                 return true;
00079         }
00080 
00081         virtual void updateHook()
00082         {
00083                 extras::FileDescriptorActivity* fd_activity =
00084                         dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
00085                 assert(0 != fd_activity);
00086 
00087                 ++countUpdate;
00088                 if (fd_activity->hasError())
00089                 {
00090                         ++countError;
00091                 }
00092                 else if (fd_activity->hasTimeout())
00093                 {
00094                         ++countTimeout;
00095                 }
00096                 else
00097                 {
00098                         if (fd_activity->isUpdated(fd[0]))
00099                         {
00100                                 ++countRead;
00101                                 // remove pipe contents
00102                                 char ch;
00103                                 int rc = read(fd[0], &ch, sizeof(ch));
00104                                 if (0 >= rc)
00105                                 {
00106 //                                      std::cerr << "Failed read: rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00107                                 }
00108                         }
00109                 }
00110         }
00111 
00112         virtual void cleanupHook()
00113         {
00114                 if (-1 != fd[0]) close(fd[0]);
00115                 if (-1 != fd[1]) close(fd[1]);
00116                 fd[0] = fd[1] = -1;
00117         }
00118 
00119         int countError;
00120         int countTimeout;
00121         int countRead;
00122         int countUpdate;
00123         int fd[2];      // from pipe()
00124 };
00125 
00126 // Registers the fixture into the 'registry'
00127 BOOST_FIXTURE_TEST_SUITE( ActivitiesThreadTestSuite, ActivitiesThreadTest )
00128 
00129 BOOST_AUTO_TEST_CASE(testFileDescriptor )
00130 {
00131     FileDescriptorActivity mtask( 15 );
00132     BOOST_CHECK( mtask.isActive() == false );
00133     BOOST_CHECK( mtask.isRunning() == false );
00134     BOOST_CHECK( !mtask.thread()->isRunning() );
00135     BOOST_CHECK_EQUAL( 0.0, mtask.thread()->getPeriod() );
00136 
00137     // Adapt priority levels to OS.
00138     int bprio = 15, rtsched = ORO_SCHED_RT;
00139     os::CheckPriority( rtsched, bprio );
00140 
00141     BOOST_CHECK_EQUAL( bprio, mtask.thread()->getPriority() );
00142     BOOST_CHECK_EQUAL( rtsched, mtask.thread()->getScheduler() );
00143 
00144     FileDescriptorActivity m2task( 15 );
00145     BOOST_CHECK( mtask.thread() != m2task.thread() );
00146 
00147     // starting...
00148     BOOST_CHECK( mtask.start() == true );
00149     BOOST_CHECK( mtask.isRunning() == false );
00150     BOOST_CHECK( m2task.isRunning() == false );
00151     BOOST_CHECK( m2task.start() == true );
00152     BOOST_CHECK( m2task.isRunning() == false );
00153 
00154     usleep(1000000/4);
00155 
00156     // stopping...
00157     BOOST_CHECK( mtask.stop() == true );
00158     BOOST_CHECK( mtask.isRunning() == false );
00159     BOOST_CHECK( m2task.isRunning() == false );
00160     BOOST_CHECK( m2task.stop() == true );
00161     BOOST_CHECK( m2task.isRunning() == false );
00162 
00163     // Starting thread if thread not running
00164     BOOST_CHECK( mtask.thread()->stop() == false );
00165     BOOST_CHECK( mtask.thread()->isRunning() == false );
00166     BOOST_CHECK( mtask.start() );
00167     BOOST_CHECK( mtask.isRunning() == false );
00168     BOOST_CHECK( mtask.thread()->isRunning() == false);
00169 }
00170 
00171 BOOST_AUTO_TEST_CASE(testFileDescriptor_Write )
00172 {
00173         TestFileDescriptor              mcomp("Comp");
00174     mcomp.setActivity( new FileDescriptorActivity( 15 ) );
00175     FileDescriptorActivity* mtask = dynamic_cast<FileDescriptorActivity*>( mcomp.getActivity() );
00176         char                                    ch='a';
00177         int                                             rc;
00178 
00179     BOOST_CHECK( mtask->hasError() == false );
00180     BOOST_CHECK( mtask->hasTimeout() == false );
00181 
00182     BOOST_CHECK( mcomp.configure() == true );
00183     BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == true );
00184 
00185     BOOST_CHECK( mcomp.start() == true );
00186     BOOST_CHECK( mtask->hasError() == false );
00187     BOOST_CHECK( mtask->hasTimeout() == false );
00188 
00189         // no activity
00190     usleep(1000000/4);
00191     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00192     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00193     BOOST_CHECK_EQUAL( 0, mcomp.countRead );
00194     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00195 
00196         // write to fd
00197         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00198         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00199     BOOST_CHECK_EQUAL( 1, rc );
00200     usleep(1000000/10);
00201     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00202     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00203     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00204     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00205 
00206         ++ch;
00207         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00208         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00209     BOOST_CHECK_EQUAL( 1, rc );
00210     usleep(1000000/10);
00211     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00212     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00213     BOOST_CHECK_EQUAL( 2, mcomp.countRead );
00214     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00215 
00216         // unwatch
00217     BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == true );
00218         mtask->unwatch(mcomp.fd[0]);
00219     BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == false );
00220 
00221         ++ch;
00222         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00223         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00224     BOOST_CHECK_EQUAL( 1, rc );
00225     usleep(1000000/10);
00226     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00227     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00228     BOOST_CHECK_EQUAL( 2, mcomp.countRead );    // no change
00229     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00230 
00231 #if 0
00232         // close pipe => cause error
00233         (void)close(mcomp.fd[1]);
00234     usleep(1000000/100);
00235 
00236     BOOST_CHECK_EQUAL( 1, mcomp.countError );
00237     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00238     BOOST_CHECK_EQUAL( 2, mcomp.countRead );
00239     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00240 #endif
00241 
00242     // Note: normally not allowed once loaded in a TC:
00243     BOOST_CHECK( mtask->stop() == true );
00244 }
00245 
00246 BOOST_AUTO_TEST_CASE(testFileDescriptor_Timeout )
00247 {
00248         TestFileDescriptor              mcomp("Comp");
00249     mcomp.setActivity( new FileDescriptorActivity( 15 ) );
00250     FileDescriptorActivity* mtask = dynamic_cast<FileDescriptorActivity*>( mcomp.getActivity() );
00251         char                                    ch='a';
00252         int                                             rc;
00253         static const int                RATE = 10;
00254         static const int                timeout_ms = 1000 / RATE;
00255 
00256     BOOST_CHECK( mcomp.configure() == true );
00257         mtask->setTimeout( timeout_ms );
00258         BOOST_CHECK( timeout_ms == mtask->getTimeout() );
00259     BOOST_CHECK( mcomp.start() == true );
00260 
00261         // no activity
00262     usleep(1000000/4);
00263     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00264     BOOST_CHECK_CLOSE_FRACTION( 4., (double)mcomp.countTimeout, 2. );
00265     BOOST_CHECK_EQUAL( 0, mcomp.countRead );
00266     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00267 
00268         // write to fd
00269         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00270         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00271     BOOST_CHECK_EQUAL( 1, rc );
00272     usleep(1000000/RATE);       // ~1 timeout period
00273     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00274     BOOST_CHECK_CLOSE_FRACTION( 4. , (double)mcomp.countTimeout, 1. );
00275     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00276     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00277 
00278         // no activity
00279     usleep(1000000/3);
00280     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00281     BOOST_CHECK_CLOSE_FRACTION( 4. + 3., (double)mcomp.countTimeout, 2. );
00282     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00283     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00284 }
00285 
00286 BOOST_AUTO_TEST_SUITE_END()
00287 


rtt
Author(s): RTT Developers
autogenerated on Sat Jun 8 2019 18:46:33