// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief FdDispatcher.test unit tests */
+ \brief FdEvent.test unit tests */
-//#include "FdDispatcher.test.hh"
-//#include "FdDispatcher.test.ih"
+//#include "FdEvent.test.hh"
+//#include "FdEvent.test.ih"
// Custom includes
#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <iostream>
-#include "FdDispatcher.hh"
+#include "FdEvent.hh"
#include <boost/bind.hpp>
{
++calls;
event = ev;
- switch (event & senf::scheduler::FdDispatcher::EV_ALL) {
- case senf::scheduler::FdDispatcher::EV_READ:
+ switch (event & senf::scheduler::FdEvent::EV_ALL) {
+ case senf::scheduler::FdEvent::EV_READ:
size = recv(fd,buffer,1024,0);
break;
- case senf::scheduler::FdDispatcher::EV_PRIO:
+ case senf::scheduler::FdEvent::EV_PRIO:
size = recv(fd,buffer,1024,MSG_OOB);
break;
- case senf::scheduler::FdDispatcher::EV_WRITE:
+ case senf::scheduler::FdEvent::EV_WRITE:
size = write(fd,buffer,size);
break;
}
BOOST_AUTO_UNIT_TEST(fdDispatcher)
{
- senf::scheduler::FdDispatcher dispatcher (senf::scheduler::FdManager::instance(), senf::scheduler::FIFORunner::instance());
senf::scheduler::FdManager::instance().timeout(1000);
int pid (start_server());
error("connect");
BOOST_FAIL("connect");
}
+
+ {
+ senf::scheduler::FdEvent sockread ("testHandler", boost::bind(&callback, sock, _1),
+ sock, senf::scheduler::FdEvent::EV_READ);
+ senf::scheduler::FdEvent sockwrite ("testHandler", boost::bind(&callback, sock, _1),
+ sock, senf::scheduler::FdEvent::EV_WRITE, false);
+ event = 0;
+ SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
+ SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
+ BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_READ );
+ BOOST_CHECK_EQUAL( size, 4 );
+ buffer[size] = 0;
+ BOOST_CHECK_EQUAL( buffer, "READ" );
+
+ strcpy(buffer,"WRITE");
+ size=5;
+ SENF_CHECK_NO_THROW( sockwrite.enable() );
+ event = 0;
+ sleep(1);
+ SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
+ SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
+ BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_WRITE );
+
+ SENF_CHECK_NO_THROW( sockwrite.disable() );
+ event = 0;
+ sleep(1);
+ SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
+ SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
+ BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_HUP | senf::scheduler::FdEvent::EV_READ );
+ BOOST_CHECK_EQUAL( size, 2 );
+ buffer[size]=0;
+ BOOST_CHECK_EQUAL( buffer, "OK" );
+
+ BOOST_CHECK_EQUAL( calls, 3 );
+ SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
+ BOOST_CHECK_EQUAL( calls, 3 );
+
+ // Ensure, removing an already closed file-descriptor doesn't wreak havoc
+ close(sock);
+ }
- BOOST_CHECK( dispatcher.add("testHandler", sock, boost::bind(&callback, sock, _1),
- senf::scheduler::FdDispatcher::EV_READ) );
- event = 0;
- SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
- SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
- BOOST_CHECK_EQUAL( event, senf::scheduler::FdDispatcher::EV_READ );
- BOOST_CHECK_EQUAL( size, 4 );
- buffer[size] = 0;
- BOOST_CHECK_EQUAL( buffer, "READ" );
-
- strcpy(buffer,"WRITE");
- size=5;
- BOOST_CHECK( dispatcher.add("testHandler", sock, boost::bind(&callback, sock, _1),
- senf::scheduler::FdDispatcher::EV_WRITE) );
- event = 0;
- sleep(1);
- SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
- BOOST_CHECK_EQUAL( event, senf::scheduler::FdDispatcher::EV_WRITE );
+ BOOST_CHECK_EQUAL( calls, 3 );
- SENF_CHECK_NO_THROW( dispatcher.remove(sock, senf::scheduler::FdDispatcher::EV_WRITE) );
- event = 0;
- sleep(1);
- SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
- SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
- BOOST_CHECK_EQUAL( event, senf::scheduler::FdDispatcher::EV_HUP | senf::scheduler::FdDispatcher::EV_READ );
- BOOST_CHECK_EQUAL( size, 2 );
- buffer[size]=0;
- BOOST_CHECK_EQUAL( buffer, "OK" );
+ BOOST_CHECK (stop_server(pid));
+}
- BOOST_CHECK_EQUAL( calls, 3 );
- SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
- BOOST_CHECK_EQUAL( calls, 3 );
+namespace {
+
+ bool is_close(senf::ClockService::clock_type a, senf::ClockService::clock_type b)
+ {
+ return (a<b ? b-a : a-b) < senf::ClockService::milliseconds(100);
+ }
+
+ bool called (false);
+ void handler(int events)
+ {
+ called=true;
+ }
+}
+
+BOOST_AUTO_UNIT_TEST(fileDispatcher)
+{
+ senf::scheduler::detail::FileDispatcher::instance().timeout(500);
+
+ int fd (open("test.empty.file", O_RDWR|O_CREAT|O_TRUNC, 0600));
- // Ensure, removing an already closed file-descriptor doesn't wreak havoc
- close(sock);
- SENF_CHECK_NO_THROW( dispatcher.remove(sock) );
+ senf::ClockService::clock_type t (senf::ClockService::now());
+ try {
+ senf::scheduler::FdEvent fde ("testHandler", &handler,
+ fd, senf::scheduler::FdEvent::EV_READ);
+ SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
+ SENF_CHECK_NO_THROW( senf::scheduler::detail::FileDispatcher::instance().prepareRun() );
+ SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
+
+ BOOST_CHECK( called );
+ BOOST_CHECK_PREDICATE( is_close, (t)(senf::ClockService::now()) );
+ }
+ catch (std::exception const & ex) {
+ std::cerr << "Exception:\n" << ex.what() << "\n";
+ throw;
+ }
+ close(fd);
+ called = false;
+ t = senf::ClockService::now();
+ SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() );
+ SENF_CHECK_NO_THROW( senf::scheduler::detail::FileDispatcher::instance().prepareRun() );
SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() );
- BOOST_CHECK_EQUAL( calls, 3 );
+ BOOST_CHECK( ! called );
+ BOOST_CHECK_PREDICATE(
+ is_close, (t+senf::ClockService::milliseconds(500))(senf::ClockService::now()) );
- BOOST_CHECK (stop_server(pid));
+ unlink("test.empty.file");
+ senf::scheduler::detail::FileDispatcher::instance().timeout(-1);
}
///////////////////////////////cc.e////////////////////////////////////////