Skip to content

Commit

Permalink
tests: Add tests for FileDescriptorActivity
Browse files Browse the repository at this point in the history
  • Loading branch information
snrkiwi committed Apr 4, 2014
1 parent 6cf8c90 commit e887898
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ IF (BUILD_TESTING)
COMPILE_DEFINITIONS "${COMPILE_DEFS}")
ADD_TEST( core-test ${RUNTIME_OUTPUT_DIRECTORY}/core-test )

ADD_EXECUTABLE( task-test test-runner.cpp tasks_test.cpp taskthread_test.cpp tasks_multiple_test.cpp )
ADD_EXECUTABLE( task-test test-runner.cpp tasks_test.cpp taskthread_test.cpp taskthread_fd_test.cpp tasks_multiple_test.cpp )
TARGET_LINK_LIBRARIES( task-test orocos-rtt-${OROCOS_TARGET}_dynamic ${TEST_LIBRARIES})
SET_TARGET_PROPERTIES( task-test PROPERTIES
COMPILE_FLAGS "${CMAKE_CXX_FLAGS_ADD}"
Expand Down
286 changes: 286 additions & 0 deletions tests/taskthread_fd_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
/***************************************************************************
tag: S Roderick taskthread_fd_test.cpp
taskthread_fd_test.cpp - description
-------------------
copyright : (C) 2012 S Roderick
email : [email protected]
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/


#include "taskthread_test.hpp"

#include <iostream>
#include <errno.h>

#include <TaskContext.hpp>
#include <extras/FileDescriptorActivity.hpp>
#include <os/MainThread.hpp>
#include <Logger.hpp>
#include <rtt-config.h>

using namespace std;

#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>


using namespace RTT;


struct TestFileDescriptor
: public TaskContext
{
TestFileDescriptor(std::string name) :
TaskContext(name, TaskContext::PreOperational),
countError(0),
countTimeout(0),
countRead(0),
countUpdate(0)
{
fd[0] = fd[1] = -1;
}

virtual ~TestFileDescriptor()
{
}

virtual bool configureHook()
{
int rc = pipe(fd);
assert(0 == rc);
(void)rc; // avoid compiler warning

extras::FileDescriptorActivity* fd_activity =
dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
assert(0 != fd_activity);

fd_activity->watch(fd[0]);
// set no timeout - leave that for test code

return true;
}

virtual bool startHook()
{
countError = 0;
countTimeout = 0;
countRead = 0;
countUpdate = 0;
return true;
}

virtual void updateHook()
{
extras::FileDescriptorActivity* fd_activity =
dynamic_cast<extras::FileDescriptorActivity*>(getActivity());
assert(0 != fd_activity);

++countUpdate;
if (fd_activity->hasError())
{
++countError;
}
else if (fd_activity->hasTimeout())
{
++countTimeout;
}
else
{
if (fd_activity->isUpdated(fd[0]))
{
++countRead;
// remove pipe contents
char ch;
int rc = read(fd[0], &ch, sizeof(ch));
if (0 >= rc)
{
// std::cerr << "Failed read: rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
}
}
}
}

virtual void cleanupHook()
{
if (-1 != fd[0]) close(fd[0]);
if (-1 != fd[1]) close(fd[1]);
fd[0] = fd[1] = -1;
}

int countError;
int countTimeout;
int countRead;
int countUpdate;
int fd[2]; // from pipe()
};

// Registers the fixture into the 'registry'
BOOST_FIXTURE_TEST_SUITE( ActivitiesThreadTestSuite, ActivitiesThreadTest )

BOOST_AUTO_TEST_CASE(testFileDescriptor )
{
FileDescriptorActivity mtask( 15 );
BOOST_CHECK( mtask.isActive() == false );
BOOST_CHECK( mtask.isRunning() == false );
BOOST_CHECK( !mtask.thread()->isRunning() );
BOOST_CHECK_EQUAL( 0.0, mtask.thread()->getPeriod() );

// Adapt priority levels to OS.
int bprio = 15, rtsched = ORO_SCHED_RT;
os::CheckPriority( rtsched, bprio );

BOOST_CHECK_EQUAL( bprio, mtask.thread()->getPriority() );
BOOST_CHECK_EQUAL( rtsched, mtask.thread()->getScheduler() );

FileDescriptorActivity m2task( 15 );
BOOST_CHECK( mtask.thread() != m2task.thread() );

// starting...
BOOST_CHECK( mtask.start() == true );
BOOST_CHECK( mtask.isRunning() == false );
BOOST_CHECK( m2task.isRunning() == false );
BOOST_CHECK( m2task.start() == true );
BOOST_CHECK( m2task.isRunning() == false );

usleep(1000000/4);

// stopping...
BOOST_CHECK( mtask.stop() == true );
BOOST_CHECK( mtask.isRunning() == false );
BOOST_CHECK( m2task.isRunning() == false );
BOOST_CHECK( m2task.stop() == true );
BOOST_CHECK( m2task.isRunning() == false );

// Starting thread if thread not running
BOOST_CHECK( mtask.thread()->stop() == false );
BOOST_CHECK( mtask.thread()->isRunning() == false );
BOOST_CHECK( mtask.start() );
BOOST_CHECK( mtask.isRunning() == false );
BOOST_CHECK( mtask.thread()->isRunning() == false);
}

BOOST_AUTO_TEST_CASE(testFileDescriptor_Write )
{
TestFileDescriptor mcomp("Comp");
FileDescriptorActivity mtask( 15, mcomp.engine());
char ch='a';
int rc;

BOOST_CHECK( mtask.hasError() == false );
BOOST_CHECK( mtask.hasTimeout() == false );

BOOST_CHECK( mcomp.configure() == true );
BOOST_CHECK( mtask.isWatched(mcomp.fd[0]) == true );

BOOST_CHECK( mtask.start() == true );
BOOST_CHECK( mtask.isRunning() == false );
BOOST_CHECK( mtask.hasError() == false );
BOOST_CHECK( mtask.hasTimeout() == false );

// no activity
usleep(1000000/4);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
BOOST_CHECK_EQUAL( 0, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );

// write to fd
rc = write(mcomp.fd[1], &ch, sizeof(ch));
if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
BOOST_CHECK_EQUAL( 1, rc );
usleep(1000000/10);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
BOOST_CHECK_EQUAL( 1, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );

++ch;
rc = write(mcomp.fd[1], &ch, sizeof(ch));
if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
BOOST_CHECK_EQUAL( 1, rc );
usleep(1000000/10);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
BOOST_CHECK_EQUAL( 2, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );

// unwatch
BOOST_CHECK( mtask.isWatched(mcomp.fd[0]) == true );
mtask.unwatch(mcomp.fd[0]);
BOOST_CHECK( mtask.isWatched(mcomp.fd[0]) == false );

++ch;
rc = write(mcomp.fd[1], &ch, sizeof(ch));
if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
BOOST_CHECK_EQUAL( 1, rc );
usleep(1000000/10);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
BOOST_CHECK_EQUAL( 2, mcomp.countRead ); // no change
BOOST_CHECK_LE( 0, mcomp.countUpdate );

#if 0
// close pipe => cause error
(void)close(mcomp.fd[1]);
usleep(1000000/100);

BOOST_CHECK_EQUAL( 1, mcomp.countError );
BOOST_CHECK_EQUAL( 0, mcomp.countTimeout );
BOOST_CHECK_EQUAL( 2, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );
#endif

BOOST_CHECK( mtask.stop() == true );
}

BOOST_AUTO_TEST_CASE(testFileDescriptor_Timeout )
{
TestFileDescriptor mcomp("Comp");
FileDescriptorActivity mtask( 15, mcomp.engine());
char ch='a';
int rc;
static const int RATE = 10;
static const int timeout_ms = 1000 / RATE;

BOOST_CHECK( mcomp.configure() == true );
mtask.setTimeout( timeout_ms );
BOOST_CHECK( timeout_ms == mtask.getTimeout() );
BOOST_CHECK( mtask.start() == true );
BOOST_CHECK( mtask.isRunning() == false );

// no activity
usleep(1000000/4);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_CLOSE_FRACTION( 4., (double)mcomp.countTimeout, 2. );
BOOST_CHECK_EQUAL( 0, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );

// write to fd
rc = write(mcomp.fd[1], &ch, sizeof(ch));
if (1 != rc) std::cerr << "rc=" << rc << " errno=" << errno << ":" << strerror(errno) << std::endl;
BOOST_CHECK_EQUAL( 1, rc );
usleep(1000000/RATE); // ~1 timeout period
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_CLOSE_FRACTION( 4. , (double)mcomp.countTimeout, 1. );
BOOST_CHECK_EQUAL( 1, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );

// no activity
usleep(1000000/3);
BOOST_CHECK_EQUAL( 0, mcomp.countError );
BOOST_CHECK_CLOSE_FRACTION( 4. + 3., (double)mcomp.countTimeout, 2. );
BOOST_CHECK_EQUAL( 1, mcomp.countRead );
BOOST_CHECK_LE( 0, mcomp.countUpdate );
}

BOOST_AUTO_TEST_SUITE_END()

2 changes: 2 additions & 0 deletions tests/taskthread_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class ActivitiesThreadTest
void testSequential();
void testScheduler();
void testAllocation();
void testFileDescriptor();
void testFileDescriptor_NoFD();
};

#endif

0 comments on commit e887898

Please sign in to comment.