Thread: [complement-svn] SF.net SVN: complement: [1461] trunk/complement/explore/test/sockios
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2006-12-18 17:29:27
|
Revision: 1461 http://svn.sourceforge.net/complement/?rev=1461&view=rev Author: complement Date: 2006-12-18 09:29:25 -0800 (Mon, 18 Dec 2006) Log Message: ----------- sockios test suite added; try test sigpipe: broken line Modified Paths: -------------- trunk/complement/explore/test/sockios/Makefile.inc trunk/complement/explore/test/sockios/unit_test.cc Added Paths: ----------- trunk/complement/explore/test/sockios/sockios_test.cc trunk/complement/explore/test/sockios/sockios_test.h trunk/complement/explore/test/sockios/sockios_test_suite.cc trunk/complement/explore/test/sockios/sockios_test_suite.h Modified: trunk/complement/explore/test/sockios/Makefile.inc =================================================================== --- trunk/complement/explore/test/sockios/Makefile.inc 2006-12-18 17:27:35 UTC (rev 1460) +++ trunk/complement/explore/test/sockios/Makefile.inc 2006-12-18 17:29:25 UTC (rev 1461) @@ -1,5 +1,6 @@ -# -*- makefile -*- Time-stamp: <06/07/17 10:27:56 ptr> +# -*- makefile -*- Time-stamp: <06/12/18 16:43:21 ptr> PRGNAME = sockios_ut SRC_CC = unit_test.cc ConnectionProcessor.cc message.cc client.cc client-mw.cc \ - client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc read0_on_exec.cc + client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc read0_on_exec.cc \ + sockios_test.cc sockios_test_suite.cc Added: trunk/complement/explore/test/sockios/sockios_test.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.cc (rev 0) +++ trunk/complement/explore/test/sockios/sockios_test.cc 2006-12-18 17:29:25 UTC (rev 1461) @@ -0,0 +1,354 @@ +// -*- C++ -*- Time-stamp: <06/12/18 18:51:17 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005, 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include "sockios_test.h" +#include "message.h" + +#include <boost/test/unit_test.hpp> + +#include <sockios/sockstream> +#include <sockios/sockmgr.h> + +#include <list> + +#include <arpa/inet.h> + +#include <sys/shm.h> +#include <sys/wait.h> + +#include <signal.h> + +using namespace boost::unit_test_framework; +using namespace std; + +void sockios_test::hostname_test() +{ + unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 + +#ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( local, 0x0100007f ); +#endif + +#ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( local, 0x7f000001 ); +#endif + + BOOST_CHECK_EQUAL( std::hostname( local ), "localhost [127.0.0.1]" ); + +#ifdef __unix + char buff[1024]; + + gethostname( buff, 1024 ); + + BOOST_CHECK_EQUAL( std::hostname(), buff ); +#endif +} + +void sockios_test::service_test() +{ +#ifdef __unix + BOOST_CHECK( std::service( "ftp", "tcp" ) == 21 ); + BOOST_CHECK( std::service( 7, "udp" ) == "echo" ); +#else + BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); +#endif +} + +void sockios_test::hostaddr_test1() +{ +#ifdef __unix + in_addr addr = std::findhost( "localhost" ); + +# ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); +# endif + +# ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); +# endif + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +void sockios_test::hostaddr_test2() +{ +#ifdef __unix + list<in_addr> haddrs; + std::gethostaddr( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 + localhost_found = true; + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +void sockios_test::hostaddr_test3() +{ +#ifdef __unix + list<sockaddr> haddrs; + gethostaddr2( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + switch ( i->sa_family ) { + case PF_INET: + if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { + localhost_found = true; + } + break; + case PF_INET6: + if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { + localhost_found = true; + } + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +class Cnt +{ + public: + Cnt( sockstream& ) + { xmt::Locker lk(lock); ++cnt; } + + ~Cnt() + { xmt::Locker lk(lock); --cnt; } + + void connect( sockstream& ) + { } + + void close() + { } + + static xmt::Mutex lock; + static int cnt; +}; + +xmt::Mutex Cnt::lock; +int Cnt::cnt = 0; + +void sockios_test::ctor_dtor() +{ + // Check, that naumber of ctors of Cnt is the same as number of called dtors + // i.e. all created Cnt freed. + // due to async nature of communication, no way to check Cnt::cnt + // before server stop. + { + sockmgr_stream_MP<Cnt> srv( port ); + + { + sockstream s1( "localhost", port ); + + BOOST_CHECK( s1.good() ); + BOOST_CHECK( s1.is_open() ); + + s1 << "1234" << endl; + + BOOST_CHECK( s1.good() ); + BOOST_CHECK( s1.is_open() ); + } + + srv.close(); + srv.wait(); + + Cnt::lock.lock(); + BOOST_CHECK( Cnt::cnt == 0 ); + Cnt::lock.unlock(); + + } + { + sockmgr_stream_MP<Cnt> srv( port ); + + { + sockstream s1( "localhost", port ); + sockstream s2( "localhost", port ); + + BOOST_CHECK( s1.good() ); + BOOST_CHECK( s1.is_open() ); + BOOST_CHECK( s2.good() ); + BOOST_CHECK( s2.is_open() ); + + s1 << "1234" << endl; + s2 << "1234" << endl; + + BOOST_CHECK( s1.good() ); + BOOST_CHECK( s1.is_open() ); + BOOST_CHECK( s2.good() ); + BOOST_CHECK( s2.is_open() ); + } + + srv.close(); + srv.wait(); + + Cnt::lock.lock(); + BOOST_CHECK( Cnt::cnt == 0 ); + Cnt::lock.unlock(); + + } +} + +class loader +{ + public: + loader( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); +}; + +loader::loader( std::sockstream& ) +{ +} + +void loader::connect( std::sockstream& s ) +{ + char buf[1024]; + + s.read( buf, 1024 ); + s.write( buf, 1024 ); + s.flush(); +} + +void loader::close() +{ +} + +xmt::Thread::ret_code client_thr( void * ) +{ + xmt::Thread::ret_code ret; + + ret.iword = 0; + + sockstream s( "localhost", port ); + + char buf[1024]; + + fill( buf, buf + 1024, 0 ); + + while( true ) { + s.write( buf, 1024 ); + s.flush(); + + s.read( buf, 1024 ); + } + + return ret; +} + +void sigpipe_handler( int sig, siginfo_t *si, void * ) +{ + cerr << "-----------------------------------------------\n" + << "my pid: " << xmt::getpid() << ", ppid: " << xmt::getppid() << "\n" + << "signal: " << sig << ", number " << si->si_signo + << " errno " << si->si_errno + << " code " << si->si_code << endl; +} + +void sockios_test::sigpipe() +{ + shmid_ds ds; + int id = shmget( 5000, 1024, IPC_CREAT | IPC_EXCL | 0600 ); + BOOST_REQUIRE( id != -1 ); + // if ( id == -1 ) { + // cerr << "Error on shmget" << endl; + // } + BOOST_REQUIRE( shmctl( id, IPC_STAT, &ds ) != -1 ); + // if ( shmctl( id, IPC_STAT, &ds ) == -1 ) { + // cerr << "Error on shmctl" << endl; + // } + void *buf = shmat( id, 0, 0 ); + BOOST_REQUIRE( buf != reinterpret_cast<void *>(-1) ); + // if ( buf == reinterpret_cast<void *>(-1) ) { + // cerr << "Error on shmat" << endl; + // } + + xmt::__Condition<true>& fcnd = *new( buf ) xmt::__Condition<true>(); + fcnd.set( false ); + xmt::__Condition<true>& tcnd = *new( (char *)buf + sizeof(xmt::__Condition<true>) ) xmt::__Condition<true>(); + tcnd.set( false ); + + try { + xmt::fork(); + + fcnd.try_wait(); + + try { + /* + * This process will be killed, + * so I don't care about safe termination. + */ + xmt::Thread *th1 = new xmt::Thread( client_thr ); + for ( int i = 0; i < 10; ++i ) { + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + } + + xmt::delay( xmt::timespec(5,0) ); + + tcnd.set( true ); + + th1->join(); + + exit( 0 ); + } + catch ( ... ) { + } + } + catch ( xmt::fork_in_parent& child ) { + try { + xmt::signal_handler( SIGPIPE, &sigpipe_handler ); + sockmgr_stream_MP<loader> srv( port ); + + fcnd.set( true ); + + tcnd.try_wait(); + + kill( child.pid(), SIGTERM ); + + int stat; + waitpid( child.pid(), &stat, 0 ); + + srv.close(); + srv.wait(); + } + catch ( ... ) { + } + } + + (&fcnd)->~__Condition<true>(); + + shmdt( buf ); + shmctl( id, IPC_RMID, &ds ); +} Added: trunk/complement/explore/test/sockios/sockios_test.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.h (rev 0) +++ trunk/complement/explore/test/sockios/sockios_test.h 2006-12-18 17:29:25 UTC (rev 1461) @@ -0,0 +1,29 @@ +// -*- C++ -*- Time-stamp: <06/12/18 16:54:00 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005, 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#ifndef __sockios_test_h +#define __sockios_test_h + +struct sockios_test +{ + void hostname_test(); + void service_test(); + + void hostaddr_test1(); + void hostaddr_test2(); + void hostaddr_test3(); + + void ctor_dtor(); + + void sigpipe(); +}; + +#endif // __sockios_test_h Added: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc (rev 0) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2006-12-18 17:29:25 UTC (rev 1461) @@ -0,0 +1,43 @@ +// -*- C++ -*- Time-stamp: <06/12/18 17:10:02 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005, 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include "sockios_test_suite.h" +#include "sockios_test.h" + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test_framework; + + +sockios_test_suite::sockios_test_suite() : + test_suite( "sockios library test suite" ) +{ + boost::shared_ptr<sockios_test> instance( new sockios_test() ); + test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostname_test, instance ); + test_case *service_tc = BOOST_CLASS_TEST_CASE( &sockios_test::service_test, instance ); + + test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test1, instance ); + test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test2, instance ); + test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test3, instance ); + test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); + test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); + + // hostaddr2_tc->depends_on( hostaddr1_tc ); + + add( hostname_tc ); + add( service_tc ); + + add( hostaddr1_tc ); + add( hostaddr2_tc ); + add( hostaddr3_tc ); + add( ctor_dtor_tc ); + add( sigpipe_tc ); +} Added: trunk/complement/explore/test/sockios/sockios_test_suite.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.h (rev 0) +++ trunk/complement/explore/test/sockios/sockios_test_suite.h 2006-12-18 17:29:25 UTC (rev 1461) @@ -0,0 +1,23 @@ +// -*- C++ -*- Time-stamp: <06/12/18 16:52:16 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005, 2006 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#ifndef __sockios_test_suite_h +#define __sockios_test_suite_h + +#include <boost/test/unit_test.hpp> + +struct sockios_test_suite : + public boost::unit_test_framework::test_suite +{ + sockios_test_suite(); +}; + +#endif // __sockios_test_suite_h Modified: trunk/complement/explore/test/sockios/unit_test.cc =================================================================== --- trunk/complement/explore/test/sockios/unit_test.cc 2006-12-18 17:27:35 UTC (rev 1460) +++ trunk/complement/explore/test/sockios/unit_test.cc 2006-12-18 17:29:25 UTC (rev 1461) @@ -1,8 +1,8 @@ -// -*- C++ -*- Time-stamp: <06/11/28 10:07:49 ptr> +// -*- C++ -*- Time-stamp: <06/12/18 16:41:59 ptr> /* * - * Copyright (c) 2002, 2003, 2005 + * Copyright (c) 2002, 2003, 2005, 2006 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -13,6 +13,8 @@ using namespace boost::unit_test_framework; +#include "sockios_test_suite.h" + #include <iostream> #include <list> #include <mt/xmt.h> @@ -347,235 +349,7 @@ void test_read0(); void test_read0_srv(); -struct sockios_test -{ - void hostname_test(); - void service_test(); - void hostaddr_test1(); - void hostaddr_test2(); - void hostaddr_test3(); - - void ctor_dtor(); -}; - -void sockios_test::hostname_test() -{ - unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 - -#ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( local, 0x0100007f ); -#endif - -#ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( local, 0x7f000001 ); -#endif - - BOOST_CHECK_EQUAL( hostname( local ), "localhost [127.0.0.1]" ); - -#ifdef __unix - char buff[1024]; - - gethostname( buff, 1024 ); - - BOOST_CHECK_EQUAL( hostname(), buff ); -#endif -} - -void sockios_test::service_test() -{ -#ifdef __unix - BOOST_CHECK( service( "ftp", "tcp" ) == 21 ); - BOOST_CHECK( service( 7, "udp" ) == "echo" ); -#else - BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); -#endif -} - -void sockios_test::hostaddr_test1() -{ -#ifdef __unix - in_addr addr = findhost( "localhost" ); - -# ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); -# endif - -# ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); -# endif - -#else - BOOST_ERROR( "Not implemented" ); -#endif -} - -void sockios_test::hostaddr_test2() -{ -#ifdef __unix - list<in_addr> haddrs; - gethostaddr( "localhost", back_inserter(haddrs) ); - - bool localhost_found = false; - - for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 - localhost_found = true; - break; - } - } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif -} - -void sockios_test::hostaddr_test3() -{ -#ifdef __unix - list<sockaddr> haddrs; - gethostaddr2( "localhost", back_inserter(haddrs) ); - - bool localhost_found = false; - - for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - switch ( i->sa_family ) { - case PF_INET: - if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { - localhost_found = true; - } - break; - case PF_INET6: - if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { - localhost_found = true; - } - break; - } - } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif -} - -class Cnt -{ - public: - Cnt( sockstream& ) - { xmt::Locker lk(lock); ++cnt; } - - ~Cnt() - { xmt::Locker lk(lock); --cnt; } - - void connect( sockstream& ) - { } - - void close() - { } - - static xmt::Mutex lock; - static int cnt; -}; - -xmt::Mutex Cnt::lock; -int Cnt::cnt = 0; - -void sockios_test::ctor_dtor() -{ - // Check, that naumber of ctors of Cnt is the same as number of called dtors - // i.e. all created Cnt freed. - // due to async nature of communication, no way to check Cnt::cnt - // before server stop. - { - sockmgr_stream_MP<Cnt> srv( port ); - - { - sockstream s1( "localhost", port ); - - BOOST_CHECK( s1.good() ); - BOOST_CHECK( s1.is_open() ); - - s1 << "1234" << endl; - - BOOST_CHECK( s1.good() ); - BOOST_CHECK( s1.is_open() ); - } - - srv.close(); - srv.wait(); - - Cnt::lock.lock(); - BOOST_CHECK( Cnt::cnt == 0 ); - Cnt::lock.unlock(); - - } - { - sockmgr_stream_MP<Cnt> srv( port ); - - { - sockstream s1( "localhost", port ); - sockstream s2( "localhost", port ); - - BOOST_CHECK( s1.good() ); - BOOST_CHECK( s1.is_open() ); - BOOST_CHECK( s2.good() ); - BOOST_CHECK( s2.is_open() ); - - s1 << "1234" << endl; - s2 << "1234" << endl; - - BOOST_CHECK( s1.good() ); - BOOST_CHECK( s1.is_open() ); - BOOST_CHECK( s2.good() ); - BOOST_CHECK( s2.is_open() ); - } - - srv.close(); - srv.wait(); - - Cnt::lock.lock(); - BOOST_CHECK( Cnt::cnt == 0 ); - Cnt::lock.unlock(); - - } -} - -struct sockios_test_suite : - public test_suite -{ - sockios_test_suite(); -}; - -sockios_test_suite::sockios_test_suite() : - test_suite( "sockios library test suite" ) -{ - boost::shared_ptr<sockios_test> instance( new sockios_test() ); - test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostname_test, instance ); - test_case *service_tc = BOOST_CLASS_TEST_CASE( &sockios_test::service_test, instance ); - - test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test1, instance ); - test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test2, instance ); - test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test3, instance ); - test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); - - // hostaddr2_tc->depends_on( hostaddr1_tc ); - - add( hostname_tc ); - add( service_tc ); - - add( hostaddr1_tc ); - add( hostaddr2_tc ); - add( hostaddr3_tc ); - add( ctor_dtor_tc ); -} - test_suite *init_unit_test_suite( int argc, char **argv ) { test_suite *ts = BOOST_TEST_SUITE( "libsockios test" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-01-30 15:09:58
|
Revision: 1486 http://svn.sourceforge.net/complement/?rev=1486&view=rev Author: complement Date: 2007-01-30 07:09:56 -0800 (Tue, 30 Jan 2007) Log Message: ----------- use shared memory segment for sync (named objects, if required); remove delays and reduce amount of threads for some tests, to reduce test suite time; test for problem: two 'connect', but no 'close' on closed sockstream Modified Paths: -------------- trunk/complement/explore/test/sockios/client-wc.cc trunk/complement/explore/test/sockios/read0_on_exec.cc trunk/complement/explore/test/sockios/sockios_test.cc trunk/complement/explore/test/sockios/sockios_test.h trunk/complement/explore/test/sockios/sockios_test_suite.cc trunk/complement/explore/test/sockios/unit_test.cc Modified: trunk/complement/explore/test/sockios/client-wc.cc =================================================================== --- trunk/complement/explore/test/sockios/client-wc.cc 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/client-wc.cc 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/15 10:49:16 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 17:48:29 ptr> /* * Copyright (c) 2004, 2006 @@ -28,6 +28,7 @@ Suspicious processing with FreeBSD and OpenBSD servers. */ +static Condition cnd_close; class Srv // { @@ -42,10 +43,11 @@ { s << "hello" << endl; - xmt::delay( xmt::timespec( 1, 0 ) ); + // xmt::delay( xmt::timespec( 1, 0 ) ); s.close(); // ::shutdown( s.rdbuf()->fd(), 2 ); + cnd_close.set( true ); } void Srv::connect( std::sockstream& ) @@ -104,7 +106,7 @@ BOOST_CHECK( buf == "hello" ); pr_lock.unlock(); - xmt::delay( xmt::timespec( 5, 0 ) ); + // xmt::delay( xmt::timespec( 5, 0 ) ); // sock << 'a' << endl; @@ -113,6 +115,8 @@ and no other solution! (another solution is nonblock sockets or aio, but this is another story) */ + cnd_close.try_wait(); + char a; sock.read( &a, 1 ); @@ -132,6 +136,7 @@ void srv_close_connection_test() { Thread srv( server_proc ); + cnd_close.set( false ); Thread client( client_proc ); client.join(); Modified: trunk/complement/explore/test/sockios/read0_on_exec.cc =================================================================== --- trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <06/12/15 10:50:48 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 19:17:54 ptr> /* - * Copyright (c) 2006 + * Copyright (c) 2006, 2007 * Petr Ovtchenkov * * Licensed under the Academic Free License Version 3.0 @@ -21,7 +21,7 @@ #include <sys/types.h> #include <sys/wait.h> -#include <sys/shm.h> +#include <mt/shm.h> using namespace std; using namespace xmt; @@ -122,63 +122,61 @@ void test_read0() { - shmid_ds ds; - int id = shmget( 5000, 1024, IPC_CREAT | IPC_EXCL | 0600 ); - if ( id == -1 ) { - cerr << "Error on shmget" << endl; - } - if ( shmctl( id, IPC_STAT, &ds ) == -1 ) { - cerr << "Error on shmctl" << endl; - } - void *buf = shmat( id, 0, 0 ); - if ( buf == reinterpret_cast<void *>(-1) ) { - cerr << "Error on shmat" << endl; - } + const char fname[] = "/tmp/sockios_test.shm"; + try { + xmt::shm_alloc<0> seg; - Semaphore& sem = *new( buf ) Semaphore( 1, true ); + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); + // xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - try { - // cerr << "** 1" << endl; - // cndf.set( false ); + xmt::allocator_shm<xmt::__Condition<true>,0> shm; - xmt::fork(); // <---- key line - sem.wait(); // wait server for listen us - // cerr << "** 2" << endl; + xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + // nm.named( fcnd, 1 ); + fcnd.set( false ); - Condition cnd; - cnd.set( false ); + try { + xmt::fork(); // <---- key line + fcnd.try_wait(); // wait server for listen us - xmt::Thread thr( thread_entry, &cnd ); + Condition cnd; + cnd.set( false ); - cnd.try_wait(); // wait for read call + xmt::Thread thr( thread_entry, &cnd ); - delay( xmt::timespec(1,0) ); + cnd.try_wait(); // wait for read call - // cerr << "system" << endl; - system( "echo > /dev/null" ); // <------ key line - // cerr << "after system" << endl; + delay( xmt::timespec(1,0) ); - thr.join(); - // cerr << "exit child" << endl; - exit( 0 ); - } - catch ( xmt::fork_in_parent& child ) { - // cerr << "** 3" << endl; - sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server + // cerr << "system" << endl; + system( "echo > /dev/null" ); // <------ key line + // cerr << "after system" << endl; - // cndf.set( true ); // server wait, I hope - sem.post(); - int stat; - // cerr << "wait " << child.pid() << endl; - waitpid( child.pid(), &stat, 0 ); - // cerr << "close all" << endl; - srv.close(); - srv.wait(); - } - (&sem)->~Semaphore(); + thr.join(); + // cerr << "exit child" << endl; + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + // cerr << "** 3" << endl; + sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server - shmdt( buf ); - shmctl( id, IPC_RMID, &ds ); + fcnd.set( true ); + + int stat; + waitpid( child.pid(), &stat, 0 ); + srv.close(); + srv.wait(); + } + + (&fcnd)->~__Condition<true>(); + shm.deallocate( &fcnd, 1 ); + + seg.deallocate(); + unlink( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } } class ConnectionProcessor6 // dummy variant @@ -190,7 +188,7 @@ void close(); }; -static Semaphore *sem2; +static __Semaphore<true> *sem2; ConnectionProcessor6::ConnectionProcessor6( std::sockstream& s ) { @@ -216,55 +214,53 @@ void test_read0_srv() { - shmid_ds ds; - int id = shmget( 5000, 1024, IPC_CREAT | IPC_EXCL | 0600 ); - if ( id == -1 ) { - cerr << "Error on shmget" << endl; - } - if ( shmctl( id, IPC_STAT, &ds ) == -1 ) { - cerr << "Error on shmctl" << endl; - } - void *buf = shmat( id, 0, 0 ); - if ( buf == reinterpret_cast<void *>(-1) ) { - cerr << "Error on shmat" << endl; - } + const char fname[] = "/tmp/sockios_test.shm"; + try { + xmt::shm_alloc<0> seg; - sem2 = new( buf ) Semaphore( 2, true ); + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); + xmt::allocator_shm<xmt::__Semaphore<true>,0> shm; - sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); + sem2 = new ( shm.allocate( 1 ) ) xmt::__Semaphore<true>( 2 ); - { - // It should work as before system call... - sockstream s( "localhost", ::port ); + sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); - s << "1" << endl; + { + // It should work as before system call... + sockstream s( "localhost", ::port ); - BOOST_CHECK( s.good() ); + s << "1" << endl; - sem2->wait(); - } + BOOST_CHECK( s.good() ); - system( "echo > /dev/null" ); // <------ key line + sem2->wait(); + } - { - // ... as after system call. - sockstream s( "localhost", ::port ); + system( "echo > /dev/null" ); // <------ key line - s << "1" << endl; + { + // ... as after system call. + sockstream s( "localhost", ::port ); - BOOST_CHECK( s.good() ); + s << "1" << endl; - sem2->wait(); - } + BOOST_CHECK( s.good() ); - BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call + sem2->wait(); + } - srv.close(); + BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call - srv.wait(); + srv.close(); - sem2->~Semaphore(); + srv.wait(); - shmdt( buf ); - shmctl( id, IPC_RMID, &ds ); + sem2->~__Semaphore<true>(); + shm.deallocate( sem2, 1 ); + seg.deallocate(); + unlink( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } } Modified: trunk/complement/explore/test/sockios/sockios_test.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.cc 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/sockios_test.cc 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/18 18:51:17 ptr> +// -*- C++ -*- Time-stamp: <07/01/30 11:45:52 ptr> /* * @@ -21,7 +21,9 @@ #include <arpa/inet.h> -#include <sys/shm.h> +#include <mt/shm.h> + +// #include <sys/shm.h> #include <sys/wait.h> #include <signal.h> @@ -276,79 +278,193 @@ void sockios_test::sigpipe() { - shmid_ds ds; - int id = shmget( 5000, 1024, IPC_CREAT | IPC_EXCL | 0600 ); - BOOST_REQUIRE( id != -1 ); - // if ( id == -1 ) { - // cerr << "Error on shmget" << endl; - // } - BOOST_REQUIRE( shmctl( id, IPC_STAT, &ds ) != -1 ); - // if ( shmctl( id, IPC_STAT, &ds ) == -1 ) { - // cerr << "Error on shmctl" << endl; - // } - void *buf = shmat( id, 0, 0 ); - BOOST_REQUIRE( buf != reinterpret_cast<void *>(-1) ); - // if ( buf == reinterpret_cast<void *>(-1) ) { - // cerr << "Error on shmat" << endl; - // } + const char fname[] = "/tmp/sockios_test.shm"; + enum { + in_Child_Condition = 1, + threads_Started_Condition = 2 + }; + try { + xmt::shm_alloc<0> seg; - xmt::__Condition<true>& fcnd = *new( buf ) xmt::__Condition<true>(); - fcnd.set( false ); - xmt::__Condition<true>& tcnd = *new( (char *)buf + sizeof(xmt::__Condition<true>) ) xmt::__Condition<true>(); - tcnd.set( false ); + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); + xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - try { - xmt::fork(); + xmt::allocator_shm<xmt::__Condition<true>,0> shm; - fcnd.try_wait(); + xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + nm.named( fcnd, in_Child_Condition ); + fcnd.set( false ); + xmt::__Condition<true>& tcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + nm.named( tcnd, threads_Started_Condition ); + tcnd.set( false ); + try { - /* - * This process will be killed, - * so I don't care about safe termination. - */ - xmt::Thread *th1 = new xmt::Thread( client_thr ); - for ( int i = 0; i < 10; ++i ) { - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); + xmt::fork(); + + fcnd.try_wait(); + + try { + /* + * This process will be killed, + * so I don't care about safe termination. + */ + xmt::Thread *th1 = new xmt::Thread( client_thr ); + for ( int i = 0; i < /* 10 */ 2; ++i ) { + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + new xmt::Thread( client_thr ); + } + + xmt::delay( xmt::timespec(1,0) ); + + tcnd.set( true ); + + th1->join(); + + exit( 0 ); } + catch ( ... ) { + } + } + catch ( xmt::fork_in_parent& child ) { + try { + xmt::signal_handler( SIGPIPE, &sigpipe_handler ); + sockmgr_stream_MP<loader> srv( port ); - xmt::delay( xmt::timespec(5,0) ); + fcnd.set( true ); - tcnd.set( true ); + tcnd.try_wait(); - th1->join(); + kill( child.pid(), SIGTERM ); - exit( 0 ); + int stat; + waitpid( child.pid(), &stat, 0 ); + + srv.close(); + srv.wait(); + } + catch ( ... ) { + } } - catch ( ... ) { - } + + (&tcnd)->~__Condition<true>(); + shm.deallocate( &tcnd, 1 ); + (&fcnd)->~__Condition<true>(); + shm.deallocate( &fcnd, 1 ); + + seg.deallocate(); + unlink( fname ); } - catch ( xmt::fork_in_parent& child ) { + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} + +class long_msg_processor // +{ + public: + long_msg_processor( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::__Condition<true> *cnd; +}; + +long_msg_processor::long_msg_processor( std::sockstream& ) +{ + cerr << "long_msg_processor::long_msg_processor" << endl; +} + +void long_msg_processor::connect( std::sockstream& s ) +{ + cerr << "long_msg_processor::connect" << endl; + + string l; + + getline( s, l ); + + cerr << "Is good? " << s.good() << endl; +} + +void long_msg_processor::close() +{ + cerr << "long_msg_processor::close()" << endl; + cnd->set( true ); +} + +xmt::__Condition<true> *long_msg_processor::cnd; + +void sockios_test::long_msg_test() +{ + const char fname[] = "/tmp/sockios_test.shm"; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); + xmt::shm_name_mgr<0>& nm = seg.name_mgr(); + + xmt::allocator_shm<xmt::__Condition<true>,0> shm; + + xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + fcnd.set( false ); + + xmt::__Condition<true>& srv_cnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + srv_cnd.set( false ); + + long_msg_processor::cnd = &srv_cnd; + try { - xmt::signal_handler( SIGPIPE, &sigpipe_handler ); - sockmgr_stream_MP<loader> srv( port ); + xmt::fork(); - fcnd.set( true ); + fcnd.try_wait(); - tcnd.try_wait(); + { + sockstream s( "localhost", port ); - kill( child.pid(), SIGTERM ); + s << "POST /test.php HTTP/1.1\r\n" + << "xmlrequest=<?xml version=\"1.0\"?>\ +<RWRequest><REQUEST domain=\"network\" service=\"ComplexReport\" nocache=\"n\" \ +contact_id=\"1267\" entity=\"1\" filter_entity_id=\"1\" \ +clientName=\"ui.ent\"><ROWS><ROW type=\"group\" priority=\"1\" ref=\"entity_id\" \ +includeascolumn=\"n\"/><ROW type=\"group\" priority=\"2\" \ +ref=\"advertiser_line_item_id\" includeascolumn=\"n\"/><ROW type=\"total\"/></ROWS><COLUMNS><COLUMN \ +ref=\"advertiser_line_item_name\"/><COLUMN ref=\"seller_imps\"/><COLUMN \ +ref=\"seller_clicks\"/><COLUMN ref=\"seller_convs\"/><COLUMN \ +ref=\"click_rate\"/><COLUMN ref=\"conversion_rate\"/><COLUMN ref=\"roi\"/><COLUMN \ +ref=\"network_revenue\"/><COLUMN ref=\"network_gross_cost\"/><COLUMN \ +ref=\"network_gross_profit\"/><COLUMN ref=\"network_revenue_ecpm\"/><COLUMN \ +ref=\"network_gross_cost_ecpm\"/><COLUMN \ +ref=\"network_gross_profit_ecpm\"/></COLUMNS><FILTERS><FILTER ref=\"time\" \ +macro=\"yesterday\"/></FILTERS></REQUEST></RWRequest>"; + s.flush(); + } + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + sockmgr_stream_MP<long_msg_processor> srv( port ); + fcnd.set( true ); - int stat; - waitpid( child.pid(), &stat, 0 ); + srv_cnd.try_wait(); srv.close(); srv.wait(); + } - catch ( ... ) { - } + + (&fcnd)->~__Condition<true>(); + shm.deallocate( &fcnd, 1 ); + + (&srv_cnd)->~__Condition<true>(); + shm.deallocate( &srv_cnd, 1 ); + + seg.deallocate(); + unlink( fname ); } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } - (&fcnd)->~__Condition<true>(); - - shmdt( buf ); - shmctl( id, IPC_RMID, &ds ); } Modified: trunk/complement/explore/test/sockios/sockios_test.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.h 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/sockios_test.h 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,8 +1,8 @@ -// -*- C++ -*- Time-stamp: <06/12/18 16:54:00 ptr> +// -*- C++ -*- Time-stamp: <07/01/30 10:55:51 ptr> /* * - * Copyright (c) 2002, 2003, 2005, 2006 + * Copyright (c) 2002, 2003, 2005, 2006, 2007 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -24,6 +24,7 @@ void ctor_dtor(); void sigpipe(); + void long_msg_test(); }; #endif // __sockios_test_h Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,8 +1,8 @@ -// -*- C++ -*- Time-stamp: <06/12/18 17:10:02 ptr> +// -*- C++ -*- Time-stamp: <07/01/30 10:57:38 ptr> /* * - * Copyright (c) 2002, 2003, 2005, 2006 + * Copyright (c) 2002, 2003, 2005, 2006, 2007 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -29,6 +29,7 @@ test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test3, instance ); test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); + test_case *long_msg_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_msg_test, instance ); // hostaddr2_tc->depends_on( hostaddr1_tc ); @@ -40,4 +41,5 @@ add( hostaddr3_tc ); add( ctor_dtor_tc ); add( sigpipe_tc ); + add( long_msg_tc ); } Modified: trunk/complement/explore/test/sockios/unit_test.cc =================================================================== --- trunk/complement/explore/test/sockios/unit_test.cc 2007-01-30 15:06:35 UTC (rev 1485) +++ trunk/complement/explore/test/sockios/unit_test.cc 2007-01-30 15:09:56 UTC (rev 1486) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/18 16:41:59 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 19:19:10 ptr> /* * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-02-09 10:34:43
|
Revision: 1522 http://svn.sourceforge.net/complement/?rev=1522&view=rev Author: complement Date: 2007-02-09 02:34:41 -0800 (Fri, 09 Feb 2007) Log Message: ----------- clean tests Modified Paths: -------------- trunk/complement/explore/test/sockios/Makefile.inc trunk/complement/explore/test/sockios/sockios_test.cc trunk/complement/explore/test/sockios/sockios_test.h trunk/complement/explore/test/sockios/sockios_test_suite.cc trunk/complement/explore/test/sockios/unit_test.cc Added Paths: ----------- trunk/complement/explore/test/sockios/names.cc Removed Paths: ------------- trunk/complement/explore/test/sockios/read0_on_exec.cc Modified: trunk/complement/explore/test/sockios/Makefile.inc =================================================================== --- trunk/complement/explore/test/sockios/Makefile.inc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/Makefile.inc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <06/12/18 16:43:21 ptr> +# -*- makefile -*- Time-stamp: <07/02/07 10:26:26 ptr> PRGNAME = sockios_ut SRC_CC = unit_test.cc ConnectionProcessor.cc message.cc client.cc client-mw.cc \ - client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc read0_on_exec.cc \ - sockios_test.cc sockios_test_suite.cc + client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc \ + names.cc sockios_test.cc sockios_test_suite.cc Added: trunk/complement/explore/test/sockios/names.cc =================================================================== --- trunk/complement/explore/test/sockios/names.cc (rev 0) +++ trunk/complement/explore/test/sockios/names.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -0,0 +1,140 @@ +// -*- C++ -*- Time-stamp: <07/02/07 10:28:34 ptr> + +/* + * + * Copyright (c) 2002, 2003, 2005-2007 + * Petr Ovtchenkov + * + * Licensed under the Academic Free License version 3.0 + * + */ + +#include "sockios_test.h" + +#include <boost/test/unit_test.hpp> + +#include <sockios/sockstream> +#include <sockios/sockmgr.h> + +#include <list> + +#include <arpa/inet.h> + +using namespace boost::unit_test_framework; +using namespace std; + +/* ************************************************************ */ + +void names_sockios_test::hostname_test() +{ + unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 + +#ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( local, 0x0100007f ); +#endif + +#ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( local, 0x7f000001 ); +#endif + + BOOST_CHECK_EQUAL( std::hostname( local ), "localhost [127.0.0.1]" ); + +#ifdef __unix + char buff[1024]; + + gethostname( buff, 1024 ); + + BOOST_CHECK_EQUAL( std::hostname(), buff ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::service_test() +{ +#ifdef __unix + BOOST_CHECK( std::service( "ftp", "tcp" ) == 21 ); + BOOST_CHECK( std::service( 7, "udp" ) == "echo" ); +#else + BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test1() +{ +#ifdef __unix + in_addr addr = std::findhost( "localhost" ); + +# ifdef _LITTLE_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); +# endif + +# ifdef _BIG_ENDIAN + BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); +# endif + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test2() +{ +#ifdef __unix + list<in_addr> haddrs; + std::gethostaddr( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 + localhost_found = true; + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} + +/* ************************************************************ */ + +void names_sockios_test::hostaddr_test3() +{ +#ifdef __unix + list<sockaddr> haddrs; + gethostaddr2( "localhost", back_inserter(haddrs) ); + + bool localhost_found = false; + + for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { + switch ( i->sa_family ) { + case PF_INET: + if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { + localhost_found = true; + } + break; + case PF_INET6: + if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && + ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { + localhost_found = true; + } + break; + } + } + + BOOST_CHECK( localhost_found == true ); + +#else + BOOST_ERROR( "Not implemented" ); +#endif +} Deleted: trunk/complement/explore/test/sockios/read0_on_exec.cc =================================================================== --- trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/read0_on_exec.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,259 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/01/29 19:17:54 ptr> - -/* - * Copyright (c) 2006, 2007 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License Version 3.0 - * - */ - -#include <boost/test/unit_test.hpp> - -using namespace boost::unit_test_framework; - -#include <iostream> -#include <mt/xmt.h> - -#include <sockios/sockstream> -#include <sockios/sockmgr.h> - -#include <sys/types.h> -#include <sys/wait.h> - -#include <mt/shm.h> - -using namespace std; -using namespace xmt; - -/* - * The problem: - * 1. Server listen socket (process A) - * 2. Client connect to server (process B, server --- process A) - * 3. Client try to read from socket (from server) and block on it, - * due to server write nothing (thread i) [Hmm, really here - poll with POLLIN flag and then read] - * 4. In another thread (thread ii) client call system() - * 5. Due to fork/execl (in system()) client return from read (step 3) - * with 0, i.e. as on close connection - * - * The POSIX say: - * (execl) - * If the Asynchronous Input and Output option is supported, any - * outstanding asynchronous I/O operations may be canceled. Those - * asynchronous I/O operations that are not canceled will complete - * as if the exec function had not yet occurred, but any associated - * signal notifications are suppressed. It is unspecified whether - * the exec function itself blocks awaiting such I/O completion. In no event, - * however, will the new process image created by the exec function be affected - * by the presence of outstanding asynchronous I/O operations at the time - * the exec function is called. Whether any I/O is cancelled, and which I/O may - * be cancelled upon exec, is implementation-dependent. - * - * Client open socket --------- system() - * \ - * read...[poll signaled, read -> 0] - * - * The same issue on server side: poll that wait POLLIN from clients - * signaled too. - * - */ - -extern int port; -extern xmt::Mutex pr_lock; - -// static __Condition<true> cndf; - -class ConnectionProcessor5 // dummy variant -{ - public: - ConnectionProcessor5( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -ConnectionProcessor5::ConnectionProcessor5( std::sockstream& s ) -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server seen connection" ); - - BOOST_REQUIRE( s.good() ); - pr_lock.unlock(); - - // cerr << "ConnectionProcessor5::ConnectionProcessor5\n"; - delay( xmt::timespec(3,0) ); - - int n = 1; - // cerr << "ConnectionProcessor5::ConnectionProcessor5, write\n"; - s.write( (const char *)&n, sizeof( int ) ).flush(); -} - -void ConnectionProcessor5::connect( std::sockstream& s ) -{ -} - -void ConnectionProcessor5::close() -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server: client close connection" ); - pr_lock.unlock(); -} - -Thread::ret_code thread_entry( void *par ) -{ - Thread::ret_code rt; - Condition& cnd = *reinterpret_cast<Condition *>(par); - - // sem.wait(); // wait server for listen us - sockstream sock( "localhost", ::port ); - int buff = 0; - // cerr << "thread_entry" << endl; - cnd.set( true ); - // Note: due to this is another process then main, boost can report - // about errors here, but don't count error it in summary, if it occur! - BOOST_CHECK( sock.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line - BOOST_CHECK( buff == 1 ); - // cerr << "Read pass" << endl; - - rt.iword = 0; - return rt; -} - -void test_read0() -{ - const char fname[] = "/tmp/sockios_test.shm"; - try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - // xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - // nm.named( fcnd, 1 ); - fcnd.set( false ); - - try { - xmt::fork(); // <---- key line - fcnd.try_wait(); // wait server for listen us - - Condition cnd; - cnd.set( false ); - - xmt::Thread thr( thread_entry, &cnd ); - - cnd.try_wait(); // wait for read call - - delay( xmt::timespec(1,0) ); - - // cerr << "system" << endl; - system( "echo > /dev/null" ); // <------ key line - // cerr << "after system" << endl; - - thr.join(); - // cerr << "exit child" << endl; - exit( 0 ); - } - catch ( xmt::fork_in_parent& child ) { - // cerr << "** 3" << endl; - sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server - - fcnd.set( true ); - - int stat; - waitpid( child.pid(), &stat, 0 ); - srv.close(); - srv.wait(); - } - - (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); - - seg.deallocate(); - unlink( fname ); - } - catch ( xmt::shm_bad_alloc& err ) { - BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); - } -} - -class ConnectionProcessor6 // dummy variant -{ - public: - ConnectionProcessor6( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -static Condition cnd6; - -ConnectionProcessor6::ConnectionProcessor6( std::sockstream& s ) -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server seen connection" ); - - BOOST_REQUIRE( s.good() ); - pr_lock.unlock(); - - cnd6.set( true ); -} - -void ConnectionProcessor6::connect( std::sockstream& s ) -{ -} - -void ConnectionProcessor6::close() -{ - pr_lock.lock(); - BOOST_MESSAGE( "Server: client close connection" ); - pr_lock.unlock(); -} - -void test_read0_srv() -{ - try { - sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); - - BOOST_CHECK( srv.good() ); - cnd6.set( false ); - - { - // It should work as before system call... - sockstream s( "localhost", ::port ); - - s << "1" << endl; - - BOOST_CHECK( s.good() ); - - cnd6.try_wait(); - } - - cnd6.set( false ); - - system( "echo > /dev/null" ); // <------ key line - - BOOST_CHECK( srv.good() ); - - { - // ... as after system call. - sockstream s( "localhost", ::port ); - - s << "1" << endl; - - BOOST_CHECK( s.good() ); - - cnd6.try_wait(); - } - - BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call - - srv.close(); - srv.wait(); - } - catch ( xmt::shm_bad_alloc& err ) { - BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); - } -} Modified: trunk/complement/explore/test/sockios/sockios_test.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/31 23:47:57 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 11:32:06 ptr> /* * @@ -17,126 +17,44 @@ #include <sockios/sockstream> #include <sockios/sockmgr.h> -#include <list> - -#include <arpa/inet.h> - #include <mt/shm.h> - -// #include <sys/shm.h> #include <sys/wait.h> - #include <signal.h> using namespace boost::unit_test_framework; using namespace std; -void sockios_test::hostname_test() -{ - unsigned long local = htonl( 0x7f000001 ); // 127.0.0.1 +const char fname[] = "/tmp/sockios_test.shm"; +xmt::shm_alloc<0> seg; +xmt::allocator_shm<xmt::__Condition<true>,0> shm_cnd; +xmt::allocator_shm<xmt::__Barrier<true>,0> shm_b; -#ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( local, 0x0100007f ); -#endif - -#ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( local, 0x7f000001 ); -#endif - - BOOST_CHECK_EQUAL( std::hostname( local ), "localhost [127.0.0.1]" ); - -#ifdef __unix - char buff[1024]; - - gethostname( buff, 1024 ); - - BOOST_CHECK_EQUAL( std::hostname(), buff ); -#endif -} - -void sockios_test::service_test() +sockios_test::sockios_test() { -#ifdef __unix - BOOST_CHECK( std::service( "ftp", "tcp" ) == 21 ); - BOOST_CHECK( std::service( 7, "udp" ) == "echo" ); -#else - BOOST_ERROR( "requests for service (/etc/services) not implemented on this platform" ); -#endif } -void sockios_test::hostaddr_test1() +sockios_test::~sockios_test() { -#ifdef __unix - in_addr addr = std::findhost( "localhost" ); - -# ifdef _LITTLE_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x0100007f ); -# endif - -# ifdef _BIG_ENDIAN - BOOST_CHECK_EQUAL( addr.s_addr, 0x7f000001 ); -# endif - -#else - BOOST_ERROR( "Not implemented" ); -#endif } -void sockios_test::hostaddr_test2() +void sockios_test::init() { -#ifdef __unix - list<in_addr> haddrs; - std::gethostaddr( "localhost", back_inserter(haddrs) ); - - bool localhost_found = false; - - for ( list<in_addr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - if ( i->s_addr == htonl( 0x7f000001 ) ) { // 127.0.0.1 - localhost_found = true; - break; - } + try { + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif + catch ( const xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } } -void sockios_test::hostaddr_test3() +void sockios_test::finit() { -#ifdef __unix - list<sockaddr> haddrs; - gethostaddr2( "localhost", back_inserter(haddrs) ); + seg.deallocate(); + unlink( fname ); +} - bool localhost_found = false; +/* ************************************************************ */ - for ( list<sockaddr>::const_iterator i = haddrs.begin(); i != haddrs.end(); ++i ) { - switch ( i->sa_family ) { - case PF_INET: - if ( ((sockaddr_in *)&*i)->sin_addr.s_addr == htonl( 0x7f000001 ) ) { - localhost_found = true; - } - break; - case PF_INET6: - if ( ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[0] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[1] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[2] == 0 && - ((sockaddr_in6 *)&*i)->sin6_addr.in6_u.u6_addr32[3] == 1 ) { - localhost_found = true; - } - break; - } - } - - BOOST_CHECK( localhost_found == true ); - -#else - BOOST_ERROR( "Not implemented" ); -#endif -} - class Cnt { public: @@ -182,7 +100,7 @@ BOOST_CHECK( s1.good() ); BOOST_CHECK( s1.is_open() ); while ( Cnt::get_visits() == 0 ) { - xmt::delay( xmt::timespec(0,10000) ); + xmt::Thread::yield(); } Cnt::lock.lock(); BOOST_CHECK( Cnt::cnt == 1 ); @@ -222,7 +140,7 @@ BOOST_CHECK( s2.good() ); BOOST_CHECK( s2.is_open() ); while ( Cnt::get_visits() < 2 ) { - xmt::delay( xmt::timespec(0,10000) ); + xmt::Thread::yield(); } Cnt::lock.lock(); BOOST_CHECK( Cnt::cnt == 2 ); @@ -242,6 +160,8 @@ Cnt::lock.unlock(); } +/* ************************************************************ */ + class loader { public: @@ -268,7 +188,7 @@ { } -xmt::Thread::ret_code client_thr( void * ) +xmt::Thread::ret_code client_thr( void *p ) { xmt::Thread::ret_code ret; @@ -280,11 +200,15 @@ fill( buf, buf + 1024, 0 ); + xmt::Barrier& b = *reinterpret_cast<xmt::Barrier *>(p); + b.wait(); + while( true ) { s.write( buf, 1024 ); s.flush(); s.read( buf, 1024 ); + xmt::Thread::yield(); } return ret; @@ -292,34 +216,22 @@ void sigpipe_handler( int sig, siginfo_t *si, void * ) { +#if 0 cerr << "-----------------------------------------------\n" << "my pid: " << xmt::getpid() << ", ppid: " << xmt::getppid() << "\n" << "signal: " << sig << ", number " << si->si_signo << " errno " << si->si_errno << " code " << si->si_code << endl; +#endif } void sockios_test::sigpipe() { - const char fname[] = "/tmp/sockios_test.shm"; - enum { - in_Child_Condition = 1, - threads_Started_Condition = 2 - }; try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - nm.named( fcnd, in_Child_Condition ); + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); fcnd.set( false ); - xmt::__Condition<true>& tcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); - nm.named( tcnd, threads_Started_Condition ); + xmt::__Condition<true>& tcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); tcnd.set( false ); try { @@ -332,15 +244,15 @@ * This process will be killed, * so I don't care about safe termination. */ - xmt::Thread *th1 = new xmt::Thread( client_thr ); - for ( int i = 0; i < /* 10 */ 2; ++i ) { - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); - new xmt::Thread( client_thr ); + const int b_count = 10; + xmt::Barrier b( b_count ); + xmt::Thread *th1 = new xmt::Thread( client_thr, &b ); + + for ( int i = 0; i < (b_count - 1); ++i ) { + new xmt::Thread( client_thr, &b ); } - xmt::delay( xmt::timespec(1,0) ); + xmt::delay( xmt::timespec(0,500000000) ); tcnd.set( true ); @@ -373,18 +285,17 @@ } (&tcnd)->~__Condition<true>(); - shm.deallocate( &tcnd, 1 ); + shm_cnd.deallocate( &tcnd, 1 ); (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); - - seg.deallocate(); - unlink( fname ); + shm_cnd.deallocate( &fcnd, 1 ); } catch ( xmt::shm_bad_alloc& err ) { BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } } +/* ************************************************************ */ + class long_msg_processor // { public: @@ -420,21 +331,13 @@ xmt::__Condition<true> *long_msg_processor::cnd; -void sockios_test::long_msg_test() +void sockios_test::long_msg() { - const char fname[] = "/tmp/sockios_test.shm"; try { - xmt::shm_alloc<0> seg; - - seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0600 ); - xmt::shm_name_mgr<0>& nm = seg.name_mgr(); - - xmt::allocator_shm<xmt::__Condition<true>,0> shm; - - xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); fcnd.set( false ); - xmt::__Condition<true>& srv_cnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Condition<true>& srv_cnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); srv_cnd.set( false ); long_msg_processor::cnd = &srv_cnd; @@ -478,16 +381,244 @@ } (&fcnd)->~__Condition<true>(); - shm.deallocate( &fcnd, 1 ); + shm_cnd.deallocate( &fcnd, 1 ); (&srv_cnd)->~__Condition<true>(); - shm.deallocate( &srv_cnd, 1 ); + shm_cnd.deallocate( &srv_cnd, 1 ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} - seg.deallocate(); - unlink( fname ); +/* ************************************************************ + * The problem: + * 1. Server listen socket (process A) + * 2. Client connect to server (process B, server --- process A) + * 3. Client try to read from socket (from server) and block on it, + * due to server write nothing (thread i) [Hmm, really here + * poll with POLLIN flag and then read] + * 4. In another thread (thread ii) client call system() + * 5. Due to fork/execl (in system()) client return from read (step 3) + * with 0, i.e. as on close connection + * + * The POSIX say: + * (execl) + * If the Asynchronous Input and Output option is supported, any + * outstanding asynchronous I/O operations may be canceled. Those + * asynchronous I/O operations that are not canceled will complete + * as if the exec function had not yet occurred, but any associated + * signal notifications are suppressed. It is unspecified whether + * the exec function itself blocks awaiting such I/O completion. In no event, + * however, will the new process image created by the exec function be affected + * by the presence of outstanding asynchronous I/O operations at the time + * the exec function is called. Whether any I/O is cancelled, and which I/O may + * be cancelled upon exec, is implementation-dependent. + * + * Client open socket --------- system() + * \ + * read...[poll signaled, read -> 0] + * + * The same issue on server side: poll that wait POLLIN from clients + * signaled too. + * + */ + +class ConnectionProcessor5 // dummy variant +{ + public: + ConnectionProcessor5( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::__Barrier<true> *b; +}; + + +xmt::__Barrier<true> *ConnectionProcessor5::b = 0; + +ConnectionProcessor5::ConnectionProcessor5( std::sockstream& s ) +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server seen connection" ); + + BOOST_REQUIRE( s.good() ); + // pr_lock.unlock(); + + // cerr << "ConnectionProcessor5::ConnectionProcessor5\n"; + // delay( xmt::timespec(3,0) ); + + int n = 1; + // cerr << "ConnectionProcessor5::ConnectionProcessor5, write\n"; + b->wait(); + s.write( (const char *)&n, sizeof( int ) ).flush(); +} + +void ConnectionProcessor5::connect( std::sockstream& s ) +{ +} + +void ConnectionProcessor5::close() +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server: client close connection" ); + // pr_lock.unlock(); +} + +xmt::Thread::ret_code thread_entry( void *par ) +{ + xmt::Thread::ret_code rt; + xmt::Condition& cnd = *reinterpret_cast<xmt::Condition *>(par); + + // sem.wait(); // wait server for listen us + sockstream sock( "localhost", ::port ); + int buff = 0; + // cerr << "thread_entry" << endl; + cnd.set( true ); + // Note: due to this is another process then main, boost can report + // about errors here, but don't count error it in summary, if it occur! + BOOST_CHECK( sock.read( (char *)&buff, sizeof(int) ).good() ); // <---- key line + BOOST_CHECK( buff == 1 ); + // cerr << "Read pass" << endl; + + rt.iword = 0; + return rt; +} + +void sockios_test::read0() +{ + try { + xmt::__Condition<true>& fcnd = *new ( shm_cnd.allocate( 1 ) ) xmt::__Condition<true>(); + xmt::__Barrier<true>& b = *new ( shm_b.allocate( 1 ) ) xmt::__Barrier<true>(); + ConnectionProcessor5::b = &b; + // nm.named( fcnd, 1 ); + fcnd.set( false ); + + try { + xmt::fork(); // <---- key line + fcnd.try_wait(); // wait server for listen us + + xmt::Condition cnd; + cnd.set( false ); + + xmt::Thread thr( thread_entry, &cnd ); + + cnd.try_wait(); // wait for read call + + // delay( xmt::timespec(1,0) ); + + // cerr << "system" << endl; + system( "echo > /dev/null" ); // <------ key line + // cerr << "after system" << endl; + + b.wait(); + + thr.join(); + // cerr << "exit child" << endl; + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + // cerr << "** 3" << endl; + sockmgr_stream_MP<ConnectionProcessor5> srv( ::port ); // start server + + fcnd.set( true ); + + int stat; + waitpid( child.pid(), &stat, 0 ); + srv.close(); + srv.wait(); + } + + (&b)->~__Barrier<true>(); + shm_b.deallocate( &b, 1 ); + (&fcnd)->~__Condition<true>(); + shm_cnd.deallocate( &fcnd, 1 ); } catch ( xmt::shm_bad_alloc& err ) { BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } +} +/* ************************************************************ */ + +class ConnectionProcessor6 // dummy variant +{ + public: + ConnectionProcessor6( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::Condition cnd; +}; + +xmt::Condition ConnectionProcessor6::cnd; + +ConnectionProcessor6::ConnectionProcessor6( std::sockstream& s ) +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server seen connection" ); + + BOOST_REQUIRE( s.good() ); + // pr_lock.unlock(); + + cnd.set( true ); } + +void ConnectionProcessor6::connect( std::sockstream& s ) +{ +} + +void ConnectionProcessor6::close() +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server: client close connection" ); + // pr_lock.unlock(); +} + +void sockios_test::read0_srv() +{ + try { + sockmgr_stream_MP<ConnectionProcessor6> srv( ::port ); + + BOOST_CHECK( srv.good() ); + ConnectionProcessor6::cnd.set( false ); + + { + // It should work as before system call... + sockstream s( "localhost", ::port ); + + s << "1" << endl; + + BOOST_CHECK( s.good() ); + + ConnectionProcessor6::cnd.try_wait(); + } + + ConnectionProcessor6::cnd.set( false ); + + system( "echo > /dev/null" ); // <------ key line + + BOOST_CHECK( srv.good() ); + + { + // ... as after system call. + sockstream s( "localhost", ::port ); + + s << "1" << endl; + + BOOST_CHECK( s.good() ); + + ConnectionProcessor6::cnd.try_wait(); + } + + BOOST_CHECK( srv.good() ); // server must correctly process interrupt during system call + + srv.close(); + srv.wait(); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} Modified: trunk/complement/explore/test/sockios/sockios_test.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.h 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test.h 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/30 10:55:51 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 10:51:25 ptr> /* * @@ -12,7 +12,7 @@ #ifndef __sockios_test_h #define __sockios_test_h -struct sockios_test +struct names_sockios_test { void hostname_test(); void service_test(); @@ -20,11 +20,23 @@ void hostaddr_test1(); void hostaddr_test2(); void hostaddr_test3(); +}; +struct sockios_test +{ + sockios_test(); + ~sockios_test(); + + void init(); + void finit(); + void ctor_dtor(); + void long_msg(); + void sigpipe(); - void long_msg_test(); + void read0(); + void read0_srv(); }; #endif // __sockios_test_h Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/01/30 10:57:38 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 11:00:07 ptr> /* * @@ -20,18 +20,14 @@ sockios_test_suite::sockios_test_suite() : test_suite( "sockios library test suite" ) { - boost::shared_ptr<sockios_test> instance( new sockios_test() ); - test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostname_test, instance ); - test_case *service_tc = BOOST_CLASS_TEST_CASE( &sockios_test::service_test, instance ); + boost::shared_ptr<names_sockios_test> names_instance( new names_sockios_test() ); - test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test1, instance ); - test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test2, instance ); - test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &sockios_test::hostaddr_test3, instance ); - test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); - test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); - test_case *long_msg_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_msg_test, instance ); + test_case *hostname_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostname_test, names_instance ); + test_case *service_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::service_test, names_instance ); - // hostaddr2_tc->depends_on( hostaddr1_tc ); + test_case *hostaddr1_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test1, names_instance ); + test_case *hostaddr2_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test2, names_instance ); + test_case *hostaddr3_tc = BOOST_CLASS_TEST_CASE( &names_sockios_test::hostaddr_test3, names_instance ); add( hostname_tc ); add( service_tc ); @@ -39,7 +35,32 @@ add( hostaddr1_tc ); add( hostaddr2_tc ); add( hostaddr3_tc ); + + + boost::shared_ptr<sockios_test> instance( new sockios_test() ); + test_case *init_tc = BOOST_CLASS_TEST_CASE( &sockios_test::init, instance ); + test_case *finit_tc = BOOST_CLASS_TEST_CASE( &sockios_test::finit, instance ); + + test_case *ctor_dtor_tc = BOOST_CLASS_TEST_CASE( &sockios_test::ctor_dtor, instance ); + test_case *long_msg_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_msg, instance ); + test_case *sigpipe_tc = BOOST_CLASS_TEST_CASE( &sockios_test::sigpipe, instance ); + + test_case *read0_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0, instance ); + test_case *read0_srv_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0_srv, instance ); + + long_msg_tc->depends_on( init_tc ); + long_msg_tc->depends_on( ctor_dtor_tc ); + sigpipe_tc->depends_on( ctor_dtor_tc ); + sigpipe_tc->depends_on( init_tc ); + read0_tc->depends_on( sigpipe_tc ); + read0_srv_tc->depends_on( sigpipe_tc ); + finit_tc->depends_on( init_tc ); + + add( init_tc ); add( ctor_dtor_tc ); + add( long_msg_tc ); add( sigpipe_tc ); - add( long_msg_tc ); + add( read0_tc, 0, 5 ); + add( read0_srv_tc ); + add( finit_tc ); } Modified: trunk/complement/explore/test/sockios/unit_test.cc =================================================================== --- trunk/complement/explore/test/sockios/unit_test.cc 2007-02-09 10:31:07 UTC (rev 1521) +++ trunk/complement/explore/test/sockios/unit_test.cc 2007-02-09 10:34:41 UTC (rev 1522) @@ -1,8 +1,8 @@ -// -*- C++ -*- Time-stamp: <07/01/29 19:19:10 ptr> +// -*- C++ -*- Time-stamp: <07/02/07 10:09:14 ptr> /* * - * Copyright (c) 2002, 2003, 2005, 2006 + * Copyright (c) 2002, 2003, 2005-2007 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -344,23 +344,13 @@ void test_client_close_socket(); void test_more_bytes_in_socket(); void test_more_bytes_in_socket2(); -void test_read0(); -void test_read0_srv(); - test_suite *init_unit_test_suite( int argc, char **argv ) { test_suite *ts = BOOST_TEST_SUITE( "libsockios test" ); ts->add( new sockios_test_suite() ); - // ts->add( BOOST_TEST_CASE( &hostname_test ) ); - // ts->add( BOOST_TEST_CASE( &service_test ) ); - - // ts->add( BOOST_TEST_CASE( &hostaddr_test1 ) ); - // ts->add( BOOST_TEST_CASE( &hostaddr_test2 ) ); - // ts->add( BOOST_TEST_CASE( &hostaddr_test3 ) ); - ts->add( BOOST_TEST_CASE( &test_client_server_poll ) ); // ts->add( BOOST_TEST_CASE( &test_client_server_select ) ); @@ -385,8 +375,6 @@ ts->add( BOOST_TEST_CASE( &test_client_close_socket ) ); ts->add( BOOST_TEST_CASE( &test_more_bytes_in_socket ), 0, 5 ); ts->add( BOOST_TEST_CASE( &test_more_bytes_in_socket2 ), 0, 5 ); - ts->add( BOOST_TEST_CASE( &test_read0 ), 0, 7 ); - ts->add( BOOST_TEST_CASE( &test_read0_srv ) ); return ts; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-02-26 16:38:40
|
Revision: 1533 http://svn.sourceforge.net/complement/?rev=1533&view=rev Author: complement Date: 2007-02-26 08:38:34 -0800 (Mon, 26 Feb 2007) Log Message: ----------- add long reading test Modified Paths: -------------- trunk/complement/explore/test/sockios/sockios_test.cc trunk/complement/explore/test/sockios/sockios_test.h trunk/complement/explore/test/sockios/sockios_test_suite.cc Modified: trunk/complement/explore/test/sockios/sockios_test.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-21 17:57:04 UTC (rev 1532) +++ trunk/complement/explore/test/sockios/sockios_test.cc 2007-02-26 16:38:34 UTC (rev 1533) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/07 11:32:06 ptr> +// -*- C++ -*- Time-stamp: <07/02/26 17:18:51 ptr> /* * @@ -622,3 +622,76 @@ BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); } } + +/* ************************************************************ */ + +class LongBlockReader // dummy variant +{ + public: + LongBlockReader( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); + + static xmt::Condition cnd; +}; + +xmt::Condition LongBlockReader::cnd; + +LongBlockReader::LongBlockReader( std::sockstream& s ) +{ + BOOST_REQUIRE( s.good() ); +} + +void LongBlockReader::connect( std::sockstream& s ) +{ + char buf[1024]; + int count = 0; + + for ( int i = 0; i < 1024 * 1024; ++i ) { + s.read( buf, 1024 ); + } + cnd.set( true ); +} + +void LongBlockReader::close() +{ + // pr_lock.lock(); + // BOOST_MESSAGE( "Server: client close connection" ); + // pr_lock.unlock(); +} + +void sockios_test::long_block_read() +{ + LongBlockReader::cnd.set( false ); + + sockmgr_stream_MP<LongBlockReader> srv( ::port ); + + BOOST_REQUIRE( srv.good() ); + + sockstream s; + + s.open( "localhost", ::port ); + + BOOST_REQUIRE( s.good() ); + + char buf[1024]; + + for ( int i = 0; i < 1024 * 1024; ++i ) { + s.write( buf, 1024 ); + } + s.flush(); + + BOOST_CHECK( s.good() ); + + s.close(); + LongBlockReader::cnd.try_wait(); + + srv.close(); + srv.wait(); + + // try { + // } + // catch () { + // } +} Modified: trunk/complement/explore/test/sockios/sockios_test.h =================================================================== --- trunk/complement/explore/test/sockios/sockios_test.h 2007-02-21 17:57:04 UTC (rev 1532) +++ trunk/complement/explore/test/sockios/sockios_test.h 2007-02-26 16:38:34 UTC (rev 1533) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/13 10:23:29 ptr> +// -*- C++ -*- Time-stamp: <07/02/26 15:09:26 ptr> /* * @@ -37,6 +37,7 @@ void sigpipe(); void read0(); void read0_srv(); + void long_block_read(); void srv2_fork(); }; Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-21 17:57:04 UTC (rev 1532) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-02-26 16:38:34 UTC (rev 1533) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/02/07 11:00:07 ptr> +// -*- C++ -*- Time-stamp: <07/02/26 15:33:23 ptr> /* * @@ -47,6 +47,7 @@ test_case *read0_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0, instance ); test_case *read0_srv_tc = BOOST_CLASS_TEST_CASE( &sockios_test::read0_srv, instance ); + test_case *long_block_read_tc = BOOST_CLASS_TEST_CASE( &sockios_test::long_block_read, instance ); long_msg_tc->depends_on( init_tc ); long_msg_tc->depends_on( ctor_dtor_tc ); @@ -54,6 +55,7 @@ sigpipe_tc->depends_on( init_tc ); read0_tc->depends_on( sigpipe_tc ); read0_srv_tc->depends_on( sigpipe_tc ); + long_block_read_tc->depends_on( init_tc ); finit_tc->depends_on( init_tc ); add( init_tc ); @@ -62,5 +64,6 @@ add( sigpipe_tc ); add( read0_tc, 0, 5 ); add( read0_srv_tc ); + add( long_block_read_tc ); add( finit_tc ); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-07-18 09:27:12
|
Revision: 1621 http://svn.sourceforge.net/complement/?rev=1621&view=rev Author: complement Date: 2007-07-18 02:27:10 -0700 (Wed, 18 Jul 2007) Log Message: ----------- fix listen interfaces tests Modified Paths: -------------- trunk/complement/explore/test/sockios/ConnectionProcessor.cc trunk/complement/explore/test/sockios/ConnectionProcessor.h trunk/complement/explore/test/sockios/sockios_test_suite.cc Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.cc =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 06:29:40 UTC (rev 1620) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 09:27:10 UTC (rev 1621) @@ -56,6 +56,40 @@ // ****************** +trivial_sockios_test::trivial_sockios_test() : + hostaddr( findhost( hostname().c_str() ) ) // take primary host IP +{ + // Oh, this trick not work well: hostname may be assigned to 127.0.0.1 too... + // I need list of interfaces... + + list<net_iface> ifaces; + try { + get_ifaces( ifaces ); + } + catch ( runtime_error& err ) { + EXAM_ERROR_ASYNC( err.what() ); + } + + list<net_iface>::const_iterator i; + for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { + if ( i->name == "eth0" ) { + hostaddr = i->addr.inet.sin_addr; + // hostaddr = i->addr.any; // .inet.sin_addr; + break; + } + } + EXAM_CHECK_ASYNC( i != ifaces.end() ); + + for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { + if ( i->name == "lo" ) { + localaddr = i->addr.inet.sin_addr; + // hostaddr = i->addr.any; // .inet.sin_addr; + break; + } + } + EXAM_CHECK_ASYNC( i != ifaces.end() ); +} + int EXAM_IMPL(trivial_sockios_test::simple) { #ifndef __FIT_NO_POLL @@ -93,6 +127,62 @@ // ****************** +int EXAM_IMPL(trivial_sockios_test::listen_iface) +{ +#ifndef __FIT_NO_POLL + try { + // server not listen localhost, but listen ext interface: + sockmgr_stream_MP<ConnectionProcessor> srv( hostaddr, port ); // start server + + EXAM_CHECK( srv.is_open() ); + EXAM_CHECK( srv.good() ); + + { + EXAM_MESSAGE( "Client start" ); + + // std::sockstream sock( hostname(hostaddr.s_addr).c_str(), ::port ); + // std::sockstream sock( (*(sockaddr_in *)&hostaddr).sin_addr, ::port ); + std::sockstream sock( hostaddr, ::port ); + string srv_line; + + EXAM_CHECK( sock.good() ); + + sock << ::message << endl; + + EXAM_CHECK( sock.good() ); + + // sock.clear(); + getline( sock, srv_line ); + + EXAM_CHECK( sock.good() ); + + EXAM_CHECK( srv_line == ::message_rsp ); + + EXAM_MESSAGE( "Client close connection (client's end of life)" ); + // sock.close(); // no needs, that will done in sock destructor + } + + { + std::sockstream sock( localaddr, ::port ); + + EXAM_CHECK( !sock.is_open() ); + } + + srv.close(); // close server, so we don't wait server termination on next line + srv.wait(); // Wait for server stop to serve clients connections + } + catch ( std::domain_error& err ) { + EXAM_ERROR( "host not found by name" ); + } +#else + EXAM_ERROR( "poll-based sockmgr not implemented on this platform" ); +#endif + + return EXAM_RESULT; +} + +// ****************** + ConnectionProcessor2::ConnectionProcessor2( std::sockstream& s ) : count( 0 ) { Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.h =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 06:29:40 UTC (rev 1620) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 09:27:10 UTC (rev 1621) @@ -36,7 +36,15 @@ class trivial_sockios_test { public: + trivial_sockios_test(); + int EXAM_DECL(simple); + int EXAM_DECL(listen_iface); + + private: + in_addr hostaddr; + // sockaddr hostaddr; + in_addr localaddr; }; class ConnectionProcessor2 // Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 06:29:40 UTC (rev 1620) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:27:10 UTC (rev 1621) @@ -29,179 +29,6 @@ using namespace std; -int EXAM_IMPL(test_client_server_poll_nonlocal_ack) -{ -#ifndef __FIT_NO_POLL - try { - - // Oh, this trick not work well: hostname may be assigned to 127.0.0.1 too... - // I need list of interfaces... - - // take primary host IP: - in_addr hostaddr( findhost( hostname().c_str() ) ); - list<net_iface> ifaces; - try { - get_ifaces( ifaces ); - } - catch ( runtime_error& err ) { - EXAM_ERROR( err.what() ); - } - - list<net_iface>::const_iterator i; - for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { - if ( i->name == "eth0" ) { - hostaddr = i->addr.inet.sin_addr; - break; - } - } - EXAM_CHECK( i != ifaces.end() ); - - // server not listen localhost, but listen ext interface: - sockmgr_stream_MP<ConnectionProcessor> srv( hostaddr, port ); // start server - - EXAM_CHECK( srv.is_open() ); - EXAM_CHECK( srv.good() ); - - { - EXAM_MESSAGE( "Client start" ); - - // in_addr hostaddr( findhost( hostname().c_str() ) ); - sockaddr hostaddr; - - list<net_iface> ifaces; - try { - get_ifaces( ifaces ); - } - catch ( runtime_error& err ) { - EXAM_ERROR( err.what() ); - } - - list<net_iface>::const_iterator i; - for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { - if ( i->name == "eth0" ) { - hostaddr = i->addr.any; // .inet.sin_addr; - break; - } - } - EXAM_CHECK( i != ifaces.end() ); - - // std::sockstream sock( hostname(hostaddr.s_addr).c_str(), ::port ); - std::sockstream sock( (*(sockaddr_in *)&hostaddr).sin_addr, ::port ); - string srv_line; - - EXAM_CHECK( sock.good() ); - - sock << ::message << endl; - - EXAM_CHECK( sock.good() ); - - // sock.clear(); - getline( sock, srv_line ); - - EXAM_CHECK( sock.good() ); - - EXAM_CHECK( srv_line == ::message_rsp ); - - EXAM_MESSAGE( "Client close connection (client's end of life)" ); - // sock.close(); // no needs, that will done in sock destructor - } - - srv.close(); // close server, so we don't wait server termination on next line - srv.wait(); // Wait for server stop to serve clients connections - } - catch ( std::domain_error& err ) { - EXAM_ERROR( "host not found by name" ); - } -#else - EXAM_ERROR( "poll-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} - -int EXAM_IMPL(test_client_server_poll_nonlocal_nac) -{ -#ifndef __FIT_NO_POLL - try { - // take primary host IP: - in_addr hostaddr( findhost( hostname().c_str() ) ); - list<net_iface> ifaces; - try { - get_ifaces( ifaces ); - } - catch ( runtime_error& err ) { - EXAM_ERROR( err.what() ); - } - - list<net_iface>::const_iterator i; - for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { - if ( i->name == "eth0" ) { - hostaddr = i->addr.inet.sin_addr; - break; - } - } - EXAM_CHECK( i != ifaces.end() ); - - // server not listen localhost, but listen ext interface: - sockmgr_stream_MP<ConnectionProcessor> srv( hostaddr, port ); // start server - - { - EXAM_MESSAGE( "Client start" ); - - // in_addr hostaddr( findhost( hostname().c_str() ) ); - sockaddr hostaddr; - - list<net_iface> ifaces; - try { - get_ifaces( ifaces ); - } - catch ( runtime_error& err ) { - EXAM_ERROR( err.what() ); - } - - list<net_iface>::const_iterator i; - for ( i = ifaces.begin(); i != ifaces.end(); ++i ) { - if ( i->name == "eth0" ) { - hostaddr = i->addr.any; // .inet.sin_addr; - break; - } - } - EXAM_CHECK( i != ifaces.end() ); - - // std::sockstream sock( hostname(hostaddr.s_addr).c_str(), ::port ); - std::sockstream sock( (*(sockaddr_in *)&hostaddr).sin_addr, ::port ); - string srv_line; - - EXAM_CHECK( sock.good() ); - - sock << ::message << endl; - - EXAM_CHECK( sock.good() ); - - // sock.clear(); - getline( sock, srv_line ); - - EXAM_CHECK( sock.good() ); - - EXAM_CHECK( srv_line == ::message_rsp ); - - EXAM_MESSAGE( "Client close connection (client's end of life)" ); - // sock.close(); // no needs, that will done in sock destructor - } - - srv.close(); // close server, so we don't wait server termination on next line - srv.wait(); // Wait for server stop to serve clients connections - } - catch ( std::domain_error& err ) { - EXAM_ERROR( "host not found by name" ); - } -#else - EXAM_ERROR( "poll-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} - int EXAM_IMPL(test_client_server_poll_local_ack) { #ifndef __FIT_NO_POLL @@ -381,8 +208,7 @@ // Old tests - t.add( test_client_server_poll_nonlocal_ack, "test_client_server_poll_nonlocal_ack" ); - t.add( test_client_server_poll_nonlocal_nac, "test_client_server_poll_nonlocal_nac" ); + t.add( &trivial_sockios_test::listen_iface, trivial_test, "listen_iface", tc[0] ); t.add( test_client_server_poll_local_ack, "test_client_server_poll_local_ack" ); t.add( test_mass_processing_poll, "test_mass_processing_poll" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-07-18 09:42:27
|
Revision: 1622 http://svn.sourceforge.net/complement/?rev=1622&view=rev Author: complement Date: 2007-07-18 02:42:23 -0700 (Wed, 18 Jul 2007) Log Message: ----------- check of correct understanding ip expressed as string added to existent test; separate test removed Modified Paths: -------------- trunk/complement/explore/test/sockios/ConnectionProcessor.cc trunk/complement/explore/test/sockios/sockios_test_suite.cc Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.cc =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 09:27:10 UTC (rev 1621) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 09:42:23 UTC (rev 1622) @@ -116,6 +116,22 @@ // sock.close(); // no needs, that will done in sock destructor } + { + std::sockstream sock( "127.0.0.1", ::port ); + string srv_line; + + sock << ::message << endl; + + EXAM_CHECK( sock.good() ); + + // sock.clear(); + getline( sock, srv_line ); + + EXAM_CHECK( sock.good() ); + + EXAM_CHECK( srv_line == ::message_rsp ); + } + srv.close(); // close server, so we don't wait server termination on next line srv.wait(); // Wait for server stop to serve clients connections #else Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:27:10 UTC (rev 1621) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:42:23 UTC (rev 1622) @@ -29,47 +29,6 @@ using namespace std; -int EXAM_IMPL(test_client_server_poll_local_ack) -{ -#ifndef __FIT_NO_POLL - try { - // server listen localhost (127.0.0.1), but not listen ext interface: - sockmgr_stream_MP<ConnectionProcessor> srv( 0x7f000001, port ); // start server - - { - EXAM_MESSAGE( "Client start" ); - - std::sockstream sock( "127.0.0.1", ::port ); - string srv_line; - - sock << ::message << endl; - - EXAM_CHECK( sock.good() ); - - // sock.clear(); - getline( sock, srv_line ); - - EXAM_CHECK( sock.good() ); - - EXAM_CHECK( srv_line == ::message_rsp ); - - EXAM_MESSAGE( "Client close connection (client's end of life)" ); - // sock.close(); // no needs, that will done in sock destructor - } - - srv.close(); // close server, so we don't wait server termination on next line - srv.wait(); // Wait for server stop to serve clients connections - } - catch ( std::domain_error& err ) { - EXAM_ERROR( "host not found by name" ); - } -#else - EXAM_ERROR( "poll-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} - int generator_1() { static int i = 0; @@ -210,7 +169,6 @@ t.add( &trivial_sockios_test::listen_iface, trivial_test, "listen_iface", tc[0] ); - t.add( test_client_server_poll_local_ack, "test_client_server_poll_local_ack" ); t.add( test_mass_processing_poll, "test_mass_processing_poll" ); t.add( srv_close_connection_test, "srv_close_connection_test" ); t.add( test_shared_socket, "test_shared_socket" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-07-18 09:49:48
|
Revision: 1623 http://svn.sourceforge.net/complement/?rev=1623&view=rev Author: complement Date: 2007-07-18 02:49:45 -0700 (Wed, 18 Jul 2007) Log Message: ----------- 'mass write' test removed --- it really was not completed and do nothing Modified Paths: -------------- trunk/complement/explore/test/sockios/Makefile.inc trunk/complement/explore/test/sockios/sockios_test_suite.cc Removed Paths: ------------- trunk/complement/explore/test/sockios/client-mw.cc trunk/complement/explore/test/sockios/client-mw.h Modified: trunk/complement/explore/test/sockios/Makefile.inc =================================================================== --- trunk/complement/explore/test/sockios/Makefile.inc 2007-07-18 09:42:23 UTC (rev 1622) +++ trunk/complement/explore/test/sockios/Makefile.inc 2007-07-18 09:49:45 UTC (rev 1623) @@ -1,6 +1,6 @@ # -*- makefile -*- Time-stamp: <07/07/18 08:37:31 ptr> PRGNAME = sockios_ut -SRC_CC = ConnectionProcessor.cc message.cc client-mw.cc \ +SRC_CC = ConnectionProcessor.cc message.cc \ client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc \ names.cc sockios_test.cc sockios_test_suite.cc unit_test.cc Deleted: trunk/complement/explore/test/sockios/client-mw.cc =================================================================== --- trunk/complement/explore/test/sockios/client-mw.cc 2007-07-18 09:42:23 UTC (rev 1622) +++ trunk/complement/explore/test/sockios/client-mw.cc 2007-07-18 09:49:45 UTC (rev 1623) @@ -1,51 +0,0 @@ -// -*- C++ -*- Time-stamp: <05/12/01 20:29:05 ptr> - -/* - * - * Copyright (c) 2002, 2003 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License Version 2.1 - * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - */ - -#include <exam/suite.h> - -#include <string> -#include <sockios/sockstream> -#include <iostream> -#include <iomanip> -#include <mt/xmt.h> - -#include "client-mw.h" -#include "message.h" - -using namespace std; -using namespace xmt; - -int EXAM_IMPL(ClientMassWrite::client_proc) -{ - using namespace test_area; - - EXAM_MESSAGE( "Client start" ); - for ( int i_close = 0; i_close < ni2; ++i_close ) { - std::sockstream sock( "localhost", ::port ); - - for ( int i_send = 0; i_send < ni1; ++i_send ) { - sock.write( bin_buff1, bin_buff1_size ); - } - - EXAM_CHECK( sock.good() ); - } - EXAM_MESSAGE( "Client end" ); - - return EXAM_RESULT; -} Deleted: trunk/complement/explore/test/sockios/client-mw.h =================================================================== --- trunk/complement/explore/test/sockios/client-mw.h 2007-07-18 09:42:23 UTC (rev 1622) +++ trunk/complement/explore/test/sockios/client-mw.h 2007-07-18 09:49:45 UTC (rev 1623) @@ -1,33 +0,0 @@ -// -*- C++ -*- Time-stamp: <05/12/01 20:29:26 ptr> - -/* - * - * Copyright (c) 2002, 2003 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License Version 2.1 - * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - */ - -#ifndef __ClientMassWrite_h -#define __ClientMassWrite_h - -#include <exam/suite.h> - -// Clients simulator - -class ClientMassWrite -{ - public: - static int EXAM_DECL(client_proc); -}; - -#endif // __ClientMassWrite_h Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:42:23 UTC (rev 1622) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:49:45 UTC (rev 1623) @@ -36,34 +36,6 @@ return i++; } -#include "client-mw.h" - -int EXAM_IMPL(test_mass_processing_poll) -{ -#ifndef __FIT_NO_POLL - using namespace test_area; - - EXAM_REQUIRE( bin_buff1_size == 0 ); // test integrity of test suite - EXAM_REQUIRE( bin_buff1 == 0 ); // test integrity of test suite - - bin_buff1_size = 48; - bin_buff1 = new char [bin_buff1_size]; - EXAM_REQUIRE( bin_buff1 != 0 ); - generate_n( bin_buff1, bin_buff1_size, generator_1 ); - - ni1 = 10; - ni2 = 5; - - delete bin_buff1; - bin_buff1 = 0; - bin_buff1_size = 0; -#else - EXAM_ERROR( "poll-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} - int EXAM_IMPL(test_shared_socket) { #ifndef __FIT_NO_POLL @@ -169,7 +141,6 @@ t.add( &trivial_sockios_test::listen_iface, trivial_test, "listen_iface", tc[0] ); - t.add( test_mass_processing_poll, "test_mass_processing_poll" ); t.add( srv_close_connection_test, "srv_close_connection_test" ); t.add( test_shared_socket, "test_shared_socket" ); t.add( test_client_close_socket, "test_client_close_socket" ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-07-18 10:02:05
|
Revision: 1624 http://svn.sourceforge.net/complement/?rev=1624&view=rev Author: complement Date: 2007-07-18 03:02:02 -0700 (Wed, 18 Jul 2007) Log Message: ----------- refine test Modified Paths: -------------- trunk/complement/explore/test/sockios/ConnectionProcessor.cc trunk/complement/explore/test/sockios/ConnectionProcessor.h trunk/complement/explore/test/sockios/sockios_test_suite.cc Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.cc =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 09:49:45 UTC (rev 1623) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 10:02:02 UTC (rev 1624) @@ -261,3 +261,76 @@ { EXAM_MESSAGE_ASYNC( "Server: client close connection" ); } + +int EXAM_IMPL(trivial_sockios_test::shared_socket) +{ +#ifndef __FIT_NO_POLL + sockmgr_stream_MP<ConnectionProcessor2> srv( port ); // start server + + EXAM_CHECK( srv.is_open() ); + EXAM_CHECK( srv.good() ); + + { + EXAM_MESSAGE( "Client start" ); + std::sockstream sock( "localhost", ::port ); + string srv_line; + + sock << ::message << endl; + + EXAM_CHECK( sock.good() ); + + // sock.clear(); + getline( sock, srv_line ); + + EXAM_CHECK( sock.good() ); + + EXAM_CHECK( srv_line == ::message_rsp ); + + EXAM_MESSAGE( "Client close connection (client's end of life)" ); + + { + std::sockstream sock2; + sock2.attach( sock.rdbuf()->fd() ); + + sock2 << ::message1 << endl; + + EXAM_CHECK( sock.good() ); + EXAM_CHECK( sock2.good() ); + + srv_line.clear(); + getline( sock2, srv_line ); + + EXAM_CHECK( sock.good() ); + EXAM_CHECK( sock2.good() ); + + EXAM_CHECK( srv_line == ::message_rsp1 ); + + EXAM_MESSAGE( "Subclient close connection (subclient's end of life)" ); + } + + sock << ::message2 << endl; + + EXAM_CHECK( sock.good() ); + + // sock.clear(); + srv_line.clear(); + getline( sock, srv_line ); + + EXAM_CHECK( sock.good() ); + + EXAM_CHECK( srv_line == ::message_rsp2 ); + + EXAM_MESSAGE( "Client close connection (client's end of life)" ); + + // sock.close(); // no needs, that will done in sock destructor + } + + srv.close(); // close server, so we don't wait server termination on next line + srv.wait(); // Wait for server stop to serve clients connections +#else + EXAM_ERROR( "select-based sockmgr not implemented on this platform" ); +#endif + + return EXAM_RESULT; +} + Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.h =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 09:49:45 UTC (rev 1623) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 10:02:02 UTC (rev 1624) @@ -40,6 +40,7 @@ int EXAM_DECL(simple); int EXAM_DECL(listen_iface); + int EXAM_DECL(shared_socket); private: in_addr hostaddr; Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 09:49:45 UTC (rev 1623) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 10:02:02 UTC (rev 1624) @@ -29,82 +29,6 @@ using namespace std; -int generator_1() -{ - static int i = 0; - - return i++; -} - -int EXAM_IMPL(test_shared_socket) -{ -#ifndef __FIT_NO_POLL - sockmgr_stream_MP<ConnectionProcessor2> srv( port ); // start server - - { - EXAM_MESSAGE( "Client start" ); - std::sockstream sock( "localhost", ::port ); - string srv_line; - - sock << ::message << endl; - - EXAM_CHECK( sock.good() ); - - // sock.clear(); - getline( sock, srv_line ); - - EXAM_CHECK( sock.good() ); - - EXAM_CHECK( srv_line == ::message_rsp ); - - EXAM_MESSAGE( "Client close connection (client's end of life)" ); - - { - std::sockstream sock2; - sock2.attach( sock.rdbuf()->fd() ); - - sock2 << ::message1 << endl; - - EXAM_CHECK( sock.good() ); - EXAM_CHECK( sock2.good() ); - - srv_line.clear(); - getline( sock2, srv_line ); - - EXAM_CHECK( sock.good() ); - EXAM_CHECK( sock2.good() ); - - EXAM_CHECK( srv_line == ::message_rsp1 ); - - EXAM_MESSAGE( "Subclient close connection (subclient's end of life)" ); - } - - sock << ::message2 << endl; - - EXAM_CHECK( sock.good() ); - - // sock.clear(); - srv_line.clear(); - getline( sock, srv_line ); - - EXAM_CHECK( sock.good() ); - - EXAM_CHECK( srv_line == ::message_rsp2 ); - - EXAM_MESSAGE( "Client close connection (client's end of life)" ); - - // sock.close(); // no needs, that will done in sock destructor - } - - srv.close(); // close server, so we don't wait server termination on next line - srv.wait(); // Wait for server stop to serve clients connections -#else - EXAM_ERROR( "select-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} - int EXAM_DECL(test_client_close_socket); int EXAM_DECL(test_more_bytes_in_socket); int EXAM_DECL(test_more_bytes_in_socket2); @@ -139,10 +63,10 @@ // Old tests - t.add( &trivial_sockios_test::listen_iface, trivial_test, "listen_iface", tc[0] ); + t.add( &trivial_sockios_test::listen_iface, trivial_test, "trivial_sockios_test::listen_iface", tc[0] ); t.add( srv_close_connection_test, "srv_close_connection_test" ); - t.add( test_shared_socket, "test_shared_socket" ); + t.add( &trivial_sockios_test::shared_socket, trivial_test, "trivial_sockios_test::shared_socket", tc[0] ); t.add( test_client_close_socket, "test_client_close_socket" ); t.add( test_more_bytes_in_socket, "test_more_bytes_in_socket" ); // timeout 5 t.add( test_more_bytes_in_socket2, "test_more_bytes_in_socket2" ); // timeout 5 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <com...@us...> - 2007-07-18 20:32:36
|
Revision: 1631 http://svn.sourceforge.net/complement/?rev=1631&view=rev Author: complement Date: 2007-07-18 13:32:22 -0700 (Wed, 18 Jul 2007) Log Message: ----------- refine tests Modified Paths: -------------- trunk/complement/explore/test/sockios/ConnectionProcessor.cc trunk/complement/explore/test/sockios/ConnectionProcessor.h trunk/complement/explore/test/sockios/Makefile.inc trunk/complement/explore/test/sockios/sockios_test_suite.cc Removed Paths: ------------- trunk/complement/explore/test/sockios/client-wc.cc trunk/complement/explore/test/sockios/client-wc.h trunk/complement/explore/test/sockios/close_socket.cc Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.cc =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.cc 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/18 10:17:29 ptr> +// -*- C++ -*- Time-stamp: <07/07/18 23:10:22 ptr> /* * @@ -17,7 +17,10 @@ #include <sockios/sockmgr.h> +#include <mt/xmt.h> + using namespace std; +using namespace xmt; ConnectionProcessor::ConnectionProcessor( std::sockstream& s ) { @@ -334,3 +337,237 @@ return EXAM_RESULT; } +/* ****************** + * + * Check correct processing of case when server close connection. + * Suspicious processing with FreeBSD and OpenBSD servers. + * + */ +static condition cnd_close; + +class Srv // +{ + public: + Srv( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); +}; + +Srv::Srv( std::sockstream& s ) +{ + s << "hello" << endl; + + // xmt::delay( xmt::timespec( 1, 0 ) ); + + s.close(); + // ::shutdown( s.rdbuf()->fd(), 2 ); + cnd_close.set( true ); +} + +void Srv::connect( std::sockstream& ) +{ +} + +void Srv::close() +{ +} + +#ifndef __FIT_NO_POLL +typedef sockmgr_stream_MP<Srv> srv_type; +#elif defined(__FIT_NO_SELECT) +typedef sockmgr_stream_MP_SELECT<Srv> srv_type; +#else +# error Either poll or select should be present! +#endif + +static srv_type *srv_p; +condition cnd; + +Thread::ret_code server_proc( void * ) +{ + Thread::ret_code rt; + rt.iword = 0; + + cnd.set( false ); + srv_type srv( port ); // start server + + ::srv_p = &srv; + + if ( !srv.is_open() || !srv.good() ) { + ++rt.iword; + } + + cnd.set( true ); + + srv.wait(); + + return rt; +} + +Thread::ret_code client_proc( void * ) +{ + Thread::ret_code rt; + rt.iword = 0; + + cnd.try_wait(); + + EXAM_MESSAGE_ASYNC( "Client start" ); + std::sockstream sock( "localhost", ::port ); + + string buf; + + getline( sock, buf ); + + if ( !sock.is_open() || !sock.good() ) { + ++rt.iword; + } + + EXAM_CHECK_ASYNC( buf == "hello" ); + + // xmt::delay( xmt::timespec( 5, 0 ) ); + + // sock << 'a' << endl; + + /* + read required here, due to we can see FIN packet only on read, + and no other solution! (another solution is nonblock sockets or + aio, but this is another story) + */ + cnd_close.try_wait(); + + char a; + sock.read( &a, 1 ); + + EXAM_CHECK_ASYNC( !sock.good() ); + + srv_p->close(); + + EXAM_MESSAGE_ASYNC( "Client end" ); + + return rt; +} + +int EXAM_IMPL(trivial_sockios_test::srv_close_connection) +{ + Thread srv( server_proc ); + cnd_close.set( false ); + Thread client( client_proc ); + + EXAM_CHECK( client.join().iword == 0 ); + EXAM_CHECK( srv.join().iword == 0 ); + + return EXAM_RESULT; +} + +/* + * Server listen tcp socket; client connect to server and try to read + * what server write to socket; server don't write anything, but we + * try to close connection (close socket on client's side, but from + * differrent thread from reading socket). + * I suspect that closing socket on client side don't lead to break down + * through read call. + */ + +class ConnectionProcessor3 // dummy variant +{ + public: + ConnectionProcessor3( std::sockstream& ); + + void connect( std::sockstream& ); + void close(); +}; + +ConnectionProcessor3::ConnectionProcessor3( std::sockstream& s ) +{ + EXAM_MESSAGE_ASYNC( "Server seen connection" ); + + EXAM_CHECK_ASYNC( s.good() ); + connect( s ); + // cerr << "Server see connection\n"; // Be silent, avoid interference + // with Input line prompt +} + +void ConnectionProcessor3::connect( std::sockstream& s ) +{ + EXAM_MESSAGE_ASYNC( "Server start connection processing" ); + + EXAM_CHECK_ASYNC( s.good() ); + + // string msg; + + // getline( s, msg ); + char c = '1'; + s.write( &c, 1 ); + s.flush(); + // cnd2.set( true ); + // EXAM_CHECK_EQUAL( msg, ::message ); + EXAM_CHECK_ASYNC( s.good() ); + + // s << ::message_rsp << endl; // server's response + + // BOOST_REQUIRE( s.good() ); + EXAM_MESSAGE_ASYNC( "Server stop connection processing" ); + + return; +} + +void ConnectionProcessor3::close() +{ + EXAM_MESSAGE_ASYNC( "Server: client close connection" ); +} + +std::sockstream *psock = 0; + +Thread::ret_code thread_entry_call( void * ) +{ + Thread::ret_code rt; + rt.iword = 0; + + cnd.set( true ); + + EXAM_MESSAGE_ASYNC( "Client start" ); + + EXAM_CHECK_ASYNC( psock->good() ); + + char c = '0'; + psock->read( &c, 1 ); + EXAM_CHECK_ASYNC( c == '1' ); + cnd_close.set( true ); + psock->read( &c, 1 ); + + return rt; +} + +int EXAM_IMPL(trivial_sockios_test::client_close_socket) +{ +#ifndef __FIT_NO_POLL + sockmgr_stream_MP<ConnectionProcessor3> srv( port ); // start server + + cnd.set( false ); + cnd_close.set( false ); + + // open client's socket _before_ thread launch to demonstrate problem with + // socket close (close socket's descriptor in one thread don't lead to real + // shutdown events if socket in use in another thread) + psock = new std::sockstream( "localhost", ::port ); + xmt::Thread thr( thread_entry_call ); + cnd.try_wait(); + // close socket; you may expect that sock.read break down, but this + // will not happens: this thread has one copy of (psock) file descriptor, + // thread_entry_call has another; we close only one + cnd_close.try_wait(); + // but call shutdown is what you want here: + psock->rdbuf()->shutdown( sock_base::stop_in | sock_base::stop_out ); + psock->close(); + thr.join(); + delete psock; + + srv.close(); // close server, so we don't wait server termination on next line + srv.wait(); // Wait for server stop to serve clients connections +#else + EXAM_ERROR( "select-based sockmgr not implemented on this platform" ); +#endif + + return EXAM_RESULT; +} Modified: trunk/complement/explore/test/sockios/ConnectionProcessor.h =================================================================== --- trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/ConnectionProcessor.h 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/18 10:08:07 ptr> +// -*- C++ -*- Time-stamp: <07/07/19 00:16:00 ptr> /* * @@ -42,6 +42,9 @@ int EXAM_DECL(listen_iface); int EXAM_DECL(shared_socket); + int EXAM_DECL(srv_close_connection); + int EXAM_DECL(client_close_socket); + private: in_addr hostaddr; // sockaddr hostaddr; Modified: trunk/complement/explore/test/sockios/Makefile.inc =================================================================== --- trunk/complement/explore/test/sockios/Makefile.inc 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/Makefile.inc 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,6 +1,6 @@ -# -*- makefile -*- Time-stamp: <07/07/18 08:37:31 ptr> +# -*- makefile -*- Time-stamp: <07/07/19 00:16:55 ptr> PRGNAME = sockios_ut SRC_CC = ConnectionProcessor.cc message.cc \ - client-wc.cc close_socket.cc bytes_in_socket.cc bytes_in_socket2.cc \ + bytes_in_socket.cc bytes_in_socket2.cc \ names.cc sockios_test.cc sockios_test_suite.cc unit_test.cc Deleted: trunk/complement/explore/test/sockios/client-wc.cc =================================================================== --- trunk/complement/explore/test/sockios/client-wc.cc 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/client-wc.cc 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,146 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/07/18 08:46:23 ptr> - -/* - * Copyright (c) 2004, 2006, 2007 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License Version 3.0 - * - */ - -#include <exam/suite.h> - -#include <string> -#include <sockios/sockstream> -#include <sockios/sockmgr.h> -#include <iostream> -#include <iomanip> -#include <mt/xmt.h> - -#include "client-wc.h" -#include "message.h" - -using namespace std; -using namespace xmt; - -/* - Check correct processing of case when server close connection. - Suspicious processing with FreeBSD and OpenBSD servers. - - */ -static condition cnd_close; - -class Srv // -{ - public: - Srv( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -Srv::Srv( std::sockstream& s ) -{ - s << "hello" << endl; - - // xmt::delay( xmt::timespec( 1, 0 ) ); - - s.close(); - // ::shutdown( s.rdbuf()->fd(), 2 ); - cnd_close.set( true ); -} - -void Srv::connect( std::sockstream& ) -{ -} - -void Srv::close() -{ -} - -#ifndef __FIT_NO_POLL -typedef sockmgr_stream_MP<Srv> srv_type; -#elif defined(__FIT_NO_SELECT) -typedef sockmgr_stream_MP_SELECT<Srv> srv_type; -#else -# error Either poll or select should be present! -#endif - -static srv_type *srv_p; -condition cnd; - -Thread::ret_code server_proc( void * ) -{ - Thread::ret_code rt; - rt.iword = 0; - - cnd.set( false ); - srv_type srv( port ); // start server - - ::srv_p = &srv; - - if ( !srv.is_open() || !srv.good() ) { - ++rt.iword; - } - - cnd.set( true ); - - srv.wait(); - - return rt; -} - -Thread::ret_code client_proc( void * ) -{ - Thread::ret_code rt; - rt.iword = 0; - - cnd.try_wait(); - - EXAM_MESSAGE_ASYNC( "Client start" ); - std::sockstream sock( "localhost", ::port ); - - string buf; - - getline( sock, buf ); - - if ( !sock.is_open() || !sock.good() ) { - ++rt.iword; - } - - EXAM_CHECK_ASYNC( buf == "hello" ); - - // xmt::delay( xmt::timespec( 5, 0 ) ); - - // sock << 'a' << endl; - - /* - read required here, due to we can see FIN packet only on read, - and no other solution! (another solution is nonblock sockets or - aio, but this is another story) - */ - cnd_close.try_wait(); - - char a; - sock.read( &a, 1 ); - - EXAM_CHECK_ASYNC( !sock.good() ); - - srv_p->close(); - - EXAM_MESSAGE_ASYNC( "Client end" ); - - return rt; -} - -int EXAM_IMPL(srv_close_connection_test) -{ - Thread srv( server_proc ); - cnd_close.set( false ); - Thread client( client_proc ); - - EXAM_CHECK( client.join().iword == 0 ); - EXAM_CHECK( srv.join().iword == 0 ); - - return EXAM_RESULT; -} Deleted: trunk/complement/explore/test/sockios/client-wc.h =================================================================== --- trunk/complement/explore/test/sockios/client-wc.h 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/client-wc.h 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,19 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/07/18 09:20:14 ptr> - -/* - * - * Copyright (c) 2004, 2007 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License version 3.0 - * - */ - -#ifndef __client_wc_h -#define __client_wc_h - -#include <exam/suite.h> - -int EXAM_DECL(srv_close_connection_test); - -#endif // __client_wc_h Deleted: trunk/complement/explore/test/sockios/close_socket.cc =================================================================== --- trunk/complement/explore/test/sockios/close_socket.cc 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/close_socket.cc 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,148 +0,0 @@ -// -*- C++ -*- Time-stamp: <07/07/11 21:34:53 ptr> - -/* - * - * Copyright (c) 2006 - * Petr Ovtchenkov - * - * Licensed under the Academic Free License Version 2.1 - * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - */ - -#include <exam/suite.h> - -#include <iostream> -#include <list> -#include <mt/xmt.h> - -#include <sockios/sockstream> -#include <sockios/sockmgr.h> - -using namespace std; -using namespace xmt; - -/* - * Server listen tcp socket; client connect to server and try to read - * what server write to socket; server don't write anything, but we - * try to close connection (close socket on client's side, but from - * differrent thread from reading socket). - * I suspect that closing socket on client side don't lead to break down - * through read call. - */ - -extern int port; - -class ConnectionProcessor3 // dummy variant -{ - public: - ConnectionProcessor3( std::sockstream& ); - - void connect( std::sockstream& ); - void close(); -}; - -ConnectionProcessor3::ConnectionProcessor3( std::sockstream& s ) -{ - EXAM_MESSAGE_ASYNC( "Server seen connection" ); - - EXAM_CHECK_ASYNC( s.good() ); - connect( s ); - // cerr << "Server see connection\n"; // Be silent, avoid interference - // with Input line prompt -} - -condition cnd2; - -void ConnectionProcessor3::connect( std::sockstream& s ) -{ - EXAM_MESSAGE_ASYNC( "Server start connection processing" ); - - EXAM_CHECK_ASYNC( s.good() ); - - // string msg; - - // getline( s, msg ); - char c = '1'; - s.write( &c, 1 ); - s.flush(); - // cnd2.set( true ); - // EXAM_CHECK_EQUAL( msg, ::message ); - EXAM_CHECK_ASYNC( s.good() ); - - // s << ::message_rsp << endl; // server's response - - // BOOST_REQUIRE( s.good() ); - EXAM_MESSAGE_ASYNC( "Server stop connection processing" ); - - return; -} - -void ConnectionProcessor3::close() -{ - EXAM_MESSAGE_ASYNC( "Server: client close connection" ); -} - -condition cnd1; -// Condition cnd2; -std::sockstream *psock = 0; - -Thread::ret_code thread_entry_call( void * ) -{ - Thread::ret_code rt; - rt.iword = 0; - - cnd1.set( true ); - - EXAM_MESSAGE_ASYNC( "Client start" ); - - EXAM_CHECK_ASYNC( psock->good() ); - - char c = '0'; - psock->read( &c, 1 ); - EXAM_CHECK_ASYNC( c == '1' ); - cnd2.set( true ); - psock->read( &c, 1 ); - - return rt; -} - -int EXAM_IMPL(test_client_close_socket) -{ -#ifndef __FIT_NO_POLL - sockmgr_stream_MP<ConnectionProcessor3> srv( port ); // start server - - cnd1.set( false ); - cnd2.set( false ); - - // open client's socket _before_ thread launch to demonstrate problem with - // socket close (close socket's descriptor in one thread don't lead to real - // shutdown events if socket in use in another thread) - psock = new std::sockstream( "localhost", ::port ); - xmt::Thread thr( thread_entry_call ); - cnd1.try_wait(); - // close socket; you may expect that sock.read break down, but this - // will not happens: this thread has one copy of (psock) file descriptor, - // thread_entry_call has another; we close only one - cnd2.try_wait(); - // but call shutdown is what you want here: - psock->rdbuf()->shutdown( sock_base::stop_in | sock_base::stop_out ); - psock->close(); - thr.join(); - delete psock; - - srv.close(); // close server, so we don't wait server termination on next line - srv.wait(); // Wait for server stop to serve clients connections -#else - EXAM_ERROR( "select-based sockmgr not implemented on this platform" ); -#endif - - return EXAM_RESULT; -} Modified: trunk/complement/explore/test/sockios/sockios_test_suite.cc =================================================================== --- trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 16:31:53 UTC (rev 1630) +++ trunk/complement/explore/test/sockios/sockios_test_suite.cc 2007-07-18 20:32:22 UTC (rev 1631) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <07/07/18 10:23:40 ptr> +// -*- C++ -*- Time-stamp: <07/07/19 00:19:19 ptr> /* * @@ -25,11 +25,8 @@ #include "ConnectionProcessor.h" -#include "client-wc.h" - using namespace std; -int EXAM_DECL(test_client_close_socket); int EXAM_DECL(test_more_bytes_in_socket); int EXAM_DECL(test_more_bytes_in_socket2); @@ -65,9 +62,9 @@ t.add( &trivial_sockios_test::listen_iface, trivial_test, "trivial_sockios_test::listen_iface", tc[0] ); - t.add( srv_close_connection_test, "srv_close_connection_test" ); + t.add( &trivial_sockios_test::srv_close_connection, trivial_test, "trivial_sockios_test::srv_close_connection", tc[0] ); t.add( &trivial_sockios_test::shared_socket, trivial_test, "trivial_sockios_test::shared_socket", tc[0] ); - t.add( test_client_close_socket, "test_client_close_socket" ); + t.add( &trivial_sockios_test::client_close_socket, trivial_test, "trivial_sockios_test::client_close_socket", tc[0] ); t.add( test_more_bytes_in_socket, "test_more_bytes_in_socket" ); // timeout 5 t.add( test_more_bytes_in_socket2, "test_more_bytes_in_socket2" ); // timeout 5 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |