]>
git.saurik.com Git - wxWidgets.git/blob - tests/streams/socketstream.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/streams/socketstream.cpp
3 // Purpose: Test wxSocketInputStream/wxSocketOutputStream
4 // Author: Vadim Zeitlin
5 // Copyright: (c) 2008 Vadim Zeitlin
6 // Licence: wxWindows licence
7 ///////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx/wx.h".
17 // for all others, include the necessary headers
22 #include "wx/socket.h"
23 #include "wx/sckstrm.h"
24 #include "wx/thread.h"
31 const int TEST_PORT_READ
= 0x7778; // arbitrary, chosen because == "wx"
32 const int TEST_PORT_WRITE
= 0x7779; // well, "wy"
34 // these cond and mutex are used to minimize the risk of the main thread
35 // Connect()-ing before this thread starts Accept()-ing connections but
36 // unfortunately we can't make this truly safe, see comment in
37 // SocketServerThread::Entry()
39 wxCondition
gs_cond(gs_mutex
);
40 } // anonymous namespace
42 // return address for the given port on local host
43 static inline wxIPV4address
LocalAddress(int port
)
52 // A thread which creates a listening socket on the specified port and executes
53 // the given function with each socket which connects to it
54 class SocketServerThread
: public wxThread
57 // port is the port to listen on and function will be called on each
59 SocketServerThread(int port
, void (*accept
)(wxSocketBase
&))
60 : wxThread(wxTHREAD_JOINABLE
),
71 wxSocketServer
srv(LocalAddress(m_port
), wxSOCKET_REUSEADDR
);
73 // FIXME: this is still not atomic, of course and the main thread could
74 // call Connect() before we have time to Accept() but there is
75 // no way to fix it with current API
77 wxMutexLocker
lock(gs_mutex
);
81 wxSocketBase
*socket
= srv
.Accept();
92 void (*m_accept
)(wxSocketBase
&);
94 DECLARE_NO_COPY_CLASS(SocketServerThread
)
97 // The test case for socket streams
99 public BaseStreamTestCase
<wxSocketInputStream
, wxSocketOutputStream
>
103 virtual ~socketStream();
105 virtual void setUp();
106 virtual void tearDown();
108 // repeat all socket tests several times with different socket flags, so we
109 // define this macro which is used several times in the test suite
111 // there must be some more elegant way to do this but I didn't find it...
112 #define ALL_SOCKET_TESTS() \
113 CPPUNIT_TEST(Input_GetC); \
114 CPPUNIT_TEST(Input_Eof); \
115 CPPUNIT_TEST(Input_Read); \
116 CPPUNIT_TEST(Input_LastRead); \
117 CPPUNIT_TEST(Input_CanRead); \
118 CPPUNIT_TEST(Input_Peek); \
119 CPPUNIT_TEST(Input_Ungetch); \
121 CPPUNIT_TEST(Output_PutC); \
122 CPPUNIT_TEST(Output_Write); \
123 CPPUNIT_TEST(Output_LastWrite)
125 CPPUNIT_TEST_SUITE(socketStream
);
127 // some tests don't pass with NOWAIT flag but this is probably not a
128 // bug (TODO: check this)
130 CPPUNIT_TEST( PseudoTest_SetNoWait
);
133 CPPUNIT_TEST( PseudoTest_SetWaitAll
);
135 CPPUNIT_TEST_SUITE_END();
138 // Implement base class functions.
139 virtual wxSocketInputStream
*DoCreateInStream();
140 virtual wxSocketOutputStream
*DoCreateOutStream();
142 // socket thread functions
143 static void WriteSocket(wxSocketBase
& socket
)
145 socket
.Write("hello, world!", 13);
148 static void ReadSocket(wxSocketBase
& socket
)
151 while ( socket
.Read(&ch
, 1).LastCount() == 1 )
155 void PseudoTest_SetNoWait() { ms_flags
= wxSOCKET_NOWAIT
; }
156 void PseudoTest_SetWaitAll() { ms_flags
= wxSOCKET_WAITALL
; }
158 wxSocketClient
*m_readSocket
,
160 wxThread
*m_writeThread
,
163 static wxSocketFlags ms_flags
;
166 wxSocketFlags
socketStream::ms_flags
= wxSOCKET_NONE
;
168 socketStream::socketStream()
171 m_writeSocket
= NULL
;
176 wxSocketBase::Initialize();
179 socketStream::~socketStream()
181 wxSocketBase::Shutdown();
184 void socketStream::setUp()
186 // create the socket threads and wait until they are ready to accept
187 // connections (if we called Connect() before this happens, it would fail)
189 wxMutexLocker
lock(gs_mutex
);
192 new SocketServerThread(TEST_PORT_READ
, &socketStream::WriteSocket
);
193 CPPUNIT_ASSERT_EQUAL( wxCOND_NO_ERROR
, gs_cond
.Wait() );
196 new SocketServerThread(TEST_PORT_WRITE
, &socketStream::ReadSocket
);
197 CPPUNIT_ASSERT_EQUAL( wxCOND_NO_ERROR
, gs_cond
.Wait() );
200 m_readSocket
= new wxSocketClient(ms_flags
);
201 CPPUNIT_ASSERT( m_readSocket
->Connect(LocalAddress(TEST_PORT_READ
)) );
203 m_writeSocket
= new wxSocketClient(ms_flags
);
204 CPPUNIT_ASSERT( m_writeSocket
->Connect(LocalAddress(TEST_PORT_WRITE
)) );
207 void socketStream::tearDown()
209 wxDELETE(m_readSocket
);
210 wxDELETE(m_writeSocket
);
212 m_writeThread
->Wait();
213 wxDELETE(m_writeThread
);
215 m_readThread
->Wait();
216 wxDELETE(m_readThread
);
219 wxSocketInputStream
*socketStream::DoCreateInStream()
221 wxSocketInputStream
*pStrInStream
= new wxSocketInputStream(*m_readSocket
);
222 CPPUNIT_ASSERT(pStrInStream
->IsOk());
226 wxSocketOutputStream
*socketStream::DoCreateOutStream()
228 wxSocketOutputStream
*pStrOutStream
= new wxSocketOutputStream(*m_writeSocket
);
229 CPPUNIT_ASSERT(pStrOutStream
->IsOk());
230 return pStrOutStream
;
233 // Register the stream sub suite, by using some stream helper macro.
234 STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(socketStream
)