Author: tabish
Date: Tue Apr 27 21:41:24 2010
New Revision: 938679
URL: http://svn.apache.org/viewvc?rev=938679&view=rev
Log:
Adds new Socket tests, fixes some socket options handling
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.cpp
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.h
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
URL:
http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp?rev=938679&r1=938678&r2=938679&view=diff
==============================================================================
---
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
(original)
+++
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.cpp
Tue Apr 27 21:41:24 2010
@@ -69,7 +69,8 @@ TcpSocket::TcpSocket() throw ( SocketExc
outputShutdown( false ),
closed( false ),
trafficClass( 0 ),
- soTimeout( -1 ) {
+ soTimeout( -1 ),
+ soLinger( -1 ) {
}
////////////////////////////////////////////////////////////////////////////////
@@ -153,12 +154,50 @@ void TcpSocket::accept( SocketImpl* sock
////////////////////////////////////////////////////////////////////////////////
InputStream* TcpSocket::getInputStream() throw( IOException ) {
- return inputStream;
+
+ if( this->socketHandle == NULL || this->closed ) {
+ throw IOException( __FILE__, __LINE__, "The Socket is not Connected."
);
+ }
+
+ if( this->inputShutdown ) {
+ throw IOException( __FILE__, __LINE__, "Input has been shut down on
this Socket." );
+ }
+
+ try{
+
+ if( this->inputStream == NULL ) {
+ this->inputStream = new TcpSocketInputStream( this );
+ }
+
+ return inputStream;
+ }
+ DECAF_CATCH_RETHROW( decaf::io::IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
+ DECAF_CATCHALL_THROW( decaf::io::IOException )
}
////////////////////////////////////////////////////////////////////////////////
OutputStream* TcpSocket::getOutputStream() throw( IOException ) {
- return outputStream;
+
+ if( this->socketHandle == NULL || this->closed ) {
+ throw IOException( __FILE__, __LINE__, "The Socket is not Connected."
);
+ }
+
+ if( this->outputShutdown ) {
+ throw IOException( __FILE__, __LINE__, "Output has been shut down on
this Socket." );
+ }
+
+ try{
+
+ if( this->outputStream == NULL ) {
+ this->outputStream = new TcpSocketOutputStream( this );
+ }
+
+ return outputStream;
+ }
+ DECAF_CATCH_RETHROW( decaf::io::IOException )
+ DECAF_CATCH_EXCEPTION_CONVERT( Exception, decaf::io::IOException )
+ DECAF_CATCHALL_THROW( decaf::io::IOException )
}
////////////////////////////////////////////////////////////////////////////////
@@ -255,10 +294,6 @@ void TcpSocket::connect( const std::stri
apr_socket_opt_set( socketHandle, APR_SO_NONBLOCK, oldNonblockSetting
);
apr_socket_timeout_set( socketHandle, oldTimeoutSetting );
- // Create an input/output stream for this socket.
- inputStream = new TcpSocketInputStream( this );
- outputStream = new TcpSocketOutputStream( this );
-
} catch( IOException& ex ) {
ex.setMark( __FILE__, __LINE__);
try{ close(); } catch( lang::Exception& cx){ /* Absorb */ }
@@ -456,6 +491,18 @@ int TcpSocket::getOption( int option ) c
apr_interval_time_t tvalue = 0;
checkResult( apr_socket_timeout_get( socketHandle, &tvalue ) );
return (int)( tvalue / 1000 );
+ } else if( option == SocketOptions::SOCKET_OPTION_LINGER ) {
+
+ checkResult( apr_socket_opt_get( socketHandle, APR_SO_LINGER,
&value ) );
+
+ // In case the socket linger is on by default we reset to match,
+ // we just use one since we really don't know what the linger time
is
+ // with APR.
+ if( value == 1 && this->soLinger == -1 ) {
+ this->soLinger = 1;
+ }
+
+ return this->soLinger;
}
if( option == SocketOptions::SOCKET_OPTION_REUSEADDR ) {
@@ -464,6 +511,10 @@ int TcpSocket::getOption( int option ) c
aprId = APR_SO_SNDBUF;
} else if( option == SocketOptions::SOCKET_OPTION_RCVBUF ) {
aprId = APR_SO_RCVBUF;
+ } else if( option == SocketOptions::SOCKET_OPTION_TCP_NODELAY ) {
+ aprId = APR_TCP_NODELAY;
+ } else if( option == SocketOptions::SOCKET_OPTION_KEEPALIVE ) {
+ aprId = APR_SO_KEEPALIVE;
} else {
throw IOException(
__FILE__, __LINE__,
@@ -496,6 +547,15 @@ void TcpSocket::setOption( int option, i
checkResult( apr_socket_timeout_set( socketHandle, value * 1000 )
);
this->soTimeout = value;
return;
+ } else if( option == SocketOptions::SOCKET_OPTION_LINGER ) {
+
+ // Store the real setting for later.
+ this->soLinger = value;
+
+ // Now use the APR API to set it to the boolean state that APR
expects
+ value = value <= 0 ? 0 : 1;
+ checkResult( apr_socket_opt_set( socketHandle, APR_SO_LINGER,
(apr_int32_t)value ) );
+ return;
}
if( option == SocketOptions::SOCKET_OPTION_REUSEADDR ) {
@@ -504,6 +564,10 @@ void TcpSocket::setOption( int option, i
aprId = APR_SO_SNDBUF;
} else if( option == SocketOptions::SOCKET_OPTION_RCVBUF ) {
aprId = APR_SO_RCVBUF;
+ } else if( option == SocketOptions::SOCKET_OPTION_TCP_NODELAY ) {
+ aprId = APR_TCP_NODELAY;
+ } else if( option == SocketOptions::SOCKET_OPTION_KEEPALIVE ) {
+ aprId = APR_SO_KEEPALIVE;
} else {
throw IOException(
__FILE__, __LINE__,
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
URL:
http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h?rev=938679&r1=938678&r2=938679&view=diff
==============================================================================
---
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
(original)
+++
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/tcp/TcpSocket.h
Tue Apr 27 21:41:24 2010
@@ -113,6 +113,12 @@ namespace tcp {
*/
int soTimeout;
+ /**
+ * value of soLinger, used to return a meaningful answer since APR
+ * only returns the on / off state.
+ */
+ mutable int soLinger;
+
public:
/**
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.cpp
URL:
http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.cpp?rev=938679&r1=938678&r2=938679&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.cpp
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.cpp
Tue Apr 27 21:41:24 2010
@@ -67,6 +67,120 @@ void SocketTest::testGetReuseAddress() {
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Socket Reuse Address value not what was
expected.", false, s.getReuseAddress() );
}
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testClose() {
+
+ ServerSocket ss(0);
+ Socket client( "localhost", ss.getLocalPort() );
+
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE( "Exception on setSoLinger unexpected",
client.setSoLinger( false, 100 ) );
+
+ client.close();
+
+ CPPUNIT_ASSERT_THROW_MESSAGE(
+ "Should have thrown an IOException",
+ client.getOutputStream(),
+ IOException );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetInputStream() {
+
+ ServerSocket ss(0);
+ Socket client( "localhost", ss.getLocalPort() );
+
+ InputStream* is = client.getInputStream();
+
+ CPPUNIT_ASSERT( is != NULL );
+
+ is->close();
+ client.close();
+ ss.close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetKeepAlive() {
+
+ try {
+
+ ServerSocket ss(0);
+ Socket client( "localhost", ss.getLocalPort() );
+
+ client.setKeepAlive( true );
+
+ CPPUNIT_ASSERT_MESSAGE( "getKeepAlive false when it should be true",
+ client.getKeepAlive() );
+
+ client.setKeepAlive( false );
+
+ CPPUNIT_ASSERT_MESSAGE( "getKeepAlive true when it should be False",
+ !client.getKeepAlive() );
+
+ } catch (Exception e) {
+ CPPUNIT_FAIL( "Error during test of Get SO_KEEPALIVE" );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetLocalPort() {
+
+ ServerSocket server(0);
+ Socket client( "localhost", server.getLocalPort() );
+
+ CPPUNIT_ASSERT_MESSAGE( "Returned incorrect port", 0 !=
client.getLocalPort() );
+
+ client.close();
+ server.close();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetSoLinger() {
+
+ try {
+
+ ServerSocket ss(0);
+ Socket client( "localhost", ss.getLocalPort() );
+
+ client.setSoLinger( true, 100 );
+
+ CPPUNIT_ASSERT_MESSAGE( "getSoLinger returned incorrect value",
+ 100 == client.getSoLinger() );
+
+ client.setSoLinger( false, 100 );
+
+ CPPUNIT_ASSERT_MESSAGE( "getSoLinger returned incorrect value",
+ -1 == client.getSoLinger() );
+
+ } catch (Exception e) {
+ CPPUNIT_FAIL( "Error during test of Get SO_LINGER" );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetSoTimeout() {
+
+ ServerSocket server(0);
+ Socket client( "localhost", server.getLocalPort() );
+
+ client.setSoTimeout( 100 );
+ CPPUNIT_ASSERT_MESSAGE( "Returned incorrect timeout", 100 ==
client.getSoTimeout() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void SocketTest::testGetTcpNoDelay() {
+
+ ServerSocket server(0);
+ Socket client( "localhost", server.getLocalPort() );
+
+ client.setTcpNoDelay( true );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Returned incorrect TCP_NODELAY value,
should be true",
+ true, client.getTcpNoDelay() );
+
+ client.setTcpNoDelay( false );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Returned incorrect TCP_NODELAY value,
should be false",
+ false, client.getTcpNoDelay() );
+}
+
// TODO - Remove or replace old tests
////////////////////////////////////////////////////////////////////////////////
@@ -234,6 +348,7 @@ void SocketTest::testTx() {
client->connect("127.0.0.1", port);
client->setSoLinger( false, 0 );
+ client->setTcpNoDelay( true );
synchronized(&serverThread.mutex)
{
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.h
URL:
http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.h?rev=938679&r1=938678&r2=938679&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.h
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/net/SocketTest.h
Tue Apr 27 21:41:24 2010
@@ -30,10 +30,18 @@ namespace net{
CPPUNIT_TEST( testConnectUnknownHost );
CPPUNIT_TEST( testConstructor );
CPPUNIT_TEST( testGetReuseAddress );
-// CPPUNIT_TEST( testTx );
-// CPPUNIT_TEST( testTrx );
-// CPPUNIT_TEST( testTrxNoDelay );
-// CPPUNIT_TEST( testRxFail );
+ CPPUNIT_TEST( testClose );
+ CPPUNIT_TEST( testGetInputStream );
+ CPPUNIT_TEST( testGetKeepAlive );
+ CPPUNIT_TEST( testGetLocalPort );
+ CPPUNIT_TEST( testGetSoLinger );
+ CPPUNIT_TEST( testGetSoTimeout );
+ CPPUNIT_TEST( testGetTcpNoDelay );
+
+ CPPUNIT_TEST( testTx );
+ CPPUNIT_TEST( testTrx );
+ CPPUNIT_TEST( testTrxNoDelay );
+ CPPUNIT_TEST( testRxFail );
CPPUNIT_TEST_SUITE_END();
public:
@@ -47,6 +55,13 @@ namespace net{
void testConnectUnknownHost();
void testConstructor();
void testGetReuseAddress();
+ void testClose();
+ void testGetInputStream();
+ void testGetKeepAlive();
+ void testGetLocalPort();
+ void testGetSoLinger();
+ void testGetSoTimeout();
+ void testGetTcpNoDelay();
// Old Tests
void testConnect();