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->isRunning() == false );
00187     BOOST_CHECK( mtask->hasError() == false );
00188     BOOST_CHECK( mtask->hasTimeout() == false );
00189 
00190         // no activity
00191     usleep(1000000/4);
00192     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00193     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00194     BOOST_CHECK_EQUAL( 0, mcomp.countRead );
00195     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00196 
00197         // write to fd
00198         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00199         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00200     BOOST_CHECK_EQUAL( 1, rc );
00201     usleep(1000000/10);
00202     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00203     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00204     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00205     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00206 
00207         ++ch;
00208         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00209         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00210     BOOST_CHECK_EQUAL( 1, rc );
00211     usleep(1000000/10);
00212     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00213     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00214     BOOST_CHECK_EQUAL( 2, mcomp.countRead );
00215     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00216 
00217         // unwatch
00218     BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == true );
00219         mtask->unwatch(mcomp.fd[0]);
00220     BOOST_CHECK( mtask->isWatched(mcomp.fd[0]) == false );
00221 
00222         ++ch;
00223         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00224         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00225     BOOST_CHECK_EQUAL( 1, rc );
00226     usleep(1000000/10);
00227     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00228     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00229     BOOST_CHECK_EQUAL( 2, mcomp.countRead );    // no change
00230     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00231 
00232 #if 0
00233         // close pipe => cause error
00234         (void)close(mcomp.fd[1]);
00235     usleep(1000000/100);
00236 
00237     BOOST_CHECK_EQUAL( 1, mcomp.countError );
00238     BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
00239     BOOST_CHECK_EQUAL( 2, mcomp.countRead );
00240     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00241 #endif
00242 
00243     // Note: normally not allowed once loaded in a TC:
00244     BOOST_CHECK( mtask->stop() == true );
00245 }
00246 
00247 BOOST_AUTO_TEST_CASE(testFileDescriptor_Timeout )
00248 {
00249         TestFileDescriptor              mcomp("Comp");
00250     mcomp.setActivity( new FileDescriptorActivity( 15 ) );
00251     FileDescriptorActivity* mtask = dynamic_cast<FileDescriptorActivity*>( mcomp.getActivity() );
00252         char                                    ch='a';
00253         int                                             rc;
00254         static const int                RATE = 10;
00255         static const int                timeout_ms = 1000 / RATE;
00256 
00257     BOOST_CHECK( mcomp.configure() == true );
00258         mtask->setTimeout( timeout_ms );
00259         BOOST_CHECK( timeout_ms == mtask->getTimeout() );
00260     BOOST_CHECK( mcomp.start() == true );
00261     BOOST_CHECK( mtask->isRunning() == false );
00262 
00263         // no activity
00264     usleep(1000000/4);
00265     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00266     BOOST_CHECK_CLOSE_FRACTION( 4., (double)mcomp.countTimeout, 2. );
00267     BOOST_CHECK_EQUAL( 0, mcomp.countRead );
00268     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00269 
00270         // write to fd
00271         rc = write(mcomp.fd[1], &ch, sizeof(ch));
00272         if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
00273     BOOST_CHECK_EQUAL( 1, rc );
00274     usleep(1000000/RATE);       // ~1 timeout period
00275     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00276     BOOST_CHECK_CLOSE_FRACTION( 4. , (double)mcomp.countTimeout, 1. );
00277     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00278     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00279 
00280         // no activity
00281     usleep(1000000/3);
00282     BOOST_CHECK_EQUAL( 0, mcomp.countError );
00283     BOOST_CHECK_CLOSE_FRACTION( 4. + 3., (double)mcomp.countTimeout, 2. );
00284     BOOST_CHECK_EQUAL( 1, mcomp.countRead );
00285     BOOST_CHECK_LE( 0, mcomp.countUpdate );
00286 }
00287 
00288 BOOST_AUTO_TEST_SUITE_END()
00289 


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:16:19